//#include #include "util.h" #include "parser.h" #include "search.h" #include "foodopts.h" #include "eval.h" #include "lib.h" recipe ** cookbook; static struct opts { int json; 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 listi; int list; char listfmt[2048]; int hash; int search; int search_strict; int help; } opt = { .json = 0, .html = 0, .rcp = 0, .query = "", .add_val = {""}, .includes = {""}, .includes_n = 0, .eval = 1, .add = 0, .add_n = 0, .title = 0, .listi = 0, .list = 0, .listfmt = "", .hash = 0, .search = 0, .search_strict = 0, .help = 0, }; void print_help(char * argv0) { printf("%s [OPTION] FILE ...\n", argv0); printf("OPTIONS:\n"); printf("--format json,html,rcp\n"); printf("--to-{json,html,rcp}\n"); printf("-j json\n"); 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 main(int argc, char * argv[]) { fdebug("--- Debug mode is on ---\n"); int c; struct foodoption long_options[] = {/* name, has_arg, flag, val, help, arg */ {"help", no_argument, 0, 'h', "Print this help", 0, "General" }, {"include", required_argument, 0, 'I', "Path to recipe library, can be passed multiple times", "PATH", 0 }, {"no-eval", no_argument, 0, 'n', "Don't evaluate recipes", 0, 0 }, {"to-json", no_argument, 0, 'j', "Format recipe to json", 0, "Output format" }, {"to-html", no_argument, 0, 'w', "Format recipe to html", 0, 0 }, {"to-rcp", no_argument, 0, 'r', "Format recipe to rcp", 0, 0 }, {"list-ingredients", no_argument, 0, 'L', "List ingredients for matched recipes", 0, 0 }, {"list", optional_argument, 0, 'l', "List matched recipes with optional FORMAT {t,p,h,s}", "[FORMAT]", 0 }, {"search", required_argument, 0, 's', "Return recipes matching QUERY", "QUERY", "Filters" }, {"title", required_argument, 0, 't', "Return recipes matching TITLE", "TITLE", 0 }, {"strict", required_argument, 0, 'S', "Return recipes matching QUERY, exactly", "QUERY", 0 }, {"hash", required_argument, 0, 'H', "Return recipes by HASH", "HASH", 0 }, {"add-item", required_argument, 0, 'a', "Add item to matched recipes", "ITEM", "Other" }, //{"add-step", required_argument, 0, 'o'},, 0 {0, 0, 0, 0, 0} }; while (1) { int option_index = 0; c = get_foodopt (argc, argv, ":jnLhrws:S:t:H:I:a:l:", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf("Flag setting\n"); break; break; case 'I': strcpy(opt.includes[opt.includes_n++], optarg); break; case 't': opt.title = 1; strcpy(opt.query, 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 'H': opt.hash = 1; strcpy(opt.query, optarg); break; case 'j': opt.json = 1; break; case 'w': opt.html = 1; break; case 'r': opt.rcp = 1; break; case 'l': opt.list = 1; strcpy(opt.listfmt, optarg); break; case 'L': opt.listi = 1; break; case 'h': opt.help = 1; break; case 'n': opt.eval = 0; break; case 'a': opt.add = 1; strcpy(opt.add_val[opt.add_n++], optarg); break; case '?': fprintf(stderr, "%s: option '%c' not recognised, try -h for help\n", argv[0], optopt); return -1; break; case ':': switch (optopt) { case 'l': opt.list = 1; strcpy(opt.listfmt, "DEFAULT"); break; default: fprintf(stderr, "%s: missing argument %s for -%c\n", argv[0], get_argument(optopt, long_options), optopt); return -1; break; } break; default: abort (); } } if (opt.help) { foodopt_help(argv[0], long_options); return 0; } if (opt.json + opt.rcp + opt.html + opt.list + opt.listi > 1) { fprintf(stderr, "%s: only one output format is allowed at a time\n", argv[0]); return 1; } if (opt.eval == 0 && opt.hash == 1) { fprintf(stderr, "%s: can't search hash without evaluation\n", argv[0]); return 1; } char ** lib = NULL; 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) { fprintf(stderr, "Couldn't parse recipe: %s\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); 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.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.listi) { pprint_items(r); } if (opt.list) { listing(r , opt.listfmt); } else { if (opt.json) tojson(r); else if (opt.html) tohtml(r); else if (opt.rcp) torcp(r); else { // listing(r); } } free_recipe(r); } free_library(lib, n); return 0; }