diff options
author | gramanas <anastasis.gramm2@gmail.com> | 2021-11-13 21:05:38 +0200 |
---|---|---|
committer | gramanas <anastasis.gramm2@gmail.com> | 2021-11-14 11:07:42 +0200 |
commit | 382da0ada99a2874052f0e6ccb2c25e012d47fc9 (patch) | |
tree | a92357f558dab48f376e666594da4aa6576f4861 /parser.c | |
parent | 2e00a24994e094efc47fce4501b134caa801ea2c (diff) | |
download | foodtools-382da0ada99a2874052f0e6ccb2c25e012d47fc9.tar.gz foodtools-382da0ada99a2874052f0e6ccb2c25e012d47fc9.tar.bz2 foodtools-382da0ada99a2874052f0e6ccb2c25e012d47fc9.zip |
Update Makefile and add list ingredients draft
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 263 |
1 files changed, 0 insertions, 263 deletions
diff --git a/parser.c b/parser.c deleted file mode 100644 index df8d80b..0000000 --- a/parser.c +++ /dev/null @@ -1,263 +0,0 @@ -#include <libgen.h> - -#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) -{ - fdebug("^ title\n"); - int rc = 0; - - if (s[0] == '@' && strlen(s) > 1) { - char tmp[LINE_SIZE] = ""; - strcpy(tmp, ++s); - trim(tmp); - r->title = strdup(tmp); - } else { - r->title = strdup(r->filename); - rc = 1; - } - *type = ITEMS; - return rc; -} - -static const int -parse_item(const char * s, recipe * r, pt * type, char * error) -{ - fdebug("^ item\n"); - if (!strcmp(s, "---")) { - *type = STEPS; - return 0; - } - - /* 1 - 9 in ascii */ - if ((s[0] > 48 && s[0] < 58) || s[0] == '!') { - fdebug("INCLUDING: %s\n", s); - - char tmp[LINE_SIZE] = ""; - char path[LINE_SIZE] = ""; - - char *endptr; - int n = (int)strtol(s, &endptr, 10); - if (endptr[0] != '!') { - sprintf(error, "malformed include: %s", s); - return 1; - } - - strcpy(tmp, ++endptr); - trim(tmp); - - if (!strlen(tmp)) { - sprintf(error, "malformed include: %s", s); - return 1; - } - - if (tmp[0] == '/' || tmp[0] == '~') { - strcpy(path, tmp); - } else { - strcpy(path, r->path); - strcat(path, "/"); - strcat(path, tmp); - } - - recipe * rr = parse(path, r->filename); - if (!rr) { - sprintf(error, "Couldn't include %s", path); - return 1; - } - rr->n = n; - //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; - int c = 0; - char buf[LINE_SIZE] = ""; - for (int i = 0; i < l; i++) { - if (val) { - if (s[i] == ',' || s[i] == '=') { - buf[c++] = '\0'; - if (!strlen(buf)) { - sprintf(error, "malformed ingredient: %s", s); - return 1; - } - trim(buf); - if (strlen(buf)) { - new_item(r); - r->i[r->in - 1]->name = strdup(buf); - itemc++; - buf[0] = '\0'; - c = 0; - } - if (s[i] == '=') - val = 0; - continue; - } - } - buf[c++] = s[i]; - } - - buf[c] = '\0'; - trim(buf); - - if (!itemc) { - sprintf(error, "malformed ingderient: %s", buf); - return 1; - } - - if (!strlen(buf)) { - 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); - } - - return 0; -} - -static const int -parse_step(const char * s, recipe * r, char * error) -{ - fdebug("^ step\n"); - - if ((s[0] == '>' || - s[0] == '-' || - s[0] == '+') && strlen(s+1)) { - new_step(r); - r->s[r->sn - 1]->type = s[0] == '>' ? COOK : s[0] == '-' ? PREP : SERVE; - char *tmp = strdup(s+1); - trim(tmp); - r->s[r->sn - 1]->inst = tmp; - return 0; - } - - sprintf(error, "malformed step: %s", s); - return 1; -} - -static const int -handle_line(const char * s, recipe * r, char * error, pt * type, const char * prev) -{ - fdebug("Handling line: %s\n", s); - - if (strlen(s) == 0) return 0; - if (s[0] == '#') return 0; - - switch (*type) { - case TITLE: - if (parse_title(s, r, type)) - if (parse_item(s, r, type, error)) - return 1; - break; - case ITEMS: - if (parse_item(s, r, type, error)) - return 1; - break; - case STEPS: - if (parse_step(s, r, error)) - return 1; - } - - return 0; -} - -static const int -next_escaped_line(FILE *f, char * line, int * lino, char * error) { - if (!fgets(line, LINE_SIZE, f)) - return 1; - (*lino)++; - - if (line[strlen(line) - 1] != '\n' && !feof(f)) { - sprintf(error, "line exceeds %d characters", LINE_SIZE); - return -1; - } - - trim(line); - int l = strlen(line); - - /* Last char is `\n` check if */ - /* (last - 1) is `\` */ - while (l > 0 && line[l - 1] == '\\') { - char tmp[LINE_SIZE] = ""; - - if (!fgets(tmp, LINE_SIZE, f)) - /* return line on EOF */ - break; - (*lino)++; - - trim(tmp); - if (strlen(tmp) + l >= LINE_SIZE) { - sprintf(error, "line exceeds %d characters", LINE_SIZE); - return -1; - } - - /* remove `\` */ - line[l - 1] = '\0'; - strcat(line, tmp); - l = strlen(line); - } - return 0; -} - -recipe * -parse(char * path, const char * prev) -{ - fdebug("Parsing: %s\n", path); - - FILE *f; - if (!strcmp(path, "-")) { - f = stdin; - } else { - char tmp[LINE_SIZE] = ""; - if (path[0] == '~') { - strcpy(tmp, getenv("HOME")); - strcat(tmp, path + 1); - } else { - strcpy(tmp, path); - } - f = fopen(tmp, "r"); - if (!f) return NULL; - } - - recipe * r = new_recipe(); - char line[LINE_SIZE] = ""; - char *dirc, *bname; - - dirc = strdup(path); - bname = strdup(path); - r->path = strdup(dirname(dirc)); - r->filename = strdup(basename(bname)); - free(dirc); free(bname); - - /* (re)init px */ - 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; - } - - if (strlen(error) > 0) { - fprintf(stderr, "%s:%d: %s\n", path, lino, error); - free_recipe(r); - return NULL; - } - - return r; -} |