diff options
Diffstat (limited to 'main.c')
| -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); | 
