From 705c02be2e482d9d85a080dcbaad667cd063043a Mon Sep 17 00:00:00 2001 From: ThreshMain Date: Tue, 18 Jan 2022 20:55:07 +0100 Subject: [PATCH] Bug-fix with UTF-8 not correctly calculating the width --- TODO | 1 + custom_string.c | 16 +++++++++----- custom_string.h | 3 ++- main.c | 2 +- string_table.c | 58 +++++++++++++++++++++++++++++++++++-------------- 5 files changed, 57 insertions(+), 23 deletions(-) diff --git a/TODO b/TODO index 9c0691f..3664234 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,5 @@ - [ ] Updated delimiter to string instead of single char + - [ ] Support UTF-8 delimiter - [ ] Add support for more encodings - [x] Implement all options for the printing - [x] Add support for printing to file diff --git a/custom_string.c b/custom_string.c index fbb115f..6b0340d 100644 --- a/custom_string.c +++ b/custom_string.c @@ -8,6 +8,7 @@ string_t *create_string(char *chars, int buffer_size) { strncpy(string->chars, chars, buffer_size); string->length = (int) strlen(chars); string->capacity = buffer_size; + string->char_count = 0; return string; } @@ -16,21 +17,26 @@ string_t *create_string_empty(int buffer_size) { string->chars = (char *) malloc(buffer_size * sizeof(char)); string->length = 0; string->capacity = buffer_size; + string->char_count = 0; return string; } -void append_char_to_string(string_t *string, char c) { - if (string->length + 2 > string->capacity) { +void append_char_to_string(string_t *string, char *c, int length) { + while (string->length + 1 + length > string->capacity) { string->capacity *= 2; string->chars = (char *) realloc(string->chars, sizeof(*string->chars) * string->capacity); } - string->chars[string->length] = c; - string->length++; + for (int i = 0; i < length; ++i) { + string->chars[string->length] = (char) *c; + string->length++; + c++; + } + string->char_count++; string->chars[string->length] = '\0'; } void free_string(string_t *string) { free(string->chars); free(string); -} \ No newline at end of file +} diff --git a/custom_string.h b/custom_string.h index 9048153..15906fb 100644 --- a/custom_string.h +++ b/custom_string.h @@ -2,6 +2,7 @@ #define TABLE_PRINTER_CUSTOM_STRING_H typedef struct { char *chars; + int char_count; int length; // -1 meaning not dynamic int capacity; @@ -11,7 +12,7 @@ string_t *create_string(char *chars, int buffer_size); string_t *create_string_empty(int buffer_size); -void append_char_to_string(string_t *string, char c); +void append_char_to_string(string_t *string, char *c, int length); void free_string(string_t *string); diff --git a/main.c b/main.c index 16957e4..b0afc28 100644 --- a/main.c +++ b/main.c @@ -2,7 +2,7 @@ #include "string_table.h" #include "options.h" -#define VERSION_NAME "0.0.3" +#define VERSION_NAME "0.0.4" void print_version() { printf("Table printer version: %s\n", VERSION_NAME); diff --git a/string_table.c b/string_table.c index 2a3df15..04f9839 100644 --- a/string_table.c +++ b/string_table.c @@ -2,6 +2,7 @@ #include #include #include +#include string_table_t *create_string_table(int width) { string_table_t *string_table = (string_table_t *) malloc(sizeof(string_table_t)); @@ -18,36 +19,61 @@ string_table_t *create_string_table(int width) { string_table_t *get_string_table(options_t *options) { string_table_t *table = NULL; - string_t *buffer = create_string_empty(12); - string_array_t *line = create_string_array(3); + string_t *field_buffer = create_string_empty(12); + string_array_t *line_buffer = create_string_array(3); + + string_t *char_buffer = NULL; int input; int width = 0; while ((input = getc(options->stream)) != EOF) { if (input == options->delimiter) { - add_string_to_array(line, buffer); - buffer = create_string_empty(12); + add_string_to_array(line_buffer, field_buffer); + field_buffer = create_string_empty(12); width++; continue; } if (input == '\n' || input == '\r') { - if(buffer->length == 0) continue; - add_string_to_array(line, buffer); - buffer = create_string_empty(12); + if (field_buffer->length == 0) continue; + add_string_to_array(line_buffer, field_buffer); + field_buffer = create_string_empty(12); width++; if (table == NULL) { table = create_string_table(width); } - add_row_to_table(table, line); - line = create_string_array(3); + add_row_to_table(table, line_buffer); + line_buffer = create_string_array(3); width = 0; } else { - append_char_to_string(buffer, (char) input); + + char current_char = (char) input; + + if (current_char < 0) { + unsigned char value = (unsigned char) current_char; + if (value & 0x40) { + if (char_buffer && char_buffer->length > 0) { + append_char_to_string(field_buffer, char_buffer->chars, char_buffer->length); + free_string(char_buffer); + char_buffer = NULL; + } + } + if (char_buffer == NULL) { + char_buffer = create_string_empty(2); + } + append_char_to_string(char_buffer, ¤t_char, 1); + continue; + } + if (char_buffer && char_buffer->length > 0) { + append_char_to_string(field_buffer, char_buffer->chars, char_buffer->length); + free_string(char_buffer); + char_buffer = NULL; + } + append_char_to_string(field_buffer, ¤t_char, 1); } } - free_string(buffer); - free_string_array(line); + free_string(field_buffer); + free_string_array(line_buffer); return table; } @@ -55,8 +81,8 @@ void recalculate_max_column_length(string_table_t *string_table, string_array_t for (int i = 0; i < string_table->width; ++i) { int max_length = string_table->max_column_length[i]; if (i < new_row->length) { - if (new_row->strings[i]->length > max_length) { - max_length = new_row->strings[i]->length; + if (new_row->strings[i]->char_count > max_length) { + max_length = new_row->strings[i]->char_count; } } else { fprintf(stderr, "Error: column %d is not defined\n", i); @@ -69,7 +95,7 @@ void add_row_to_table(string_table_t *string_table, string_array_t *new_row) { if (string_table->length + 1 > string_table->capacity) { string_table->capacity *= 2; string_table->rows = (string_array_t **) realloc(string_table->rows, - sizeof(*string_table->rows) * string_table->capacity); + sizeof(string_array_t *) * string_table->capacity); } recalculate_max_column_length(string_table, new_row); string_table->rows[string_table->length] = new_row; @@ -154,7 +180,7 @@ void print_table(string_table_t *string_table, options_t *options) { } fprintf(options->out_stream, " "); string_t *string = row->strings[j]; - int padding = string_table->max_column_length[j] - string->length; + int padding = string_table->max_column_length[j] - string->char_count; rotate_color(&color_index, COLOR_COUNT, options); print_aligned_string("%s", string->chars, padding, options->flags & ALIGN_LEFT, options); set_frame_color(options);