--- lbbs/src/editor.c 2025/06/12 03:16:35 1.14 +++ lbbs/src/editor.c 2025/06/12 12:53:49 1.17 @@ -20,6 +20,7 @@ #include "log.h" #include "common.h" #include "str_process.h" +#include "memory_pool.h" #include #include #include @@ -28,6 +29,51 @@ #include #define EDITOR_ESC_DISPLAY_STR "\033[32m*\033[m" +#define EDITOR_MEM_POOL_LINE_PER_CHUNK 1000 +#define EDITOR_MEM_POOL_CHUNK_LIMIT (MAX_EDITOR_DATA_LINES / EDITOR_MEM_POOL_LINE_PER_CHUNK + 1) + +static MEMORY_POOL *p_mp_data_line; +static MEMORY_POOL *p_mp_editor_data; + +int editor_memory_pool_init(void) +{ + if (p_mp_data_line != NULL || p_mp_editor_data != NULL) + { + log_error("Editor mem pool already initialized\n"); + return -1; + } + + p_mp_data_line = memory_pool_init(MAX_EDITOR_DATA_LINE_LENGTH, EDITOR_MEM_POOL_LINE_PER_CHUNK, EDITOR_MEM_POOL_CHUNK_LIMIT); + if (p_mp_data_line == NULL) + { + log_error("Memory pool init error\n"); + return -2; + } + + p_mp_editor_data = memory_pool_init(sizeof(EDITOR_DATA), 1, 1); + if (p_mp_data_line == NULL) + { + log_error("Memory pool init error\n"); + return -3; + } + + return 0; +} + +void editor_memory_pool_cleanup(void) +{ + if (p_mp_data_line != NULL) + { + memory_pool_cleanup(p_mp_data_line); + p_mp_data_line = NULL; + } + + if (p_mp_editor_data != NULL) + { + memory_pool_cleanup(p_mp_editor_data); + p_mp_editor_data = NULL; + } +} EDITOR_DATA *editor_data_load(const char *p_data) { @@ -43,10 +89,10 @@ EDITOR_DATA *editor_data_load(const char return NULL; } - p_editor_data = malloc(sizeof(EDITOR_DATA)); + p_editor_data = memory_pool_alloc(p_mp_editor_data); if (p_editor_data == NULL) { - log_error("malloc(EDITOR_DATA) error: OOM\n"); + log_error("memory_pool_alloc() error\n"); return NULL; } @@ -61,10 +107,10 @@ EDITOR_DATA *editor_data_load(const char (p_editor_data->display_line_lengths[i - 1] > 0 && p_data[line_offsets[i - 1] + p_editor_data->display_line_lengths[i - 1] - 1] == '\n')) { // Allocate new data line - p_data_line = malloc(MAX_EDITOR_DATA_LINE_LENGTH); + p_data_line = memory_pool_alloc(p_mp_data_line); if (p_data_line == NULL) { - log_error("malloc(MAX_EDITOR_DATA_LINE_LENGTH * %d) error: OOM\n", i); + log_error("memory_pool_alloc() error: i = %d\n", i); // Cleanup editor_data_cleanup(p_editor_data); return NULL; @@ -137,17 +183,17 @@ void editor_data_cleanup(EDITOR_DATA *p_ if (p_editor_data->display_line_lengths[i] > 0 && p_editor_data->p_display_lines[i][p_editor_data->display_line_lengths[i] - 1] == '\n') { - free(p_data_line); + memory_pool_free(p_mp_data_line, p_data_line); p_data_line = NULL; } } if (p_data_line != NULL) { - free(p_data_line); + memory_pool_free(p_mp_data_line, p_data_line); } - free(p_editor_data); + memory_pool_free(p_mp_editor_data, p_editor_data); } int editor_data_insert(EDITOR_DATA *p_editor_data, long *p_display_line, long *p_offset, @@ -162,6 +208,9 @@ int editor_data_insert(EDITOR_DATA *p_ed long line_offsets[MAX_EDITOR_DATA_LINE_LENGTH + 1]; long split_line_total; long i, j; + int len; + int eol; + int display_len; if (p_editor_data == NULL || p_last_updated_line == NULL) { @@ -215,16 +264,16 @@ int editor_data_insert(EDITOR_DATA *p_ed { if (p_editor_data->display_line_total >= MAX_EDITOR_DATA_LINES) { - log_error("Split line error, display_line_total(%ld) reach limit(%d)\n", - p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES); + // log_error("Split line error, display_line_total(%ld) reach limit(%d)\n", + // p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES); return -2; } // Allocate new data line - p_data_line = malloc(MAX_EDITOR_DATA_LINE_LENGTH); + p_data_line = memory_pool_alloc(p_mp_data_line); if (p_data_line == NULL) { - log_error("malloc(MAX_EDITOR_DATA_LINE_LENGTH) error: OOM\n"); + log_error("memory_pool_alloc() error\n"); return -2; } @@ -305,8 +354,20 @@ int editor_data_insert(EDITOR_DATA *p_ed // Insert blank display line after last_display_line if (p_editor_data->display_line_total >= MAX_EDITOR_DATA_LINES) { - log_error("display_line_total over limit %d >= %d\n", p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES); - return -3; + // log_error("display_line_total over limit %d >= %d\n", p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES); + // Terminate prior display line with \n, to avoid error on cleanup + if (display_line + i - 1 >= 0 && p_editor_data->display_line_lengths[display_line + i - 1] > 0) + { + len = split_line(p_editor_data->p_display_lines[display_line + i - 1], SCREEN_COLS - 1, &eol, &display_len); + p_editor_data->p_display_lines[display_line + i - 1][len] = '\n'; + p_editor_data->p_display_lines[display_line + i - 1][len + 1] = '\0'; + p_editor_data->display_line_lengths[display_line + i - 1] = len + 1; + } + if (*p_offset >= p_editor_data->display_line_lengths[*p_display_line]) + { + *p_offset = p_editor_data->display_line_lengths[*p_display_line] - 1; + } + break; } for (j = p_editor_data->display_line_total; j > last_display_line + 1; j--) { @@ -335,12 +396,15 @@ int editor_data_insert(EDITOR_DATA *p_ed if (*p_offset >= p_editor_data->display_line_lengths[*p_display_line]) { *p_offset -= p_editor_data->display_line_lengths[*p_display_line]; - (*p_display_line)++; - if (*p_display_line >= p_editor_data->display_line_total) + if (*p_display_line + 1 >= p_editor_data->display_line_total) { log_error("*p_display_line(%d) >= display_line_total(%d)\n", *p_display_line, p_editor_data->display_line_total); } + else + { + (*p_display_line)++; + } } return 0; @@ -455,7 +519,7 @@ int editor_data_delete(EDITOR_DATA *p_ed p_data_line[offset_data_line + len_data_line] = '\0'; // Recycle next data line - free(p_editor_data->p_display_lines[display_line + 1]); + memory_pool_free(p_mp_data_line, p_editor_data->p_display_lines[display_line + 1]); } else { @@ -512,7 +576,7 @@ static int editor_display_key_handler(in { case 0: // Set msg snprintf(p_ctx->msg, sizeof(p_ctx->msg), - "| Í˳ö[\033[32mCtrl-C\033[33m] | °ïÖú[\033[32mh\033[33m] |"); + "| Í˳ö[\033[32mCtrl-W\033[33m] | °ïÖú[\033[32mh\033[33m] |"); break; } @@ -737,7 +801,7 @@ int editor_display(EDITOR_DATA *p_editor case KEY_NULL: case KEY_TIMEOUT: goto cleanup; - case Ctrl('C'): + case Ctrl('W'): loop = 0; break; case Ctrl('S'): // Start of line