diff options
-rw-r--r-- | lib/simple_omelette.rcp | 4 | ||||
-rw-r--r-- | src/cookbook.c | 2 | ||||
-rw-r--r-- | src/food.c | 14 | ||||
-rw-r--r-- | src/lib.c | 66 | ||||
-rw-r--r-- | src/lib.h | 4 | ||||
-rw-r--r-- | src/parser.c | 28 | ||||
-rw-r--r-- | tests/types.c | 4 |
7 files changed, 86 insertions, 36 deletions
diff --git a/lib/simple_omelette.rcp b/lib/simple_omelette.rcp index f278e1c..e7f8791 100644 --- a/lib/simple_omelette.rcp +++ b/lib/simple_omelette.rcp @@ -1,10 +1,10 @@ # -*- mode: fundamental -*- @title -# default lib search path FOOD_LIB=/var/lib/food +# default lib search path FOOD_LIB=/usr/local/share/food # order: # 1a. full path if s[0] = / or ~ -# 1b. local path +# 1b. file local path # 2. default library path # !pasta.rcp = 3 # !~/code/food_compiler/lib/include.rcp diff --git a/src/cookbook.c b/src/cookbook.c index 08fa325..0fab1e2 100644 --- a/src/cookbook.c +++ b/src/cookbook.c @@ -136,7 +136,7 @@ main(int argc, char * argv[]) } char ** lib = NULL; - int n = collect_library(&lib, argv, argc, optind); + int n = collect_library(&lib, argv, argc, optind, NULL, 0); cookbook = (recipe **)malloc(sizeof(recipe *) * n); for (int i = 0; i < n; i++) { @@ -13,6 +13,8 @@ static struct opts { int html; int rcp; char query[2048]; + char includes[100][2048]; + int includes_n; int title; int eval; int list; @@ -25,6 +27,8 @@ static struct opts { .html = 0, .rcp = 0, .query = "", + .includes = {""}, + .includes_n = 0, .eval = 1, .title = 0, .list = 0, @@ -68,6 +72,7 @@ main(int argc, char * argv[]) {"to-html", no_argument, 0, 'w'}, {"to-rcp", no_argument, 0, 'r'}, {"format", required_argument, 0, 'f'}, + {"include", required_argument, 0, 'I'}, {"search", required_argument, 0, 's'}, {"title", required_argument, 0, 't'}, {"strict", required_argument, 0, 'S'}, @@ -79,7 +84,7 @@ main(int argc, char * argv[]) int option_index = 0; - c = getopt_long (argc, argv, "jnlhrwf:s:S:t:H:", + c = getopt_long (argc, argv, "jnlhrwf:s:S:t:H:I:", long_options, &option_index); if (c == -1) @@ -104,6 +109,9 @@ main(int argc, char * argv[]) else fprintf(stderr, "invalid format: %s\n", optarg); break; + case 'I': + strcpy(opt.includes[opt.includes_n++], optarg); + break; case 't': opt.title = 1; strcpy(opt.query, optarg); @@ -153,7 +161,9 @@ main(int argc, char * argv[]) } char ** lib = NULL; - int n = collect_library(&lib, argv, argc, optind); + 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); @@ -1,40 +1,70 @@ #include "lib.h" #include "util.h" -int -collect_library(char *** dst, char * argv[], int argc, int optind) +const char * default_food_lib = "/usr/local/share/food"; + +const char * +foodlib_env() { - int n = 0; - FILE *fp; - char path[1035]; + char * env = getenv("FOOD_LIB"); - char ** lib = NULL; + if (env) return env; - for (int i = optind; i < argc; i++) { - lib = realloc(lib, sizeof(char **) * (n + 1)); - lib[n] = strdup(argv[i]); - fdebug("%d: %s\n", n, lib[n]); - n = n + 1; - } + return default_food_lib; +} + +static int +rcp_find(char *** lib, int lib_n, const char * path) +{ + int n = lib_n; + char line[1035]; + FILE *fp; - fp = popen("/bin/find /home/gramanas/code/foodtools/lib/ -name '*.rcp'", "r"); + char cmd[2048] = "/bin/find "; + strcat(cmd, path); + strcat(cmd, " -name '*.rcp'"); + + fp = popen(cmd, "r"); if (fp == NULL) { fprintf(stderr, "Couldn't run /bin/find\n"); return 0; } /* Read the output a line at a time */ - while (fgets(path, sizeof(path), fp) != NULL) { - lib = realloc(lib, sizeof(char **) * (n + 1)); - trim(path); - lib[n] = strdup(path); - fdebug("%d: %s\n", n, lib[n]); + while (fgets(line, sizeof(line), fp) != NULL) { + *lib = realloc(*lib, sizeof(char **) * (n + 1)); + trim(line); + (*lib)[n] = strdup(line); + fdebug("%d: %s\n", n, (*lib)[n]); n = n + 1; } /* close */ pclose(fp); + return n; +} + +int +collect_library(char *** dst, + char * argv[], int argc, int optind, + char includes[][2048], int includes_n) +{ + int n = 0; + char ** lib = NULL; + + for (int i = optind; i < argc; i++) { + lib = realloc(lib, sizeof(char **) * (n + 1)); + lib[n] = strdup(argv[i]); + fdebug("%d: %s\n", n, lib[n]); + n = n + 1; + } + + //n += rcp_find(&lib, "/home/gramanas/code/foodtools/lib/"); + for (int i = 0; i < includes_n; i++) { + n = rcp_find(&lib, n, includes[i]); + } + *dst = lib; return n; // no of items } @@ -1,7 +1,9 @@ #ifndef __LIB_H #define __LIB_H -int collect_library(char *** lib, char * argv[], int argc, int optind); +int collect_library(char *** lib, + char * argv[], int argc, int optind, + char includes[][2048], int includes_n); void free_library(char ** lib, int n); #endif /* __LIB_H */ diff --git a/src/parser.c b/src/parser.c index df8d80b..5009ca1 100644 --- a/src/parser.c +++ b/src/parser.c @@ -6,7 +6,7 @@ typedef enum parser_type { TITLE = 0, ITEMS, - STEPS, + STEPS, } pt; static const int @@ -58,16 +58,22 @@ parse_item(const char * s, recipe * r, pt * type, char * error) sprintf(error, "malformed include: %s", s); return 1; } - + + /* First search for full path */ if (tmp[0] == '/' || tmp[0] == '~') { strcpy(path, tmp); } else { + /* Then search for file local path */ strcpy(path, r->path); strcat(path, "/"); strcat(path, tmp); } - recipe * rr = parse(path, r->filename); + recipe * rr = NULL; + rr = parse(path, r->filename); + + /* TODO: Check for path from included libs */ + if (!rr) { sprintf(error, "Couldn't include %s", path); return 1; @@ -76,10 +82,10 @@ parse_item(const char * s, recipe * r, pt * type, char * error) //copy_items(r, rr); new_subrecipe(r, rr); //free_recipe(rr); - + return 0; } - + int l = strlen(s); int val = 1; /* key vs value flag */ int itemc = 0; @@ -121,7 +127,7 @@ parse_item(const char * s, recipe * r, pt * type, char * error) sprintf(error, "empty ingredient quantity: %s", s); return 1; } - + for (int i = 0; i < itemc; i++) { r->i[r->in - 1 - i]->qty = strdup(buf); } @@ -144,7 +150,7 @@ parse_step(const char * s, recipe * r, char * error) r->s[r->sn - 1]->inst = tmp; return 0; } - + sprintf(error, "malformed step: %s", s); return 1; } @@ -171,7 +177,7 @@ handle_line(const char * s, recipe * r, char * error, pt * type, const char * pr if (parse_step(s, r, error)) return 1; } - + return 0; } @@ -204,7 +210,7 @@ next_escaped_line(FILE *f, char * line, int * lino, char * error) { sprintf(error, "line exceeds %d characters", LINE_SIZE); return -1; } - + /* remove `\` */ line[l - 1] = '\0'; strcat(line, tmp); @@ -217,7 +223,7 @@ recipe * parse(char * path, const char * prev) { fdebug("Parsing: %s\n", path); - + FILE *f; if (!strcmp(path, "-")) { f = stdin; @@ -247,7 +253,7 @@ parse(char * path, const char * prev) char error[LINE_SIZE] = ""; int lino = 0; enum parser_type type = TITLE; - + while (!next_escaped_line(f, line, &lino, error)) { if (handle_line(line, r, error, &type, prev)) break; diff --git a/tests/types.c b/tests/types.c index 9f08ac8..30498fe 100644 --- a/tests/types.c +++ b/tests/types.c @@ -1,6 +1,8 @@ /* -*- eval: (outline-minor-mode); outline-regexp: "START_TEST("; -*- */ -static check_empty_recipe(recipe * r) { +static int +check_empty_recipe(recipe * r) +{ ck_assert_int_eq(r->n, 1); ck_assert_int_eq(r->in, 0); ck_assert_int_eq(r->sn, 0); |