чување 79c840be376d62dc2a8a3d670fdf38bfc22280f8
родитељ 922278a1b54fe9e766099bbcb0c5e1d892dcab05
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Wed, 17 Feb 2021 22:30:47 +0100
WIP 2021-02
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
| M | defs.h | | | 6 | ++++++ |
| M | table.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, ¤t_symbol_set,
- ¤t_inner_symbol_set);
- if (result)
- return result;
+ if (set_symbol_set(arg, ¤t_symbol_set,
+ ¤t_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, ¤t_symbol_set,
- ¤t_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, ¤t_symbol_set,
+ ¤t_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++)