static Cmdret conf_setting(List *args, Cmdarg *ca) { log_msg("CONFIG", "conf_setting"); char *name = list_arg(args, 1, VAR_STRING); Token *oper = tok_arg(args, 2); Token *rhs = tok_arg(args, 3); if (!name|| !oper || !rhs) return NORET; char *value = cmdline_line_from(ca->cmdline, 3); set_opt(name, value); return NORET; }
static Cmdret conf_variable(List *args, Cmdarg *ca) { log_msg("CONFIG", "conf_variable"); log_err("CONFIG", "%s", ca->cmdline->line); /* statement needs valid name */ Token *lhs = tok_arg(args, 1); char *key = list_arg(args, 1, VAR_STRING); if (!lhs || !key) return NORET; /* find where '=' delimits statement */ int delm = -1; for (int i = 0; i < utarray_len(args->items); i++) { char *op = list_arg(args, i, VAR_STRING); if (op && !strcmp(op, "=")) { delm = i+1; break; } } if (delm == -1 || delm >= utarray_len(args->items)) return NORET; char *expr = cmdline_line_from(ca->cmdline, delm); fn_var var = { .key = strdup(key), .var = strdup(expr), }; /* when delm isn't 3 the key should be expanded */ if (delm != 3) { char *pvar = opt_var(key, cmd_callstack()); if (!pvar) goto cleanup; char *newexpr = repl_elem(pvar, expr, args, 2, delm - 1); if (!newexpr) goto cleanup; SWAP_ALLOC_PTR(var.var, newexpr); } fn_func *blk = cmd_callstack(); if (!ca->flags) blk = NULL; set_var(&var, blk); return NORET; cleanup: free(var.key); free(var.var); return NORET; }
Token* container_elem(Token *ary, List *args, int fst, int lst) { log_msg("CMDLINE", "access_container"); Token *get = ary; for (int i = fst; i < lst; i++) { List *accessor = list_arg(args, i, VAR_LIST); if (!accessor || utarray_len(accessor->items) > 1) return NULL; int index = -1; if (!str_num(list_arg(accessor, 0, VAR_STRING), &index)) return NULL; List *ret = token_val(get, VAR_LIST); if (!ret) return NULL; get = tok_arg(ret, index); } return get; }
char* repl_elem(char *line, char *expr, List *args, int fst, int lst) { Cmdline cmd; cmdline_build(&cmd, line); Token *ary = tok_arg(cmdline_lst(&cmd), 0); log_msg("CMDLINE", "line %s", cmd.line); Token *elem = container_elem(ary, args, fst, lst); if (!elem) { cmdline_cleanup(&cmd); return NULL; } int len = strlen(line) - (elem->end - elem->start) + strlen(expr); char *newexpr = malloc(sizeof(char*)*len); newexpr[0] = '\0'; strncat(newexpr, line, elem->start); strcat(newexpr, expr); strcat(newexpr, &line[elem->end]); cmdline_cleanup(&cmd); return newexpr; }