sled

Једноставни уређивач текста
git clone https://git.sr.ht/~strahinja/sled
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 48bda8f4e48cd895be313ac0b4800059a0648f30
родитељ 106963d46bf2afc6a06dd3cdd2ed381254f8689f
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Sun, 13 Feb 2022 00:08:04 +0100

Read & draw lines from file

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
Mconfig.def.h | 29+++++++++++++++++------------
Mconfig.h | 29+++++++++++++++++------------
Mdraw.c | 69+++++++++++++++++++++++++++++++++++++++++++++------------------------
Mdraw.h | 1+
Msled.c | 310+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mutil.c | 12++++++++++++
Mutil.h | 1+
измењених датотека: 7, додавања: 276(+), брисања: 175(-)

diff --git a/config.def.h b/config.def.h @@ -1,27 +1,32 @@ /* See the file LICENSE for copyright and license details. */ -#define DLG_FG TB_BLACK -#define DLG_BG TB_WHITE -#define ERROR_FG TB_WHITE | TB_BOLD -#define ERROR_BG TB_RED -#define PROMPT_FG TB_YELLOW | TB_BOLD -#define PROMPT_BG TB_MAGENTA -#define SHADOW_FG TB_BLACK -#define SHADOW_BG TB_BLACK | TB_BOLD -#define TITLE_FG TB_BLACK -#define TITLE_BG TB_WHITE +#define DLG_FG TB_BLACK +#define DLG_BG TB_WHITE +#define ERROR_FG TB_WHITE | TB_BOLD +#define ERROR_BG TB_RED +#define PROMPT_FG TB_YELLOW | TB_BOLD +#define PROMPT_BG TB_MAGENTA +#define SHADOW_FG TB_BLACK +#define SHADOW_BG TB_BLACK | TB_BOLD +#define TEXT_FG TB_WHITE +#define TEXT_BG TB_DEFAULT +#define TITLE_FG TB_BLACK +#define TITLE_BG TB_WHITE void format_filename(char* result, size_t result_size, const char* format, const struct DrawState* state); +void format_position(char* result, size_t result_size, const char* format, + const struct DrawState* state); + static const struct StatusSegment status_segments[] = { {.format = "%s%s", .callback = format_filename, .fg = TB_BLACK, .bg = TB_WHITE, .alignment = LEFT}, - {.format = "%ld/%ld (%ldu/%ldf/%ldo)", - .callback = NULL, + {.format = "%ld/%ld (%ld%%)", + .callback = format_position, .fg = TB_WHITE | TB_BOLD, .bg = TB_BLUE, .alignment = CENTER}, diff --git a/config.h b/config.h @@ -1,27 +1,32 @@ /* See the file LICENSE for copyright and license details. */ -#define DLG_FG TB_BLACK -#define DLG_BG TB_WHITE -#define ERROR_FG TB_WHITE | TB_BOLD -#define ERROR_BG TB_RED -#define PROMPT_FG TB_YELLOW | TB_BOLD -#define PROMPT_BG TB_MAGENTA -#define SHADOW_FG TB_BLACK -#define SHADOW_BG TB_BLACK | TB_BOLD -#define TITLE_FG TB_BLACK -#define TITLE_BG TB_WHITE +#define DLG_FG TB_BLACK +#define DLG_BG TB_WHITE +#define ERROR_FG TB_WHITE | TB_BOLD +#define ERROR_BG TB_RED +#define PROMPT_FG TB_YELLOW | TB_BOLD +#define PROMPT_BG TB_MAGENTA +#define SHADOW_FG TB_BLACK +#define SHADOW_BG TB_BLACK | TB_BOLD +#define TEXT_FG TB_WHITE +#define TEXT_BG TB_DEFAULT +#define TITLE_FG TB_BLACK +#define TITLE_BG TB_WHITE void format_filename(char* result, size_t result_size, const char* format, const struct DrawState* state); +void format_position(char* result, size_t result_size, const char* format, + const struct DrawState* state); + static const struct StatusSegment status_segments[] = { {.format = "%s%s", .callback = format_filename, .fg = TB_BLACK, .bg = TB_WHITE, .alignment = LEFT}, - {.format = "%ld/%ld (%ldu/%ldf/%ldo)", - .callback = NULL, + {.format = "%ld/%ld (%ld%%)", + .callback = format_position, .fg = TB_WHITE | TB_BOLD, .bg = TB_BLUE, .alignment = CENTER}, diff --git a/draw.c b/draw.c @@ -59,32 +59,32 @@ void init_drawstate(struct DrawState* state, char* error, char* filename, char* prompt) { - state->error = error; - state->filename = filename; - state->buffer = NULL; - state->column = 0; - state->display_column = 0; - state->first_shown_column = 0; - state->first_shown_row = 0; - state->row = 0; - state->rows_count = 0; - state->saved_column = -1; - state->help_width = calculate_help_width(state); - state->paste_buffer = NULL; - state->paste_rows_count = 0; - state->prompt = prompt; - state->prompt_callback = NULL; - state->running = 1; - state->dirty = 0; - state->in_prompt = 0; - state->show_help = 0; + state->error = error; + state->filename = filename; + state->buffer = NULL; + state->column = 0; + state->display_column = 0; + state->first_shown_column = 0; + state->first_shown_row = 0; + state->row = 0; + state->rows_count = 0; + state->saved_column = -1; + state->help_width = calculate_help_width(state); + state->paste_buffer = NULL; + state->paste_rows_count = 0; + state->prompt = prompt; + state->prompt_callback = NULL; + state->running = 1; + state->dirty = 0; + state->in_prompt = 0; + state->show_help = 0; } void free_drawstate(struct DrawState* state) { - struct BufferLine* current = NULL; - size_t i = 0; + struct BufferLine* current = NULL; + size_t i = 0; for (i = 0; i < state->rows_count; i++) { @@ -466,9 +466,30 @@ draw_help(const struct DrawState* state) const struct DrawState* draw_screen(const struct DrawState* state) { + const struct BufferLine* current = NULL; + int max_screen_lines = state->maxy - 1; + int cy = 0; + size_t i = state->first_shown_row; + if (!state) return NULL; + if (state->rows_count == 0) + return state; + + current = state->buffer; + while ((i < state->rows_count) && (cy < max_screen_lines)) + { + current = state->buffer + i; + + if (current->text) + u32_draw_string(0, cy, TEXT_FG, TEXT_BG, current->text, + state->maxx - 2, state->maxx, 1, 1, CENTER, 0, + 0, NULL, 0, 0); + i++; + cy++; + } + return state; } @@ -530,13 +551,13 @@ draw(const struct DrawState* state) if (!state) return NULL; + if (!draw_screen(state)) + return NULL; + if (state->show_help) if (!draw_help(state)) return NULL; - if (!draw_screen(state)) - return NULL; - if (!draw_status(state)) return NULL; diff --git a/draw.h b/draw.h @@ -28,6 +28,7 @@ struct DrawState { char* prompt; char* filename; struct BufferLine* buffer; + size_t buffer_size; int column; int row; int first_shown_column; diff --git a/sled.c b/sled.c @@ -17,6 +17,8 @@ #include "draw.h" #include "config.h" +#define ALLOC_DELTA 10 + enum { LOAD_ERR_NONE = 0, LOAD_ERR_CANT_ALLOC = 1, @@ -41,6 +43,8 @@ int version(); int usage(); void format_filename(char* result, size_t result_size, const char* format, const struct DrawState* state); +void format_position(char* result, size_t result_size, const char* format, + const struct DrawState* state); void format_msgs(char* result, size_t result_size, const char* format, const struct DrawState* state); void overwrite_copy_msgid_callback(struct DrawState* state, struct tb_event* ev); @@ -53,14 +57,14 @@ int load_file(struct DrawState* dstate, long* lineno, long* col); int save_file(struct DrawState* state); void save_msgstr(struct DrawState* state); void cancel_msgstr(struct DrawState* state); -//struct DrawState* copy_msgid_to_input(struct DrawState* state); -//struct DrawState* yank_msgstr_to_paste_buffer(struct DrawState* state); -//struct DrawState* paste_paste_buffer_to_input(struct DrawState* state); +// struct DrawState* copy_msgid_to_input(struct DrawState* state); +// struct DrawState* yank_msgstr_to_paste_buffer(struct DrawState* state); +// struct DrawState* paste_paste_buffer_to_input(struct DrawState* state); void goto_msgid(struct DrawState* state, const size_t msgid_number); -//void next_match(struct DrawState* state); -//void prev_match(struct DrawState* state); -//void next_untranslated(struct DrawState* state); -//void next_fuzzy(struct DrawState* state); +// void next_match(struct DrawState* state); +// void prev_match(struct DrawState* state); +// void next_untranslated(struct DrawState* state); +// void next_fuzzy(struct DrawState* state); void show_edit(struct DrawState* state); void move_up(struct DrawState* state); void move_down(struct DrawState* state); @@ -127,16 +131,25 @@ format_filename(char* result, size_t result_size, const char* format, if (!result) return; snprintf(result, result_size, format, u8_basename(state->filename), - state->dirty ? "*" : ""); + state->dirty ? "*" : ""); } void -format_msgs(char* result, size_t result_size, const char* format, +format_position(char* result, size_t result_size, const char* format, const struct DrawState* state) { if (!result) return; + snprintf(result, result_size, format, state->column, state->row, + state->rows_count ? state->row / state->rows_count * 100 : 0); +} +void +format_msgs(char* result, size_t result_size, const char* format, + const struct DrawState* state) +{ + if (!result) + return; } void @@ -144,10 +157,10 @@ overwrite_copy_msgid_callback(struct DrawState* state, struct tb_event* ev) { if (!state) return; -/* - if (ev->ch == 'y') - copy_msgid_to_input(state); - */ + /* + if (ev->ch == 'y') + copy_msgid_to_input(state); + */ state->prompt_callback = NULL; } @@ -156,10 +169,10 @@ overwrite_paste_callback(struct DrawState* state, struct tb_event* ev) { if (!state) return; -/* - if (ev->ch == 'y') - paste_paste_buffer_to_input(state); - */ + /* + if (ev->ch == 'y') + paste_paste_buffer_to_input(state); + */ state->prompt_callback = NULL; } @@ -205,76 +218,119 @@ quit_callback(struct DrawState* state, struct tb_event* ev) struct DrawState* load_msgstr(struct DrawState* state) { -/* - int msgstr_index = state->msgstr_index; - struct PoEntry* current = &state->entries[state->msgid_number - 1]; - size_t num_lines = current->msgstr_count == 0 - ? 1 - : u32_lines_in_string(*(current->msgstr + msgstr_index), 0, 0); - struct BufferLine* newbuf = NULL; - struct BufferLine* pnewbuf = NULL; - - for (size_t i = 0; i < state->input_rows_count; i++) - free_bufferline(state->input_buffer + i); - free(state->input_buffer); + /* + int msgstr_index = state->msgstr_index; + struct PoEntry* current = &state->entries[state->msgid_number + - 1]; size_t num_lines = current->msgstr_count == 0 ? 1 : + u32_lines_in_string(*(current->msgstr + msgstr_index), 0, 0); struct + BufferLine* newbuf = NULL; struct BufferLine* pnewbuf = NULL; - newbuf = calloc(num_lines, sizeof(struct BufferLine)); - if (!newbuf) - return NULL; + for (size_t i = 0; i < state->input_rows_count; i++) + free_bufferline(state->input_buffer + i); + free(state->input_buffer); - pnewbuf = newbuf; - for (size_t i = 0; i < num_lines; i++) - { - init_bufferline(pnewbuf); - uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t)); - if (!newtext) + newbuf = calloc(num_lines, sizeof(struct BufferLine)); + if (!newbuf) return NULL; - pnewbuf->text = newtext; - pnewbuf++; - } - state->input_rows_count = num_lines; + pnewbuf = newbuf; + for (size_t i = 0; i < num_lines; i++) + { + init_bufferline(pnewbuf); + uint32_t* newtext = calloc(MAXBUFLINE, + sizeof(uint32_t)); if (!newtext) return NULL; pnewbuf->text = + newtext; pnewbuf++; + } - if (current->msgstr_count > 0) - { - const uint32_t* pumsgstr = *(current->msgstr + msgstr_index); - if (pumsgstr) + state->input_rows_count = num_lines; + + if (current->msgstr_count > 0) { - pnewbuf = newbuf; - while (*pumsgstr) + const uint32_t* pumsgstr = *(current->msgstr + + msgstr_index); if (pumsgstr) { - size_t len = 0; - size_t newlen = 0; - const uint32_t* old_pumsgstr = pumsgstr; - len = u32_next_line(*(current->msgstr - + msgstr_index), - &pumsgstr, 0, 0); - u32_strncpy(pnewbuf->text, old_pumsgstr, - MIN(len + 1, MAXBUFLINE)); - newlen = u32_decode_tabs(pnewbuf->text, - MAXBUFLINE); - pnewbuf->length = newlen; - pnewbuf++; + pnewbuf = newbuf; + while (*pumsgstr) + { + size_t len = 0; + size_t newlen = 0; + const uint32_t* old_pumsgstr = pumsgstr; + len = u32_next_line(*(current->msgstr + + + msgstr_index), &pumsgstr, 0, 0); u32_strncpy(pnewbuf->text, + old_pumsgstr, MIN(len + 1, MAXBUFLINE)); newlen = + u32_decode_tabs(pnewbuf->text, MAXBUFLINE); pnewbuf->length = newlen; + pnewbuf++; + } } + else + newbuf[0].length = 0; } else newbuf[0].length = 0; - } - else - newbuf[0].length = 0; - state->input_buffer = newbuf; - */ + state->input_buffer = newbuf; + */ return state; } -int +int load_file(struct DrawState* dstate, long* lineno, long* col) { + struct BufferLine* newchunk + = calloc(ALLOC_DELTA, sizeof(struct BufferLine)); + struct BufferLine* line = NULL; + struct BufferLine* current = NULL; + FILE* input = NULL; + char input_line[MAXBUFLINE]; + + if (!newchunk) + return LOAD_ERR_CANT_ALLOC; + + dstate->buffer = newchunk; + line = dstate->buffer; + dstate->buffer_size = ALLOC_DELTA; + dstate->rows_count = 0; + + if (!(input = fopen(dstate->filename, "rt"))) + return LOAD_ERR_CANT_OPEN_FILE; + + while (!feof(input)) + { + char* eol = NULL; + uint32_t* newtext = NULL; + + if (!fgets(input_line, MAXBUFLINE, input)) + continue; + eol = strchr(input_line, '\n'); + if (eol) + *eol = 0; + + line = dstate->buffer + dstate->rows_count; + if (line == dstate->buffer + dstate->buffer_size) + { + dstate->buffer_size += ALLOC_DELTA; + newchunk = realloc(dstate->buffer, + dstate->buffer_size * sizeof(struct BufferLine)); + if (!newchunk) + return LOAD_ERR_CANT_ALLOC; + dstate->buffer = newchunk; + line = dstate->buffer + dstate->buffer_size + - ALLOC_DELTA; + } + init_bufferline(line); + newtext = calloc(MAXBUFLINE, sizeof(uint32_t)); + if (!newtext) + return LOAD_ERR_CANT_ALLOC; + line->text = newtext; + line->length = u32_u8_strcpy(line->text, input_line); + dstate->rows_count++; + } + return LOAD_ERR_NONE; } -int +int save_file(struct DrawState* state) { return SAVE_ERR_NONE; @@ -932,8 +988,8 @@ insert_char(struct DrawState* state, uint32_t ch) state->input_display_column = display_length(state, state->input_buffer[state->input_row].text, state->input_column); - if (state->input_display_column - state->input_first_shown_column - > state->edit_width - 4) + if (state->input_display_column - + state->input_first_shown_column > state->edit_width - 4) { state->input_first_shown_column = state->input_display_column @@ -1089,10 +1145,9 @@ insert_line(struct DrawState* state) = state->input_buffer[i - 1].length; } u32_strncpy(state->input_buffer[state->input_row + 1].text, - state->input_buffer[state->input_row].text + state->input_column, - MAXBUFLINE); - state->input_buffer[state->input_row + 1].length - = u32_strlen(state->input_buffer[state->input_row + 1].text); + state->input_buffer[state->input_row].text + + state->input_column, MAXBUFLINE); state->input_buffer[state->input_row + + 1].length = u32_strlen(state->input_buffer[state->input_row + 1].text); state->input_buffer[state->input_row].text[state->input_column] = 0; state->input_buffer[state->input_row].length = u32_strlen(state->input_buffer[state->input_row].text); @@ -1186,7 +1241,7 @@ handle_editbox_key_event(struct tb_event* ev, struct DrawState* state) /*&& !state->edit_info_focused*/) erase_backwards(state); else if (ev->key == TB_KEY_CTRL_C) - ;//yank_msgstr_to_paste_buffer(state); + ; // yank_msgstr_to_paste_buffer(state); else if (ev->key == TB_KEY_CTRL_K) erase_to_end(state); else if (ev->key == TB_KEY_CTRL_N) @@ -1208,8 +1263,8 @@ handle_editbox_key_event(struct tb_event* ev, struct DrawState* state) else if (ev->key == TB_KEY_CTRL_W) erase_prev_word(state); else if (ev->key == TB_KEY_CTRL_Z) - ;//toggle_fuzzy(state); - else if (ev->key == TB_KEY_DELETE/* && !state->edit_info_focused*/) + ; // toggle_fuzzy(state); + else if (ev->key == TB_KEY_DELETE /* && !state->edit_info_focused*/) erase_forward(state); else if (ev->key == TB_KEY_END || ev->key == TB_KEY_CTRL_E) move_end(state); @@ -1224,14 +1279,14 @@ handle_editbox_key_event(struct tb_event* ev, struct DrawState* state) else if (ev->key == TB_KEY_ESC) cancel_msgstr(state); else if (ev->key == TB_KEY_F5) - ;//copy_msgid_to_input(state); + ; // copy_msgid_to_input(state); else if (ev->key == TB_KEY_F6) - //state->edit_info_focused = !state->edit_info_focused; + // state->edit_info_focused = !state->edit_info_focused; ; else if (ev->key == TB_KEY_F8) - ;//next_untranslated(state); + ; // next_untranslated(state); else if (ev->key == TB_KEY_F9) - ;//next_fuzzy(state); + ; // next_fuzzy(state); else if (ev->key == TB_KEY_HOME || ev->key == TB_KEY_CTRL_A) move_start(state); else if (ev->key == TB_KEY_PGDN || ev->key == TB_KEY_CTRL_F) @@ -1333,7 +1388,7 @@ handle_key_event(struct tb_event* ev, struct DrawState* state) state->dirty = 0; } else if (ev->key == TB_KEY_CTRL_Z || ev->ch == 'z') - ;//toggle_fuzzy(state); + ; // toggle_fuzzy(state); else if (ev->key == TB_KEY_END || ev->ch == 'G') move_list_end(state); else if (ev->key == TB_KEY_ENTER) @@ -1354,15 +1409,15 @@ handle_key_event(struct tb_event* ev, struct DrawState* state) state->error[0] = 0; } else if (ev->key == TB_KEY_F3 || ev->ch == 'n') - ;//next_match(state); + ; // next_match(state); else if (ev->key == TB_KEY_F4 || ev->ch == 'N') - ;//prev_match(state); + ; // prev_match(state); else if (ev->key == TB_KEY_F7 || ev->ch == '/') - ;//show_search(state); + ; // show_search(state); else if (ev->key == TB_KEY_F8 || ev->ch == 'u') - ;//next_untranslated(state); + ; // next_untranslated(state); else if (ev->key == TB_KEY_F9 || ev->ch == 'f') - ;//next_fuzzy(state); + ; // next_fuzzy(state); else if (ev->key == TB_KEY_HOME || ev->ch == 'g') move_list_start(state); else @@ -1374,44 +1429,45 @@ handle_search_key_event(struct tb_event* ev, struct DrawState* state) { if (!state) return; -/* - if (ev->key == TB_KEY_ARROW_LEFT) - ;//move_search_left(state); - else if (ev->key == TB_KEY_ARROW_RIGHT) - ;//move_search_right(state); - else if ((ev->key == TB_KEY_BACKSPACE || ev->key == TB_KEY_BACKSPACE2)) - ;//erase_search_backwards(state); - else if (ev->key == TB_KEY_CTRL_K) - erase_search_to_end(state); - else if (ev->key == TB_KEY_CTRL_R) - move_search_prev_word(state); - else if (ev->key == TB_KEY_CTRL_T) - move_search_next_word(state); - else if (ev->key == TB_KEY_CTRL_U) - erase_search_to_start(state); - else if (ev->key == TB_KEY_CTRL_W) - erase_search_prev_word(state); - else if (ev->key == TB_KEY_DELETE) - erase_search_forward(state); - else if (ev->key == TB_KEY_END || ev->key == TB_KEY_CTRL_E) - move_search_end(state); - else if (ev->key == TB_KEY_ENTER) - hide_search(state); - else if (ev->key == TB_KEY_ESC) - cancel_search(state); - else if (ev->key == TB_KEY_F3) - next_match(state); - else if (ev->key == TB_KEY_F4) - prev_match(state); - else if (ev->key == TB_KEY_HOME || ev->key == TB_KEY_CTRL_A) - move_search_start(state); - else if (ev->key == TB_KEY_SPACE) - insert_search_char(state, ' '); - else if (ev->key == TB_KEY_TAB) - insert_search_char(state, '\t'); - else if (ev->ch != 0) - insert_search_char(state, ev->ch); - */ + /* + if (ev->key == TB_KEY_ARROW_LEFT) + ;//move_search_left(state); + else if (ev->key == TB_KEY_ARROW_RIGHT) + ;//move_search_right(state); + else if ((ev->key == TB_KEY_BACKSPACE || ev->key == + TB_KEY_BACKSPACE2)) + ;//erase_search_backwards(state); + else if (ev->key == TB_KEY_CTRL_K) + erase_search_to_end(state); + else if (ev->key == TB_KEY_CTRL_R) + move_search_prev_word(state); + else if (ev->key == TB_KEY_CTRL_T) + move_search_next_word(state); + else if (ev->key == TB_KEY_CTRL_U) + erase_search_to_start(state); + else if (ev->key == TB_KEY_CTRL_W) + erase_search_prev_word(state); + else if (ev->key == TB_KEY_DELETE) + erase_search_forward(state); + else if (ev->key == TB_KEY_END || ev->key == TB_KEY_CTRL_E) + move_search_end(state); + else if (ev->key == TB_KEY_ENTER) + hide_search(state); + else if (ev->key == TB_KEY_ESC) + cancel_search(state); + else if (ev->key == TB_KEY_F3) + next_match(state); + else if (ev->key == TB_KEY_F4) + prev_match(state); + else if (ev->key == TB_KEY_HOME || ev->key == TB_KEY_CTRL_A) + move_search_start(state); + else if (ev->key == TB_KEY_SPACE) + insert_search_char(state, ' '); + else if (ev->key == TB_KEY_TAB) + insert_search_char(state, '\t'); + else if (ev->ch != 0) + insert_search_char(state, ev->ch); + */ } int @@ -1468,7 +1524,7 @@ main(int argc, char** argv) } tb_init(); - *error = 0; + *error = 0; state.maxx = 0; while (state.running) @@ -1478,8 +1534,8 @@ main(int argc, char** argv) int maxx = tb_width(); if (maxx != state.maxx) { - state.maxx = maxx; - state.help_width = calculate_help_width(&state); + state.maxx = maxx; + state.help_width = calculate_help_width(&state); } state.maxy = tb_height(); diff --git a/util.c b/util.c @@ -298,6 +298,18 @@ u32_strncat(uint32_t* to, const uint32_t* from, size_t max) } size_t +u32_u8_strcpy(uint32_t* to, const char* from) +{ + uint32_t* ufrom = calloc(strlen(from) + 1, sizeof(uint32_t)); + if (!ufrom) + return 0; + u8_string_to_unicode(ufrom, from, strlen(from)); + size_t len = u32_strcpy(to, ufrom); + free(ufrom); + return len; +} + +size_t u32_u8_strncpy(uint32_t* to, const char* from, size_t max) { uint32_t* ufrom = calloc(strlen(from) + 1, sizeof(uint32_t)); diff --git a/util.h b/util.h @@ -41,6 +41,7 @@ uint32_t* u32_strchr(uint32_t* haystack, const uint32_t needle); size_t u32_strcpy(uint32_t* to, const uint32_t* from); size_t u32_strncpy(uint32_t* to, const uint32_t* from, size_t max); size_t u32_strncat(uint32_t* to, const uint32_t* from, size_t max); +size_t u32_u8_strcpy(uint32_t* to, const char* from); size_t u32_u8_strncpy(uint32_t* to, const char* from, size_t max); size_t u8_u32_strncpy(char* to, const uint32_t* from, size_t max); size_t u32_lines_in_string(const uint32_t* s, const int include_eol,