чување f93dc9f2500a39c11848f4bf156574290297470d
родитељ 8e5abdfb4fea9dfbbcb8781f7edd2b7d543a0600
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Tue, 29 Sep 2020 22:10:11 +0200
Added tests, updated TODO; working on UTF8 support
Diffstat:
измењених датотека: 8, додавања: 112(+), брисања: 39(-)
diff --git a/TODO b/TODO
@@ -3,7 +3,12 @@
* v0.1-alpha
- [ ] Ignore malformed UTF-8 sequences (currently segmentation faults)
+ [ ] Handle tty ANSI codes (test/neofetch.sh)
+
+ [ ] Handle tabs - unwrap to spaces at tab stops (test/lsb_release.sh)
+
+ [ ] Ignore malformed UTF-8 sequences. Currently segmentation faults
+ (test/who-Huw.sh with LC_ALL=sr_RS.UTF8 and cyrillic user names)
[ ] Read and display columns
diff --git a/defs.h b/defs.h
@@ -32,7 +32,15 @@
#define PROGRAMNAME "table"
#define VERSION "0.1-alpha"
-#define BUFSIZE 4096
+#define BUFSIZE 1024
+
+// Minimal table column width without the ending char
+// | A | B | C |
+// ^^^^--This
+// [Max screen columns]
+// [Max table columns] = --------------------
+// MIN_TABLE_COL_WIDTH
+#define MIN_TABLE_COL_WIDTH 4
typedef enum
{
diff --git a/table.c b/table.c
@@ -83,22 +83,11 @@ substr(char* src, int start, int finish)
return result-substr_len;
}
-uint8_t*
-u8_substr(uint8_t* src, size_t start, size_t finish)
+uint32_t*
+u32_substr(uint32_t* src, size_t src_len, size_t start, size_t finish,
+ uint32_t* dest, size_t* dest_len)
{
- uint8_t* substr;
- size_t substr_len = 0;
- uint8_t* psubstr;
-
- uint32_t tempbuf[BUFSIZE];
- size_t tempbuf_len = 0;
- uint32_t* ptempbuf;
-
- uint32_t* substr_u32;
-
- ptempbuf = u8_to_u32(src, u8_strlen(src), tempbuf, &tempbuf_len);
-
- size_t normalized_finish = u8_width(src, BUFSIZE, "utf-8");
+ size_t normalized_finish = src_len;
if (finish < normalized_finish)
normalized_finish = finish;
size_t normalized_start = 0;
@@ -107,13 +96,10 @@ u8_substr(uint8_t* src, size_t start, size_t finish)
if (normalized_start > normalized_finish)
normalized_start = normalized_finish;
size_t len = normalized_finish - normalized_start;
- substr_u32 = u32_cpy_alloc(ptempbuf + start, len);
- substr = (uint8_t*) malloc(BUFSIZE);
- psubstr = u32_to_u8(substr_u32, len, substr, &substr_len);
- u8_cpy(substr, psubstr, substr_len);
- substr[substr_len] = (uint8_t)'\0';
- return substr;
+ dest = u32_cpy(dest, src + normalized_start, len);
+ *dest_len = len;
+ return dest;
}
int
@@ -153,6 +139,21 @@ set_columns(char* arg, int* cols)
return 0;
}
+size_t
+number_of_columns(const uint32_t* input, const size_t tempbuf_len, uint32_t delimiter)
+{
+ size_t result = 0;
+
+ for (size_t i = 0; i < tempbuf_len; i++)
+ {
+ if (input[i] == delimiter)
+ {
+ result++;
+ }
+ }
+ return result;
+}
+
int
main(int argc, char** argv)
{
@@ -160,7 +161,8 @@ main(int argc, char** argv)
Command cmd = CMD_NONE;
char* filename = NULL;
int current_symbol_set = TABLE_SYMBOLS_DOUBLE;
- int cols = 80;
+ size_t max_table_columns = 0;
+ int rune_columns = 80;
while ((arg = *++argv))
{
@@ -178,7 +180,7 @@ main(int argc, char** argv)
else if (!strcmp(substr(arg, 0, strlen("columns=")), "columns="))
{
arg += strlen("columns=");
- result = set_columns(arg, &cols);
+ result = set_columns(arg, &rune_columns);
if (result)
return result;
}
@@ -234,7 +236,7 @@ main(int argc, char** argv)
}
else if (cmd == CMD_COLUMNS)
{
- result = set_columns(arg, &cols);
+ result = set_columns(arg, &rune_columns);
if (result)
return result;
cmd = CMD_NONE;
@@ -267,44 +269,77 @@ main(int argc, char** argv)
fprintf(stdout, "%s", table_symbols[current_symbol_set][0]);
int col = 0;
- while (col++ < cols-2)
+ while (col++ < rune_columns-2)
fprintf(stdout, "%s", table_symbols[current_symbol_set][1]);
fprintf(stdout, "%s\n", table_symbols[current_symbol_set][2]);
+ uint32_t* unicode_line = NULL;
+ size_t unicode_line_len = 0;
+ uint32_t* punicode_line = NULL;
+
+ uint8_t* cropped_line = NULL;
+ size_t cropped_line_len = 0;
+ uint8_t* pcropped_line = NULL;
+
+ uint32_t* unicode_cropped_line = NULL;
+ size_t unicode_cropped_line_len = 0;
+ uint32_t* punicode_cropped_line = NULL;
do
{
fgets(line, sizeof(line), input);
if (!feof(input))
{
- uint8_t* eol = u8_strchr(line, '\n');
+ uint8_t* eol = u8_strchr(line, (ucs4_t)'\n');
if (eol)
- *eol = '\0';
+ *eol = (uint8_t)'\0';
+
+ if (unicode_line)
+ unicode_line = (uint32_t*) realloc(unicode_line, sizeof(uint32_t) * BUFSIZE);
+ else
+ unicode_line = (uint32_t*) malloc(sizeof(uint32_t) * BUFSIZE);
+ unicode_line_len = sizeof(sizeof(uint32_t) * BUFSIZE);
+ punicode_line = u8_to_u32(line, u8_strlen(line), unicode_line,
+ &unicode_line_len);
+
fprintf(stdout, "%s", table_symbols[current_symbol_set][3]);
- /*uint8_t format[BUFSIZE];*/
- /*sprintf(format, "%%%ds", cols-2);*/
- uint8_t* cropped_line = u8_substr(line, 0, cols-2);
+
+ unicode_cropped_line = (uint32_t*) malloc(sizeof(uint32_t) * BUFSIZE);
+ unicode_cropped_line_len = sizeof(sizeof(uint32_t) * BUFSIZE);
+ punicode_cropped_line = u32_substr(punicode_line, unicode_line_len,
+ 0, rune_columns-2,
+ unicode_cropped_line, &unicode_cropped_line_len);
+
if (cropped_line)
+ free(cropped_line);
+ cropped_line = (uint8_t*) malloc(sizeof(uint8_t) * BUFSIZE);
+ cropped_line_len = sizeof(uint8_t) * BUFSIZE;
+ pcropped_line = u32_to_u8(punicode_cropped_line,
+ unicode_cropped_line_len,
+ cropped_line,
+ &cropped_line_len);
+
+ if (pcropped_line)
{
- fprintf(stdout, "%s", cropped_line);
+ pcropped_line[cropped_line_len] = (uint8_t)'\0';
+ fprintf(stdout, "%s", pcropped_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++)
- /*for (int i = 0; i < cols-2-strlen(cropped_line); i++)*/
+
+ for (int i = 0; i < rune_columns-2-u8_width(cropped_line, cropped_line_len, "utf-8"); i++)
{
fprintf(stdout, " ");
}
+
fprintf(stdout, "%s\n", table_symbols[current_symbol_set][5]);
- /*fprintf(stdout, "u8_strlen(s) = %d\n", u8_strlen(cropped_line));*/
}
}
while (!feof(input));
+
fprintf(stdout, "%s", table_symbols[current_symbol_set][6]);
col = 0;
- while (col++ < cols-2)
+ while (col++ < rune_columns-2)
fprintf(stdout, "%s", table_symbols[current_symbol_set][7]);
fprintf(stdout, "%s\n", table_symbols[current_symbol_set][8]);
- /*error(2, "Invalid arguments\n");*/
return 0;
}
diff --git a/test/cp-help.sh b/test/cp-help.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+SRCDIR=.
+
+cp --help | $SRCDIR/table
diff --git a/test/lsb_release.sh b/test/lsb_release.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+SRCDIR=.
+
+lsb_release -a 2>/dev/null | $SRCDIR/table
diff --git a/test/neofetch.sh b/test/neofetch.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+SRCDIR=.
+
+neofetch | $SRCDIR/table
diff --git a/test/uname-a.sh b/test/uname-a.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+SRCDIR=.
+
+uname -a | $SRCDIR/table
diff --git a/test/who-Huw.sh b/test/who-Huw.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+SRCDIR=.
+
+who -Huw | $SRCDIR/table