table

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

чување 369805ab4ce05c2c10d067bbd5d7a369cf8b6e13
родитељ dfceadf55b39395b50db10dc4f15941fbf1b19b0
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Wed, 17 May 2023 16:30:52 +0200

Also make the truncated part of cells honor alignment (they always
short-circuited to left alignment)

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

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

diff --git a/defs.h b/defs.h @@ -11,6 +11,8 @@ #define ANSI_SGR_BOLD_ON "\e[1m" #define ANSI_SGR_BOLD_OFF "\e[0m" +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + typedef unsigned char UBYTE; typedef unsigned int UINT; typedef unsigned long ULONG; diff --git a/table.c b/table.c @@ -151,6 +151,18 @@ startswith(const char* s, const char* what) return result; } +size_t +current_column_width() +{ + return format ? format[current_table_column] : format_value; +} + +int +within_column(size_t column_start, size_t current_rune_column) +{ + return current_rune_column < column_start + current_column_width(); +} + int set_symbol_set(char* arg, int* current_symbol_set, int* current_inner_symbol_set) { @@ -364,31 +376,138 @@ set_quotes_behavior(const char* arg, int* quotes) } int +skip_while_sgr(const u8* s, size_t* char_delta, int also_print, int whole_string) +{ + const u8* ps = s; + + *char_delta = 0; + while (*ps) + { + if (*ps != '\e' || *(ps + 1) != '[') + { + if (whole_string) + { + ps++; + continue; + } + else + return 0; + } + + if (also_print) + { + printf("%c", (char)*ps++); + printf("%c", (char)*ps++); + } + else + ps += 2; + *char_delta += 2; + + while (*ps && *(ps - 1) != 'm') + { + if (also_print) + printf("%c", (char)*ps++); + else + ps++; + (*char_delta)++; + } + } + return 0; +} + +int print_aligned(const u8* s, size_t rune_length, size_t to_size, Alignment align, size_t* current_rune_column) { size_t i; + const u8* ps = s; + u32 uch; + size_t ch_len; + size_t colwidth = current_column_width(); + size_t output_runes = 0; + size_t skipped_runes = 0; + size_t output_chars = 0; + size_t skipped_chars = 0; if (align == ALIGN_CENTER) - for (i = 0; i < (to_size - rune_length) / 2; i++) + for (i = 0; 2 * i + rune_length < to_size; i++) { printf(" "); (*current_rune_column)++; } else if (align == ALIGN_RIGHT) - for (i = 0; i < (to_size - rune_length); i++) + for (i = 0; i + rune_length < to_size; i++) { printf(" "); (*current_rune_column)++; } - printf("%s", s); - (*current_rune_column) += rune_length; - if (align == ALIGN_CENTER) - for (i = 0; i < (to_size - rune_length) / 2; i++) + + if (align == ALIGN_LEFT) + { + output_runes = 0; + while (output_runes != MIN(rune_length, colwidth)) { - printf(" "); - (*current_rune_column)++; + skip_while_sgr(ps, &skipped_chars, 1, 0); + ps += skipped_chars; + + u8_char_to_u32(&uch, ps, &ch_len); + output_chars = 0; + while (output_chars != ch_len) + { + printf("%c", (char)*ps++); + output_chars++; + } + output_runes++; + } + skip_while_sgr(ps, &skipped_chars, 1, 1); + ps += skipped_chars; + } + else if (align == ALIGN_CENTER) + { + skipped_runes = 0; + while (2 * skipped_runes + to_size < rune_length) + { + skip_while_sgr(ps, &skipped_chars, 1, 0); + ps += skipped_chars; + + u8_char_to_u32(&uch, ps, &ch_len); + ps += ch_len; + skipped_runes++; + } + + output_runes = 0; + while (output_runes != MIN(rune_length, colwidth)) + { + skip_while_sgr(ps, &skipped_chars, 1, 0); + ps += skipped_chars; + + u8_char_to_u32(&uch, ps, &ch_len); + output_chars = 0; + while (output_chars != ch_len) + { + printf("%c", (char)*ps++); + output_chars++; + } + output_runes++; + } + skip_while_sgr(ps, &skipped_chars, 1, 1); + ps += skipped_chars; + } + else if (align == ALIGN_RIGHT) + { + skipped_runes = 0; + while (skipped_runes + to_size < rune_length) + { + skip_while_sgr(ps, &skipped_chars, 1, 0); + ps += skipped_chars; + + u8_char_to_u32(&uch, ps, &ch_len); + ps += ch_len; + skipped_runes++; } + printf("%s", (char*)ps); + } + (*current_rune_column) += rune_length; return 0; } @@ -424,14 +543,6 @@ round_div(UINT a, UINT b) } int -within_column(size_t column_start, size_t current_rune_column) -{ - return format ? (current_rune_column - < column_start + *(format + current_table_column)) - : (current_rune_column < column_start + format_value); -} - -int main(int argc, char** argv) { char* arg; @@ -869,8 +980,7 @@ continue_line: if (uch == delimiter && !in_quote && current_table_column < table_columns - 1) { - size_t colwidth = format ? *(format + current_table_column) - : format_value; + size_t colwidth = current_column_width(); if (handle_ansi && lineno == 0) poutbuf += sprintf((char*)poutbuf, "%s", @@ -917,26 +1027,19 @@ continue_line: } else if (!ch_len) /* UTF-8 error */ { - if (within_column(column_start, - current_rune_column + outbufrunelen)) - { - sprintf((char*)poutbuf, "%c", *pline++); - poutbuf++; - outbufrunelen++; - } + sprintf((char*)poutbuf, "%c", *pline); + poutbuf++; + outbufrunelen++; + pline++; colno++; } else if (uch == (u32)L'\t' && expand_tabs) { - while (within_column(column_start, - current_rune_column + outbufrunelen)) + while ((current_rune_column + outbufrunelen) % tab_length != 0) { sprintf((char*)poutbuf, " "); poutbuf++; outbufrunelen++; - if ((current_rune_column + outbufrunelen) % tab_length - == 0) - break; } pline++; colno++; @@ -944,15 +1047,9 @@ continue_line: else { pch_end = pline + ch_len; - if (within_column(column_start, - current_rune_column + outbufrunelen)) - { - while (pline != pch_end) - poutbuf += sprintf((char*)poutbuf, "%c", - *pline++); - outbufrunelen++; - } - pline = pch_end; + while (pline != pch_end) + poutbuf += sprintf((char*)poutbuf, "%c", *pline++); + outbufrunelen++; colno += ch_len; } goto do_line;