aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Winston2024-05-05 15:05:34 -0400
committerBen Winston2024-05-05 15:05:34 -0400
commitcab0455b878c04ce40208f9258cc147a4683f5fc (patch)
tree94df557c20e125616c352b8acc369af8ef09f65f
parent501d47b8a7694de7ec33f2a44cbe6744113aebb9 (diff)
be flexible with search arguments
-rw-r--r--main.c113
1 files changed, 79 insertions, 34 deletions
diff --git a/main.c b/main.c
index f9acb47..a92c422 100644
--- a/main.c
+++ b/main.c
@@ -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);