diff options
| author | Ben Winston | 2024-05-05 15:05:34 -0400 |
|---|---|---|
| committer | Ben Winston | 2024-05-05 15:05:34 -0400 |
| commit | cab0455b878c04ce40208f9258cc147a4683f5fc (patch) | |
| tree | 94df557c20e125616c352b8acc369af8ef09f65f | |
| parent | 501d47b8a7694de7ec33f2a44cbe6744113aebb9 (diff) | |
be flexible with search arguments
| -rw-r--r-- | main.c | 113 |
1 files changed, 79 insertions, 34 deletions
@@ -11,6 +11,8 @@ #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) { @@ -58,46 +60,64 @@ toml_table_t* get_toml_data(const char* filename) { } static struct option search_options[] = { - {"title", required_argument, 0, 't'}, - {"author", required_argument, 0, 'a'}, {"show", no_argument, 0, 's'}, {0, 0, 0, 0} // marks the end of the array }; -char** search(int argc, char* argv[]) { - toml_table_t* data = get_toml_data(BOOKI_FILE); +struct search_opt { + int show; + int count; + char* opts[MAX_SEARCH_OPTS]; + char* args[MAX_SEARCH_OPTS]; +}; - if (!data) { - return NULL; - } +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; - char* title = NULL; - char* author = NULL; - int show = 0; + opterr = 0; // turn off getopt error messages - while ((opt = getopt_long(argc, argv, "t:a:", search_options, &opt_idx)) != -1) { + // look at each option + while ((opt = getopt_long_only(argc, argv, "", search_options, &opt_idx)) != -1) { switch(opt) { - case 't': - title = optarg; - break; - case 'a': - author = optarg; - break; case 's': - show = 1; + show = true; break; case '?': - if (optopt == 't' || optopt == 'a') - fprintf(stderr, "search flags require an argument"); + // 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("bad arg\n"); - return NULL; + 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) { @@ -105,11 +125,44 @@ char** search(int argc, char* argv[]) { 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)) + break; + } else { + continue; + } + } + + // 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; @@ -144,18 +197,10 @@ char** search(int argc, char* argv[]) { free(book_author.u.s); } - // always print on no search terms - bool print_title = (title == NULL); - bool print_author = (author == NULL); - if (title != NULL) - print_title = regex_match(title, book_title.u.s); - if (author != NULL) - print_author = regex_match(author, author_str); - - - if (print_title && print_author) { + // print! + if (print) { printf("%s by %s\n", book_title.u.s, author_str); - if (show) { + if (search_opts.show) { //toml_datum_t d; for (int i = 0; ; i++) { const char* key = toml_key_in(book, i); |
