static int path_iter_f(jd_var *result, jd_var *context, jd_var *arg) { jd_var *var = jd_get_idx(context, 0); jd_var *stack = jd_get_idx(context, 1); (void) arg; jd_set_void(result); if (jd_count(stack) == 0) return 1; scope { jd_var *slot = jd_nv(); int i; size_t cnt; jd_pop(stack, 1, result); slot = jd_rv(var, jd_bytes(result, NULL)); if (!slot) jd_die("Can't find %s", jd_bytes(result, NULL)); if (slot->type == ARRAY) { cnt = jd_count(slot); for (i = cnt - 1; i >= 0; i--) jd_sprintf(jd_push(stack, 1), "%V.%u", result, i); } else if (slot->type == HASH) { jd_var *keys = jd_keys(jd_nv(), slot); cnt = jd_count(keys); for (i = cnt - 1; i >= 0; i--) jd_sprintf(jd_push(stack, 1), "%V.%V", result, jd_get_idx(keys, i)); } } return 1; }
int liquify_block_for_begin_(LIQUIFYCTX *ctx, struct liquify_part *part, struct liquify_stack *stack) { struct for_data *data; struct liquify_param *param; jd_var empty = JD_INIT; jd_var *v; if(stack->data) { data = (struct for_data *) stack->data; } else { data = (struct for_data *) calloc(1, sizeof(struct for_data)); if(!data) { return -1; } /* This is the first pass through the loop */ param = part->d.tag.pfirst; if(liquify_assign_(&(param->expr), ctx->dict, &empty)) { PARTERRS(ctx->tpl, part, "expected: lvalue as iterator\n"); return -1; } data->self = &(param->expr); param = param->next; if(!param || !EXPR_IS(&(param->expr), TOK_IDENT) || strcmp(EXPR_IDENT(&(param->expr)), "in")) { PARTERRS(ctx->tpl, part, "expected: 'in'\n"); return -1; } param = param->next; if(liquify_eval_(&(param->expr), ctx->dict, &(data->list), 0)) { PARTERRS(ctx->tpl, part, "expected: identifier\n"); return -1; } if(data->list.type == HASH) { jd_keys(&(data->keys), &(data->list)); } stack->data = (void *) data; } v = for_current(ctx, data); if(v) { liquify_assign_(data->self, ctx->dict, v); } else { liquify_inhibit_(ctx); } return 0; }