diff options
| author | Tristan Riehs <tristan.riehs@inria.fr> | 2025-11-11 14:41:24 +0100 |
|---|---|---|
| committer | Tristan Riehs <tristan.riehs@inria.fr> | 2025-11-11 14:41:24 +0100 |
| commit | 5e53e2acfe669fc0c0df4d39f6ffc9e45d35591a (patch) | |
| tree | ece9ea6e1e58b8eb4fae591491829ccbd12a0342 /src | |
| parent | 799000ebd482e913139708c44fb5d17984451379 (diff) | |
Make progress on ftag add
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 119 |
1 files changed, 107 insertions, 12 deletions
@@ -7,6 +7,11 @@ #define DATABASE_PATH (FTAG_ROOT "/ftag.sqlite3") +struct ftag_command { + const char *name; + void (*func)(int argc, char **argv); +}; + static void ftag_init(int, char **); static void ftag_help(int, char **); static void ftag_tag(int, char **); @@ -18,34 +23,31 @@ static void parse_args(int argc, const struct ftag_command *commands, int command_count); -struct ftag_command { - const char *name; - void (*func)(int argc, char **argv); -}; - static const struct ftag_command toplevel_commands[] = { {.name = "init", .func = ftag_init}, - {.name = "help", .func = ftag_help} + {.name = "help", .func = ftag_help}, + {.name = "tag", .func = ftag_tag} }; static const int toplevel_command_count = sizeof(toplevel_commands) / sizeof(struct ftag_command); -static sqlite3 *db; -static void __sqlite3_check(int rc, sqlite3 *db, const char *file, int line) +static void __sqlite3_check(int rc, sqlite3 *db, const char *file, int line, const char *func) { if (rc == SQLITE_OK) return; - fprintf(stderr, "%s:%d: %s\n", file, line, sqlite3_errmsg(db)); - assert(0); + fprintf(stderr, "%s:%d: %s: %s\n", file, line, func, sqlite3_errmsg(db)); + sqlite3_close(db); + exit(EXIT_FAILURE); } -#define sqlite3_check(RC, DB) __sqlite3_check(RC, DB, __FILE__, __LINE__) +#define sqlite3_check(RC, DB) __sqlite3_check(RC, DB, __FILE__, __LINE__, __func__) static void ftag_init(int, char **) { char cmd[1024]; memset(cmd, 0, sizeof(cmd)); - snprintf(cmd, sizeof(cmd)-1, "sqlite3 %s < %s", DATABASE_PATH, FTAG_ROOT "/sql/init.sql"); + snprintf(cmd, sizeof(cmd)-1, + "sqlite3 %s < %s", DATABASE_PATH, FTAG_ROOT "/sql/init.sql"); execl("/usr/bin/sh", "/usr/bin/sh", "-c", cmd, NULL); perror("exec"); exit(EXIT_FAILURE); @@ -62,6 +64,99 @@ static void ftag_help(int, char **) printf(" ftag root %s\n", FTAG_ROOT); } +/* Check that the tag we are trying to create does not exist yet. If this + * callback is ever called, then it already exist, this is a fatal error. */ +static int ftag_tag_check(void *, int count, char **cols, char **col_names) +{ + assert(cols[1]); + assert(cols[2]); + fprintf(stderr, + "ftag tag add: error: tag %s already exists, its description is:\n", + cols[1]); + fprintf(stderr, "%s\n", cols[2]); + return 1; +} + +static int ftag_tag_last_id(void *_id, int count, char **cols, char **col_names) +{ + printf("%s: count is %d\n", __func__, count); + printf("%s: ", __func__); + for (int i = 0; i < count; i++) { + printf("col_names[%d] = %s\t", i, col_names[i]); + } + printf("\n"); + printf("%s: ", __func__); + for (int i = 0; i < count; i++) { + printf("cols[%d] = %s\t", i, cols[i]); + } + printf("\n"); + + /* int *id = _id; */ + /* assert(count == 1); */ + /* assert(cols); */ + /* assert(cols[0]); */ + /* *id = atoi(cols[0]); */ + return 0; +} + +static void ftag_tag_add(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, + "ftag tag add: error: must supply two arguments, " + "the tag name and its description\n"); + exit(EXIT_FAILURE); + } + const char *new_tag_name = argv[0]; + assert(strlen(new_tag_name) <= 255); + assert(strchr(new_tag_name, '\'') == NULL); + + char sql[1024]; + sqlite3 *db = NULL; + int rc; + + rc = sqlite3_open(DATABASE_PATH, &db); + sqlite3_check(rc, db); + + memset(sql, 0, sizeof(sql)); + snprintf(sql, sizeof(sql)-1, + "SELECT * FROM tags WHERE name = '%s';", new_tag_name); + rc = sqlite3_exec(db, sql, ftag_tag_check, NULL, NULL); + sqlite3_check(rc, db); + + int last_id = -1; + memset(sql, 0, sizeof(sql)); + snprintf(sql, sizeof(sql)-1, "SELECT MAX(id) FROM tags;"); + rc = sqlite3_exec(db, sql, ftag_tag_last_id, &last_id, NULL); + sqlite3_check(rc, db); + + const char *new_tag_desc = argv[1]; + assert(strlen(new_tag_desc) <= 600); + assert(strchr(new_tag_desc, '\'') == NULL); + last_id++; + memset(sql, 0, sizeof(sql)); + snprintf(sql, sizeof(sql)-1, + "INSERT INTO tags VALUES(%d, '%s', '%s');", + last_id, new_tag_name, new_tag_desc); + rc = sqlite3_exec(db, sql, NULL, NULL, NULL); + sqlite3_check(rc, db); +} + +static void ftag_tag_list(int argc, char **argv) +{ + ; +} + +static void ftag_tag(int argc, char **argv) +{ + const struct ftag_command tag_commands[] = { + {.name = "add", .func = ftag_tag_add}, + {.name = "list", .func = ftag_tag_list} + }; + int tag_command_count = sizeof(tag_commands) / sizeof(struct ftag_command); + parse_args(argc, argv, tag_commands, tag_command_count); +} + static void parse_args(int argc, char **argv, const struct ftag_command *commands, |
