#include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #include "db.h" #include "externs.h" #include "softcode.h" int parse_output(char *str, char *retbuf) { char buf[4096]; char *mbuf; char *p; int type = 1; if(!(p = is_math(str)) || *p) { p = str; while((p = is_string(p))); /* Whole loop */ if(p && *p) return(-1); type = 0; } if(type) { if(parse_statement(str, retbuf)) return(-1); return(type); } strcpy(retbuf, str); mbuf = retbuf; while((p = is_string(retbuf))) { strncpy(buf, mbuf, p-mbuf); *(buf+(p-mbuf)) = '\0'; extract_char(buf); extract_char(buf+strlen(buf)-1); sprintf(mbuf, "%s%s", buf, p); p = mbuf+strlen(buf); mbuf = p; } return(type); } char *is_string(char *str) { char *p = str; if(!*p) return(NULL); while(*p) { if(*p++ != '"') return(NULL); while(*p && *p != '"') p++; if(*p++ != '"') return(NULL); break; } return(p); } static void add_part(char *str, int len, char ***parts, int *num_parts) { char buf[4096]; strncpy(buf, str, len); *(buf+len) = '\0'; *parts = (char **)stack_realloc_tmp(*parts, sizeof(char *)*((*num_parts)+1)); (*parts)[(*num_parts)++] = stack_string_alloc(buf, 0); } static int split_line(char *str, char ***parts) { char *p; int num_parts = 0; *parts = (char **)stack_alloc(sizeof(char *), 0, 0); while(*str) { if(*str == '\"') { for(p = str+1;*p && *p != '\"';p++); if(!*p) { syntax_error(); return(-1); } p++; add_part(str, p-str, parts, &num_parts); } else { if((p = strchr(str, '\"'))) add_part(str, p-str, parts, &num_parts); else { add_part(str, strlen(str), parts, &num_parts); p = str+strlen(str); } } str = p; } return(num_parts); } void sc_do_print(char *arg1, char *arg2) { OBJ *victim; char *msg; char buf[4096], output[4096] = ""; char **parts; int i, num_parts; if(!*arg1) { victim = code_ptr->executor; msg = "\"\""; } else if(!*arg2) { victim = code_ptr->executor; msg = arg1; } else { victim = match_object(code_ptr->object, arg1, NOTYPE); if(!victim) { notify(code_ptr->executor, no_match(arg1)); return; } msg = arg2; } if((num_parts = split_line(msg, &parts)) == -1) return; for(i = 0;i < num_parts;++i) { if(is_math(parts[i])) { if(parse_statement(parts[i], buf)) return; strcat(output, buf); } else if(is_string(parts[i])) { extract_char(parts[i]); extract_char(last_char(parts[i])); strcat(output, parts[i]); } else if(!strcmp(parts[i], ";") && i+1 == num_parts) break; else { syntax_error(); return; } } if(i != num_parts) raw_notify(victim, output, 0); else notify(victim, output); } void sc_do_let(char *arg1, char *arg2) { char varname[4096]; char buf[4096], parsed_arg2[4096] = ""; SCVAR *var; char **parts; int i, num_parts; bool type; if(*(arg1++) != '~') { syntax_error(); return; } if(!get_varname(arg1, varname)) { syntax_error(); return; } if((num_parts = split_line(arg2, &parts)) == -1) return; if(!num_parts) { syntax_error(); return; } if(*last_char(varname) == '$') { type = VAR_STR; *last_char(varname) = '\0'; /* Get rid of the '$' */ for(i = 0;i < num_parts;++i) { if(!is_string(parts[i])) break; extract_char(parts[i]); extract_char(last_char(parts[i])); strcat(parsed_arg2, parts[i]); } if(i != num_parts) { notify(code_ptr->executor, tprintf("|+R|Type Mismatch in |+Y|%d|+R|.", code_ptr->pline->line)); notify(code_ptr->executor, tprintf("%d %s", code_ptr->pline->line, code_ptr->pline->code)); end_program(code_ptr->program, 0); return; } } else { type = VAR_NUM; for(i = 0;i < num_parts;++i) { if(!is_math(parts[i])) break; if(parse_statement(parts[i], buf)) return; strcat(parsed_arg2, buf); } if(i != num_parts) { notify(code_ptr->executor, tprintf("|+R|Type Mismatch in |+Y|%d|+R|.", code_ptr->pline->line)); notify(code_ptr->executor, tprintf("%d %s", code_ptr->pline->line, code_ptr->pline->code)); end_program(code_ptr->program, 0); return; } } var = find_var(varname, type); if(!var->can_modify) { notify(code_ptr->executor, tprintf("|+R|Attempt to modify a secure variable in |+Y|%d|+R|.", code_ptr->pline->line)); notify(code_ptr->executor, tprintf("%d %s", code_ptr->pline->line, code_ptr->pline->code)); end_program(code_ptr->program, 0); return; } if(type == VAR_STR) var->cvalue = stack_string_realloc(var->cvalue, tprintf("\"%s\"", parsed_arg2)); else var->nvalue = atoi(parsed_arg2); } void sc_do_input(char *arg1, char *arg2) { char *varname; OBJ *victim; SCINPUT *new_input; if(!*arg1) { victim = code_ptr->executor; varname = "\"\""; } else if(!*arg2) { victim = code_ptr->executor; varname = arg1; } else { if(!(victim = match_object(code_ptr->object, arg1, NOTYPE))) { notify(code_ptr->object, no_match(arg1)); return; } varname = arg2; } if(*varname++ != '~') { syntax_error(); return; } new_input = (SCINPUT *)stack_alloc(sizeof(SCINPUT), 1, 0); if(*last_char(varname) == '$') { *last_char(varname) = '$'; cvar_val(varname); /* Create the variable */ if(!code_ptr) /* cvar_val() NULLs this if varname is invalid */ return; new_input->var = find_var(varname, VAR_STR); } else { ivar_val(varname); if(!code_ptr) return; new_input->var = find_var(varname, VAR_NUM); } new_input->next = code_ptr->input; code_ptr->input = new_input; } int check_softcode_input(OBJ *player, char *str) { CODE *c; SCINPUT *freeme; for(c = code_list;c;c = c->next) if(c->input && c->executor == player) break; if(!c) return(0); if(!string_compare(str, "quit")) { code_ptr = c; notify(player, tprintf("Aborting program %s.", c->program->name)); end_program(c->program, 1); return(1); } if(c->input->var->type == VAR_STR) c->input->var->cvalue = stack_string_realloc(c->input->var->cvalue, tprintf("\"%s\"", str)); else c->input->var->nvalue = atoi(str); freeme = c->input; c->input = c->input->next; stack_free(freeme); return(1); }