const char *translate(const char *format, const void *userdata, const char *vars, variant args[]) { unsigned int i = 0; const char *ic = vars; char symbol[32]; char *oc = symbol; opstack *stack = NULL; const char *rv; brelease(); free_variables(); assert(format); assert(*ic == 0 || isalnum(*ic)); while (*ic) { *oc++ = *ic++; if (!isalnum(*ic)) { variant x = args[i++]; *oc = '\0'; oc = symbol; add_variable(strcpy(balloc(strlen(symbol) + 1), symbol), x); while (*ic && !isalnum(*ic)) ++ic; } } if (format[0] == '"') { rv = parse(&stack, format, userdata); } else { rv = parse_string(&stack, format, userdata); } if (rv != NULL) { if (rv[0]) { log_error("residual data after parsing: %s\n", rv); } rv = (const char *)opop(&stack).v; free(stack->begin); free(stack); } return rv; }
rt_public void eif_try_call (call_data * a) { uint32 pid = 0; /* Pattern id of the frozen feature */ EIF_NATURAL_32 i; EIF_NATURAL_32 n; BODY_INDEX body_id = a -> body_index; EIF_TYPED_VALUE * v; /* Push arguments to the evaluation stack */ for (n = a -> count, i = 0; i < n; i++) { v = iget (); * v = a -> argument [i]; if ((v -> it_r) && (v -> type & SK_HEAD) == SK_REF) { v -> it_r = eif_access (v -> it_r); } } /* Push current to the evaluation stack */ v = iget (); v -> it_r = eif_access (a -> target); v -> type = SK_REF; /* Make a call */ if (egc_frozen [body_id]) { /* We are below zero Celsius, i.e. ice */ pid = (uint32) FPatId(body_id); (pattern[pid].toc)(egc_frozen[body_id]); /* Call pattern */ } else { /* The proper way to start the interpretation of a melted feature is to call `xinterp' * in order to initialize the calling context (which is not done by `interpret'). * `tagval' will therefore be set, but we have to resynchronize the registers anyway. */ xinterp(MTC melt[body_id], 0); } /* Save result of a call */ v = a -> result; if (v) { * v = * opop (); switch (v -> type & SK_HEAD) { case SK_REF: case SK_EXP: /* Avoid reference result to be GC'ed by storing it in the protected location, pointed by `a -> result_address. */ * (a -> result_address) = v -> it_r; } } }