buffer.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. #ifndef BUFFER_H
  2. #define BUFFER_H
  3. struct buffer {
  4. DA_DEF_STRUCT_ITEM(char, data);
  5. size_t cur;
  6. };
  7. enum buffer_err {
  8. BUFFER_ERR_OK = 0,
  9. BUFFER_ERR_EMPTY,
  10. BUFFER_ERR_NOT_FOUND,
  11. BUFFER_ERR_INVALID_CUR_POS,
  12. BUFFER_ERR_FAIL_READ_FILE,
  13. BUFFER_ERR_START_GT_END,
  14. BUFFER_ERR_INVALID_END_SIZE,
  15. };
  16. struct ret_buffer_err {
  17. struct buffer f1;
  18. enum buffer_err f2;
  19. };
  20. struct ret_size_t_err {
  21. size_t f1;
  22. enum buffer_err f2;
  23. };
  24. struct ret_buffer_size_t_err {
  25. struct buffer f1;
  26. size_t f2;
  27. enum buffer_err f3;
  28. };
  29. struct buffer buffer_create(void);
  30. void buffer_destroy(struct buffer buf);
  31. struct ret_buffer_err buffer_load_from_file(struct buffer buf,
  32. const char *filepath);
  33. enum buffer_err buffer_save_to_file(struct buffer buf, const char *filepath);
  34. struct buffer buffer_mv_cur_left(struct buffer buf);
  35. struct buffer buffer_mv_cur_right(struct buffer buf);
  36. struct buffer buffer_mv_cur_up(struct buffer buf);
  37. struct buffer buffer_mv_cur_down(struct buffer buf);
  38. struct buffer buffer_insert_char(struct buffer buf, size_t index, char c);
  39. struct buffer buffer_remove_char_mv_cur(struct buffer buf, size_t index);
  40. struct buffer buffer_remove_char(struct buffer buf, size_t index);
  41. struct ret_buffer_size_t_err buffer_remove_between(struct buffer buf,
  42. size_t start, size_t end);
  43. struct ret_size_t_err buffer_index_bw_word(struct buffer buf);
  44. struct ret_size_t_err buffer_index_fw_word(struct buffer buf);
  45. struct ret_size_t_err buffer_index_bw_char(struct buffer buf, char c);
  46. struct ret_size_t_err buffer_index_fw_char(struct buffer buf, char c);
  47. #if defined(BUFFER_IMP) || defined(IMP)
  48. #include <ctype.h>
  49. #include "file.h"
  50. #include "da.h"
  51. #include "unwrap.h"
  52. struct buffer
  53. buffer_create(void)
  54. {
  55. struct buffer buf = {0};
  56. DA_CREATE(buf.data, sizeof(char));
  57. return buf;
  58. }
  59. void
  60. buffer_destroy(struct buffer buf)
  61. {
  62. free(buf.data.items);
  63. }
  64. struct ret_buffer_err
  65. buffer_load_from_file(struct buffer buf, const char *filepath)
  66. {
  67. void *ptr;
  68. size_t file_size;
  69. enum file_err err;
  70. RET_UNWRAP3(ptr, file_size, err,
  71. struct ret_void_p_err, file_read_all(filepath));
  72. if ( err != FILE_ERR_OK ) {
  73. return (struct ret_buffer_err) {
  74. .f1 = buf,
  75. .f2 = BUFFER_ERR_FAIL_READ_FILE
  76. };
  77. }
  78. buffer_destroy(buf);
  79. buf.data.items = ptr;
  80. buf.data.size = file_size - 1;
  81. buf.data.cap = file_size;
  82. return (struct ret_buffer_err) {
  83. .f1 = buf,
  84. .f2 = BUFFER_ERR_OK
  85. };
  86. }
  87. enum buffer_err
  88. buffer_save_to_file(struct buffer buf, const char *filepath)
  89. {
  90. (void) buf;
  91. (void) filepath;
  92. return BUFFER_ERR_OK;
  93. }
  94. struct buffer
  95. buffer_mv_cur_left(struct buffer buf)
  96. {
  97. if ( buf.cur == 0 ) {
  98. return buf;
  99. }
  100. --buf.cur;
  101. return buf;
  102. }
  103. struct buffer
  104. buffer_mv_cur_right(struct buffer buf)
  105. {
  106. if ( buf.cur == buf.data.size ) {
  107. return buf;
  108. }
  109. ++buf.cur;
  110. return buf;
  111. }
  112. struct buffer
  113. buffer_mv_cur_up(struct buffer buf)
  114. {
  115. return buf;
  116. }
  117. struct buffer
  118. buffer_mv_cur_down(struct buffer buf)
  119. {
  120. return buf;
  121. }
  122. struct buffer
  123. buffer_insert_char(struct buffer buf, size_t index, char c)
  124. {
  125. if ( index > buf.data.size ) {
  126. DA_APPEND(buf.data, c);
  127. ++buf.cur;
  128. return buf;
  129. }
  130. DA_INSERT(buf.data, c, index);
  131. ++buf.cur;
  132. return buf;
  133. }
  134. struct buffer
  135. buffer_remove_char_mv_cur(struct buffer buf, size_t index)
  136. {
  137. if ( buf.data.size == 0 ) {
  138. return buf;
  139. }
  140. if ( index > buf.data.size ) {
  141. return buf;
  142. }
  143. if ( buf.data.size == index ) {
  144. buf.data.items[--buf.data.size] = 0;
  145. --buf.cur;
  146. return buf;
  147. }
  148. DA_DELETE(buf.data, index);
  149. --buf.cur;
  150. return buf;
  151. }
  152. struct buffer
  153. buffer_remove_char(struct buffer buf, size_t index)
  154. {
  155. if ( buf.data.size == 0 ) {
  156. return buf;
  157. }
  158. if ( index > buf.data.size ) {
  159. return buf;
  160. }
  161. if ( buf.data.size == index ) {
  162. buf.data.items[--buf.data.size] = 0;
  163. return buf;
  164. }
  165. DA_DELETE(buf.data, index);
  166. return buf;
  167. }
  168. struct ret_buffer_size_t_err
  169. buffer_remove_between(struct buffer buf, size_t start, size_t end)
  170. {
  171. enum buffer_err err = BUFFER_ERR_OK;
  172. if ( buf.data.size == 0 ) {
  173. err = BUFFER_ERR_EMPTY;
  174. goto err;
  175. }
  176. if ( start == end ) {
  177. return (struct ret_buffer_size_t_err) {
  178. .f1 = buffer_remove_char(buf, start),
  179. .f2 = 1,
  180. .f3 = BUFFER_ERR_OK,
  181. };
  182. }
  183. if ( start > end ) {
  184. err = BUFFER_ERR_START_GT_END;
  185. goto err;
  186. }
  187. DA_DEF_STRUCT_ITEM(char, da);
  188. DA_ASSIGN(da, buf.data);
  189. /* There is no need to check start > buf.data.size, because */
  190. /* we know that start < end */
  191. if ( end > da.size ) {
  192. err = BUFFER_ERR_INVALID_END_SIZE;
  193. goto err;
  194. }
  195. size_t nrm = end - start;
  196. memmove(da.items+start, da.items+end, da.size - nrm);
  197. da.size -= nrm;
  198. return (struct ret_buffer_size_t_err) {
  199. .f1 = buf,
  200. .f2 = nrm,
  201. .f3 = BUFFER_ERR_OK,
  202. };
  203. err: ;
  204. return (struct ret_buffer_size_t_err) {
  205. .f1 = buf,
  206. .f2 = 0,
  207. .f3 = err
  208. };
  209. }
  210. struct ret_size_t_err
  211. buffer_index_bw_word(struct buffer buf)
  212. {
  213. enum buffer_err err = BUFFER_ERR_OK;
  214. if ( buf.data.size == 0 ) {
  215. err = BUFFER_ERR_EMPTY;
  216. goto err;
  217. }
  218. if ( buf.cur > buf.data.size ) {
  219. err = BUFFER_ERR_INVALID_CUR_POS;
  220. goto err;
  221. }
  222. bool found_letter = false;
  223. size_t i = buf.cur - 1;
  224. for ( ; i > 0; --i) {
  225. char c = buf.data.items[i];
  226. if ( isalnum(c) ) {
  227. found_letter = true;
  228. } else if ( found_letter ) {
  229. ++i;
  230. goto exit;
  231. }
  232. }
  233. if ( i == 0 ) {
  234. char c = buf.data.items[i];
  235. if ( isalnum(c) ) {
  236. found_letter = true;
  237. } else if ( found_letter ) {
  238. ++i;
  239. goto exit;
  240. }
  241. }
  242. exit: ;
  243. return (struct ret_size_t_err) {
  244. .f1 = i,
  245. .f2 = BUFFER_ERR_OK,
  246. };
  247. err: ;
  248. return (struct ret_size_t_err) {
  249. .f1 = 0,
  250. .f2 = err,
  251. };
  252. }
  253. struct ret_size_t_err
  254. buffer_index_fw_word(struct buffer buf)
  255. {
  256. enum buffer_err err = BUFFER_ERR_OK;
  257. if ( buf.data.size == 0 ) {
  258. err = BUFFER_ERR_EMPTY;
  259. goto err;
  260. }
  261. if ( buf.cur > buf.data.size ) {
  262. err = BUFFER_ERR_INVALID_CUR_POS;
  263. goto err;
  264. }
  265. bool found_letter = false;
  266. size_t i = buf.cur;
  267. for ( ; i < buf.data.size; ++i) {
  268. char c = buf.data.items[i];
  269. if ( isalnum(c) ) {
  270. found_letter = true;
  271. } else if ( found_letter ) {
  272. goto exit;
  273. }
  274. }
  275. if ( i == 0 ) {
  276. char c = buf.data.items[i];
  277. if ( isalnum(c) ) {
  278. found_letter = true;
  279. } else if ( found_letter ) {
  280. goto exit;
  281. }
  282. }
  283. exit: ;
  284. return (struct ret_size_t_err) {
  285. .f1 = i,
  286. .f2 = BUFFER_ERR_OK,
  287. };
  288. err: ;
  289. return (struct ret_size_t_err) {
  290. .f1 = 0,
  291. .f2 = err,
  292. };
  293. }
  294. struct ret_size_t_err
  295. buffer_index_bw_char(struct buffer buf, char c)
  296. {
  297. enum buffer_err err;
  298. if ( buf.data.size == 0 ) {
  299. err = BUFFER_ERR_EMPTY;
  300. goto err;
  301. }
  302. if ( buf.cur > buf.data.size ) {
  303. err = BUFFER_ERR_INVALID_CUR_POS;
  304. goto err;
  305. }
  306. const char *str = buf.data.items;
  307. bool cond = false;
  308. /* TODO: Find a way to not use ssize_t buf size_t */
  309. ssize_t closest = -1;
  310. for ( ssize_t i = 0; i < (ssize_t) buf.cur; ++i ) {
  311. cond = str[i] == c;
  312. closest = ( cond ) * i + ( ! cond ) * closest;
  313. }
  314. if ( closest == -1 ) {
  315. err = BUFFER_ERR_NOT_FOUND;
  316. goto err;
  317. }
  318. return (struct ret_size_t_err) {
  319. .f1 = (size_t) closest,
  320. .f2 = BUFFER_ERR_OK,
  321. };
  322. err: ;
  323. return (struct ret_size_t_err) {
  324. .f1 = 0,
  325. .f2 = err,
  326. };
  327. }
  328. struct ret_size_t_err
  329. buffer_index_fw_char(struct buffer buf, char c)
  330. {
  331. enum buffer_err err;
  332. if ( buf.data.size == 0 ) {
  333. err = BUFFER_ERR_EMPTY;
  334. goto err;
  335. }
  336. if ( buf.cur > buf.data.size ) {
  337. err = BUFFER_ERR_INVALID_CUR_POS;
  338. goto err;
  339. }
  340. const char *str = buf.data.items;
  341. for ( size_t i = buf.cur; i < buf.data.size; ++i ) {
  342. if ( str[i] == c ) {
  343. return (struct ret_size_t_err) {
  344. .f1 = i,
  345. .f2 = BUFFER_ERR_OK,
  346. };
  347. }
  348. }
  349. err = BUFFER_ERR_NOT_FOUND;
  350. err: ;
  351. return (struct ret_size_t_err) {
  352. .f1 = 0,
  353. .f2 = err,
  354. };
  355. }
  356. #endif /* defined(BUFFER_IMP) || defined(IMP) */
  357. #endif