char * parse_expression(char *s, struct lacy_env *env) { int t = next_token(&s); switch (t) { case FOR: tree_push(FOR, NULL); s = parse_foreach(s, env); break; case DONE: tree_push(DONE, NULL); break; case INCLUDE: tree_push(INCLUDE, NULL); s = parse_include(s, env); break; default: fatal("excepted for\n"); } t = next_token(&s); switch (t) { case EXP_END: break; default: fatal("excepted expression end\n"); } return s; }
/* * Called by the client to mark the directory just returned from * tree_next() as needing to be visited. */ void tree_descend(struct tree *t) { if (t->visit_type != TREE_REGULAR) return; if (tree_current_is_physical_dir(t)) { tree_push(t, t->basename); t->stack->flags |= isDir; } else if (tree_current_is_dir(t)) { tree_push(t, t->basename); t->stack->flags |= isDirLink; } }
char * parse_var(char *s, struct page *p, struct lacy_env *env) { struct ut_str var; str_init(&var); while (*s != '\0') { if (iswhitespace(*s) == 1) { ++s; continue; } if ('.' == *s) { tree_push(IDENT, var.s); tree_push(MEMBER, NULL); str_clear(&var); } else if (slook_ahead(s, "}}", 2)) { s += 2; if (0 == strcmp(var.s, "content")) { if (env_has_next(env)) { env_inc(env); build_tree(env); env_dec(env); } } else { tree_push(IDENT, var.s); } break; } else { str_append(&var, *s); } ++s; } str_free(&var); return s; }
char * parse_foreach(char *s, struct lacy_env *env) { int t = next_token(&s); switch (t) { case IDENT: tree_push(IDENT, curtok.s); break; default: fatal("excepted ident"); } t = next_token(&s); switch (t) { case IN: break; default: fatal("excepted IN"); } t = next_token(&s); switch (t) { case IDENT: tree_push(IDENT, curtok.s); break; case SH_START: s = parse_sh_exp(s, env); break; default: fatal("excepted List or Shell expression"); } t = next_token(&s); switch (t) { case DO: tree_push(DO, NULL); break; default: fatal("excepted DO"); } return s; }
char * parse_sh_exp(char *s, struct lacy_env *env) { struct ut_str var; str_init(&var); while (*s != '\0') { if (slook_ahead(s, "$}", 2)) { s += 2; tree_push(SH_BLOCK, var.s); break; } else { str_append(&var, *s); } ++s; } str_free(&var); return s; }
void do_build_tree(char *s, struct lacy_env *env) { int escaped = 0; struct page *p = env_get_page(env); struct ut_str buffer; str_init(&buffer); while (*s != '\0') { if (*s == '\\') { escaped = 1; s++; } if (slook_ahead(s, "{{", 2)) { if (escaped) { str_append(&buffer, *s); escaped = 0; } else { s += 2; tree_push(BLOCK, buffer.s); str_clear(&buffer); s = parse_var(s, p, env); continue; } } else if (slook_ahead(s, "{%", 2)) { if (escaped) { str_append(&buffer, *s); escaped = 0; } else { s += 2; tree_push(BLOCK, buffer.s); str_clear(&buffer); s = parse_expression(s, env); continue; } } else if (slook_ahead(s, "{$", 2)) { if (escaped) { str_append(&buffer, *s); escaped = 0; } else { s += 2; tree_push(BLOCK, buffer.s); str_clear(&buffer); s = parse_sh_exp(s, env); continue; } } else { if (escaped) { str_append(&buffer, '\\'); str_append(&buffer, *s); escaped = 0; } else { str_append(&buffer, *s); } } ++s; } tree_push(BLOCK, buffer.s); str_free(&buffer); }