чување 0196d46eb718a69e9930b04d104c92ae434491bb
родитељ 9b5d8320dcb8d4fd9db780a7571701fecfd13297
Аутор: Страхиња Радић <sr@strahinja.org>
Датум: Thu, 18 Jul 2024 15:14:19 +0200
Add assert(3) calls (non-exhaustive, first version)
Diffstat:
| M | config.mk | | | 4 | ++-- |
| M | draw.c | | | 65 | +++++++++++++++++++++++++++++++++++------------------------------ |
| M | sled.c | | | 286 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
| M | util.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--;