From d102e028aee6571c0fd9dfd4074cfb3c15f4594e Mon Sep 17 00:00:00 2001 From: "Gabriel A. Giovanini" Date: Sat, 17 Feb 2024 11:41:23 +0100 Subject: ref: Refactor newer folder structure Create a lib dict and importer project. * dict: holds the main application * importer: code to read from source to a common database. * lib: shared code --- lib/CMakeLists.txt | 5 +++ lib/data.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/data.h | 47 +++++++++++++++++++++ lib/list.c | 55 +++++++++++++++++++++++++ lib/list.h | 29 +++++++++++++ lib/ui.c | 87 +++++++++++++++++++++++++++++++++++++++ lib/ui.h | 23 +++++++++++ lib/util.c | 61 ++++++++++++++++++++++++++++ lib/util.h | 15 +++++++ 9 files changed, 439 insertions(+) create mode 100644 lib/CMakeLists.txt create mode 100644 lib/data.c create mode 100644 lib/data.h create mode 100644 lib/list.c create mode 100644 lib/list.h create mode 100644 lib/ui.c create mode 100644 lib/ui.h create mode 100644 lib/util.c create mode 100644 lib/util.h (limited to 'lib') diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 0000000..023cdf1 --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB lib CONFIGURE_DEPENDS "*.h" "*.c") + +add_library(lib ${lib}) +target_compile_options(lib PRIVATE -Wall -Wextra -Wpedantic -Werror) +target_link_libraries(lib sqlite3 ncursesw m c) diff --git a/lib/data.c b/lib/data.c new file mode 100644 index 0000000..7ebf597 --- /dev/null +++ b/lib/data.c @@ -0,0 +1,117 @@ +#include +#include +#include + +#include "data.h" + +const char *insert_into = "INSERT INTO words (LINE) VALUES($VVV);"; +const char *select_words = "SELECT Id, Line FROM words WHERE line like $VVV LIMIT 10;"; +const char *create_table = "CREATE TABLE IF NOT EXISTS words (ID INTEGER PRIMARY KEY AUTOINCREMENT, LINE TEXT NOT NULL);"; + +Data* new_data(const char* con) { + Data* data = (Data*)malloc(sizeof(Data)); + + int v = sqlite3_open(con, &(data->db)); + if (v != SQLITE_OK) { + print_result_code(v); + return NULL; + } + + sqlite3_enable_load_extension(data->db, 1); + v = sqlite3_load_extension(data->db, "ext/libsqlite3ext", "sqlite3_spellfix_init",0); + if (v != SQLITE_OK) { + print_result_code(v); + return NULL; + } + + return data; +} + +void free_data(Data* data) { + sqlite3_close(data->db); + free(data); +} + +void insert(Data* data, char* line, int len) { + sqlite3_stmt *stmt; + int r = sqlite3_prepare_v2(data->db, insert_into, -1, &stmt, NULL); + + if (r != SQLITE_OK) { + printf("Error executing insert: "); + print_result_code(r); + printf("\n"); + return; + } + + sqlite3_bind_text(stmt, 1, line, len, NULL); + + int c = sqlite3_step(stmt); + if (c != SQLITE_DONE) { + printf("Error executing insert: "); + print_result_code(r); + printf("\n"); + } + + sqlite3_finalize(stmt); +} + +void bootstrap(Data* data) { + sqlite3_stmt *stmt; + int r = sqlite3_prepare_v2(data->db, create_table, -1, &stmt, NULL); + + if (r != SQLITE_OK) { + printf("Error preparing bootstrap: "); + print_result_code(r); + printf("\n"); + return; + } + + int c = sqlite3_step(stmt); + if (c != SQLITE_DONE) { + printf("Error executing bootstrap: "); + print_result_code(r); + printf("\n"); + } + + sqlite3_finalize(stmt); +} + +LIST* data_select(Data* data, char *sch, int len) { + sqlite3_stmt *stmt; + int r = sqlite3_prepare_v2(data->db, select_words, -1, &stmt, NULL); + + if (r != SQLITE_OK) { + printf("Error executing select: "); + print_result_code(r); + printf("\n"); + return NULL; + } + + LIST *list = NULL; + + sqlite3_bind_text(stmt, 1, sch, len, NULL); + + int m = sqlite3_step(stmt); + while(m == SQLITE_ROW) { + Word *word = (Word*)malloc(sizeof(Word)); + + int id = sqlite3_column_int(stmt, 0); + const unsigned char *line = sqlite3_column_text(stmt, 1); + unsigned char *line2 = malloc(sizeof(char*)+strlen((char*)line)); + memcpy(line2, line, strlen((char*)line)); + + word->Id = id; + word->Line = line2; + list = list_add(list, word); + + m = sqlite3_step(stmt); + } + + sqlite3_finalize(stmt); + + return list; +} + +void print_result_code(int code) { + printf(sqlite3_errstr(code)); +} diff --git a/lib/data.h b/lib/data.h new file mode 100644 index 0000000..56edd34 --- /dev/null +++ b/lib/data.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "list.h" + +/* + * This word into the dictionary + */ +typedef struct word { + int Id; + const unsigned char *Line; +} Word; + +/* + * This is database connection. + */ +typedef struct data { + sqlite3 *db; +} Data; + + +/* + * create a new data struct from sqlite filename. + */ +Data* new_data(const char*); + + +void free_data(Data*); + +/* + * Create the tables. + */ +void bootstrap(Data*); + +/* + * insert line into database. + */ +void insert(Data*, char*, int); + +/* + * Select all words. + */ +LIST* data_select(Data*, char*, int); + +/* + * Print result code from sqlite. + */ +void print_result_code(int error); diff --git a/lib/list.c b/lib/list.c new file mode 100644 index 0000000..fc0fddf --- /dev/null +++ b/lib/list.c @@ -0,0 +1,55 @@ +#include "list.h" +#include + +LIST* list_add(LIST* list, void* item) +{ + + if (list == NULL) + { + list = (LIST*)malloc(sizeof(LIST)); + list->size = 0; + list->list = (void**)malloc(sizeof(0)); + + } + + list->size ++; + void** new_list = (void**)reallocarray(list->list, list->size, sizeof(void*)); + + new_list[list->size-1] = item; + list->list = new_list; + + return list; + +} + +LIST* list_remove(LIST* list, unsigned int pos) +{ + for(unsigned int i = pos; i < list->size - 1; i++) + list->list[i] = list->list[i + 1]; + + list->size--; + + void** new_list = reallocarray(list->list, list->size, sizeof(void*)); + list->list = new_list; + + return list; +} + +void list_free(LIST* list) { + for (unsigned int x = 0; x < list->size; x++) + free(list->list[x]); + + free(list->list); + free(list); +} + + +void *list_get(LIST *list, unsigned int index) { + if (list == NULL) + return NULL; + + if (index < list->size) + return list->list[index]; + + return NULL; +} diff --git a/lib/list.h b/lib/list.h new file mode 100644 index 0000000..dd28722 --- /dev/null +++ b/lib/list.h @@ -0,0 +1,29 @@ +#pragma once +#include + +#define LIST_SIZE_FACTOR 1.5 +struct list { + unsigned int size; + unsigned int allocated_size; + void** list; +}; + +typedef struct list LIST; + +/** +* Add an item to a list +* @list: array list structure. +* @item: item to be added to the list. +*/ +LIST* list_add(LIST* list, void* item); + +/** +* Remove an item from a given list +* @list: array list structure. +* @pos: position of item to be removed. +*/ +LIST *list_remove(LIST *list, unsigned int pos); + +void list_free(LIST* list); + +void *list_get(LIST *list, unsigned int index); diff --git a/lib/ui.c b/lib/ui.c new file mode 100644 index 0000000..1a285a0 --- /dev/null +++ b/lib/ui.c @@ -0,0 +1,87 @@ +#define NCURSES_WIDECHAR 1 + +#include +#include +#include +#include +#include +#include "ui.h" + +const char *uload = "█"; + +PROGRESS_BAR* new_progress_bar(WINDOW* scr, float total) { + PROGRESS_BAR *bar = (PROGRESS_BAR*)malloc(sizeof(PROGRESS_BAR)); + bar->scr = scr; + bar->total = total; + bar->current = 0; + return bar; +} + +void bar_step(PROGRESS_BAR* bar, float step){ + bar->current += step; + + int x, y; + int hx, hy; + + getmaxyx(bar->scr, y, x); + + hx = x/2; + hy = y/2; + + float total = (bar->current/bar->total); + + wmove(bar->scr, hy-1, 0); + for (int i = 0; i < ((float)x*total); i++) + wprintw(bar->scr, uload); + + wmove(bar->scr, hy, hx-4); + wprintw(bar->scr,"%03.0f%% ", total*100); + + int len = floor(log10(abs((int)bar->total))) + 3; + + wmove(bar->scr, hy+1, hx - len); + wprintw(bar->scr, "%.0f/%.0f", bar->current, bar->total); + + + wmove(bar->scr,0,0); + wrefresh(bar->scr); +} + + +TEXT_BOX* new_text_box(WINDOW* scr, int length) { + TEXT_BOX *text = (TEXT_BOX*)malloc(sizeof(TEXT_BOX)); + text->scr = scr; + text->length = length; + text->current = 0; + text->text = malloc(sizeof(char)*(length+1)); + memset(text->text, '\0', length); + return text; +} + +void get_char(TEXT_BOX* text, void (*sch)(char*, int)) { + while(1){ + wchar_t c; + get_wch((wint_t*)&c); + + switch(c) { + case KEY_BACKSPACE: + if (text->current > 0) { + text->text[text->current--] = '\0'; + } + break; + default: + if (text->current < (text->length-2)) { + text->text[text->current] = c; + text->text[++text->current] = '\0'; + } + } + + char str[text->length]; + wcstombs(str, text->text, sizeof(text->text)); + sch(str, (int)strlen(str)); + + move(0,0); + wrefresh(text->scr); + wprintw(text->scr, "%*ls", text->current,text->text); + } +} diff --git a/lib/ui.h b/lib/ui.h new file mode 100644 index 0000000..90b352f --- /dev/null +++ b/lib/ui.h @@ -0,0 +1,23 @@ +#pragma once +#include + +typedef struct progress_bar { + float total; + float current; + WINDOW *scr; +} PROGRESS_BAR; + +PROGRESS_BAR* new_progress_bar(WINDOW*, float); +void bar_step(PROGRESS_BAR*, float); + + +typedef struct text_box { + wchar_t *text; + int length; + int current; + WINDOW *scr; +} TEXT_BOX; + +TEXT_BOX* new_text_box(WINDOW*, int); +void get_char(TEXT_BOX* text, void (*sch)(char*, int)); + diff --git a/lib/util.c b/lib/util.c new file mode 100644 index 0000000..6720082 --- /dev/null +++ b/lib/util.c @@ -0,0 +1,61 @@ +#include +#include +#include + +#include "util.h" + +#define BUF_SIZE 100 + +char* copy_achar(const char* src) { + int len = strlen(src) + 1; + char* dest = (char*)malloc(sizeof(char)*len); + strcpy(dest, src); + + return dest; +} + + +int load_or_save_db(sqlite3 *pInMemory, const char *zFilename, int isSave){ + int rc; /* Function return code */ + sqlite3 *pFile; /* Database connection opened on zFilename */ + sqlite3_backup *pBackup; /* Backup object used to copy data */ + sqlite3 *pTo; /* Database to copy to (pFile or pInMemory) */ + sqlite3 *pFrom; /* Database to copy from (pFile or pInMemory) */ + + rc = sqlite3_open(zFilename, &pFile); + if( rc==SQLITE_OK ){ + pFrom = (isSave ? pInMemory : pFile); + pTo = (isSave ? pFile : pInMemory); + + pBackup = sqlite3_backup_init(pTo, "main", pFrom, "main"); + if( pBackup ){ + (void)sqlite3_backup_step(pBackup, -1); + (void)sqlite3_backup_finish(pBackup); + } + rc = sqlite3_errcode(pTo); + } + + (void)sqlite3_close(pFile); + return rc; +} + +unsigned int count_file_lines(FILE *file) { + char buf[BUF_SIZE]; + unsigned int counter = 0; + for(;;) + { + size_t res = fread(buf, 1, BUF_SIZE, file); + if (ferror(file)) + return -1; + + size_t i; + for(i = 0; i < res; i++) + if (buf[i] == '\n') + counter++; + + if (feof(file)) + break; + } + + return counter; +} diff --git a/lib/util.h b/lib/util.h new file mode 100644 index 0000000..c03dbae --- /dev/null +++ b/lib/util.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +/* + * Copy of a char to a newly created string of the same size. + */ +char* copy_achar(const char*); + + +int load_or_save_db(sqlite3 *pInMemory, const char *zFilename, int isSave); + + +unsigned int count_file_lines(FILE *file); -- cgit v1.2.3