#include <stdio.h> #include "../lint.h" #include "../interface.h" #include "../object.h" /* Define variables */ extern struct object *previous_ob; /* Define functions */ extern char *malloc(unsigned); static var obj_prev = { "obj_previous", 0 }; static var obj_props = { "obj_props", 0 }; static var obj_no_change = { "obj_no_change", 0 }; /* fp[0]: string to be expanded fp[1]: target object */ static void object_check_call(struct svalue *fp) { extern struct svalue const0; extern struct svalue *process_value (char *, int); extern char *process_string(char *, int); extern void INLINE push_malloced_string(char *p); extern struct object *query_simul_efun_ob(); extern struct object *current_object; struct svalue *ret = 0; char *p, *p2, *str, *retstr; int more; if (fp[0].type != T_STRING) { push_svalue(&fp[0]); return; } assign_svalue(&VAR(obj_prev), &fp[1]); str = fp[0].u.string; if (str[0] == '@' && str[1] == '@') { p = &str[2]; p2 = &p[-1]; while ((p2 = (char *) strchr(&p2[1], '@')) && (p2[1] != '@')) ; if (!p2) { ret = process_value(p, 1); } else if (p2[2] == '\0') { int len = strlen(p); p2 = (char *) alloca(len - 1); strncpy(p2, p, len - 2); p2[len - 2] = '\0'; ret = process_value(p2, 1); } else retstr = process_string(str, 1); } else retstr = process_string(str, 1); if (ret) { push_svalue(ret); } else { push_string(retstr, STRING_MALLOC); if (str != retstr) free(retstr); } assign_svalue(&VAR(obj_prev), &const0); } static func func_check_call = { "check_call", object_check_call, }; static void object_query_prop(struct svalue *fp) { extern struct object *previous_ob; extern struct svalue const0; extern struct svalue *process_value (char *, int); extern char *process_string(char *, int); extern void INLINE push_malloced_string(char *p); extern struct object *query_simul_efun_ob(); extern struct object *current_object; struct svalue *ret = 0; struct svalue *val; static struct svalue tmp; char *p, *p2, *str, *retstr; int more; extern struct svalue *get_map_lvalue(struct mapping *, struct svalue *, int ); if (VAR(obj_props).type != T_MAPPING) { push_number(0); return; } val = get_map_lvalue(VAR(obj_props).u.map, fp, 0); if (val->type != T_STRING) { push_svalue(val); return; } tmp.type = T_OBJECT; tmp.u.ob = previous_ob; assign_svalue(&VAR(obj_prev), &tmp); str = val->u.string; if (str[0] == '@' && str[1] == '@') { p = &str[2]; p2 = &p[-1]; while ((p2 = (char *) strchr(&p2[1], '@')) && (p2[1] != '@')) ; if (!p2) { ret = process_value(p, 1); } else if (p2[2] == '\0') { int len = strlen(p); p2 = (char *) alloca(len - 1); strncpy(p2, p, len - 2); p2[len - 2] = '\0'; ret = process_value(p2, 1); } else retstr = process_string(str, 1); } else retstr = process_string(str, 1); if (ret) { push_svalue(ret); } else { push_string(retstr, STRING_MALLOC); if (str != retstr) free(retstr); } assign_svalue(&VAR(obj_prev), &const0); } static func func_query_prop = { "query_prop", object_query_prop, }; static void object_add_prop(struct svalue *fp) { extern struct svalue *get_map_lvalue(struct mapping *, struct svalue *, int ); struct svalue *oval; if (VAR(obj_no_change).u.number || VAR(obj_props).type != T_MAPPING) { push_number(0); return; } assign_svalue((oval=get_map_lvalue(VAR(obj_props).u.map,fp,1)),&fp[1]); if (current_object->super) { push_svalue(&fp[0]); push_svalue(get_map_lvalue(VAR(obj_props).u.map,fp,0)); push_svalue(oval); apply("notify_change_prop",current_object->super,3,0); } push_number(0); return; } static func func_add_prop = { "add_prop", object_add_prop, }; static func func_change_prop = { "change_prop", object_add_prop, }; /* Define the interface */ static var *(vars[]) = { &obj_prev, &obj_props, &obj_no_change, 0, }; static func *(funcs[]) = { &func_check_call, &func_query_prop, &func_add_prop, &func_change_prop, 0, }; struct interface stdobject = { "std/object.c", vars, funcs, };