From b30cd3e1b8d1162c529bfdd602d0d56ccd2e38c7 Mon Sep 17 00:00:00 2001 From: gramanas Date: Fri, 20 May 2022 13:15:14 +0300 Subject: aha --- src/food.c | 90 ++++++++++++++++++++++++++++++++++++---------------------- src/foodopts.c | 0 src/foodopts.h | 16 +++++++++++ src/lib.c | 6 ++-- src/parser.c | 12 ++------ src/parser.h | 9 ++++++ src/types.c | 9 ++++-- 7 files changed, 94 insertions(+), 48 deletions(-) create mode 100644 src/foodopts.c create mode 100644 src/foodopts.h (limited to 'src') diff --git a/src/food.c b/src/food.c index 7ee222e..9506713 100644 --- a/src/food.c +++ b/src/food.c @@ -13,10 +13,13 @@ static struct opts { int html; int rcp; char query[2048]; + char add_val[100][2048]; char includes[100][2048]; int includes_n; int title; int eval; + int add; + int add_n; int list; int hash; int search; @@ -27,9 +30,12 @@ static struct opts { .html = 0, .rcp = 0, .query = "", + .add_val = {""}, .includes = {""}, .includes_n = 0, .eval = 1, + .add = 0, + .add_n = 0, .title = 0, .list = 0, .hash = 0, @@ -71,6 +77,8 @@ main(int argc, char * argv[]) {"to-json", no_argument, 0, 'j'}, {"to-html", no_argument, 0, 'w'}, {"to-rcp", no_argument, 0, 'r'}, + {"add-item", required_argument, 0, 'a'}, + //{"add-step", required_argument, 0, 'o'}, {"format", required_argument, 0, 'f'}, {"include", required_argument, 0, 'I'}, {"search", required_argument, 0, 's'}, @@ -84,7 +92,7 @@ main(int argc, char * argv[]) int option_index = 0; - c = getopt_long (argc, argv, "jnlhrwf:s:S:t:H:I:", + c = getopt_long (argc, argv, "jnlhrwf:s:S:t:H:I:a:", long_options, &option_index); if (c == -1) @@ -147,6 +155,10 @@ main(int argc, char * argv[]) case 'n': opt.eval = 0; break; + case 'a': + opt.add = 1; + strcpy(opt.add_val[opt.add_n++], optarg); + break; case '?': return -1; break; @@ -164,49 +176,59 @@ main(int argc, char * argv[]) int n = collect_library(&lib, argv, argc, optind, opt.includes, opt.includes_n); - + for (int i = 0; i < n; i++) { recipe * r = parse(lib[i], NULL); - if (r) { - if (opt.eval) { - recipe * r_eval = eval(r); + if (!r) { + fprintf(stderr, "Recipe %s not found\n", lib[i]); + continue; + } + + if (opt.eval) { + recipe * r_eval = eval(r); + free_recipe(r); + r = r_eval; + } + if (opt.hash) { + if (!check_hash(r, opt.query)) { free_recipe(r); - r = r_eval; + continue; } - if (opt.hash) { - if (!check_hash(r, opt.query)) { - free_recipe(r); - continue; - } - } - if (opt.title) { - if (strcmp(r->title, opt.query)) { - free_recipe(r); - continue; - } + } + if (opt.title) { + if (strcmp(r->title, opt.query)) { + free_recipe(r); + continue; } - if (opt.search) { - int c; - if (!(c = query_for_items_pbn(r, opt.query, opt.search_strict))) { - free_recipe(r); - continue; - } - if (c < 0) - exit(1); + } + if (opt.search) { + int c; + if (!(c = query_for_items_pbn(r, opt.query, opt.search_strict))) { + free_recipe(r); + continue; } - if (opt.list) { - pprint_items(r); + if (c < 0) + exit(1); + } + if (opt.add) { + for (int j = 0; j < opt.add_n; j++) { + char err[1000]; + if (parse_item(opt.add_val[j], r, (pt *)NULL, err)) + fprintf(stderr, "Error: %s\n", err); } + } + if (opt.list) { + pprint_items(r); + } + else { + if (opt.json) tojson(r); + else if (opt.html) tohtml(r); + else if (opt.rcp) torcp(r); else { - if (opt.json) tojson(r); - else if (opt.html) tohtml(r); - else if (opt.rcp) torcp(r); - else { - listing(r); - } + listing(r); } - free_recipe(r); } + free_recipe(r); } free_library(lib, n); diff --git a/src/foodopts.c b/src/foodopts.c new file mode 100644 index 0000000..e69de29 diff --git a/src/foodopts.h b/src/foodopts.h new file mode 100644 index 0000000..544dd3f --- /dev/null +++ b/src/foodopts.h @@ -0,0 +1,16 @@ +#ifndef __FOODOPTS_H +#define __FOODOPTS_H + +#include + +/** + * This is a wrapper on getopt.h, specifically + * + * It provides a unified interface for defining + * cli options, printing the help, and looping though + * the parsing results. + * + */ + + +#endif /* __FOODOPTS_H */ diff --git a/src/lib.c b/src/lib.c index 3da93ed..a1f1f29 100644 --- a/src/lib.c +++ b/src/lib.c @@ -1,6 +1,8 @@ #include "lib.h" #include "util.h" +#define LINE_SIZE 4096 + const char * default_food_lib = "/usr/local/share/food"; const char * @@ -17,10 +19,10 @@ static int rcp_find(char *** lib, int lib_n, const char * path) { int n = lib_n; - char line[1035]; + char line[LINE_SIZE]; FILE *fp; - char cmd[2048] = "/bin/find "; + char cmd[LINE_SIZE] = "/bin/find "; strcat(cmd, path); strcat(cmd, " -name '*.rcp'"); diff --git a/src/parser.c b/src/parser.c index 5009ca1..e4bffb4 100644 --- a/src/parser.c +++ b/src/parser.c @@ -3,12 +3,6 @@ #include "parser.h" #include "util.h" -typedef enum parser_type { - TITLE = 0, - ITEMS, - STEPS, -} pt; - static const int parse_title(const char * s, recipe * r, pt * type) { @@ -24,16 +18,16 @@ parse_title(const char * s, recipe * r, pt * type) r->title = strdup(r->filename); rc = 1; } - *type = ITEMS; + if (type) *type = ITEMS; return rc; } -static const int +int parse_item(const char * s, recipe * r, pt * type, char * error) { fdebug("^ item\n"); if (!strcmp(s, "---")) { - *type = STEPS; + if (type) *type = STEPS; return 0; } diff --git a/src/parser.h b/src/parser.h index d47bad5..70b3120 100644 --- a/src/parser.h +++ b/src/parser.h @@ -5,6 +5,12 @@ #define LINE_SIZE 4096 +typedef enum parser_type { + TITLE = 0, + ITEMS, + STEPS, +} pt; + /** * Return a recipe struct after parsing file in path. * @@ -14,4 +20,7 @@ recipe * parse(char * path, const char * prev); +int +parse_item(const char * s, recipe * r, pt * type, char * error); + #endif /* __PARSER_H */ diff --git a/src/types.c b/src/types.c index 8918d98..9fbb59b 100644 --- a/src/types.c +++ b/src/types.c @@ -279,9 +279,12 @@ void copy_metadata(recipe * dst, recipe * src) { if (!dst || !src) return; - dst->filename = strdup(src->filename); - dst->path = strdup(src->path); - dst->title = strdup(src->title); + if (src->filename) + dst->filename = strdup(src->filename); + if (src->path) + dst->path = strdup(src->path); + if (src->title) + dst->title = strdup(src->title); } void -- cgit v1.2.3