| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- #ifndef BUFFER_H
- #define BUFFER_H
- struct buffer {
- DA_DEF_STRUCT_ITEM(char, data);
- size_t cur;
- };
- enum buffer_err {
- BUFFER_ERR_OK = 0,
- BUFFER_ERR_EMPTY,
- BUFFER_ERR_NOT_FOUND,
- BUFFER_ERR_INVALID_CUR_POS,
- BUFFER_ERR_FAIL_READ_FILE,
- BUFFER_ERR_START_GT_END,
- BUFFER_ERR_INVALID_END_SIZE,
- };
- struct ret_buffer_err {
- struct buffer f1;
- enum buffer_err f2;
- };
- struct ret_size_t_err {
- size_t f1;
- enum buffer_err f2;
- };
- struct ret_buffer_size_t_err {
- struct buffer f1;
- size_t f2;
- enum buffer_err f3;
- };
- struct buffer buffer_create(void);
- void buffer_destroy(struct buffer buf);
- struct ret_buffer_err buffer_load_from_file(struct buffer buf,
- const char *filepath);
- enum buffer_err buffer_save_to_file(struct buffer buf, const char *filepath);
- struct buffer buffer_mv_cur_left(struct buffer buf);
- struct buffer buffer_mv_cur_right(struct buffer buf);
- struct buffer buffer_mv_cur_up(struct buffer buf);
- struct buffer buffer_mv_cur_down(struct buffer buf);
- struct buffer buffer_insert_char(struct buffer buf, size_t index, char c);
- struct buffer buffer_remove_char_mv_cur(struct buffer buf, size_t index);
- struct buffer buffer_remove_char(struct buffer buf, size_t index);
- struct ret_buffer_size_t_err buffer_remove_between(struct buffer buf,
- size_t start, size_t end);
- struct ret_size_t_err buffer_index_bw_word(struct buffer buf);
- struct ret_size_t_err buffer_index_fw_word(struct buffer buf);
- struct ret_size_t_err buffer_index_bw_char(struct buffer buf, char c);
- struct ret_size_t_err buffer_index_fw_char(struct buffer buf, char c);
- #if defined(BUFFER_IMP) || defined(IMP)
- #include <ctype.h>
- #include "file.h"
- #include "da.h"
- #include "unwrap.h"
- struct buffer
- buffer_create(void)
- {
- struct buffer buf = {0};
- DA_CREATE(buf.data, sizeof(char));
- return buf;
- }
- void
- buffer_destroy(struct buffer buf)
- {
- free(buf.data.items);
- }
- struct ret_buffer_err
- buffer_load_from_file(struct buffer buf, const char *filepath)
- {
- void *ptr;
- size_t file_size;
- enum file_err err;
- RET_UNWRAP3(ptr, file_size, err,
- struct ret_void_p_err, file_read_all(filepath));
- if ( err != FILE_ERR_OK ) {
- return (struct ret_buffer_err) {
- .f1 = buf,
- .f2 = BUFFER_ERR_FAIL_READ_FILE
- };
- }
- buffer_destroy(buf);
- buf.data.items = ptr;
- buf.data.size = file_size - 1;
- buf.data.cap = file_size;
- return (struct ret_buffer_err) {
- .f1 = buf,
- .f2 = BUFFER_ERR_OK
- };
- }
- enum buffer_err
- buffer_save_to_file(struct buffer buf, const char *filepath)
- {
- (void) buf;
- (void) filepath;
- return BUFFER_ERR_OK;
- }
- struct buffer
- buffer_mv_cur_left(struct buffer buf)
- {
- if ( buf.cur == 0 ) {
- return buf;
- }
- --buf.cur;
- return buf;
- }
- struct buffer
- buffer_mv_cur_right(struct buffer buf)
- {
- if ( buf.cur == buf.data.size ) {
- return buf;
- }
- ++buf.cur;
- return buf;
- }
- struct buffer
- buffer_mv_cur_up(struct buffer buf)
- {
- return buf;
- }
- struct buffer
- buffer_mv_cur_down(struct buffer buf)
- {
- return buf;
- }
- struct buffer
- buffer_insert_char(struct buffer buf, size_t index, char c)
- {
- if ( index > buf.data.size ) {
- DA_APPEND(buf.data, c);
- ++buf.cur;
- return buf;
- }
- DA_INSERT(buf.data, c, index);
- ++buf.cur;
- return buf;
- }
- struct buffer
- buffer_remove_char_mv_cur(struct buffer buf, size_t index)
- {
- if ( buf.data.size == 0 ) {
- return buf;
- }
- if ( index > buf.data.size ) {
- return buf;
- }
- if ( buf.data.size == index ) {
- buf.data.items[--buf.data.size] = 0;
- --buf.cur;
- return buf;
- }
- DA_DELETE(buf.data, index);
- --buf.cur;
- return buf;
- }
- struct buffer
- buffer_remove_char(struct buffer buf, size_t index)
- {
- if ( buf.data.size == 0 ) {
- return buf;
- }
- if ( index > buf.data.size ) {
- return buf;
- }
- if ( buf.data.size == index ) {
- buf.data.items[--buf.data.size] = 0;
- return buf;
- }
- DA_DELETE(buf.data, index);
- return buf;
- }
- struct ret_buffer_size_t_err
- buffer_remove_between(struct buffer buf, size_t start, size_t end)
- {
- enum buffer_err err = BUFFER_ERR_OK;
- if ( buf.data.size == 0 ) {
- err = BUFFER_ERR_EMPTY;
- goto err;
- }
- if ( start == end ) {
- return (struct ret_buffer_size_t_err) {
- .f1 = buffer_remove_char(buf, start),
- .f2 = 1,
- .f3 = BUFFER_ERR_OK,
- };
- }
- if ( start > end ) {
- err = BUFFER_ERR_START_GT_END;
- goto err;
- }
- DA_DEF_STRUCT_ITEM(char, da);
- DA_ASSIGN(da, buf.data);
- /* There is no need to check start > buf.data.size, because */
- /* we know that start < end */
- if ( end > da.size ) {
- err = BUFFER_ERR_INVALID_END_SIZE;
- goto err;
- }
- size_t nrm = end - start;
- memmove(da.items+start, da.items+end, da.size - nrm);
- da.size -= nrm;
- return (struct ret_buffer_size_t_err) {
- .f1 = buf,
- .f2 = nrm,
- .f3 = BUFFER_ERR_OK,
- };
- err: ;
- return (struct ret_buffer_size_t_err) {
- .f1 = buf,
- .f2 = 0,
- .f3 = err
- };
- }
- struct ret_size_t_err
- buffer_index_bw_word(struct buffer buf)
- {
- enum buffer_err err = BUFFER_ERR_OK;
- if ( buf.data.size == 0 ) {
- err = BUFFER_ERR_EMPTY;
- goto err;
- }
- if ( buf.cur > buf.data.size ) {
- err = BUFFER_ERR_INVALID_CUR_POS;
- goto err;
- }
- bool found_letter = false;
- size_t i = buf.cur - 1;
- for ( ; i > 0; --i) {
- char c = buf.data.items[i];
- if ( isalnum(c) ) {
- found_letter = true;
- } else if ( found_letter ) {
- ++i;
- goto exit;
- }
- }
- if ( i == 0 ) {
- char c = buf.data.items[i];
- if ( isalnum(c) ) {
- found_letter = true;
- } else if ( found_letter ) {
- ++i;
- goto exit;
- }
- }
- exit: ;
- return (struct ret_size_t_err) {
- .f1 = i,
- .f2 = BUFFER_ERR_OK,
- };
- err: ;
- return (struct ret_size_t_err) {
- .f1 = 0,
- .f2 = err,
- };
- }
- struct ret_size_t_err
- buffer_index_fw_word(struct buffer buf)
- {
- enum buffer_err err = BUFFER_ERR_OK;
- if ( buf.data.size == 0 ) {
- err = BUFFER_ERR_EMPTY;
- goto err;
- }
- if ( buf.cur > buf.data.size ) {
- err = BUFFER_ERR_INVALID_CUR_POS;
- goto err;
- }
- bool found_letter = false;
- size_t i = buf.cur;
- for ( ; i < buf.data.size; ++i) {
- char c = buf.data.items[i];
- if ( isalnum(c) ) {
- found_letter = true;
- } else if ( found_letter ) {
- goto exit;
- }
- }
- if ( i == 0 ) {
- char c = buf.data.items[i];
- if ( isalnum(c) ) {
- found_letter = true;
- } else if ( found_letter ) {
- goto exit;
- }
- }
- exit: ;
- return (struct ret_size_t_err) {
- .f1 = i,
- .f2 = BUFFER_ERR_OK,
- };
- err: ;
- return (struct ret_size_t_err) {
- .f1 = 0,
- .f2 = err,
- };
- }
- struct ret_size_t_err
- buffer_index_bw_char(struct buffer buf, char c)
- {
- enum buffer_err err;
- if ( buf.data.size == 0 ) {
- err = BUFFER_ERR_EMPTY;
- goto err;
- }
- if ( buf.cur > buf.data.size ) {
- err = BUFFER_ERR_INVALID_CUR_POS;
- goto err;
- }
- const char *str = buf.data.items;
- bool cond = false;
- /* TODO: Find a way to not use ssize_t buf size_t */
- ssize_t closest = -1;
- for ( ssize_t i = 0; i < (ssize_t) buf.cur; ++i ) {
- cond = str[i] == c;
- closest = ( cond ) * i + ( ! cond ) * closest;
- }
- if ( closest == -1 ) {
- err = BUFFER_ERR_NOT_FOUND;
- goto err;
- }
- return (struct ret_size_t_err) {
- .f1 = (size_t) closest,
- .f2 = BUFFER_ERR_OK,
- };
- err: ;
- return (struct ret_size_t_err) {
- .f1 = 0,
- .f2 = err,
- };
- }
- struct ret_size_t_err
- buffer_index_fw_char(struct buffer buf, char c)
- {
- enum buffer_err err;
- if ( buf.data.size == 0 ) {
- err = BUFFER_ERR_EMPTY;
- goto err;
- }
- if ( buf.cur > buf.data.size ) {
- err = BUFFER_ERR_INVALID_CUR_POS;
- goto err;
- }
- const char *str = buf.data.items;
- for ( size_t i = buf.cur; i < buf.data.size; ++i ) {
- if ( str[i] == c ) {
- return (struct ret_size_t_err) {
- .f1 = i,
- .f2 = BUFFER_ERR_OK,
- };
- }
- }
- err = BUFFER_ERR_NOT_FOUND;
- err: ;
- return (struct ret_size_t_err) {
- .f1 = 0,
- .f2 = err,
- };
- }
- #endif /* defined(BUFFER_IMP) || defined(IMP) */
- #endif
|