aboutsummaryrefslogtreecommitdiff
path: root/booki.c
diff options
context:
space:
mode:
authorBen Winston2024-05-31 22:13:32 -0400
committerBen Winston2024-05-31 22:13:32 -0400
commitae9025ab31c4588b11c2c8cfc870af0462ce8d66 (patch)
treea83c531b34e703e138b39a2cd8cf94341d44533c /booki.c
parent3f526aa08dfbfc1f9193a58d767260b7dea069b7 (diff)
refactor: rearrange file
Diffstat (limited to 'booki.c')
-rw-r--r--booki.c366
1 files changed, 181 insertions, 185 deletions
diff --git a/booki.c b/booki.c
index f823049..3aa094b 100644
--- a/booki.c
+++ b/booki.c
@@ -12,7 +12,79 @@
#define MAX_SEARCH_OPTS 5
-// STRUCTS
+/*** helpers ***/
+char* load_file(char* filename) {
+ // open the file
+ FILE* fp = fopen(filename, "r");
+ if (!fp) {
+ printf("bad file\n");
+ return NULL;
+ }
+
+ // seek to the end
+ fseek(fp, 0, SEEK_END);
+ int size = ftell(fp);
+ rewind(fp);
+
+ char* data = malloc(size + 1);
+ if (!data) {
+ printf("couldn't malloc\n");
+ return NULL;
+ }
+
+ int read_size = fread(data, 1, size, fp);
+ if (read_size != size) {
+ printf("didn't read everything -- %d read of %d\n", read_size, size);
+ return NULL;
+ }
+
+ data[size] = '\0';
+ fclose(fp);
+
+ return data;
+}
+
+void open_with_editor(char* filepath) {
+ 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, filepath, NULL);
+ printf("child failed :(\n");
+ break;
+ default:
+ // wait for the child to finish
+ pid = wait(&status);
+ break;
+ }
+}
+
+bool copy(char* src, char* dest) {
+ pid_t pid;
+ int status;
+ switch((pid = fork())) {
+ case -1:
+ printf("fork failed\n");
+ return false;
+ case 0:
+ execl("/bin/cp", "/bin/cp", src, dest, NULL);
+ printf("copy failed\n");
+ return false;
+ default:
+ // wait for the chlid to finish
+ pid = wait(&status);
+ return true;
+ }
+}
+
+/*** strings ***/
struct es {
int len;
char* ptr;
@@ -42,6 +114,17 @@ int concat_es_toml(struct es* str, char* buf) {
}
}
+void free_es(struct es* str) {
+ if (str == NULL) return;
+ struct es* tmp;
+ while (str != NULL) {
+ tmp = str->next;
+ free(str);
+ str = tmp;
+ }
+}
+
+/*** books ***/
struct Book {
int id;
struct es title;
@@ -67,7 +150,94 @@ void init_book(struct Book* book) {
book->published = 0;
}
-int PARSE_LINE = 1;
+void print_book(struct Book book, bool all_fields) {
+ char str[100];
+ int size = concat_es_print(&(book.author), str);
+ printf("%.*s by %.*s\n", book.title.len, book.title.ptr, size, str);
+ if (all_fields) {
+ char* esfmt = " - %s: %.*s\n";
+ char* intfmt = " - %s: %d\n";
+ if (book.isbn.ptr) {
+ printf(esfmt, "isbn", book.isbn.len, book.isbn.ptr);
+ }
+ if (book.language.ptr) {
+ size = concat_es_print(&(book.language), str);
+ printf(esfmt, "language", size, str);
+ }
+ if (book.translator.ptr) {
+ size = concat_es_print(&(book.translator), str);
+ printf(esfmt, "translator", size, str);
+ }
+ if (book.pages) {
+ printf(intfmt, "pages", book.pages);
+ }
+ if (book.published) {
+ printf(intfmt, "published", book.published);
+ }
+ if (book.on.ptr) {
+ size = concat_es_print(&(book.on), str);
+ printf(esfmt, "on", size, str);
+ }
+ }
+}
+
+void write_book(struct Book book, FILE *output) {
+ fwrite("[[books]]\n", 1, 10, output);
+ char str[100];
+ int size;
+ if (book.id) {
+ size = sprintf(str, "id = %d\n", book.id);
+ fwrite(str, 1, size, output);
+ }
+ if (book.isbn.ptr) {
+ size = sprintf(str, "isbn = \"%.*s\"\n", book.isbn.len, book.isbn.ptr);
+ fwrite(str, 1, size, output);
+ }
+ if (book.title.ptr) {
+ size = sprintf(str, "title = \"%.*s\"\n", book.title.len, book.title.ptr);
+ fwrite(str, 1, size, output);
+ }
+ if (book.author.ptr) {
+ size = sprintf(str, "author = ");
+ size += concat_es_toml(&(book.author), str + size);
+ fwrite(str, 1, size, output);
+ }
+ if (book.pages) {
+ size = sprintf(str, "pages = %d\n", book.pages);
+ fwrite(str, 1, size, output);
+ }
+ if (book.published) {
+ size = sprintf(str, "published = %d\n", book.published);
+ fwrite(str, 1, size, output);
+ }
+ if (book.language.ptr) {
+ size = sprintf(str, "language = ");
+ size += concat_es_toml(&(book.language), str + size);
+ fwrite(str, 1, size, output);
+ }
+ if (book.translator.ptr) {
+ size = sprintf(str, "translator = ");
+ size += concat_es_toml(&(book.translator), str + size);
+ fwrite(str, 1, size, output);
+ }
+ if (book.on.ptr) {
+ size = sprintf(str, "on = ");
+ size += concat_es_toml(&(book.on), str + size);
+ fwrite(str, 1, size, output);
+ }
+
+ fwrite("\n", 1, 1, output); // trailing newline between books
+}
+
+void free_book(struct Book book) {
+ // any string can be a list of strings
+ free_es(book.author.next);
+ free_es(book.translator.next);
+ free_es(book.language.next);
+ free_es(book.on.next);
+}
+
+/*** parse toml-ish ***/
const char* get_last_word(const char* str) {
const char* last_space = strrchr(str, ' ');
@@ -229,7 +399,6 @@ void parse_book(char* current_pos, struct Book* book) {
// go to (and then past) the newline
SEEK_UNTIL(current_pos, '\n');
- PARSE_LINE += 1;
c = *(++current_pos);
}
}
@@ -237,15 +406,8 @@ void parse_book(char* current_pos, struct Book* book) {
char* next_book(char* current_pos) {
while (!(ATTR_MATCH(current_pos, "[[books]]"))) {
current_pos++;
- switch(*current_pos) {
- case '\0':
- return NULL;
- case '\n':
- PARSE_LINE += 1;
- break;
- default:
- break;
- }
+ if (*current_pos == '\0')
+ return NULL;
}
// current_pos is at the beginning of [[books]]
@@ -254,11 +416,11 @@ char* next_book(char* current_pos) {
SEEK_UNTIL(current_pos, '\n');
// current_pos is '\n', go past then return
- PARSE_LINE += 1;
current_pos++;
return current_pos;
}
+/*** search ***/
bool regex_match(const char* pattern, const struct es text) {
// empty pattern matches everything
@@ -300,37 +462,6 @@ bool regex_match(const char* pattern, const struct es text) {
return valid;
}
-char* load_file(char* filename) {
- // open the file
- FILE* fp = fopen(filename, "r");
- if (!fp) {
- printf("bad file\n");
- return NULL;
- }
-
- // seek to the end
- fseek(fp, 0, SEEK_END);
- int size = ftell(fp);
- rewind(fp);
-
- char* data = malloc(size + 1);
- if (!data) {
- printf("couldn't malloc\n");
- return NULL;
- }
-
- int read_size = fread(data, 1, size, fp);
- if (read_size != size) {
- printf("didn't read everything -- %d read of %d\n", read_size, size);
- return NULL;
- }
-
- data[size] = '\0';
- fclose(fp);
-
- return data;
-}
-
static struct option search_options[] = {
{"show", no_argument, 0, 's'},
{"edit", no_argument, 0, 'e'},
@@ -387,143 +518,6 @@ struct search_opt parse_search_options(int argc, char* argv[]) {
return opt_out;
}
-void print_book(struct Book book, bool all_fields) {
- char str[100];
- int size = concat_es_print(&(book.author), str);
- printf("%.*s by %.*s\n", book.title.len, book.title.ptr, size, str);
- if (all_fields) {
- char* esfmt = " - %s: %.*s\n";
- char* intfmt = " - %s: %d\n";
- if (book.isbn.ptr) {
- printf(esfmt, "isbn", book.isbn.len, book.isbn.ptr);
- }
- if (book.language.ptr) {
- size = concat_es_print(&(book.language), str);
- printf(esfmt, "language", size, str);
- }
- if (book.translator.ptr) {
- size = concat_es_print(&(book.translator), str);
- printf(esfmt, "translator", size, str);
- }
- if (book.pages) {
- printf(intfmt, "pages", book.pages);
- }
- if (book.published) {
- printf(intfmt, "published", book.published);
- }
- if (book.on.ptr) {
- size = concat_es_print(&(book.on), str);
- printf(esfmt, "on", size, str);
- }
- }
-}
-
-void write_book(struct Book book, FILE *output) {
- fwrite("[[books]]\n", 1, 10, output);
- char str[100];
- int size;
- if (book.id) {
- size = sprintf(str, "id = %d\n", book.id);
- fwrite(str, 1, size, output);
- }
- if (book.isbn.ptr) {
- size = sprintf(str, "isbn = \"%.*s\"\n", book.isbn.len, book.isbn.ptr);
- fwrite(str, 1, size, output);
- }
- if (book.title.ptr) {
- size = sprintf(str, "title = \"%.*s\"\n", book.title.len, book.title.ptr);
- fwrite(str, 1, size, output);
- }
- if (book.author.ptr) {
- size = sprintf(str, "author = ");
- size += concat_es_toml(&(book.author), str + size);
- fwrite(str, 1, size, output);
- }
- if (book.pages) {
- size = sprintf(str, "pages = %d\n", book.pages);
- fwrite(str, 1, size, output);
- }
- if (book.published) {
- size = sprintf(str, "published = %d\n", book.published);
- fwrite(str, 1, size, output);
- }
- if (book.language.ptr) {
- size = sprintf(str, "language = ");
- size += concat_es_toml(&(book.language), str + size);
- fwrite(str, 1, size, output);
- }
- if (book.translator.ptr) {
- size = sprintf(str, "translator = ");
- size += concat_es_toml(&(book.translator), str + size);
- fwrite(str, 1, size, output);
- }
- if (book.on.ptr) {
- size = sprintf(str, "on = ");
- size += concat_es_toml(&(book.on), str + size);
- fwrite(str, 1, size, output);
- }
-
- fwrite("\n", 1, 1, output); // trailing newline between books
-}
-
-void open(char* filepath) {
- 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, filepath, NULL);
- printf("child failed :(\n");
- break;
- default:
- // wait for the child to finish
- pid = wait(&status);
- break;
- }
-}
-
-bool copy(char* src, char* dest) {
- pid_t pid;
- int status;
- switch((pid = fork())) {
- case -1:
- printf("fork failed\n");
- return false;
- case 0:
- execl("/bin/cp", "/bin/cp", src, dest, NULL);
- printf("copy failed\n");
- return false;
- default:
- // wait for the chlid to finish
- pid = wait(&status);
- return true;
- }
-}
-
-void free_es(struct es* str) {
- if (str == NULL) return;
- struct es* tmp;
- while (str != NULL) {
- tmp = str->next;
- free(str);
- str = tmp;
- }
-}
-
-void free_book(struct Book book) {
- // any string can be a list of strings
- free_es(book.author.next);
- free_es(book.translator.next);
- free_es(book.language.next);
- free_es(book.on.next);
-}
-
void search(int argc, char* argv[], char* booki_file) {
struct search_opt search_opts = parse_search_options(argc, argv);
@@ -592,7 +586,7 @@ void search(int argc, char* argv[], char* booki_file) {
if (search_opts.edit) {
// first, close and let the user edit
fclose(edit_file);
- open(EDIT_FILE);
+ open_with_editor(EDIT_FILE);
// after they've edited, read it in and add it to fixed_file
data = load_file(EDIT_FILE);
@@ -622,6 +616,8 @@ void search(int argc, char* argv[], char* booki_file) {
}
}
}
+
+/*** add new books ***/
void add(char *booki_file) {
FILE* edit_file = fopen(EDIT_FILE, "w");
@@ -639,7 +635,7 @@ void add(char *booki_file) {
// open the file for editing
fclose(edit_file);
- open(EDIT_FILE);
+ open_with_editor(EDIT_FILE);
// read in file, add to booki file
FILE* output = fopen(booki_file, "a");
@@ -658,7 +654,6 @@ void add(char *booki_file) {
unlink(EDIT_FILE);
}
-
void help(bool err) {
printf("booki! it's a thing\n");
if (err) {
@@ -666,6 +661,7 @@ void help(bool err) {
}
}
+/*** the main event ***/
int main(int argc, char* argv[]) {
char* booki_file = getenv("BOOKI_FILE");
@@ -678,7 +674,7 @@ int main(int argc, char* argv[]) {
help(false);
return 0;
} else if (strcmp(argv[1], "open") == 0) {
- open(booki_file);
+ open_with_editor(booki_file);
} else if (strcmp(argv[1], "search") == 0) {
search(argc - 1, argv + 1, booki_file);
} else if (strcmp(argv[1], "add") == 0) {