sled

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

чување 0196d46eb718a69e9930b04d104c92ae434491bb
родитељ 9b5d8320dcb8d4fd9db780a7571701fecfd13297
Аутор: Страхиња Радић <sr@strahinja.org>
Датум:   Thu, 18 Jul 2024 15:14:19 +0200

Add assert(3) calls (non-exhaustive, first version)

Diffstat:
Mconfig.mk | 4++--
Mdraw.c | 65+++++++++++++++++++++++++++++++++++------------------------------
Msled.c | 286++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mutil.c | 33+++++++++++++++++++--------------
измењених датотека: 4, додавања: 251(+), брисања: 137(-)

diff --git a/config.mk b/config.mk @@ -1,10 +1,10 @@ #CC = cc CFLAGS = -Os -Wextra -Wall -pedantic -std=c99 CPPFLAGS = -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L \ - -D_XOPEN_SOURCE=700 + -D_XOPEN_SOURCE=700 -DNDEBUG # OpenBSD #CPPFLAGS = -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L \ -# -D_XOPEN_SOURCE=700 -D_BSD_SOURCE +# -D_XOPEN_SOURCE=700 -D_BSD_SOURCE -DNDEBUG INSTALL = install LIBS = SRC = draw.c limit.c sled.c util.c diff --git a/draw.c b/draw.c @@ -1,7 +1,7 @@ /* This program is licensed under the terms of GNU GPL v3 or (at your option) * any later version. Copyright (C) 2022-2024 Страхиња Радић. * See the file LICENSE for exact copyright and license details. */ - +#include <assert.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -47,7 +47,7 @@ static const char* help[] = { "Some vi-like keys work in command and selection modes.", "", "See the manual (man sled) for full help."}; -const char* mode_labels[] = { +static const char* mode_labels[] = { [UNKNOWN_MODE] = "UNKNOWN", [COMMAND_MODE] = "COMMAND", [HELP_MODE] = "HELP", @@ -75,7 +75,7 @@ const char* actions[] = { [ACT_READING] = "Reading...", [ACT_WRAPPING] = "Wrapping..." }; -const struct { +static const struct { ssize_t boundary; int width; } number_widths[] = { @@ -88,11 +88,11 @@ const struct { { .boundary = 9, .width = 2 } }; const char* go_to_dialog_title = "Go to line"; -const char* replace_dialog_title = "Replace with"; -const char* search_dialog_title = "Search text"; const char* prompt_dirty = "File changed, save [y/n/ESC]?"; const char* prompt_overwrite = "Not empty, overwrite? [y/n/ESC]?"; const char* prompt_reread_dirty = "File changed, lose changes [y/n/ESC]?"; +const char* replace_dialog_title = "Replace with"; +const char* search_dialog_title = "Search text"; /* clang-format on */ void get_selection(int* ssr, int* ssc, int* ser, int* sec, @@ -136,12 +136,14 @@ buffer_length(uint32_t* buffer, const ssize_t max_index) int calculate_help_width(const struct DrawState* state) { + assert(state != NULL); return state->maxx > HELP_WIDTH + 2 ? HELP_WIDTH : state->maxx - 2; } int calculate_input_dialog_width(const struct DrawState* state) { + assert(state != NULL); return state->maxx > INPUT_DLG_WIDTH + 2 ? INPUT_DLG_WIDTH : state->maxx - 2; } @@ -151,6 +153,7 @@ calculate_line_numbers_width(const struct DrawState* state) { ssize_t last_row; int i; + assert(state != NULL); last_row = MIN(state->rows_count, state->first_shown.row + state->maxy - 1); i = 0; @@ -173,9 +176,7 @@ display_length(uint32_t* buffer, const ssize_t max_index) ssize_t len = 0; int w; - if (!buffer) - return len; - + assert(buffer != NULL); for (ssize_t i = 0; *pbuf && i < max_index; i++) { pbuf = &buffer[i]; @@ -197,23 +198,17 @@ display_length(uint32_t* buffer, const ssize_t max_index) int draw(const struct DrawState* state) { - if (!state) - return 1; - + assert(state != NULL); if (draw_screen(state)) return 1; - if (IN(state->mode, M_HELP)) if (draw_help(state)) return 1; - if (IN(state->mode, M_INPUT)) if (draw_input_dialog(state)) return 1; - if (draw_status(state)) return 1; - return 0; } @@ -256,9 +251,7 @@ draw_help(const struct DrawState* state) int maxx; int maxy; - if (!state) - return 1; - + assert(state != NULL); w = state->help_width; h = HELP_HEIGHT; maxx = state->maxx; @@ -296,9 +289,7 @@ draw_input_dialog(const struct DrawState* state) int len; int dlen = 0; - if (!state) - return 1; - + assert(state != NULL); w = state->input_dialog_width; h = INPUT_DLG_HEIGHT; maxx = state->maxx; @@ -337,6 +328,7 @@ draw_line_number(const struct DrawState* state, const int i, const int cy) char numbuf[LINE_DEFAULT]; char* numbuf_end = NULL; char* pnumbuf = NULL; + assert(state != NULL); snprintf(numbuf, LINE_DEFAULT, "%d", i + 1); numbuf_end = strchr(numbuf, 0); if (numbuf_end) @@ -354,6 +346,7 @@ void draw_rect(const int startx, const int endx, const int starty, const int endy, const uint16_t fg, const uint16_t bg) { + assert((starty < endy) && (startx < endx)); for (int y = starty; y < endy; y++) for (int x = startx; x < endx; x++) tb_set_cell(x, y, ' ', fg, bg); @@ -378,9 +371,7 @@ draw_screen(const struct DrawState* state) int maxx; int fsc; /* First Shown Col */ - if (!state) - return 1; - + assert(state != NULL); maxx = state->maxx; fsc = state->first_shown.col; if (state->line_numbers) @@ -395,6 +386,7 @@ draw_screen(const struct DrawState* state) while (((ssize_t)i < state->rows_count) && (cy < max_screen_lines)) { current = state->buffer + i; + assert(current != NULL); ssi = 0; sei = 0; @@ -446,11 +438,10 @@ draw_status(const struct DrawState* state) char* buf = NULL; ssize_t seg_size; int current_start = 0; - int maxx = state->maxx; - - if (!state) - return 1; + int maxx; + assert(state != NULL); + maxx = state->maxx; seg_size = maxx / LEN(status_segments); pseg = status_segments; @@ -535,7 +526,9 @@ draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg, const uint32_t* srch, const uint16_t sfg, const uint16_t sbg, const int ssi, const int sei, const uint16_t slfg, const uint16_t slbg) { - uint32_t* us = calloc(strlen(s) + 1, sizeof(uint32_t)); + uint32_t* us = NULL; + assert(s != NULL); + us = calloc(strlen(s) + 1, sizeof(uint32_t)); if (!us) return 1; u8_string_to_unicode(us, s, mc); @@ -550,6 +543,7 @@ format_codep(char* result, ssize_t result_size, const char* format, const ssize_t seg_size, const struct DrawState* state) { char codep[LINE_DEFAULT]; + assert((state != NULL) && (format != NULL)); UNUSED(seg_size); if (state->buffer[state->coord.row].text[state->coord.col]) snprintf(codep, LINE_DEFAULT, "%06X", @@ -565,6 +559,8 @@ format_filename(char* result, ssize_t result_size, const char* format, { char* basename = NULL; const char* pbase = NULL; + + assert((state != NULL) && (format != NULL)); if (!result || seg_size < 4) return; @@ -591,6 +587,7 @@ format_mode(char* result, ssize_t result_size, const char* format, const ssize_t seg_size, const struct DrawState* state) { const char* mode_label = mode_labels[UNKNOWN_MODE]; + assert((state != NULL) && (format != NULL)); UNUSED(seg_size); if (!result) goto format_print; @@ -619,6 +616,7 @@ void format_position(char* result, ssize_t result_size, const char* format, const ssize_t seg_size, const struct DrawState* state) { + assert((state != NULL) && (format != NULL)); UNUSED(seg_size); if (!result) return; @@ -647,6 +645,7 @@ free_drawstate(struct DrawState* state, const int skip_paste_free, const int skip_filename_free) { ssize_t row = 0; + assert(state != NULL); for (row = 0; row < state->buffer_size; row++) free_bufferline(state->buffer + row); free(state->buffer); @@ -682,6 +681,7 @@ init_bufferline(struct BufferLine* bl) void init_coord(struct Coord* c, const int col, const int row) { + assert(c != NULL); c->col = col; c->row = row; } @@ -691,6 +691,7 @@ init_drawstate(struct DrawState* state, char* error, char* action, char* filename, char* prompt, const int skip_paste_and_mode_init, const int skip_filenames_init) { + assert(state != NULL); state->error = error; state->action = action; if (!skip_filenames_init) @@ -743,12 +744,14 @@ init_drawstate(struct DrawState* state, char* error, char* action, void recalculate_line_numbers(struct DrawState* state) { + assert(state != NULL); state->line_numbers_width = calculate_line_numbers_width(state); } void recalculate_size(struct DrawState* state) { + assert(state != NULL); state->maxx = tb_width(); state->help_width = calculate_help_width(state); state->input_dialog_width = calculate_input_dialog_width(state); @@ -759,6 +762,7 @@ recalculate_size(struct DrawState* state) void redraw_status(struct DrawState* state) { + assert(state != NULL); if (state->recalculate_size) { recalculate_size(state); @@ -836,6 +840,7 @@ u32_draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg, * reaches zero the highlighting is turned * off */ + assert(s != NULL); c = mc - p_l - p_r; if (align == LEFT) @@ -865,7 +870,7 @@ u32_draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg, * exit condition is also sc == c, when we have reached the maximum * number of characters to output * */ - while (ps && *ps && sc < c) + while (*ps && sc < c) { if ((hctl == 0) && ((ps - s) >= ssi) && ((ps - s) < sei)) { diff --git a/sled.c b/sled.c @@ -2,6 +2,7 @@ * any later version. Copyright (C) 2022-2024 Страхиња Радић. * See the file LICENSE for exact copyright and license details. */ +#include <assert.h> #include <errno.h> #include <fcntl.h> #include <locale.h> @@ -60,17 +61,18 @@ extern const char* errors[]; extern const char* actions[]; extern const char* mode_labels[]; extern const char* go_to_dialog_title; -extern const char* replace_dialog_title; -extern const char* search_dialog_title; extern const char* prompt_dirty; extern const char* prompt_overwrite; extern const char* prompt_reread_dirty; +extern const char* replace_dialog_title; +extern const char* search_dialog_title; -int +static int cancel_close(struct DrawState* state) { char* temp = NULL; + assert(state != NULL); if (!*state->error && !IN(state->mode, M_PROMPT) && !IN(state->mode, M_HELP)) { @@ -90,11 +92,10 @@ cancel_close(struct DrawState* state) return 0; } -int +static int clear_selection(struct DrawState* state) { - if (!state) - return 1; + assert(state != NULL); CLEAR(state->mode, M_SELECTION); init_coord(&state->sel_start, 0, 0); init_coord(&state->sel_end, 0, 0); @@ -106,14 +107,15 @@ clear_selection(struct DrawState* state) static int cp(const char* from, const char* to) { + struct stat st; + struct timespec times[2]; + char buf[MAXCOPYBUF]; int fromfd, tofd; int nread = 0; int nwritten = 0; - char buf[MAXCOPYBUF]; int result; - struct stat st; - struct timespec times[2]; + assert((from != NULL) && (to != NULL)); fromfd = open(from, O_RDONLY); if (fromfd < 0) return 1; @@ -168,6 +170,7 @@ create_file(struct DrawState* state) struct BufferLine* newchunk = NULL; uint32_t* newtext = NULL; + assert(state != NULL); newchunk = calloc(ALLOC_DELTA, sizeof(struct BufferLine)); if (!newchunk) { @@ -199,6 +202,7 @@ create_file(struct DrawState* state) static int cut_to_paste(struct DrawState* state) { + assert(state != NULL); simple_yank(state); erase_selection(state); position_to_selection_start(state); @@ -211,7 +215,8 @@ dirname(char* dir, char* path, const ssize_t dir_size) { char* p = NULL; - if (!dir || !path || !*path) + assert((dir != NULL) && (path != NULL) && (dir_size > 0)); + if (!*path) return NULL; MEMCCPY(dir, path, dir_size, p); @@ -240,20 +245,26 @@ dirname(char* dir, char* path, const ssize_t dir_size) static int do_search_replace(struct DrawState* state) { - uint32_t* buf = NULL; - uint32_t* temp = NULL; + uint32_t* buf = NULL; + uint32_t* temp = NULL; + uint32_t* before = NULL; + uint32_t* found = NULL; + uint32_t* after = NULL; /* minimum size is LINE_DEFAULT to avoid 0-allocation */ ssize_t bufsize = LINE_DEFAULT; /* size in uint32_t units */ ssize_t buflen = 0; ssize_t old_buflen = 0; - ssize_t search_len = u32_strlen(state->search); - ssize_t input_len = u32_strlen(state->input); - ssize_t after_len = 0; - int start_row = 0; - int end_row = state->rows_count; - uint32_t* before = NULL; - uint32_t* found = NULL; - uint32_t* after = NULL; + ssize_t search_len; + ssize_t input_len; + ssize_t after_len = 0; + int start_row = 0; + int end_row; + + assert((state != NULL) && (state->search != NULL) + && (state->input != NULL)); + search_len = u32_strlen(state->search); + input_len = u32_strlen(state->input); + end_row = state->rows_count; if (SEL_NOT_EMPTY(state)) get_selection(&start_row, NULL, &end_row, NULL, state); @@ -326,8 +337,7 @@ do_search_replace_alloc_error: static int enter_command_mode(struct DrawState* state) { - if (!state) - return 1; + assert(state != NULL); SET(state->mode, M_COMMAND); return 0; } @@ -335,8 +345,7 @@ enter_command_mode(struct DrawState* state) static int enter_insert_mode(struct DrawState* state) { - if (!state) - return 1; + assert(state != NULL); CLEAR(state->mode, M_COMMAND); return 0; } @@ -344,7 +353,10 @@ enter_insert_mode(struct DrawState* state) static int erase_backwards(struct DrawState* state) { - struct BufferLine* buffer_line = &state->buffer[state->coord.row]; + struct BufferLine* buffer_line; + + assert(state != NULL); + buffer_line = &state->buffer[state->coord.row]; if (SEL_NOT_EMPTY(state)) { @@ -379,7 +391,10 @@ erase_backwards(struct DrawState* state) static int erase_forward(struct DrawState* state) { - struct BufferLine* buffer_line = &state->buffer[state->coord.row]; + struct BufferLine* buffer_line; + + assert(state != NULL); + buffer_line = &state->buffer[state->coord.row]; if (SEL_NOT_EMPTY(state)) { @@ -413,6 +428,8 @@ erase_line(struct DrawState* state) struct BufferLine* next = NULL; uint32_t* ptext = NULL; char* temp = NULL; + + assert(state != NULL); if (state->rows_count == 1) { *state->buffer[0].text = 0; @@ -445,11 +462,14 @@ erase_line_error: static int erase_prev_word(struct DrawState* state) { - int i = state->coord.col; struct BufferLine* current = NULL; + int i; int d; + assert(state != NULL); + i = state->coord.col; current = state->buffer + state->coord.row; + assert((current != NULL) && (current->text != NULL)); if (i > 0 && u32_is_word_boundary(current->text[i - 1], 0)) i--; @@ -475,19 +495,22 @@ erase_prev_word(struct DrawState* state) static int erase_selection(struct DrawState* state) { + assert(state != NULL); if (SEL_NOT_EMPTY(state)) { + uint32_t* buf = NULL; + uint32_t* temp = NULL; /* Selection start row/col */ int ssr = 0; int ssc = 0; /* Selection end row/col */ - int ser = 0; - int sec = 0; - uint32_t* buf = NULL; - ssize_t bufsize = state->buffer[ser].size; - uint32_t* temp = NULL; + int ser = 0; + int sec = 0; + ssize_t bufsize; - buf = calloc(bufsize, sizeof(uint32_t)); + assert(ser < state->buffer_size); + bufsize = state->buffer[ser].size; + buf = calloc(bufsize, sizeof(uint32_t)); if (!buf) exit(print_error(ENOMEM, "Memory allocation failed")); @@ -529,7 +552,11 @@ erase_selection(struct DrawState* state) static int erase_to_end(struct DrawState* state) { - struct BufferLine* buffer_line = &state->buffer[state->coord.row]; + struct BufferLine* buffer_line; + + assert(state != NULL); + buffer_line = &state->buffer[state->coord.row]; + assert((buffer_line != NULL) && (buffer_line->text != NULL)); if (SEL_NOT_EMPTY(state)) { @@ -549,9 +576,15 @@ erase_to_end(struct DrawState* state) static int erase_to_start(struct DrawState* state) { - ssize_t i = state->coord.col; - struct BufferLine* buffer_line = &state->buffer[state->coord.row]; - ssize_t len = buffer_line->length; + struct BufferLine* buffer_line; + ssize_t i; + ssize_t len; + + assert(state != NULL); + i = state->coord.col; + buffer_line = &state->buffer[state->coord.row]; + assert((buffer_line != NULL) && (buffer_line->text != NULL)); + len = buffer_line->length; if (SEL_NOT_EMPTY(state)) { @@ -563,6 +596,7 @@ erase_to_start(struct DrawState* state) do { + assert(i < buffer_line->length); buffer_line->text[i - state->coord.col] = buffer_line->text[i]; i++; } while (buffer_line->text[i]); @@ -578,6 +612,7 @@ exit_program(struct DrawState* state) { char* temp = NULL; + assert(state != NULL); if (state->dirty) { SET(state->mode, M_PROMPT); @@ -594,6 +629,7 @@ void get_selection(int* ssr, int* ssc, int* ser, int* sec, const struct DrawState* state) { + assert(state != NULL); if (state->sel_start.row == state->sel_end.row) { if (state->sel_start.col <= state->sel_end.col) @@ -648,9 +684,7 @@ go_to_line_callback(struct DrawState* state) char* u8_input = NULL; char* temp = NULL; - if (!state) - return 1; - + assert(state != NULL); if (*state->input) { len = u32_strlen(state->input); @@ -690,9 +724,7 @@ handle_key_event(struct tb_event* ev, struct DrawState* state) const struct Key* current = NULL; char* temp = NULL; - if (!state) - return; - + assert((state != NULL) && (ev != NULL) && (state->error != NULL)); *state->error = 0; if (IN(state->mode, M_PROMPT)) @@ -762,6 +794,7 @@ handle_key_event(struct tb_event* ev, struct DrawState* state) for (size_t key = 0; key < LEN(global_keys); key++) { current = &global_keys[key]; + assert(current != NULL); if (((current->ev.mod == ev->mod) && (current->ev.key == ev->key) && !ev->ch) || (current->ev.ch && (current->ev.ch == ev->ch))) @@ -774,6 +807,7 @@ handle_key_event(struct tb_event* ev, struct DrawState* state) for (size_t key = 0; key < LEN(command_keys); key++) { current = &command_keys[key]; + assert(current != NULL); if (((current->ev.mod == ev->mod) && (current->ev.key == ev->key) && !ev->ch) || (current->ev.ch @@ -809,6 +843,7 @@ handle_key_event(struct tb_event* ev, struct DrawState* state) static int input_cancel(struct DrawState* state) { + assert((state != NULL) && (state->error != NULL)); if (*state->error) { *state->error = 0; @@ -829,6 +864,7 @@ input_enter(struct DrawState* state) { int hide_dialog = 1; + assert((state != NULL) && (state->error != NULL)); if (state->input_callback) { state->input_callback(state); @@ -851,6 +887,7 @@ input_enter(struct DrawState* state) static int input_erase_backwards(struct DrawState* state) { + assert(state != NULL); if (state->input_column > 0) { ssize_t i = state->input_column; @@ -870,6 +907,7 @@ input_erase_backwards(struct DrawState* state) static int input_erase_forward(struct DrawState* state) { + assert(state != NULL); if (state->input) { ssize_t i = state->input_column; @@ -888,7 +926,8 @@ input_erase_forward(struct DrawState* state) static int input_erase_to_end(struct DrawState* state) { - uint32_t* temp = NULL; + uint32_t* temp = NULL; + assert(state != NULL); state->input[state->input_column] = 0; input_move_end(state); U32_MEMCCPY(state->search, state->input, MAXINPUT, temp); @@ -900,11 +939,16 @@ input_erase_to_end(struct DrawState* state) static int input_erase_to_start(struct DrawState* state) { - ssize_t i = state->input_column; - ssize_t len = u32_strlen(state->input); + ssize_t i; + ssize_t len; + + assert(state != NULL); + i = state->input_column; + len = u32_strlen(state->input); do { + assert(i < len); state->input[i - state->input_column] = state->input[i]; i++; } while (state->input[i]); @@ -918,7 +962,9 @@ input_erase_to_start(struct DrawState* state) static int input_insert_char(struct DrawState* state, uint32_t ch) { - ssize_t len = u32_strlen(state->input); + ssize_t len; + assert(state != NULL); + len = u32_strlen(state->input); if (state->input_column + 1 < MAXINPUT) { ssize_t i = len + 1; @@ -953,6 +999,7 @@ input_insert_tab(struct DrawState* state) static int input_move_end(struct DrawState* state) { + assert(state != NULL); input_position_to(state, u32_strlen(state->input)); return 0; } @@ -960,6 +1007,7 @@ input_move_end(struct DrawState* state) static int input_move_left(struct DrawState* state) { + assert(state != NULL); if (state->input_column == 0) return 0; input_position_to(state, state->input_column - 1); @@ -969,10 +1017,14 @@ input_move_left(struct DrawState* state) static int input_move_next_word(struct DrawState* state) { - int i = state->input_column; - uint32_t* pline = state->input; - ssize_t len = u32_strlen(state->input); + uint32_t* pline; + ssize_t len; + int i; + assert((state != NULL) && (state->input != NULL)); + i = state->input_column; + pline = state->input; + len = u32_strlen(state->input); while (i < len && !u32_is_word_boundary(pline[i], 0)) i++; while (i < len && u32_is_word_boundary(pline[i], 0)) @@ -984,9 +1036,13 @@ input_move_next_word(struct DrawState* state) static int input_move_prev_word(struct DrawState* state) { - int i = state->input_column; - uint32_t* pline = state->input; + int i; + uint32_t* pline; + assert((state != NULL) && (state->input != NULL)); + i = state->input_column; + pline = state->input; + assert(pline != NULL); if (i > 0 && u32_is_word_boundary(pline[i - 1], 0)) i--; while (i > 0 && u32_is_word_boundary(pline[i], 0)) @@ -1001,6 +1057,7 @@ input_move_prev_word(struct DrawState* state) static int input_move_right(struct DrawState* state) { + assert(state != NULL); input_position_to(state, state->input_column + 1); return 0; } @@ -1015,7 +1072,10 @@ input_move_start(struct DrawState* state) static void input_position_to(struct DrawState* state, const int column) { - ssize_t len = u32_strlen(state->input); + ssize_t len; + + assert((state != NULL) && (state->input != NULL)); + len = u32_strlen(state->input); state->input_column = column; if (state->input_column > len) @@ -1040,6 +1100,7 @@ insert_char(struct DrawState* state, uint32_t ch) ssize_t len; ssize_t size; + assert((state != NULL) && (state->buffer != NULL)); ENSURE_SIZE(state->buffer[state->coord.row].text, ptext, state->buffer[state->coord.row].size, state->buffer[state->coord.row].length + 2, @@ -1058,6 +1119,7 @@ insert_char(struct DrawState* state, uint32_t ch) size = buffer_line->size; i = len; + assert(buffer_line->text != NULL); if (!IN(state->mode, M_OVERWRITE)) while (i + 1 < size && i > state->coord.col) { @@ -1077,6 +1139,7 @@ insert_char(struct DrawState* state, uint32_t ch) { int saved_column = state->coord.col; buffer_line = state->buffer + state->coord.row; + assert((buffer_line != NULL) && (buffer_line->text != NULL)); state->coord.col = buffer_length(buffer_line->text, wrap_width); /* clang-format off */ while (state->coord.col > 0 @@ -1111,6 +1174,7 @@ insert_line(struct DrawState* state) { struct BufferLine* buffer_line = NULL; + assert(state != NULL); if (SEL_NOT_EMPTY(state)) { erase_selection(state); @@ -1125,12 +1189,14 @@ insert_line(struct DrawState* state) { int saved_column = state->coord.col; buffer_line = state->buffer + state->coord.row; + assert((buffer_line != NULL) && (buffer_line->text != NULL)); state->coord.col = buffer_length(buffer_line->text, wrap_width); + /* clang-format off */ while (state->coord.col > 0 - && !u32_is_word_boundary(buffer_line->text[state->coord.col - - 1], - 1)) + && !u32_is_word_boundary( + buffer_line->text[state->coord.col - 1], 1)) state->coord.col--; + /* clang-format on */ if (state->coord.col == 0) { state->coord.col = saved_column; @@ -1175,8 +1241,10 @@ join_lines(struct DrawState* state) /* Selection end row */ int ser = 0; int selection = 0; - int saved_row = state->coord.row; + int saved_row; + assert(state != NULL); + saved_row = state->coord.row; if (SEL_NOT_EMPTY(state)) { get_selection(&ssr, &ssc, &ser, NULL, state); @@ -1196,8 +1264,10 @@ join_lines(struct DrawState* state) for (int row = ssr; row <= ser; row++) { + assert(ssr + 1 < state->buffer_size); current = state->buffer + ssr; next = state->buffer + ssr + 1; + assert((current != NULL) && (next != NULL)); ENSURE_SIZE(current->text, ptext, current->size, current->length + 3, current->length + LINE_ALLOC_DELTA, join_lines_error, uint32_t); @@ -1244,6 +1314,7 @@ load_file(struct DrawState* state) ssize_t input_size = limits[L_LINE_MAX]; ssize_t input_len = 0; + assert(state != NULL); input_line = calloc(input_size, 1); if (!input_line) { @@ -1370,10 +1441,14 @@ move_left(struct DrawState* state) static int move_next_word(struct DrawState* state) { - int i = state->coord.col; - uint32_t* pline = state->buffer[state->coord.row].text; - ssize_t len = state->buffer[state->coord.row].length; + uint32_t* pline; + ssize_t len; + int i; + assert((state != NULL) && (state->buffer != NULL)); + i = state->coord.col; + pline = state->buffer[state->coord.row].text; + len = state->buffer[state->coord.row].length; while (i < len && !u32_is_word_boundary(pline[i], 0)) i++; while (i < len && u32_is_word_boundary(pline[i], 0)) @@ -1385,6 +1460,7 @@ move_next_word(struct DrawState* state) static int move_page_down(struct DrawState* state) { + assert(state != NULL); if ((state->coord.row + state->maxy) < state->rows_count + 2) position_to(state, state->coord.row + state->maxy - 2, state->coord.col); @@ -1396,6 +1472,7 @@ move_page_down(struct DrawState* state) static int move_page_up(struct DrawState* state) { + assert(state != NULL); if (state->coord.row > state->maxy - 2) position_to(state, state->coord.row - (state->maxy - 2), state->coord.col); @@ -1407,9 +1484,13 @@ move_page_up(struct DrawState* state) static int move_prev_word(struct DrawState* state) { - int i = state->coord.col; - uint32_t* pline = state->buffer[state->coord.row].text; + uint32_t* pline; + int i; + assert((state != NULL) && (state->buffer != NULL)); + i = state->coord.col; + pline = state->buffer[state->coord.row].text; + assert(pline != NULL); if (i > 0 && u32_is_word_boundary(pline[i - 1], 0)) i--; while (i > 0 && u32_is_word_boundary(pline[i], 0)) @@ -1431,6 +1512,7 @@ move_right(struct DrawState* state) static int move_screen_bottom(struct DrawState* state) { + assert(state != NULL); if (state->rows_count + 2 < state->maxy) position_to(state, state->rows_count - 1, state->coord.col); else @@ -1447,6 +1529,7 @@ move_screen_bottom(struct DrawState* state) static int move_screen_middle(struct DrawState* state) { + assert(state != NULL); if (state->rows_count + 2 < state->maxy) position_to(state, state->rows_count / 2, state->coord.col); else @@ -1462,6 +1545,7 @@ move_screen_middle(struct DrawState* state) static int move_screen_top(struct DrawState* state) { + assert(state != NULL); position_to(state, state->first_shown.row, state->coord.col); return 0; } @@ -1469,6 +1553,7 @@ move_screen_top(struct DrawState* state) static int move_start(struct DrawState* state) { + assert(state != NULL); position_to(state, state->coord.row, 0); return 0; } @@ -1476,6 +1561,7 @@ move_start(struct DrawState* state) static int move_top(struct DrawState* state) { + assert(state != NULL); position_to(state, 0, state->coord.col); return 0; } @@ -1483,6 +1569,7 @@ move_top(struct DrawState* state) static int move_up(struct DrawState* state) { + assert(state != NULL); position_to(state, state->coord.row > 1 ? state->coord.row - 1 : 0, state->coord.col); return 0; @@ -1495,6 +1582,7 @@ next_match(struct DrawState* state) const uint32_t* found = NULL; ssize_t idelta; + assert(state != NULL); if (!state->search || !*state->search) return 0; @@ -1524,16 +1612,17 @@ next_match(struct DrawState* state) static int paste_from_paste(struct DrawState* state) { - uint32_t* newtext = NULL; - uint32_t* ptext = NULL; - ssize_t newsize = 0; struct BufferLine* line = NULL; struct BufferLine* newbuf = NULL; - uint32_t* rest = NULL; - ssize_t rest_size = 0; struct Coord newpos; - char* temp = NULL; - + uint32_t* newtext = NULL; + uint32_t* ptext = NULL; + uint32_t* rest = NULL; + char* temp = NULL; + ssize_t newsize = 0; + ssize_t rest_size = 0; + + assert(state != NULL); if (!state->paste_count) return 0; @@ -1677,6 +1766,8 @@ position_to(struct DrawState* state, const int row, const int column) ssize_t dlen; int old_first_shown_row; int maxx; + + assert(state != NULL); maxx = state->maxx; if (state->line_numbers) maxx -= state->line_numbers_width + 2; @@ -1784,6 +1875,7 @@ position_to(struct DrawState* state, const int row, const int column) static int position_to_selection_end(struct DrawState* state) { + assert(state != NULL); if (SEL_NOT_EMPTY(state)) { int ser = 0; @@ -1802,6 +1894,7 @@ position_to_selection_end(struct DrawState* state) static int position_to_selection_start(struct DrawState* state) { + assert(state != NULL); if (SEL_NOT_EMPTY(state)) { int ssr = 0; @@ -1825,6 +1918,7 @@ prev_match(struct DrawState* state) ssize_t idelta; ssize_t row; + assert(state != NULL); if (!state->search || !*state->search) return 0; @@ -1884,9 +1978,7 @@ print_error(const int code, const char* msg, ...) static int quit_callback(struct DrawState* state, struct tb_event* ev) { - if (!state) - return 1; - + assert(state != NULL); if (ev->ch == 'y') if (write_file(state)) return 1; @@ -1898,9 +1990,7 @@ quit_callback(struct DrawState* state, struct tb_event* ev) static int reread_callback(struct DrawState* state, struct tb_event* ev) { - if (!state) - return 1; - + assert(state != NULL); if (strchr("Yy", ev->ch)) if (reread_file(state)) return 1; @@ -1914,6 +2004,7 @@ reread_file(struct DrawState* state) int result; char* temp = NULL; + assert(state != NULL); free_drawstate(state, 1, 1); init_drawstate(state, state->error, state->action, state->filename, state->prompt, 1, 1); @@ -1943,8 +2034,7 @@ reread_or_callback(struct DrawState* state) { char* temp = NULL; - if (!state) - return 1; + assert(state != NULL); if (state->dirty) { SET(state->mode, M_PROMPT); @@ -1959,14 +2049,15 @@ reread_or_callback(struct DrawState* state) static int save_file(struct DrawState* state) { - FILE* output = NULL; + FILE* output = NULL; + struct stat st; char* buf = NULL; char* pbuf = NULL; + char* temp = NULL; ssize_t bufsize = LINE_DEFAULT; - struct stat st; - int result = SAVE_ERR_NONE; - char* temp = NULL; + int result = SAVE_ERR_NONE; + assert(state != NULL); if (!(buf = calloc(bufsize, 1))) return SAVE_ERR_CANT_ALLOC; @@ -2068,6 +2159,7 @@ save_file_cleanup: static int search_dialog_callback(struct DrawState* state) { + assert(state != NULL); next_match(state); if (!*state->error) state->input_callback = NULL; @@ -2077,6 +2169,7 @@ search_dialog_callback(struct DrawState* state) static int search_replace_replace_dialog_callback(struct DrawState* state) { + assert(state != NULL); do_search_replace(state); *state->search = 0; /*u32_strcpy(state->search, state->input); @@ -2090,6 +2183,7 @@ search_replace_replace_dialog_callback(struct DrawState* state) static int search_replace_search_dialog_callback(struct DrawState* state) { + assert(state != NULL); /*next_match(state);*/ if (!*state->error) state->input_callback = NULL; @@ -2111,6 +2205,7 @@ show_go_to_line(struct DrawState* state) { char* temp = NULL; + assert(state != NULL); state->input_title = (char*)go_to_dialog_title; state->input_callback = go_to_line_callback; if (!state->input) @@ -2133,6 +2228,7 @@ show_go_to_line(struct DrawState* state) static int show_help(struct DrawState* state) { + assert(state != NULL); SET(state->mode, M_HELP); *state->error = 0; return 0; @@ -2143,6 +2239,7 @@ show_replace(struct DrawState* state) { char* temp = NULL; + assert(state != NULL); state->input_title = (char*)replace_dialog_title; state->input_callback = search_replace_replace_dialog_callback; state->input_update_callback = NULL; @@ -2169,6 +2266,7 @@ show_search(struct DrawState* state) { char* temp = NULL; + assert(state != NULL); if (!state->search) { if (!(state->search = calloc(MAXINPUT, sizeof(uint32_t)))) @@ -2206,6 +2304,7 @@ show_search_replace(struct DrawState* state) { char* temp = NULL; + assert(state != NULL); if (!state->search) { if (!(state->search = calloc(MAXINPUT, sizeof(uint32_t)))) @@ -2247,6 +2346,7 @@ simple_insert_line(struct DrawState* state) uint32_t* ptext = NULL; char* temp = NULL; + assert(state != NULL); if (state->rows_count + 1 == state->buffer_size) { state->buffer_size += ALLOC_DELTA; @@ -2313,6 +2413,7 @@ simple_join_lines(struct DrawState* state) uint32_t* ptext = NULL; char* temp = NULL; + assert(state != NULL); if ((state->coord.row + 1) == state->rows_count) return; @@ -2359,6 +2460,7 @@ simple_yank(struct DrawState* state) int ser = 0; int sec = 0; + assert(state != NULL); if (!SEL_NOT_EMPTY(state)) { if (state->paste_count > 0) @@ -2461,6 +2563,7 @@ suspend_program(struct DrawState* state) static int toggle_line_numbers(struct DrawState* state) { + assert(state != NULL); state->line_numbers = !state->line_numbers; position_to(state, state->coord.row, state->coord.col); return 0; @@ -2469,6 +2572,7 @@ toggle_line_numbers(struct DrawState* state) static int toggle_overwrite(struct DrawState* state) { + assert(state != NULL); TOGGLE(state->mode, M_OVERWRITE); CLEAR(state->mode, M_COMMAND); return 0; @@ -2477,6 +2581,7 @@ toggle_overwrite(struct DrawState* state) static int toggle_selection(struct DrawState* state) { + assert(state != NULL); TOGGLE(state->mode, M_SELECTION); if (IN(state->mode, M_SELECTION)) assign_coord(&state->sel_start, state->coord); @@ -2505,6 +2610,7 @@ wrap_para(struct DrawState* state) int col; int added_blank = 0; + assert(state != NULL); if (!enable_wrap) goto wrap_not_enabled; @@ -2738,9 +2844,7 @@ write_file(struct DrawState* state) int result; char* temp = NULL; - if (!state) - return 1; - + assert(state != NULL); result = save_file(state); switch (result) { @@ -2786,21 +2890,21 @@ int main(int argc, char** argv) { struct tb_event ev; + struct DrawState state; + struct stat st; char error[LINE_DEFAULT]; char action[LINE_DEFAULT]; char prompt[LINE_DEFAULT]; - struct DrawState state; char* filename = NULL; char* wd = NULL; + char* dir = NULL; + char* pdir = NULL; + char* temp = NULL; + char* rfn = NULL; ssize_t filename_size = 0; - struct stat st; - int result = 0; + int result = 0; int dir_access; int dir_access_errno; - char* dir = NULL; - char* pdir = NULL; - char* temp = NULL; - char* rfn = NULL; *error = 0; *action = 0; diff --git a/util.c b/util.c @@ -1,6 +1,7 @@ /* This program is licensed under the terms of GNU GPL v3 or (at your option) * any later version. Copyright (C) 2022-2024 Страхиња Радић. * See the file LICENSE for exact copyright and license details. */ +#include <assert.h> #include <stdarg.h> #include <stddef.h> #include <stdio.h> @@ -19,7 +20,8 @@ u8_string_to_unicode(uint32_t* us, const char* s, const size_t max) int u8_len = 0; size_t added = 0; - while (s && *s) + assert(s != NULL); + while (*s) { u8_len = tb_utf8_char_to_unicode(&uch, s); if (added + 1 > max) @@ -44,9 +46,7 @@ unicode_string_to_u8(char* s, const uint32_t* us, const size_t max) size_t len; size_t added = 0; - if (!pus) - return added; - + assert((s != NULL) && (us != NULL)); ps = s; while (*pus) { @@ -66,8 +66,8 @@ int u32_has_nonblanks(const uint32_t* s) { const uint32_t* ps = s; - if (!s) - return 0; + + assert(s != NULL); while (*ps) { if (!u32_is_word_boundary(*ps, 1)) @@ -81,6 +81,7 @@ uint32_t* u32_memccpy(uint32_t* dst, const uint32_t* src, uint32_t c, size_t len) { size_t copied = 0; + assert ((dst != NULL) && (src != NULL)); while ((*dst++ = *src++) != c && copied < len) copied++; if (copied == len) @@ -92,11 +93,12 @@ u32_memccpy(uint32_t* dst, const uint32_t* src, uint32_t c, size_t len) uint32_t* u32_u8_memccpy(uint32_t* dst, const char* src, uint32_t c, size_t len) { + const char* psrc = src; + uint32_t uch; size_t copied = 0; int u8_len; - uint32_t uch; - const char* psrc = src; + assert ((dst != NULL) && (src != NULL)); do { if (!*psrc) @@ -126,8 +128,7 @@ u8_strlen(const char* s) uint32_t uc; size_t len; size_t result = 0; - if (!s) - return 0; + assert(s != NULL); while (*ps) { len = tb_utf8_char_to_unicode(&uc, ps); @@ -142,8 +143,7 @@ u32_strlen(const uint32_t* s) { const uint32_t* ps = s; size_t len = 0; - if (!s) - return 0; + assert(s != NULL); while (*ps++) len++; return len; @@ -153,6 +153,7 @@ const uint32_t* u32_strstr(const uint32_t* haystack, const uint32_t* needle) { const uint32_t* ph = haystack; + assert((haystack != NULL) && (needle != NULL)); while (*ph) { if (u32_starts_with(ph, needle)) @@ -169,6 +170,8 @@ u32_strrstr(const uint32_t* haystack, const uint32_t* needle, size_t needle_len = u32_strlen(needle); const uint32_t* ph; + assert((haystack != NULL) && (haystack_tail != NULL) + && (needle != NULL)); if (needle_len > (size_t)(haystack_tail - haystack)) return NULL; @@ -190,6 +193,7 @@ const uint32_t* u32_strchr(const uint32_t* haystack, const uint32_t needle) { const uint32_t* ph = haystack; + assert(haystack != NULL); while (*ph) { if (*ph == needle) @@ -217,6 +221,7 @@ u32_is_word_boundary(const uint32_t ch, const int strictly_whitespace) int starts_with(const char* s, const char* with) { + assert((s != NULL) && (with != NULL)); while (*s && *s == *with) { if (*s != *with) @@ -230,6 +235,7 @@ starts_with(const char* s, const char* with) int u32_starts_with(const uint32_t* s, const uint32_t* with) { + assert((s != NULL) && (with != NULL)); while (*s && *s == *with) { if (*s != *with) @@ -244,8 +250,7 @@ const char* u8_basename(const char* path) { const char* ppath; - if (!path) - return NULL; + assert(path != NULL); ppath = path + strlen(path); while (ppath != path && *ppath != '/') ppath--;