dtree

Програм из командне линије за исцртавање стабала
git clone https://git.sr.ht/~strahinja/dtree
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 18b613f6f287ac2a8fb7ec8bd3537258c5a54121
родитељ 960a99d0ec7b131bb3e800d96ca17b86f7d55110
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Tue,  2 Jul 2024 23:41:49 +0200

Bugfix: string_to_symbol_set undefined for subscripts not in "ads"; 
tidy up; add some checks and assert calls

Diffstat:
Mdtree.c | 51++++++++++++++++++++++++++++++++-------------------
измењених датотека: 1, додавања: 32(+), брисања: 19(-)

diff --git a/dtree.c b/dtree.c @@ -2,6 +2,10 @@ * any later version. Copyright (C) 2023-2024 Страхиња Радић. * See the file LICENSE for exact copyright and license details. */ +/* Comment out to turn on assert(3) */ +#define NDEBUG + +#include <assert.h> #include <errno.h> #include <limits.h> #include <stdarg.h> @@ -39,7 +43,7 @@ enum { TREE_SYMBOLS_ASCII, TREE_SYMBOLS_SINGLE, TREE_SYMBOLS_DOUBLE }; static struct Node* alloc_node(void); static void cleanup(void); -static int error(int code, char* fmt, ...); +static int error(const int code, const char* fmt, ...); static void free_node(struct Node** root); static void insert_node(struct Node** root, const int level, const char* label); static void print_indent(void); @@ -47,7 +51,7 @@ static void print_node(const struct Node* node); static void set_node(struct Node* node, const int level, const char* label); static void usage(void); static void version(const int full); -static void warning(char* fmt, ...); +static void warning(const char* fmt, ...); /* clang-format off */ static const int string_to_symbol_set[] = { @@ -71,9 +75,9 @@ static const u32 tree_symbols[][5] = { }; /* clang-format on */ +static struct Node* root = NULL; static u32* indent = NULL; static u32* pindent = NULL; -static struct Node* root = NULL; static int symbol_set = TREE_SYMBOLS_SINGLE; static struct Node* @@ -88,6 +92,7 @@ alloc_node(void) exit(1); } + assert(newnode != NULL); newnode->level = 0; newnode->label = NULL; newnode->parent = NULL; @@ -108,12 +113,15 @@ cleanup(void) } static int -error(int code, char* fmt, ...) +error(const int code, const char* fmt, ...) { - char buf[LINE_DEFAULT]; va_list args; + char buf[LINE_DEFAULT]; + int psize = 0; va_start(args, fmt); - vsnprintf(buf, sizeof buf, (const char*)fmt, args); + psize = vsnprintf(buf, sizeof buf, fmt, args); + if (psize >= sizeof buf) + buf[sizeof buf - 1] = 0; va_end(args); fprintf(stderr, "%s: %s\n", PROGRAMNAME, buf); return code; @@ -292,12 +300,15 @@ version(const int full) } static void -warning(char* fmt, ...) +warning(const char* fmt, ...) { - char buf[LINE_DEFAULT]; va_list args; + char buf[LINE_DEFAULT]; + int psize = 0; va_start(args, fmt); - vsnprintf(buf, sizeof buf, (const char*)fmt, args); + psize = vsnprintf(buf, sizeof buf, (const char*)fmt, args); + if (psize >= sizeof buf) + buf[sizeof buf - 1] = 0; va_end(args); fprintf(stderr, "%s: %s\n", PROGRAMNAME, buf); } @@ -305,15 +316,15 @@ warning(char* fmt, ...) int main(int argc, char** argv) { - int ch; - FILE* input = NULL; - char* line = NULL; - ssize_t line_delta; - ssize_t line_size; + FILE* input = NULL; + char* line = NULL; char* pline = NULL; char* tpline = NULL; /* Temporary */ char* eol = NULL; - int level = 0; + ssize_t line_delta; + ssize_t line_size; + int ch; + int level = 0; #ifdef __OpenBSD__ if (pledge("stdio rpath unveil", NULL) < 0) @@ -331,10 +342,12 @@ main(int argc, char** argv) usage(); exit(0); case 's': - if ((symbol_set = string_to_symbol_set[(int)*optarg]) - == -1) + if (!strchr("ads", *optarg)) exit(error(1, "Invalid symbol set: '%s'", optarg)); + assert((*optarg == 'a') || (*optarg == 'd') + || (*optarg == 's')); + symbol_set = string_to_symbol_set[(int)*optarg]; break; case 'V': version(1); @@ -393,6 +406,7 @@ main(int argc, char** argv) do_input: if (feof(input)) goto done_input; + assert((pline - line >= 0) && (pline - line < line_size)); if (!fgets(pline, line_size - (pline - line), input)) goto done_input; @@ -436,6 +450,7 @@ do_input: done_input: free(line); + atexit(&cleanup); if (input != stdin) fclose(input); @@ -447,8 +462,6 @@ done_input: } pindent = indent; - atexit(&cleanup); - print_node(root); return 0;