чување f6f9901bb8fca08022cf698e6fc267fc3c9d15dc
родитељ 9f5ea057100f4dd7471d0c5b48e86da92a7466bd
Аутор: Страхиња Радић <sr@strahinja.org>
Датум: Fri, 20 Feb 2026 14:05:01 +0100
Remove dirty_before_edit, introduce edit_dirty; fix related logic
Diffstat:
| M | TODO | | | 4 | ++-- |
| M | draw.c | | | 7 | ++++--- |
| M | draw.h | | | 9 | +++++---- |
| M | po.h | | | 3 | +-- |
| M | poe.c | | | 250 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
| M | poe.h | | | 7 | +++++++ |
| M | util.c | | | 11 | +++++------ |
измењених датотека: 7, додавања: 203(+), брисања: 88(-)
diff --git a/TODO b/TODO
@@ -1,14 +1,14 @@
TODO
====
-[~] Tidy up basic logic everywhere (based on sled)
+[x] Tidy up basic logic everywhere (based on sled)
[x] Check cleanness against sled, function-by-function
[x] draw.c
[x] poe.c
[x] po.c
[x] util.c
[x] Investigate insert_char
- [ ] Revise dirty <-> dirty_before_edit and the interaction with keys
+ [x] Revise dirty <-> dirty_before_edit and the interaction with keys
[x] Copy join_lines from sled's simple_join_lines
[x] str* -> memccpy
[x] Tidy up return codes and error handling
diff --git a/draw.c b/draw.c
@@ -70,7 +70,7 @@ const char* flag_strings[] = {
[FL_FUZZY] = "fuzzy"};
const char* first_entry_msgid = "*** SPECIAL: file info ***";
const char* prompt_dirty = "File changed, save [y/n/ESC]?";
-const char* prompt_cancel_dirty = "Entry changed, save [y/n/ESC]?";
+const char* prompt_edit_dirty = "Entry changed, save [y/n/ESC]?";
const char* prompt_overwrite = "Not empty, overwrite? [y/n/ESC]?";
/* clang-format on */
@@ -622,7 +622,7 @@ format_filename(char* result, ssize_t result_size, const char* format,
pbase = u8_basename(state->filename);
basename = strndup(pbase, strlen(pbase) + 1);
- dirty = (state->show_edit && state->dirty_before_edit) || state->dirty;
+ dirty = state->edit_dirty || state->dirty;
if ((ssize_t)(u8_strlen(basename) + 2) >= seg_size)
{
if (dirty)
@@ -743,9 +743,10 @@ init_drawstate(struct DrawState* state, char* filename, char* prompt)
state->prompt_callback = NULL;
state->running = 1;
state->dirty = 0;
- state->dirty_before_edit = 0;
+ state->edit_dirty = 0;
state->fuzzy_before_edit = 0;
state->in_prompt = 0;
+ state->reshow_edit = 0;
state->show_edit = 0;
state->show_help = 0;
state->edit_info_focused = 0;
diff --git a/draw.h b/draw.h
@@ -100,8 +100,8 @@ struct DrawState {
struct Coord coord; /* buffer coordinates */
struct Coord first_shown; /* display coordinates */
struct Coord input_first_shown; /* display coordinates */
- ssize_t input_rows_count; /* buffer parameter */
- int input_display_column; /* display coordinate */
+ ssize_t input_rows_count; /* buffer parameter */
+ int input_display_column; /* display coordinate */
FlagChange input_changed_fuzzy;
int saved_column; /* display coordinate */
struct BufferLine* info_buffer; /* information pane above
@@ -122,10 +122,11 @@ struct DrawState {
int nplurals;
int (*prompt_callback)(struct DrawState*, struct tb_event*);
int running;
- int dirty;
- int dirty_before_edit;
+ int dirty; /* tracking changes in the file */
+ int edit_dirty; /* tracking changes in the edit box */
ssize_t fuzzy_before_edit;
int in_prompt;
+ int reshow_edit;
int show_edit;
int show_help;
int edit_info_focused;
diff --git a/po.h b/po.h
@@ -102,8 +102,7 @@ int set_nplurals(struct DrawState* state, struct PoEntry* entry);
int set_plural_forms(struct DrawState* state, struct PoEntry* entry,
const char* plural_forms, int append);
int u32_add_comment(struct PoEntry* entry, const uint32_t* comment);
-int u32_add_extr_comment(struct PoEntry* entry,
- const uint32_t* extr_comment);
+int u32_add_extr_comment(struct PoEntry* entry, const uint32_t* extr_comment);
int u32_set_msgid(struct DrawState* state, struct PoEntry* entry,
const uint32_t* msgid, ssize_t msgid_size, int append);
int u32_set_msgid_plural(struct DrawState* state, struct PoEntry* entry,
diff --git a/poe.c b/poe.c
@@ -41,17 +41,23 @@
extern const char* errors[];
extern const char* actions[];
extern const char* prompt_dirty;
-extern const char* prompt_cancel_dirty;
+extern const char* prompt_edit_dirty;
extern const char* prompt_overwrite;
static int
cancel_callback(struct DrawState* state, struct tb_event* ev)
{
assert((state != NULL) && (ev != NULL));
- if (ev->ch == 'y')
+ if (strchr("Yy", ev->ch))
+ {
+ state->reshow_edit = 0;
save_msgstr(state);
- else
+ }
+ else /* not saving */
+ {
+ state->edit_dirty = 0;
cancel_msgstr(state);
+ }
state->prompt_callback = NULL;
return 0;
}
@@ -83,12 +89,10 @@ cancel_msgstr(struct DrawState* state)
ssize_t i;
assert(state != NULL);
- if (!state->in_prompt
- && (state->dirty
- || (state->show_edit && state->dirty_before_edit)))
+ if (state->edit_dirty)
{
state->in_prompt = 1;
- MEMCCPY(state->prompt, prompt_cancel_dirty, LINE_DEFAULT, temp);
+ MEMCCPY(state->prompt, prompt_edit_dirty, LINE_DEFAULT, temp);
state->prompt_callback = cancel_callback;
return 0;
}
@@ -107,7 +111,6 @@ cancel_msgstr(struct DrawState* state)
free(state->info_buffer);
state->info_buffer = NULL;
state->info_rows_count = 0;
- state->dirty = state->dirty_before_edit;
state->fuzzy_count = state->fuzzy_before_edit;
switch (state->input_changed_fuzzy)
{
@@ -205,14 +208,14 @@ copy_msgid_to_input(struct DrawState* state)
len = u32_next_line(current->msgid, &pmsgid, 0, 0);
u32_strncpy(pbuffer->text, old_pmsgid,
MIN(len + 1, LINE_DEFAULT));
- newlen = u32_decode_tabs(state, pbuffer->text, LINE_DEFAULT);
+ newlen = u32_decode_tabs(state, pbuffer->text, LINE_DEFAULT);
pbuffer->length = newlen;
pbuffer++;
}
state->input_rows_count = msgid_num_lines;
state->input_buffer = newbuf;
- state->dirty = 1;
+ state->edit_dirty = 1;
return 0;
}
@@ -317,6 +320,7 @@ dirname(char* dir, char* path, const ssize_t dir_size)
static int
edit_page_down(struct DrawState* state)
{
+ char* temp = NULL;
assert(state != NULL);
if (state->edit_info_focused)
{
@@ -325,18 +329,36 @@ edit_page_down(struct DrawState* state)
state->info_first_shown.row += (EDIT_HEIGHT - 3) / 2;
return 0;
}
- if (state->dirty)
- save_msgstr(state);
- else /* No need to call cancel_msgstr */
- state->dirty = state->dirty_before_edit;
+ if (state->edit_dirty)
+ {
+ state->in_prompt = 1;
+ MEMCCPY(state->prompt, prompt_edit_dirty, LINE_DEFAULT, temp);
+ state->prompt_callback = edit_page_down_callback;
+ return 0;
+ }
move_list_down(state);
state->msgstr_index = 0;
+ state->reshow_edit = state->show_edit;
return show_edit(state);
}
static int
+edit_page_down_callback(struct DrawState* state, struct tb_event* ev)
+{
+ assert((state != NULL) && (ev != NULL));
+ if (strchr("Yy", ev->ch))
+ {
+ state->reshow_edit = state->show_edit;
+ save_msgstr(state);
+ }
+ state->edit_dirty = 0;
+ return edit_page_down(state);
+}
+
+static int
edit_page_up(struct DrawState* state)
{
+ char* temp = NULL;
assert(state != NULL);
if (state->edit_info_focused)
{
@@ -346,16 +368,32 @@ edit_page_up(struct DrawState* state)
move_start(state);
return 0;
}
- if (state->dirty)
- save_msgstr(state);
- else /* No need to call cancel_msgstr */
- state->dirty = state->dirty_before_edit;
+ if (state->edit_dirty)
+ {
+ state->in_prompt = 1;
+ MEMCCPY(state->prompt, prompt_edit_dirty, LINE_DEFAULT, temp);
+ state->prompt_callback = edit_page_up_callback;
+ return 0;
+ }
move_list_up(state);
state->msgstr_index = 0;
return show_edit(state);
}
static int
+edit_page_up_callback(struct DrawState* state, struct tb_event* ev)
+{
+ assert((state != NULL) && (ev != NULL));
+ if (strchr("Yy", ev->ch))
+ {
+ state->reshow_edit = state->show_edit;
+ save_msgstr(state);
+ }
+ state->edit_dirty = 0;
+ return edit_page_up(state);
+}
+
+static int
erase_backwards(struct DrawState* state)
{
struct BufferLine* buffer_line;
@@ -380,7 +418,7 @@ erase_backwards(struct DrawState* state)
buffer_line->text[i - 1] = 0;
buffer_line->length--;
position_to(state, state->coord.row, state->coord.col - 1);
- state->dirty = 1;
+ state->edit_dirty = 1;
}
else if (state->coord.row > 0)
{
@@ -416,7 +454,7 @@ erase_forward(struct DrawState* state)
}
buffer_line->text[i] = 0;
buffer_line->length--;
- state->dirty = 1;
+ state->edit_dirty = 1;
}
else if (state->coord.row < state->input_rows_count - 1)
{
@@ -469,7 +507,7 @@ erase_prev_word(struct DrawState* state)
state->coord.col);
if (state->input_display_column < state->input_first_shown.col)
state->input_first_shown.col = state->input_display_column;
- state->dirty = 1;
+ state->edit_dirty = 1;
return 0;
}
@@ -588,7 +626,7 @@ erase_to_end(struct DrawState* state)
buffer_line->text[state->coord.col] = 0;
buffer_line->length = state->coord.col;
move_end(state);
- state->dirty = 1;
+ state->edit_dirty = 1;
return 0;
}
@@ -619,7 +657,7 @@ erase_to_start(struct DrawState* state)
buffer_line->text[len - state->coord.col] = 0;
buffer_line->length = len - state->coord.col;
move_start(state);
- state->dirty = 1;
+ state->edit_dirty = 1;
return 0;
}
@@ -629,7 +667,13 @@ exit_program(struct DrawState* state)
char* temp = NULL;
assert(state != NULL);
- if (state->dirty || (state->show_edit && state->dirty_before_edit))
+ if (state->edit_dirty)
+ {
+ state->in_prompt = 1;
+ MEMCCPY(state->prompt, prompt_edit_dirty, LINE_DEFAULT, temp);
+ state->prompt_callback = quit_callback;
+ }
+ else if (state->dirty)
{
state->in_prompt = 1;
MEMCCPY(state->prompt, prompt_dirty, LINE_DEFAULT, temp);
@@ -852,7 +896,7 @@ insert_char(struct DrawState* state, uint32_t ch)
position_to(state, state->coord.row, state->coord.col + 1);
if (add_null)
buffer_line->text[state->coord.col] = 0;
- state->dirty = 1;
+ state->edit_dirty = 1;
return 0;
insert_char_alloc_error:
@@ -922,7 +966,7 @@ insert_line(struct DrawState* state)
state->input_first_shown.row
= state->coord.row - (EDIT_HEIGHT - 3) / 2;
move_start(state);
- state->dirty = 1;
+ state->edit_dirty = 1;
return 0;
insert_line_alloc_error:
@@ -1027,7 +1071,7 @@ join_lines(struct DrawState* state)
}
free_bufferline(&state->input_buffer[state->input_rows_count - 1]);
state->input_rows_count--;
- state->dirty = 1;
+ state->edit_dirty = 1;
return 0;
join_lines_alloc_error:
@@ -1226,7 +1270,7 @@ load_info_msgid(struct DrawState* state, struct BufferLine** lines)
ENSURE_SIZE((*lines)->text, ptext, (*lines)->size, size, size,
load_info_msgid_alloc_error, uint32_t);
U32_MEMCCPY((*lines)->text, old_pumsgid, len + 1, ptext);
- llen = u32_decode_tabs(state, (*lines)->text, len + 1);
+ llen = u32_decode_tabs(state, (*lines)->text, len + 1);
(*lines)->length = llen;
if (llen > state->info_maxlen)
state->info_maxlen = llen;
@@ -1695,35 +1739,32 @@ static int
next_fuzzy(struct DrawState* state)
{
struct PoEntry* current = NULL;
+ char* temp = NULL;
ssize_t e;
- int saved_show_edit;
assert(state != NULL);
if (state->msgid_count == 0)
return 1;
+ if (state->edit_dirty)
+ {
+ state->in_prompt = 1;
+ MEMCCPY(state->prompt, prompt_edit_dirty, LINE_DEFAULT, temp);
+ state->prompt_callback = next_fuzzy_callback;
+ return 0;
+ }
+
for (e = state->msgid_number; e < state->msgid_count; e++)
{
- current = state->entries + e;
+ current = &state->entries[e];
if (current->flags & FL_FUZZY)
{
- saved_show_edit = state->show_edit;
- if (saved_show_edit)
- {
- if (state->dirty)
- save_msgstr(state);
- else /* No need to call cancel_msgstr */
- state->dirty = state->dirty_before_edit;
- }
-
goto_msgid(state, e + 1);
-
- if (saved_show_edit)
+ if (state->show_edit)
{
state->msgstr_index = 0;
show_edit(state);
}
-
return 0;
}
}
@@ -1731,6 +1772,19 @@ next_fuzzy(struct DrawState* state)
}
static int
+next_fuzzy_callback(struct DrawState* state, struct tb_event* ev)
+{
+ assert((state != NULL) && (ev != NULL));
+ if (strchr("Yy", ev->ch))
+ {
+ state->reshow_edit = state->show_edit;
+ save_msgstr(state);
+ }
+ state->edit_dirty = 0;
+ return next_fuzzy(state);
+}
+
+static int
next_match(struct DrawState* state)
{
struct PoEntry* current = NULL;
@@ -1762,14 +1816,21 @@ static int
next_plural(struct DrawState* state)
{
struct PoEntry* current = NULL;
+ char* temp = NULL;
assert((state != NULL) && (state->entries != NULL));
if (state->edit_info_focused)
{
state->error = ERR_DLG_FOCUS_EDIT;
return 1;
}
+ if (state->edit_dirty)
+ {
+ state->in_prompt = 1;
+ MEMCCPY(state->prompt, prompt_edit_dirty, LINE_DEFAULT, temp);
+ state->prompt_callback = next_plural_callback;
+ return 0;
+ }
current = &state->entries[state->msgid_number - 1];
- save_msgstr(state);
if (state->msgstr_index + 1 < current->msgstr_count)
state->msgstr_index++;
show_edit(state);
@@ -1777,43 +1838,68 @@ next_plural(struct DrawState* state)
}
static int
+next_plural_callback(struct DrawState* state, struct tb_event* ev)
+{
+ assert((state != NULL) && (ev != NULL));
+ if (strchr("Yy", ev->ch))
+ {
+ state->reshow_edit = state->show_edit;
+ save_msgstr(state);
+ }
+ state->edit_dirty = 0;
+ return next_plural(state);
+}
+
+static int
next_untranslated(struct DrawState* state)
{
struct PoEntry* current = NULL;
+ char* temp = NULL;
ssize_t e;
- int saved_show_edit;
+
assert((state != NULL) && (state->entries != NULL));
if (state->msgid_count == 0)
return 1;
+
+ if (state->edit_dirty)
+ {
+ state->in_prompt = 1;
+ MEMCCPY(state->prompt, prompt_edit_dirty, LINE_DEFAULT, temp);
+ state->prompt_callback = next_untranslated_callback;
+ return 0;
+ }
+
for (e = state->msgid_number; e < state->msgid_count; e++)
{
current = state->entries + e;
if (!current->msgstr || !*current->msgstr
|| u32_strlen(*current->msgstr) == 0)
{
- saved_show_edit = state->show_edit;
- if (saved_show_edit)
- {
- if (state->dirty)
- save_msgstr(state);
- else /* No need to call cancel_msgstr */
- state->dirty = state->dirty_before_edit;
- }
-
goto_msgid(state, e + 1);
-
- if (saved_show_edit)
+ if (state->show_edit)
{
state->msgstr_index = 0;
show_edit(state);
}
-
return 0;
}
}
return 0;
}
+static int
+next_untranslated_callback(struct DrawState* state, struct tb_event* ev)
+{
+ assert((state != NULL) && (ev != NULL));
+ if (strchr("Yy", ev->ch))
+ {
+ state->reshow_edit = state->show_edit;
+ save_msgstr(state);
+ }
+ state->edit_dirty = 0;
+ return next_untranslated(state);
+}
+
static size_t
next_msgid(struct DrawState* state, const int delta)
{
@@ -1900,7 +1986,7 @@ paste_paste_buffer_to_input(struct DrawState* state)
state->input_display_column = 0;
init_coord(&state->input_first_shown, 0, 0);
state->input_rows_count = 1;
- state->dirty = 1;
+ state->edit_dirty = 1;
return 0;
}
@@ -1943,7 +2029,7 @@ paste_paste_buffer_to_input(struct DrawState* state)
state->input_rows_count = state->paste_count;
state->input_buffer = newbuf;
- state->dirty = 1;
+ state->edit_dirty = 1;
return 0;
paste_paste_buffer_alloc_error:
@@ -2106,19 +2192,39 @@ prev_msgid(struct DrawState* state, const int delta)
static int
prev_plural(struct DrawState* state)
{
+ char* temp = NULL;
assert(state != NULL);
if (state->edit_info_focused)
{
state->error = ERR_DLG_FOCUS_EDIT;
return 1;
}
- save_msgstr(state);
+ if (state->edit_dirty)
+ {
+ state->in_prompt = 1;
+ MEMCCPY(state->prompt, prompt_edit_dirty, LINE_DEFAULT, temp);
+ state->prompt_callback = prev_plural_callback;
+ return 0;
+ }
if (state->msgstr_index > 0)
state->msgstr_index--;
show_edit(state);
return 0;
}
+static int
+prev_plural_callback(struct DrawState* state, struct tb_event* ev)
+{
+ assert((state != NULL) && (ev != NULL));
+ if (strchr("Yy", ev->ch))
+ {
+ state->reshow_edit = state->show_edit;
+ save_msgstr(state);
+ }
+ state->edit_dirty = 0;
+ return prev_plural(state);
+}
+
int
print_error(const int code, const char* msg, ...)
{
@@ -2145,7 +2251,7 @@ quit_callback(struct DrawState* state, struct tb_event* ev)
{
int result = 0;
assert((state != NULL) && (ev != NULL));
- if (ev->ch == 'y')
+ if (strchr("Yy", ev->ch))
result = write_file(state);
state->prompt_callback = NULL;
state->running = 0;
@@ -2179,7 +2285,10 @@ save_msgstr(struct DrawState* state)
ssize_t i;
assert(state != NULL);
- state->show_edit = 0;
+ if (state->reshow_edit)
+ state->reshow_edit = 0;
+ else
+ state->show_edit = 0;
state->edit_info_focused = 0;
if (state->input_buffer)
@@ -2218,16 +2327,16 @@ save_msgstr(struct DrawState* state)
for (i = 0; i < state->info_rows_count; i++)
free_bufferline(&state->info_buffer[i]);
free(state->info_buffer);
- state->dirty = (state->dirty_before_edit || state->dirty);
- // state->dirty_before_edit = 0;
+ state->dirty = 1;
+ state->edit_dirty = 0;
state->info_rows_count = 0;
state->info_buffer = NULL;
- if (u32_encode_tabs(state, to_save, to_save_size * sizeof(uint32_t)) <
- 0)
+ if (u32_encode_tabs(state, to_save, to_save_size * sizeof(uint32_t)) < 0)
goto save_msgstr_error;
current = &state->entries[state->msgid_number - 1];
if (u32_match_msgid_ending(state, current->msgid, to_save,
- to_save_size * sizeof(uint32_t)) < 0)
+ to_save_size * sizeof(uint32_t))
+ < 0)
goto save_msgstr_error;
u32_set_msgstr(state, current, to_save, state->msgstr_index, 0);
update_warning(current->msgid, to_save, ¤t->warning);
@@ -2281,8 +2390,6 @@ show_edit(struct DrawState* state)
return 1;
}
- state->dirty_before_edit = state->dirty;
- state->dirty = 0;
state->fuzzy_before_edit = state->fuzzy_count;
state->input_changed_fuzzy = UNCHANGED;
state->show_edit = 1;
@@ -2347,7 +2454,7 @@ toggle_fuzzy(struct DrawState* state)
else
state->input_changed_fuzzy = CLEARED;
}
- state->dirty = 1;
+ state->edit_dirty = 1;
}
return 0;
}
@@ -2454,8 +2561,9 @@ write_file(struct DrawState* state)
state->running = 0;
return result;
}
- state->error = ERR_NONE;
- state->dirty = 0;
+ state->error = ERR_NONE;
+ state->edit_dirty = 0;
+ state->dirty = 0;
return 0;
}
diff --git a/poe.h b/poe.h
@@ -10,7 +10,9 @@ static int copy_msgid_to_input(struct DrawState* state);
int cp(const char* from, const char* to);
static char* dirname(char* dir, char* path, const ssize_t dir_size);
static int edit_page_down(struct DrawState* state);
+static int edit_page_down_callback(struct DrawState* state, struct tb_event* ev);
static int edit_page_up(struct DrawState* state);
+static int edit_page_up_callback(struct DrawState* state, struct tb_event* ev);
static int erase_backwards(struct DrawState* state);
static int erase_forward(struct DrawState* state);
static int erase_prev_word(struct DrawState* state);
@@ -65,9 +67,13 @@ static int move_search_start(struct DrawState* state);
static int move_start(struct DrawState* state);
static int move_up(struct DrawState* state);
static int next_fuzzy(struct DrawState* state);
+static int next_fuzzy_callback(struct DrawState* state, struct tb_event* ev);
static int next_match(struct DrawState* state);
static int next_plural(struct DrawState* state);
+static int next_plural_callback(struct DrawState* state, struct tb_event* ev);
static int next_untranslated(struct DrawState* state);
+static int next_untranslated_callback(struct DrawState* state,
+ struct tb_event* ev);
static size_t next_msgid(struct DrawState* state, const int delta);
static int overwrite_copy_msgid_callback(struct DrawState* state,
struct tb_event* ev);
@@ -79,6 +85,7 @@ static void position_to(struct DrawState* state, const int row,
static int prev_match(struct DrawState* state);
static size_t prev_msgid(struct DrawState* state, const int delta);
static int prev_plural(struct DrawState* state);
+static int prev_plural_callback(struct DrawState* state, struct tb_event* ev);
int print_error(const int code, const char* msg, ...);
static int quit_callback(struct DrawState* state, struct tb_event* ev);
int redraw_status(struct DrawState* state);
diff --git a/util.c b/util.c
@@ -85,13 +85,13 @@ u32_match_msgid_ending(struct DrawState* state, const uint32_t* msgid,
ssize_t msgid_len = 0;
assert((state != NULL) && (msgstr != NULL));
+ if (!msgid)
+ return 0;
+
buf = calloc(max + 1, sizeof(uint32_t));
if (!buf)
goto u32_match_msgid_ending_alloc_error;
- if (!msgid)
- return 0;
-
buf_len = u32_strncpy(buf, msgstr, (max + 1) * sizeof(uint32_t));
msgid_len = u32_strlen(msgid);
@@ -109,8 +109,7 @@ u32_match_msgid_ending(struct DrawState* state, const uint32_t* msgid,
else if (match_msgstr_ending && msgid_len > 0
&& u32_strstr(space_dot, msgid + msgid_len - 1))
{
- if (!(buf_len > 0
- && u32_strstr(space_dot, buf + buf_len - 1)))
+ if (!(buf_len > 0 && u32_strstr(space_dot, buf + buf_len - 1)))
{
buf_len++;
buf[buf_len - 1] = msgid[msgid_len - 1];
@@ -131,7 +130,7 @@ u32_match_msgid_ending(struct DrawState* state, const uint32_t* msgid,
}
u32_strncpy(msgstr, buf, max);
-
+ free(buf);
return buf_len;
u32_match_msgid_ending_alloc_error: