Exnode_t *exexpr(Expr_t * ex, const char *name, Exid_t * sym, int type) { if (ex) { if (!sym) sym = name ? (Exid_t *) dtmatch(ex->symbols, name) : &ex->main; if (sym && sym->lex == PROCEDURE && sym->value) { if (type != DELETE_T) return excast(ex, sym->value->data.procedure.body, type, NiL, 0); exfreenode(ex, sym->value); sym->lex = NAME; sym->value = 0; } } return 0; }
static int prformat(Sfio_t* sp, void* vp, Sffmt_t* dp) { register Fmt_t* fmt = (Fmt_t*)dp; register Exnode_t* node; register char* s; register char* txt; int n; int from; int to; time_t tm; dp->flags |= SFFMT_VALUE; if (fmt->args) { if (node = (dp->fmt == '*') ? fmt->args->param[dp->size] : fmt->args->arg) fmt->value = exeval(fmt->expr, node, fmt->env); else fmt->value.integer = 0; to = fmt->args->arg->type; } else if (!(fmt->actuals = fmt->actuals->data.operand.right)) exerror("printf: not enough arguments"); else { node = fmt->actuals->data.operand.left; from = node->type; switch (dp->fmt) { case 'f': case 'g': to = FLOATING; break; case 's': case '[': to = STRING; break; default: switch (from) { case INTEGER: case UNSIGNED: to = from; break; default: to = INTEGER; break; } break; } if (to == from) fmt->value = exeval(fmt->expr, node, fmt->env); else { node = excast(fmt->expr, node, to, NiL, 0); fmt->value = exeval(fmt->expr, node, fmt->env); node->data.operand.left = 0; exfree(fmt->expr, node); if (to == STRING) { if (fmt->value.string) { n = strlen(fmt->value.string); if (s = fmtbuf(n + 1)) memcpy(s, fmt->value.string, n + 1); vmfree(fmt->expr->vm, fmt->value.string); fmt->value.string = s; } if (!fmt->value.string) fmt->value.string = ""; } } } switch (to) { case STRING: *((char**)vp) = fmt->value.string; fmt->fmt.size = -1; break; case FLOATING: *((double*)vp) = fmt->value.floating; fmt->fmt.size = sizeof(double); break; default: *((Sflong_t*)vp) = fmt->value.integer; dp->size = sizeof(Sflong_t); break; } if (dp->n_str > 0) { if (!fmt->tmp && !(fmt->tmp = sfstropen())) txt = exnospace(); else { sfprintf(fmt->tmp, "%.*s", dp->n_str, dp->t_str); txt = exstash(fmt->tmp, NiL); } } else txt = 0; switch (dp->fmt) { case 'q': case 'Q': s = *((char**)vp); *((char**)vp) = fmtquote(s, "$'", "'", strlen(s), 0); dp->fmt = 's'; dp->size = -1; break; case 'S': dp->flags &= ~SFFMT_LONG; s = *((char**)vp); if (txt) { if (streq(txt, "identifier")) { if (*s && !isalpha(*s)) *s++ = '_'; for (; *s; s++) if (!isalnum(*s)) *s = '_'; } else if (streq(txt, "invert")) { for (; *s; s++) if (isupper(*s)) *s = tolower(*s); else if (islower(*s)) *s = toupper(*s); } else if (streq(txt, "lower")) { for (; *s; s++) if (isupper(*s)) *s = tolower(*s); } else if (streq(txt, "upper")) { for (; *s; s++) if (islower(*s)) *s = toupper(*s); } else if (streq(txt, "variable")) { for (; *s; s++) if (!isalnum(*s) && *s != '_') *s = '.'; } } dp->fmt = 's'; dp->size = -1; break; case 't': case 'T': if ((tm = *((Sflong_t*)vp)) == -1) tm = time(NiL); *((char**)vp) = fmttime(txt ? txt : "%?%K", tm); dp->fmt = 's'; dp->size = -1; break; } return 0; }