From dbd6366285b23483567f2c1dc814fc9f371c4c64 Mon Sep 17 00:00:00 2001 From: gramanas Date: Mon, 20 Dec 2021 22:52:48 +0200 Subject: merge steps --- README.org | 1 + food.c | 62 +++++++++++++++++++++++++++++++++++++------------ lib/pasta red sauce.rcp | 2 +- lib/pasta-red-sauce.rcp | 2 +- lib/sandwich-base.rcp | 9 +++++++ src/eval.c | 15 ++++-------- src/search.c | 19 +++++++++++++++ src/search.h | 8 +++++++ src/types.c | 51 +++++++++++++++++++++++++++++++++++----- src/types.h | 5 ++-- 10 files changed, 138 insertions(+), 36 deletions(-) create mode 100644 lib/sandwich-base.rcp create mode 100644 src/search.c create mode 100644 src/search.h diff --git a/README.org b/README.org index 909ef3e..5e0f020 100644 --- a/README.org +++ b/README.org @@ -30,6 +30,7 @@ > cook while stirring [for 10 minutes] > add $sugar > continue cooking [until onion caramelises] + + serve cold #+end_src * cmd diff --git a/food.c b/food.c index 90ce489..d0466a3 100644 --- a/food.c +++ b/food.c @@ -2,6 +2,7 @@ #include "src/util.h" #include "src/parser.h" +#include "src/search.h" #include "src/eval.h" recipe ** cookbook; @@ -10,15 +11,21 @@ static struct opts { int json; int html; int rcp; - char *query; + char query[2048]; + int eval; int list; + int search; + int search_strict; int help; } opt = { .json = 0, .html = 0, .rcp = 0, - .query = NULL, + .query = "", + .eval = 1, .list = 0, + .search = 0, + .search_strict = 0, .help = 0, }; @@ -32,6 +39,9 @@ print_help(char * argv0) { printf("-w html\n"); printf("-r rcp\n"); printf("-l, --list-ingredients\n"); + printf("-s TERMS, --search TERMS\n"); + printf("-S TERMS, --strict TERMS\n"); + printf("-n, --no-eval\n"); } int @@ -48,10 +58,13 @@ main(int argc, char * argv[]) // {"verbose", no_argument, &verbose_flag, 1}, // {"brief", no_argument, &verbose_flag, 0}, {"help", no_argument, 0, 'h'}, + {"no-eval", no_argument, 0, 'n'}, {"to-json", no_argument, 0, 'j'}, {"to-html", no_argument, 0, 'w'}, {"to-rcp", no_argument, 0, 'r'}, {"format", required_argument, 0, 'f'}, + {"search", required_argument, 0, 's'}, + {"strict", required_argument, 0, 'S'}, {"list-ingredients", no_argument, 0, 'l'}, // {"to-rcp", required_argument, 0, 'r'}, {0, 0, 0, 0} @@ -59,7 +72,7 @@ main(int argc, char * argv[]) int option_index = 0; - c = getopt_long (argc, argv, "jlhrwf:", + c = getopt_long (argc, argv, "jnlhrwf:s:S:", long_options, &option_index); if (c == -1) @@ -84,6 +97,15 @@ main(int argc, char * argv[]) else fprintf(stderr, "invalid format: %s\n", optarg); break; + case 's': + opt.search = 1; + strcpy(opt.query, optarg); + break; + case 'S': + opt.search = 1; + opt.search_strict = 1; + strcpy(opt.query, optarg); + break; case 'j': opt.json = 1; break; @@ -99,6 +121,9 @@ main(int argc, char * argv[]) case 'h': opt.help = 1; break; + case 'n': + opt.eval = 0; + break; case '?': return -1; break; @@ -115,19 +140,26 @@ main(int argc, char * argv[]) if (optind < argc) { while (optind < argc) { recipe * r = parse(argv[optind++], NULL); - if (r && opt.list) { - /* recipe * r_merged = new_recipe(); */ - /* merge_items(r_merged, r); */ - recipe * r_merged = eval(r); - pprint_items(r_merged); - free_recipe(r_merged); - } - else if (r) { - if (opt.json) tojson(r); - if (opt.html) tohtml(r); - if (opt.rcp) torcp(r); + if (r) { + if (opt.search) { + if (!query_for_items(r, opt.query, opt.search_strict)) + continue; + } + if (opt.eval) { + recipe * r_eval = eval(r); + free_recipe(r); + r = r_eval; + } + if (opt.list) { + pprint_items(r); + } + else { + if (opt.json) tojson(r); + if (opt.html) tohtml(r); + if (opt.rcp) torcp(r); + } + free_recipe(r); } - free_recipe(r); } } else { fprintf(stderr, "Specify filenames\n"); diff --git a/lib/pasta red sauce.rcp b/lib/pasta red sauce.rcp index b0bc460..a14838f 100644 --- a/lib/pasta red sauce.rcp +++ b/lib/pasta red sauce.rcp @@ -1,6 +1,6 @@ @pasta with red sauce -!~/code/food_compiler/lib/pasta.rcp +!~/code/foodtools/lib/pasta.rcp salt = * sugar = 1 teaspoon onion = 1 diff --git a/lib/pasta-red-sauce.rcp b/lib/pasta-red-sauce.rcp index 8b98626..2b56894 100644 --- a/lib/pasta-red-sauce.rcp +++ b/lib/pasta-red-sauce.rcp @@ -1,4 +1,4 @@ -@pasta with red sauce +@pasta with red sauce 3 3!pasta.rcp salt = * diff --git a/lib/sandwich-base.rcp b/lib/sandwich-base.rcp new file mode 100644 index 0000000..98568a7 --- /dev/null +++ b/lib/sandwich-base.rcp @@ -0,0 +1,9 @@ +@ sandwitch base + +bread = two pieces / one bun +butter or mayo = * + +--- + +- toast the $bread => toasted bread +- spead the ${butter or mayo} on the ${toasted bread} diff --git a/src/eval.c b/src/eval.c index a26cc21..8bc886a 100644 --- a/src/eval.c +++ b/src/eval.c @@ -5,17 +5,12 @@ recipe * eval(recipe * r) { if (!r) return NULL; - recipe * r1 = new_recipe(); - recipe * r2 = new_recipe(); - /* attempt to merge items (adding qtys) */ - merge_items(r1, r); - distinct_sum_items(r2, r1); - free_recipe(r1); + recipe * _r = new_recipe(); - copy_metadata(r2, r); - /* /\* Resolve step type, variables, duration and step output (if any) *\/ */ - /* finalize_steps(eve, r); */ + merge_items(_r, r); + merge_steps(_r, r); + copy_metadata(_r, r); - return r2; + return _r; } diff --git a/src/search.c b/src/search.c new file mode 100644 index 0000000..cf2eab9 --- /dev/null +++ b/src/search.c @@ -0,0 +1,19 @@ +#include "util.h" +#include "search.h" + +/** + * Query recipe `r` for input `s` and return 1 if found 0 otherwise + */ +int +query_for_items(const recipe * r, const char * s, int strict) +{ + for (int i = 0; i < r->in; i++) + if (strict) { + if (!strcmp(r->i[i]->name, s)) + return 1; + } else { + if (strstr(r->i[i]->name, s) != NULL) + return 1; + } + return 0; +} diff --git a/src/search.h b/src/search.h new file mode 100644 index 0000000..1295cd4 --- /dev/null +++ b/src/search.h @@ -0,0 +1,8 @@ +#ifndef SEARCH_H +#define SEARCH_H + +#include "types.h" + +int query_for_items(const recipe * r, const char * s, int strict); + +#endif diff --git a/src/types.c b/src/types.c index d9253af..3e720b8 100644 --- a/src/types.c +++ b/src/types.c @@ -237,6 +237,17 @@ copy_items(recipe * dst, recipe * src) } } +void +copy_steps(recipe * dst, recipe * src) +{ + if (!dst || !src) return; + for (int i = 0; i < src->sn; i++) { + new_step(dst); + dst->s[dst->sn - 1]->inst = strdup(src->s[i]->inst); + dst->s[dst->sn - 1]->type = src->s[i]->type; + } +} + static void join_subrecipe_items(recipe * dst, recipe * src) { @@ -258,13 +269,27 @@ join_subrecipe_items(recipe * dst, recipe * src) } } +static void +join_subrecipe_steps(recipe * dst, recipe * src) +{ + if (!src || !dst) return; + for (int i = 0; i < src->rn; i++) { + join_subrecipe_steps(dst, src->r[i]); + for (int j = 0; j < src->r[i]->sn; j++) { + new_step(dst); + dst->s[dst->sn - 1]->inst = strdup(src->r[i]->s[j]->inst); + dst->s[dst->sn - 1]->type = src->r[i]->s[j]->type; + } + } +} + void -merge_items(recipe * dst, recipe * src) +merge_steps(recipe * dst, recipe * src) { - /* Join all items in src's subrecipes to dst */ - join_subrecipe_items(dst, src); - /* Copy src items as well to dst */ - copy_items(dst, src); + /* Join all steps in src's subrecipes to dst */ + join_subrecipe_steps(dst, src); + /* Copy src steps as well to dst */ + copy_steps(dst, src); } static int @@ -276,7 +301,11 @@ item_exists(const char * name, const recipe * r) return -1; } -void +/** + * Sum all top level item qtys in `src` and add them to `dst` + * making sure each item name exists only once. + */ +static void distinct_sum_items(recipe * dst, recipe * src) { if (!dst || !src) return; @@ -297,3 +326,13 @@ distinct_sum_items(recipe * dst, recipe * src) } } } + +void +merge_items(recipe * dst, recipe * src) +{ + /* Join all items in src's subrecipes to dst */ + join_subrecipe_items(dst, src); + /* Copy src items as well to dst */ + copy_items(dst, src); + distinct_sum_items(dst, dst); +} diff --git a/src/types.h b/src/types.h index 0d870cf..2c58537 100644 --- a/src/types.h +++ b/src/types.h @@ -65,9 +65,8 @@ void copy_items(recipe * dst, recipe * src); void merge_items(recipe * dst, recipe * src); /** - * Sum all top level item qtys in `src` and add them to `dst` - * making sure each item name exists only once. + * Merge all steps from `src` and add them to `dst` */ -void distinct_sum_items(recipe * dst, recipe * src); +void merge_steps(recipe * dst, recipe * src); #endif /* __TYPES_H */ -- cgit v1.2.3