table

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

чување c6141a030663ddd5dd2c00ec3a9669c7ef39c6da
родитељ 0c51010dca54dc9191dbff187be84a3db0129eaa
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Tue, 22 Sep 2020 20:34:54 +0200

Added options, updated usage()

Diffstat:
Mdefs.h | 33+++++++++++++++++++++++++++++++++
Mtable | 0
Mtable.c | 190+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
измењених датотека: 3, додавања: 181(+), брисања: 42(-)

diff --git a/defs.h b/defs.h @@ -20,6 +20,15 @@ #ifndef __DEFS_H #define __DEFS_H +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistr.h> +#include <unistdio.h> +#include <uniwidth.h> + #define PROGRAMNAME "table" #define VERSION "0.1" @@ -28,6 +37,8 @@ typedef enum { CMD_NONE, + CMD_COLUMNS, + CMD_SYMBOLS, CMD_VERSION } Command; @@ -38,5 +49,27 @@ enum TABLE_SYMBOLS_DOUBLE }; +static const uint8_t* table_symbols[][9] = +{ + [TABLE_SYMBOLS_ASCII] = { + // ascii + (uint8_t*)"+", (uint8_t*)"-", (uint8_t*)"+", + (uint8_t*)"|", (uint8_t*)" ", (uint8_t*)"|", + (uint8_t*)"+", (uint8_t*)"-", (uint8_t*)"+", + }, + [TABLE_SYMBOLS_SINGLE] = { + // single + (uint8_t*)"\u250c", (uint8_t*)"\u2500", (uint8_t*)"\u2510", + (uint8_t*)"\u2502", (uint8_t*)" ", (uint8_t*)"\u2502", + (uint8_t*)"\u2514", (uint8_t*)"\u2500", (uint8_t*)"\u2518", + }, + [TABLE_SYMBOLS_DOUBLE] = { + // double + (uint8_t*)"\u2554", (uint8_t*)"\u2550", (uint8_t*)"\u2557", + (uint8_t*)"\u2551", (uint8_t*)" ", (uint8_t*)"\u2551", + (uint8_t*)"\u255a", (uint8_t*)"\u2550", (uint8_t*)"\u255d", + } +}; + #endif diff --git a/table b/table Бинарне датотеке се разликују. diff --git a/table.c b/table.c @@ -17,13 +17,6 @@ * */ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistr.h> -#include <unistdio.h> -#include <uniwidth.h> #include "defs.h" int @@ -36,10 +29,25 @@ version() int usage() { - printf("Usage: %s [options]\n", PROGRAMNAME); + printf("Usage: %s [options] [filename]\n", PROGRAMNAME); printf(" Where [options] is one or more of the following:\n"); - printf(" -h or --help Prints this usage information screen\n"); - printf(" -v or --version Prints program version and exits\n"); + printf(" -c [cols]\n"); + printf(" --columns=[cols]\n"); + printf(" Set maximum table width in columns (default 80)\n"); + printf("\n"); + printf(" -h\n"); + printf(" --help\n"); + printf(" Prints this usage information screen\n"); + printf("\n"); + printf(" -s [set]\n"); + printf(" --symbols=[set]\n"); + printf(" Use table symbol set [set], where [set] is one\n"); + printf(" of the following:\n"); + printf(" ascii | single | double (default)\n"); + printf("\n"); + printf(" -v\n"); + printf(" --version\n"); + printf(" Prints program version and exits\n"); return 0; } @@ -55,8 +63,28 @@ error(int code, uint8_t* fmt, ...) return code; } +char* +substr(char* src, int start, int finish) +{ + int len = strlen(src); + if (finish > len) + finish = len; + int substr_len = finish-start; + if (substr_len < 0) + substr_len = 0; + char* result = (char*) malloc(sizeof(char) * (substr_len+1)); + + for (int i = start; i < finish && *(src+i) != '\0'; i++) + { + *result++ = *(src+i); + } + *result = '\0'; + + return result-substr_len; +} + uint8_t* -substr(uint8_t* src, int start, int finish) +u8_substr(uint8_t* src, int start, int finish) { int len = u8_strlen(src); if (finish > len) @@ -76,25 +104,86 @@ substr(uint8_t* src, int start, int finish) } int +set_symbol_set(char* arg, int* current_symbol_set) +{ + if (!strcmp(arg, "ascii")) + { + *current_symbol_set = TABLE_SYMBOLS_ASCII; + } + else if (!strcmp(arg, "single")) + { + *current_symbol_set = TABLE_SYMBOLS_SINGLE; + } + else if (!strcmp(arg, "double")) + { + *current_symbol_set = TABLE_SYMBOLS_DOUBLE; + } + else + { + return error(1, (uint8_t*)"Invalid symbol set: %s\n", arg); + } + return 0; +} + +int +set_columns(char* arg, int* cols) +{ + int c = strtol(arg, NULL, 10); + if (errno == EINVAL || errno == ERANGE) + { + return error(1, "Invalid numeric value: %s\n", arg); + } + else + { + *cols = c; + } + return 0; +} + +int main(int argc, char** argv) { char* arg; Command cmd = CMD_NONE; + char* filename = NULL; + int current_symbol_set = TABLE_SYMBOLS_DOUBLE; + int cols = 80; - while ((arg = *argv++)) + while ((arg = *++argv)) { - if (*arg++ == '-') + if (*arg == '-') { + arg++; char c = *arg++; + int result; if (c == '-') { if (!strcmp(arg, "version")) { cmd = CMD_VERSION; } + else if (!strcmp(substr(arg, 0, strlen("columns=")), "columns=")) + { + arg += strlen("columns="); + result = set_columns(arg, &cols); + if (result) + return result; + } + else if (!strcmp(substr(arg, 0, strlen("symbols=")), "symbols=")) + { + arg += strlen("symbols="); + result = set_symbol_set(arg, &current_symbol_set); + if (result) + return result; + + } + else if (!strcmp(arg, "help")) + { + return usage(); + } else { - error(1, "Invalid argument: --%s\n", arg); + error(1, (uint8_t*)"Invalid argument: --%s\n", arg); return usage(); } } @@ -102,16 +191,46 @@ main(int argc, char** argv) { switch (c) { + case 'c': + cmd = CMD_COLUMNS; + break; + case 'h': + return usage(); + break; + case 's': + cmd = CMD_SYMBOLS; + break; case 'v': cmd = CMD_VERSION; break; default: - error(1, "Invalid argument: -%c\n", c); + error(1, (uint8_t*)"Invalid argument: -%c\n", c); return usage(); } } } - arg++; + else + { + int result; + if (cmd == CMD_SYMBOLS) + { + result = set_symbol_set(arg, &current_symbol_set); + if (result) + return result; + cmd = CMD_NONE; + } + else if (cmd == CMD_COLUMNS) + { + result = set_columns(arg, &cols); + if (result) + return result; + cmd = CMD_NONE; + } + else + { + filename = arg; + } + } } if (cmd == CMD_VERSION) @@ -121,40 +240,28 @@ main(int argc, char** argv) uint8_t line[BUFSIZE]; - static const uint8_t* table_symbols[][9] = + FILE* input = NULL; + if (filename) { - [TABLE_SYMBOLS_ASCII] = { - // ascii - (uint8_t*)"+", (uint8_t*)"-", (uint8_t*)"+", - (uint8_t*)"|", (uint8_t*)" ", (uint8_t*)"|", - (uint8_t*)"+", (uint8_t*)"-", (uint8_t*)"+", - }, - [TABLE_SYMBOLS_SINGLE] = { - // single - (uint8_t*)"\u250c", (uint8_t*)"\u2500", (uint8_t*)"\u2510", - (uint8_t*)"\u2502", (uint8_t*)" ", (uint8_t*)"\u2502", - (uint8_t*)"\u2514", (uint8_t*)"\u2500", (uint8_t*)"\u2518", - }, - [TABLE_SYMBOLS_DOUBLE] = { - // double - (uint8_t*)"\u2554", (uint8_t*)"\u2550", (uint8_t*)"\u2557", - (uint8_t*)"\u2551", (uint8_t*)" ", (uint8_t*)"\u2551", - (uint8_t*)"\u255a", (uint8_t*)"\u2550", (uint8_t*)"\u255d", + input = fopen(filename, "r"); + if (!input) + { + return error(ENOENT, "File not found: %s\n", filename); } - }; - int current_symbol_set = TABLE_SYMBOLS_DOUBLE; + } + else + input = stdin; fprintf(stdout, "%s", table_symbols[current_symbol_set][0]); int col = 0; - int cols = 80; while (col++ < cols-2) fprintf(stdout, "%s", table_symbols[current_symbol_set][1]); fprintf(stdout, "%s\n", table_symbols[current_symbol_set][2]); do { - fgets(line, sizeof(line), stdin); - if (!feof(stdin)) + fgets(line, sizeof(line), input); + if (!feof(input)) { uint8_t* eol = u8_strchr(line, '\n'); if (eol) @@ -162,7 +269,7 @@ main(int argc, char** argv) fprintf(stdout, "%s", table_symbols[current_symbol_set][3]); /*uint8_t format[BUFSIZE];*/ /*sprintf(format, "%%%ds", cols-2);*/ - uint8_t* cropped_line = substr(line, 0, cols-2); + uint8_t* cropped_line = u8_substr(line, 0, cols-2); fprintf(stdout, "%s", cropped_line); /*for (int i = 0; i < cols-2-u8_mblen(cropped_line, BUFSIZE); i++)*/ for (int i = 0; i < cols-2-u8_strwidth(cropped_line, "utf-8"); i++) @@ -174,10 +281,9 @@ main(int argc, char** argv) /*fprintf(stdout, "u8_strlen(s) = %d\n", u8_strlen(cropped_line));*/ } } - while (!feof(stdin)); + while (!feof(input)); fprintf(stdout, "%s", table_symbols[current_symbol_set][6]); col = 0; - cols = 80; while (col++ < cols-2) fprintf(stdout, "%s", table_symbols[current_symbol_set][7]); fprintf(stdout, "%s\n", table_symbols[current_symbol_set][8]);