From 7a2e38d00390007348ebba3e75efb65b2e8d4fd8 Mon Sep 17 00:00:00 2001 From: Ben Winston Date: Sun, 5 May 2024 18:13:45 -0400 Subject: main.c -> booki.c --- main.c | 312 ----------------------------------------------------------------- 1 file changed, 312 deletions(-) delete mode 100644 main.c (limited to 'main.c') diff --git a/main.c b/main.c deleted file mode 100644 index b7bb92f..0000000 --- a/main.c +++ /dev/null @@ -1,312 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "toml.h" - -#define BOOKI_FILE_REL ".local/share/booki/books.toml" - -#define MAX_SEARCH_OPTS 5 - -char* BOOKI_FILE; - -const char* get_last_word(const char* str) { - const char* last_space = strrchr(str, ' '); - if ((last_space - str) > 0) - return last_space + 1; - else - return 0; -} - -bool regex_match(const char* pattern, const char* text) { - - // empty pattern matches everything - if (!*pattern) return true; - - // get lengths - int pattern_length = strlen(pattern); - int text_length = strlen(text); - - if (pattern_length > text_length) return false; - - // we only need to compare while remaining text is - // as long or longer than pattern (without special) - for (int i = 0; i <= (text_length - pattern_length); i++) { - if (strncasecmp(pattern, text + i, pattern_length) == 0) return true; - } - - return false; -} - -toml_table_t* get_toml_data(const char* filename) { - FILE* fp; - char errbuf[200]; - - fp = fopen(filename, "r"); - if (!fp) { - printf("can't open file :("); - return 0; - } - - toml_table_t* conf = toml_parse_file(fp, errbuf, sizeof(errbuf)); - fclose(fp); - - return conf; -} - -static struct option search_options[] = { - {"show", no_argument, 0, 's'}, - {0, 0, 0, 0} // marks the end of the array -}; - -struct search_opt { - int show; - int count; - char* opts[MAX_SEARCH_OPTS]; - char* args[MAX_SEARCH_OPTS]; -}; - -struct search_opt parse_search_options(int argc, char* argv[]) { - - // return struct - struct search_opt opt_out; - int count = 0; - int show = false; - - // opt options - int opt; - int opt_idx = 0; - opterr = 0; // turn off getopt error messages - - // look at each option - while ((opt = getopt_long_only(argc, argv, "", search_options, &opt_idx)) != -1) { - switch(opt) { - case 's': - show = true; - break; - case '?': - // optind points at the argument (one past the option) - opt_out.opts[count] = argv[optind-1] + 2; // '--example' -> 'example' - opt_out.args[count] = argv[optind]; - count++; - break; - default: - printf("something went wrong with parsing!\n"); - break; - } - } - - // set the count/show values - opt_out.count = count; - opt_out.show = show; - - return opt_out; -} - -char** search(int argc, char* argv[]) { - toml_table_t* data = get_toml_data(BOOKI_FILE); - - if (!data) { - return NULL; - } - - struct search_opt search_opts = parse_search_options(argc, argv); - bool print = false; - - // get the books array - toml_array_t* books = toml_array_in(data, "books"); - if (!books) { - printf("no such array: 'books'"); - return NULL; - } - - // book loop - for (int i = 0; ; i++) { - toml_table_t* book = toml_table_at(books, i); - if (!book) break; - - if (search_opts.count == 0) { - print = true; - } else { - toml_datum_t datapoint; - char* field; - bool inner_print = true; - - // loop through all options - int i; - for (i = 0; i < search_opts.count; i++) { - field = search_opts.opts[i]; - - // if the key doesn't exist, we won't print - if (!toml_key_exists(book, field)) { - break; - } - - // try and get a string - datapoint = toml_string_in(book, field); - if (datapoint.ok) { - if (!regex_match(search_opts.args[i], datapoint.u.s)) { - free(datapoint.u.s); - break; - } - free(datapoint.u.s); - } else { - // try and get an integer - datapoint = toml_int_in(book, field); - int ret; - if (datapoint.ok) { - ret = atoi(search_opts.args[i]); - if (ret == 0) { - printf("not an int: %s\n", search_opts.args[i]); - break; - } else if (ret != datapoint.u.i) { - break; - } - } else { - break; - } - } - } - - // if we made it all the way through the loop, - // we should print - print = i == search_opts.count; - } - - // get title and author for printing - toml_datum_t book_title = toml_string_in(book, "title"); - if (!book_title.ok) { - continue; - } - - // author can be a string or a list - toml_datum_t book_author = toml_string_in(book, "author"); - char author_str[100]; - char* tmp; - if (!book_author.ok) { - toml_array_t* book_author_array = toml_array_in(book, "author"); - if (!book_author_array) { - continue; - } - int len = toml_array_nelem(book_author_array); - tmp = toml_string_at(book_author_array, 0).u.s; - strcpy(author_str, tmp); - free(tmp); - for (int i = 1; i < len; i++) { - book_author = toml_string_at(book_author_array, i); - tmp = book_author.u.s; - if (i == len-1) { - strcat(author_str, " and "); - } else { - strcat(author_str, ", "); - } - strcat(author_str, book_author.u.s); - free(tmp); - } - } else { - strcpy(author_str, book_author.u.s); - free(book_author.u.s); - } - - // print! - if (print) { - printf("%s by %s\n", book_title.u.s, author_str); - if (search_opts.show) { - //toml_datum_t d; - for (int i = 0; ; i++) { - const char* key = toml_key_in(book, i); - if (!key) break; - - /* - if (strcmp("pages", key) == 0) { - d = toml_int_in(book, key); - if (d.ok) { - printf(" - %s: %d\n", - } - } - */ - - - // currently we support strings and ints - toml_datum_t s = toml_string_in(book, key); - if (s.ok) { - printf(" - %s: %s\n", key, s.u.s); - free(s.u.s); - } - toml_datum_t i = toml_int_in(book, key); - if (i.ok) { - printf(" - %s: %d\n", key, i.u.i); - } - - } - } - } - - free(book_title.u.s); - //free(book_author.u.s); - } - - toml_free(data); - - return argv + optind; -} - -void open() { - - char* home = getenv("HOME"); - if (!home) { - printf("no home?\n"); - home = "/"; // no way - } - char* editor = getenv("EDITOR"); - if (!editor) - editor = "nano"; - - pid_t pid; - int status; - switch ((pid = fork())) { - case -1: - printf("fork has failed!\n"); - break; - case 0: - execlp(editor, editor, BOOKI_FILE, NULL); - printf("child failed :(\n"); - break; - default: - // wait for the child to finish - pid = wait(&status); - break; - } -} - -void help(bool err) { - printf("booki! it's a thing\n"); - if (err) { - printf("you did something wrong\n"); - } -} - -int main(int argc, char* argv[]) { - - char* home = getenv("HOME"); - char booki_file[strlen(home) + strlen(BOOKI_FILE_REL) + 1]; - sprintf(booki_file, "%s/%s", home, BOOKI_FILE_REL); - BOOKI_FILE = booki_file; - char** remaining = NULL; - - if (argc == 1) { - help(false); - return 0; - } else if (strcmp(argv[1], "open") == 0) { - open(); - } else if (strcmp(argv[1], "search") == 0) { - remaining = search(argc - 1, argv + 1); - } - - return 0; -} -- cgit v1.2.3