static char * exec_instr( pInstr s ) { pCell tc, tc2; char buffer[16]; switch (s->opcode) { case SET: /* operand must be a string */ tc = temp_pop(); switch (tc->type) { case mu: fprintf(stderr, "exec_inst/SET: warning - unhandled case mu\n" ); break; case string_t: var_put(s->operand.contents.s, tc->contents.s); break; case int_t: var_put_int(s->operand.contents.s, tc->contents.i); break; } break; case EMIT: tc = temp_pop(); switch (tc->type) { case mu: fprintf(stderr, "exec_inst/EMIT: warning - unhandled case mu\n" ); break; case string_t: return tc->contents.s; case int_t: sprintf(buffer, "%i", tc->contents.i); return strdup(buffer); } case PUSHV: { struct var *v = var_lookup(vars, s->operand.contents.s); if (v == 0) { fprintf(stderr, "attempted to use unknown variable \"%s\" in expression.\n", s->operand.contents.s); push_str("(NULL)"); } else { switch (v->type) { case mu: fprintf(stderr, "exec_inst/PUSHV: warning - unhandled case mu\n" ); break; case string_t: push_str(strdup(v->value.s)); break; case int_t: push_int(v->value.i); break; } } } break; case INVOKE: { pRule r = rule_find(rule_base, s->operand.contents.s); if (r) { push_str(resolve_rule(rule_base, r)); } else { fprintf(stderr, "attempted to invoke non-existent rule \"%s\" in expression.\n", s->operand.contents.s); push_str(NULL); } } break; case PUSH: switch (s->operand.type) { case mu: fprintf(stderr, "exec_inst/PUSH: warning - unhandled case mu\n" ); break; case string_t: push_str(strdup(s->operand.contents.s)); break; case int_t: push_int(s->operand.contents.i); break; } break; case ADD: tc = temp_pop(); tc2 = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(tc->contents.i + tc2->contents.i); } else { char *s0, *s1; /* string concatenation */ s0 = ((tc->type == int_t) ? itoa(tc->contents.i) : (tc->contents.s)); s1 = ((tc2->type == int_t) ? itoa(tc2->contents.i) : (tc2->contents.s)); push_str(concat(s1, s0)); free(s0); free(s1); } break; case SUB: tc = temp_pop(); tc2 = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(tc2->contents.i + tc->contents.i); } break; case MUL: tc = temp_pop(); tc2 = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(tc->contents.i * tc2->contents.i); } break; case DIV: tc = temp_pop(); tc2 = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(tc2->contents.i / tc->contents.i); } break; case MOD: tc = temp_pop(); tc2 = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(tc2->contents.i % tc->contents.i); } break; case RANDOM: tc2 = temp_pop(); tc = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int((random() % (tc2->contents.i - tc->contents.i + 1)) + tc->contents.i); } break; case LESSER: tc2 = temp_pop(); tc = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(min(tc->contents.i, tc2->contents.i)); } break; case GREATER: tc2 = temp_pop(); tc = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(max(tc->contents.i, tc2->contents.i)); } break; } return NULL; }
char *strexpand(char *fmt, char **tab) { char *buf= (char *)0; if(fmt && *fmt) { if( strexpand_init(tab) == 0 ) { size_t len= strlen(fmt) + 1; /* size of output buffer */ if( (buf= (char *)malloc(len*sizeof(char))) ) { unsigned int pos= 0; /* char position in buf */ /**/ while(buf && *fmt) { char *rhs= rule_find( &fmt ); if(rhs) { while(*rhs) { buf[pos++]= *rhs++; if(pos >= len) { char *old= buf; len += 1024; buf= (char *)realloc(buf,len*sizeof(char)); if(!buf) free(old); } } } else /* !rhs */ { buf[pos++]= *fmt++; if(pos >= len) { char *old= buf; len += 1024; buf= (char *)realloc(buf,len*sizeof(char) ); if(!buf) free(old); } } } /**/ if(buf) buf[pos]= '\0'; /*printf("strexpand(): pos=%d, len=%d\n",pos,len);*/ } } strexpand_exit(); } return buf; }