table

Помоћни програм из командне линије за форматирање и приказ CSV-а
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 79c840be376d62dc2a8a3d670fdf38bfc22280f8
родитељ 922278a1b54fe9e766099bbcb0c5e1d892dcab05
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Wed, 17 Feb 2021 22:30:47 +0100

WIP 2021-02

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
Mdefs.h | 6++++++
Mtable.c | 245+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
измењених датотека: 2, додавања: 196(+), брисања: 55(-)

diff --git a/defs.h b/defs.h @@ -35,6 +35,7 @@ #define VERSION "0.1.2-beta" #define BUFSIZE 4096 +#define SMALL_BUFSIZE 256 // Minimal table column width without the borders // | A | B | C | @@ -53,11 +54,16 @@ typedef enum TRUE = 1 } BOOL; +typedef unsigned char UBYTE; +typedef unsigned int UINT; +typedef unsigned long ULONG; + typedef enum { CMD_NONE, CMD_COLUMNS, CMD_DELIMITER, + CMD_FORMAT, CMD_SYMBOLS, CMD_VERSION } Command; diff --git a/table.c b/table.c @@ -20,7 +20,7 @@ #include "defs.h" #define CHECKEXITNOMEM(ptr) { if (!ptr) exit(error(ENOMEM, \ - (uint8_t*)"Memory allocation failed (out of memory?)\n")); } + (uint8_t*)"Memory allocation failed (out of memory?)")); } #define CALLOC(ptr, ptrtype, nmemb) { ptr = calloc(nmemb, sizeof(ptrtype)); \ CHECKEXITNOMEM(ptr) } @@ -32,12 +32,50 @@ #define REALLOCARRAY(ptr, membtype, newcount) \ REALLOC(ptr, membtype, sizeof(membtype) * newcount) +#define CHECKCOPY(token, ptoken, token_size, parg) { \ + if (ptoken + 2 > token + token_size) \ + { \ + size_t old_size = token_size; \ + token_size += BUFSIZE; \ + REALLOC(token, char, token_size) \ + ptoken = token + old_size - 1; \ + } \ + *ptoken++ = *parg++; } + +#define CHECKSET(format, pformat, format_size, num) { \ + if (pformat + 2 > format + format_size) \ + { \ + size_t old_size = format_size; \ + format_size += BUFSIZE; \ + REALLOC(format, ULONG, format_size) \ + pformat = format + old_size - 1; \ + } \ + *pformat++ = num; } + #define WITHIN_COLUMN (current_rune_column < \ (current_table_column+1) * max_table_column_width \ + current_table_column) #define WITHIN_SINGLE_COLUMN (current_rune_column < rune_columns-2) +size_t colno = 0; +size_t lineno = 0; +int current_symbol_set = TABLE_SYMBOLS_DOUBLE; +int current_inner_symbol_set = TABLE_INNER_DOUBLE_SINGLE; +size_t current_table_column = 0; +size_t current_rune_column = 0; +size_t max_table_column_width = MIN_TABLE_COL_WIDTH; +size_t table_columns = 0; +size_t rune_columns = 80; +size_t tab_length = 8; +ucs4_t delimiter = ','; +ULONG* format = NULL; +size_t format_size = 0; + +BOOL handle_ansi = TRUE; +BOOL border_mode = FALSE; +BOOL expand_tabs = FALSE; + int version() { @@ -63,7 +101,7 @@ error(int code, uint8_t* fmt, ...) va_start(args, fmt); u8_vsnprintf(buf, sizeof(buf), (const char*)fmt, args); va_end(args); - fprintf(stderr, "%s: %s", PROGRAMNAME, buf); + fprintf(stderr, "%s: %s\n", PROGRAMNAME, buf); return code; } @@ -131,7 +169,7 @@ set_symbol_set(char* arg, int* current_symbol_set, } else { - return error(1, (uint8_t*)"Invalid symbol set: %s\n", arg); + return error(1, (uint8_t*)"Invalid symbol set: %s", arg); } return 0; } @@ -141,7 +179,7 @@ set_columns(const char* arg, size_t* cols) { size_t c = strtol(arg, NULL, 10); if (errno == EINVAL || errno == ERANGE) - return error(1, (uint8_t*)"Invalid numeric value: %s\n", arg); + return error(1, (uint8_t*)"Invalid numeric value: %s", arg); else *cols = c; return 0; @@ -169,6 +207,76 @@ set_delimiter(uint8_t* arg, ucs4_t* delimiter) return -1; } +int +set_format(const char* arg, ULONG** format, size_t* format_size) +{ + const char* parg = arg; + ULONG* pformat = NULL; + char* token = NULL; + size_t token_size = BUFSIZE; + char* ptoken = NULL; + ULONG num; + + CALLOC(token, char, token_size) + ptoken = token; + *format_size = SMALL_BUFSIZE; + CALLOC(*format, ULONG, *format_size) + pformat = *format; + + while (*parg) + { + if (!((*parg >= '0' && *parg <= '9') || *parg == ':')) + { + free(token); + free(*format); + *format = NULL; + return 1; + } + if (*parg == ':') + { + if (parg == arg || !*(parg+1)) + { + free(token); + free(*format); + *format = NULL; + return 2; + } + num = strtol(token, NULL, 10); + if (errno) + { + perror("strtol"); + free(token); + free(*format); + *format = NULL; + return 3; + } + CHECKSET(*format, pformat, *format_size, num) + *token = 0; + ptoken = token; + parg++; + } + else + CHECKCOPY(token, ptoken, token_size, parg) + } + if (*token) + { + num = strtol(token, NULL, 10); + if (errno) + { + perror("strtol"); + free(token); + free(*format); + *format = NULL; + return 3; + } + CHECKSET(*format, pformat, *format_size, num) + } + + free(token); + + return 0; +} + /* Return number of columns based on the input line */ size_t number_of_columns(const uint8_t* input, ucs4_t delimiter) @@ -211,22 +319,24 @@ get_max_table_column_width(size_t rune_columns, size_t table_columns) : result; } +BOOL +within_column() +{ + if (format) + { + } + else + { + } + return TRUE; +} + int main(int argc, char** argv) { char* arg; - Command cmd = CMD_NONE; - char* filename = NULL; - int current_symbol_set = TABLE_SYMBOLS_DOUBLE; - int current_inner_symbol_set = TABLE_INNER_DOUBLE_SINGLE; - size_t table_columns = 0; - size_t max_table_column_width = MIN_TABLE_COL_WIDTH; - size_t rune_columns = 80; - size_t tab_length = 8; - ucs4_t delimiter = ','; - BOOL handle_ansi = TRUE; - BOOL border_mode = FALSE; - BOOL expand_tabs = FALSE; + Command cmd = CMD_NONE; + char* filename = NULL; while ((arg = *++argv)) { @@ -234,7 +344,6 @@ main(int argc, char** argv) { arg++; char c = *arg++; - int result; if (c == '-') { if (!strcmp(arg, "version")) @@ -247,22 +356,27 @@ main(int argc, char** argv) else if (startswith(arg, "columns=")) { arg += strlen("columns="); - result = set_columns(arg, &rune_columns); - if (result) - return result; + if (set_columns(arg, &rune_columns)) + return error(EINVAL, (uint8_t*)"Invalid argument: '%s'", + arg); } else if (startswith(arg, "delimiter=")) { arg += strlen("delimiter="); - result = set_delimiter((uint8_t*)arg, &delimiter); - if (result) - return result; + if (set_delimiter((uint8_t*)arg, &delimiter)) + return error(EINVAL, (uint8_t*)"Invalid argument: '%s'", + arg); } else if (startswith(arg, "expand-tabs")) { arg += strlen("expand-tabs"); expand_tabs = TRUE; } + else if (startswith(arg, "format=")) + { + arg += strlen("format="); + set_format(arg, &format, &format_size); + } else if (startswith(arg, "no-ansi")) { arg += strlen("no-ansi"); @@ -271,16 +385,16 @@ main(int argc, char** argv) else if (startswith(arg, "symbols=")) { arg += strlen("symbols="); - result = set_symbol_set(arg, &current_symbol_set, - &current_inner_symbol_set); - if (result) - return result; + if (set_symbol_set(arg, &current_symbol_set, + &current_inner_symbol_set)) + return error(EINVAL, (uint8_t*)"Invalid argument: '%s'", + arg); } else if (!strcmp(arg, "help")) return usage(); else { - error(1, (uint8_t*)"Invalid argument: --%s\n", arg); + error(EINVAL, (uint8_t*)"Invalid argument: --%s", arg); return usage(); } } @@ -297,6 +411,9 @@ main(int argc, char** argv) case 'd': cmd = CMD_DELIMITER; break; + case 'f': + cmd = CMD_FORMAT; + break; case 'h': return usage(); break; @@ -313,32 +430,33 @@ main(int argc, char** argv) cmd = CMD_VERSION; break; default: - error(1, (uint8_t*)"Invalid argument: -%c\n", c); + error(EINVAL, (uint8_t*)"Invalid argument: -%c", c); return usage(); } } } else { - int result; - if (cmd == CMD_SYMBOLS) + if (cmd == CMD_COLUMNS) { - result = set_symbol_set(arg, &current_symbol_set, - &current_inner_symbol_set); - if (result) - return result; + if (set_columns(arg, &rune_columns)) + return error(EINVAL, (uint8_t*)"Invalid argument: '%s'", arg); } - else if (cmd == CMD_COLUMNS) + else if (cmd == CMD_DELIMITER) { - result = set_columns(arg, &rune_columns); - if (result) - return result; + if (set_delimiter((uint8_t*)arg, &delimiter)) + return error(EINVAL, (uint8_t*)"Invalid argument: '%s'", arg); } - else if (cmd == CMD_DELIMITER) + else if (cmd == CMD_FORMAT) + { + if (set_format(arg, &format, &format_size)) + return error(EINVAL, (uint8_t*)"Invalid argument: '%s'", arg); + } + else if (cmd == CMD_SYMBOLS) { - result = set_delimiter((uint8_t*)arg, &delimiter); - if (result) - return result; + if (set_symbol_set(arg, &current_symbol_set, + &current_inner_symbol_set)) + return error(EINVAL, (uint8_t*)"Invalid argument: '%s'", arg); } else filename = arg; @@ -354,23 +472,39 @@ main(int argc, char** argv) { input = fopen(filename, "r"); if (!input) - return error(ENOENT, (uint8_t*)"File not found: %s\n", filename); + return error(ENOENT, (uint8_t*)"File not found: %s", filename); } else input = stdin; - uint8_t* line = NULL; - CALLOC(line, uint8_t, BUFSIZE) - size_t pline_len = 0; - uint8_t* pline = NULL; - BOOL quote = FALSE; - size_t colno = 0; - size_t lineno = 0; + uint8_t* line = NULL; + size_t pline_len = 0; + uint8_t* pline = NULL; + BOOL quote = FALSE; ucs4_t uch; - size_t ch_len = 0; - size_t current_table_column = 0; - size_t current_rune_column = 0; + size_t ch_len = 0; + CALLOC(line, uint8_t, BUFSIZE) + + if (format) + { + ULONG* pformat = format; + ULONG format_sum = 0; + while (*pformat) + { + format_sum += *pformat; + pformat++; + } + pformat = format; + while (*pformat) + { + printf("format++ = %lu/%lu = %lu\n", *pformat, format_sum, + (rune_columns-1) * (*pformat) / format_sum); + pformat++; + } + } + else + printf("format not set\n"); while (!feof(input)) { char* eol = NULL; @@ -543,8 +677,9 @@ main(int argc, char** argv) } fclose(input); - free(line); + if (format) + free(format); current_table_column = 0; for (size_t col = 0; col < rune_columns; col++)