aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorBen Winston2024-05-05 18:13:45 -0400
committerBen Winston2024-05-05 18:13:45 -0400
commit7a2e38d00390007348ebba3e75efb65b2e8d4fd8 (patch)
tree7469045ffa4416a2d930fac4db0af46ff703d6fd /main.c
parent1daff9912f02d0d7aa3bae606f0f793b620ed4d8 (diff)
main.c -> booki.c
Diffstat (limited to 'main.c')
-rw-r--r--main.c312
1 files changed, 0 insertions, 312 deletions
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 <getopt.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#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;
-}