aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c64
-rw-r--r--readme.md2
2 files changed, 53 insertions, 13 deletions
diff --git a/main.c b/main.c
index 0e89e0e..c1c5c76 100644
--- a/main.c
+++ b/main.c
@@ -52,7 +52,6 @@ typedef struct {
} task_st;
typedef struct {
- // TODO Validate usage of size_t and ptrdiff_t variables.
task_st *tasks;
size_t count; // Will always be equal or less than capacity.
size_t capacity; // Will always be equal or less than PTRDIFF_MAX (see MAX_DATABASE_TASKS).
@@ -86,7 +85,7 @@ char *db_file_path = NULL;
char *ar_file_path = NULL;
char *string_buffer = NULL; // A temporary buffer for localized actions. Please avoid data leaks and out-of-bounds errors.
size_t string_buffer_size = 0;
-int size_x, size_y, pos_x, pos_y; // WIP Validating usage of size_t variables.
+int size_x, size_y, pos_x, pos_y;
void trigger_autosave() {
countdown_to_autosave = 13375; // ms
@@ -122,6 +121,8 @@ bool is_equal_to_any(const char *to_compare, const char *test_a, const char *tes
size_t truncate_string_utf8(char *string, size_t length) { // TODO Rename to truncate_utf_string
assert(string != NULL);
+ // TODO Review this function...
+
// Count continuation bytes.
size_t idx = length;
while (idx > 0 && ((string[idx - 1] & 0xC0) == 0x80)) {
@@ -129,14 +130,18 @@ size_t truncate_string_utf8(char *string, size_t length) { // TODO Rename to tru
}
int continuation_bytes = length - idx;
- // Adjust length if missing continuation bytes.
- if (idx > 0 // Not empty.
- // Continuation bytes are not complete.
- && (!(continuation_bytes == 0 && (string[idx - 1] & 0x80) == 0x00)
- && !(continuation_bytes == 1 && (string[idx - 1] & 0xE0) == 0xC0)
- && !(continuation_bytes == 2 && (string[idx - 1] & 0xF0) == 0xE0)
- && !(continuation_bytes == 3 && (string[idx - 1] & 0xF8) == 0xF0))
- ) {
+ // If string starts with continuation bytes, it's an invalid UTF8 string.
+ if (idx == 0 && continuation_bytes > 0) {
+ length = 0;
+ }
+ // If length truncates some continuation bytes, remove incomplete UTF8 character.
+ else if (idx > 0 // string is not empty
+ // continuation bytes are not complete
+ && !(continuation_bytes == 0 && (string[idx - 1] & 0x80) == 0x00)
+ && !(continuation_bytes == 1 && (string[idx - 1] & 0xE0) == 0xC0)
+ && !(continuation_bytes == 2 && (string[idx - 1] & 0xF0) == 0xE0)
+ && !(continuation_bytes == 3 && (string[idx - 1] & 0xF8) == 0xF0)
+ ) {
length -= (continuation_bytes + 1);
}
@@ -144,6 +149,41 @@ size_t truncate_string_utf8(char *string, size_t length) { // TODO Rename to tru
return length;
}
+// TODO Used to test the truncate_string_utf8
+void test_truncate_string_utf8() {
+ char t_a[] = { (char)0x61, (char)0x3A, (char)0xC3, (char)0xB3, 'a', 0 };
+ char t_b[] = { (char)0xC3, (char)0xB3, 0 };
+ char t_c[] = { (char)0xB3, 0 };
+ char t[1024];
+
+ fprintf(stderr, "a --- --- ---\n");
+ for (int l = 5; l >= 0; l--) {
+ memset(t, 0, 1024);
+ memcpy(t, t_a, 6);
+ fprintf(stderr, "%d : '%s'", l , t);
+ truncate_string_utf8(t, l);
+ fprintf(stderr, " '%s'\n", t);
+ }
+
+ fprintf(stderr, "b --- --- ---\n");
+ for (int l = 2; l >= 0; l--) {
+ memset(t, 0, 1024);
+ memcpy(t, t_b, 3);
+ fprintf(stderr, "%d : '%s'", l , t);
+ truncate_string_utf8(t, l);
+ fprintf(stderr, " '%s'\n", t);
+ }
+
+ fprintf(stderr, "c --- --- ---\n");
+ for (int l = 1; l >= 0; l--) {
+ memset(t, 0, 1024);
+ memcpy(t, t_c, 2);
+ fprintf(stderr, "%d : '%s'", l , t);
+ truncate_string_utf8(t, l);
+ fprintf(stderr, " '%s'\n", t);
+ }
+}
+
// Returns true when the string is empty or consists of white space characters.
bool is_empty_string(char *string) {
for (int idx = 0; string[idx] != '\0'; idx++) {
@@ -473,7 +513,7 @@ void update_total_times(database_st *db) {
int64_t *totals = db->total_times;
memset(totals, 0, NUM_WEEK_DAYS * SIZEOF_INT64);
- for (size_t idx = 0; idx < db->count; idx++) { // TODO WIP Here may be dragons because of for loop on an unsigned var.
+ for (size_t idx = 0; idx < db->count; idx++) {
int64_t *times = db->tasks[idx].times;
totals[0] = add_int64(totals[0], times[0]);
totals[1] = add_int64(totals[1], times[1]);
@@ -962,7 +1002,7 @@ void draw_tui(database_st *db, layout_st *layout) {
int column_width;
// TODO This is some sort of pagination to allow scrolling through the tasks.
- // TODO How does this behaves when no task is selected? Well!
+ // TODO Review this code.
y = 0;
size_t idx_start = (db->selected_task / layout_tasks_rows) * layout_tasks_rows;
size_t idx_stop = idx_start + (layout_tasks_rows > db->count - idx_start ? db->count - idx_start : layout_tasks_rows);
diff --git a/readme.md b/readme.md
index b3cabbe..008ceb7 100644
--- a/readme.md
+++ b/readme.md
@@ -71,6 +71,6 @@ Task Time Tracker
- [x] Check if draw_tui may be simplified by drawing entire lines of tasks at once and draw columns separators after;
- By having each column-print job decoulpled, we avoid havint to measure and compensate lengths of UTF8 strings;
- [x] Review all code for bugs related to auto-cast on ptrdiff_t (signed/unsigned);
-- [ ] Review all code for bugs related to auto-cast on size_t (signed/unsigned);
+- [x] Review all code for bugs related to auto-cast on size_t (signed/unsigned);
- [ ] Try to fix flickering of ncurses;
- [ ] Go over all `TODO` items;