void room_exist(ROOM_DATA *room) { propertyTablePut(room_table, room); // add contents if(listSize(roomGetContents(room)) > 0) { LIST_ITERATOR *cont_i = newListIterator(roomGetContents(room)); OBJ_DATA *cont = NULL; ITERATE_LIST(cont, cont_i) obj_exist(cont); deleteListIterator(cont_i); } // add its people if(listSize(roomGetCharacters(room)) > 0) { LIST_ITERATOR *ch_i = newListIterator(roomGetCharacters(room)); CHAR_DATA *ch = NULL; ITERATE_LIST(ch, ch_i) char_exist(ch); deleteListIterator(ch_i); } // add its exits LIST *ex_list = roomGetExitNames(room); LIST_ITERATOR *ex_i = newListIterator(ex_list); char *dir = NULL; ITERATE_LIST(dir, ex_i) { exit_exist(roomGetExit(room, dir)); } deleteListIterator(ex_i);
// // Takes a list of tokens, and builds the proper syntax for the command and // then sends it to the character. void show_parse_syntax_error(CHAR_DATA *ch, const char *cmd, LIST *tokens) { BUFFER *buf = newBuffer(1); LIST_ITERATOR *tok_i = newListIterator(tokens); PARSE_TOKEN *tok = NULL; bool optional_found = FALSE; int count = 0; // go through all of our tokens, and append their syntax to the buf ITERATE_LIST(tok, tok_i) { // make sure we add a space before anything else... if(count > 0) bprintf(buf, " "); count++; // have we encountered the "optional" marker? if so, switch our open/close if(tok->type == PARSE_TOKEN_OPTIONAL) { bprintf(buf, "["); optional_found = TRUE; // we don't want to put a space right after this [ count = 0; continue; } // append our message switch(tok->type) { case PARSE_TOKEN_MULTI: { bprintf(buf, "<"); LIST_ITERATOR *multi_i = newListIterator(tok->token_list); PARSE_TOKEN *mtok = NULL; int m_count = 0; ITERATE_LIST(mtok, multi_i) { if(m_count > 0) bprintf(buf, ", "); m_count++; bprintf(buf, "%s", get_datatype_format_error_mssg(mtok)); } deleteListIterator(multi_i); bprintf(buf, ">"); break; } case PARSE_TOKEN_FLAVOR: bprintf(buf, "%s%s%s", (tok->flavor_optional ? "[" : ""), tok->flavor, (tok->flavor_optional ? "]" : "")); break; default: bprintf(buf, "<%s>", get_datatype_format_error_mssg(tok)); break; } } deleteListIterator(tok_i); // send the message send_to_char(ch, "Proper syntax is: %s %s%s\r\n", cmd, bufferString(buf), (optional_found ? "]" : "")); deleteBuffer(buf); }
static Iterator newMapIterator(void *collection) { Iterator iterator; iterator = newListIterator(sizeof(string), NULL); mapBST(((Map) collection)->bst, addKeyToIterator, INORDER, iterator); return iterator; }
void do_copyover(void) { LIST_ITERATOR *sock_i = newListIterator(socket_list); SOCKET_DATA *sock = NULL; FILE *fp; char buf[100]; char control_buf[20]; char port_buf[20]; if ((fp = fopen(COPYOVER_FILE, "w+")) == NULL) return; sprintf(buf, "\n\r <*> The world starts spinning <*>\n\r"); // For each playing descriptor, save its character and account ITERATE_LIST(sock, sock_i) { compressEnd(sock, sock->compressing, FALSE); // kick off anyone who hasn't yet logged in a character if (!socketGetChar(sock) || !socketGetAccount(sock) || !charGetRoom(socketGetChar(sock))) { text_to_socket(sock, "\r\nSorry, we are rebooting. Come back in a few minutes.\r\n"); close_socket(sock, FALSE); } // save account and player info to file else { fprintf(fp, "%d %s %s %s\n", sock->control, accountGetName(sock->account), charGetName(sock->player), sock->hostname); // save the player save_player(sock->player); save_account(sock->account); text_to_socket(sock, buf); } } deleteListIterator(sock_i);
void extenderDoMenu(SOCKET_DATA *sock, OLC_EXTENDER *ext, void *data) { LIST *keys = hashCollect(ext->opt_hash); char *key = NULL; OLC_EXT_DATA *edata = NULL; // display each menu item alphabetically listSortWith(keys, strcasecmp); LIST_ITERATOR *key_i = newListIterator(keys); ITERATE_LIST(key, key_i) { // display the menu option send_to_socket(sock, "{g%s) ", key); // then display the information edata = hashGet(ext->opt_hash, key); if(edata->type == OLCEXT_C) edata->menu(sock, data); else if(ext->borrow_py != NULL) { PyObject *ret = PyObject_CallFunction(edata->pymenu, "OO", socketGetPyFormBorrowed(sock), ext->borrow_py(data)); if(ret == NULL) log_pyerr("Error running Python OLC exention menu function: %s", key); Py_XDECREF(ret); } } deleteListIterator(key_i);
/* reset all of the sockets' control values */ void reconnect_copyover_sockets() { LIST_ITERATOR *sock_i = newListIterator(socket_list); SOCKET_DATA *sock = NULL; ITERATE_LIST(sock, sock_i) FD_SET(sock->control, &fSet); deleteListIterator(sock_i); }
Iterator newDirectoryTreeIterator(string dir) { Iterator iterator; iterator = newListIterator(sizeof (string), NULL); mapDirectoryTree(dir, iterator); return iterator; }
//***************************************************************************** // methods in the mudsock module //***************************************************************************** PyObject *PySocket_all_sockets(PyObject *self) { PyObject *list = PyList_New(0); LIST_ITERATOR *sock_i = newListIterator(socket_list); SOCKET_DATA *sock = NULL; ITERATE_LIST(sock, sock_i) { PyList_Append(list, socketGetPyFormBorrowed(sock)); } deleteListIterator(sock_i);
// // unload a persistent room from memory. Will not work if PCs are present. PyObject *PyRoom_unloadPersistence(PyObject *pyroom) { ROOM_DATA *room = PyRoom_AsRoom(pyroom); if(room == NULL) { PyErr_Format(PyExc_TypeError, "tried to save nonexistent room."); return NULL; } // it's not pesistent if(!roomIsPersistent(room)) return Py_BuildValue("i", 0); // does it contain a PC? LIST_ITERATOR *ch_i = newListIterator(roomGetCharacters(room)); CHAR_DATA *ch = NULL; bool pc_found = FALSE; ITERATE_LIST(ch, ch_i) { if(!charIsNPC(ch)) { pc_found = TRUE; break; } } deleteListIterator(ch_i); if(pc_found) return Py_BuildValue("i", 0); worldStorePersistentRoom(gameworld, roomGetClass(room), room); extract_room(room); return Py_BuildValue(""); }
// // Perform resetRun on all the reset commands in the list, using // initiator and initiator_type void resetRunOn(LIST *list, void *initiator, int initiator_type, const char *locale) { if(listSize(list) > 0) { LIST_ITERATOR *list_i = newListIterator(list); RESET_DATA *reset = NULL; ITERATE_LIST(reset, list_i) resetRun(reset, initiator, initiator_type, locale); deleteListIterator(list_i); } }
PyObject *PyList_fromList(LIST *list, void *convertor) { PyObject *pylist = PyList_New(0); PyObject *(*conv_func)(void *) = convertor; LIST_ITERATOR *list_i = newListIterator(list); void *elem = NULL; ITERATE_LIST(elem, list_i) { PyObject *pyelem = conv_func(elem); PyList_Append(pylist, pyelem); Py_DECREF(pyelem); } deleteListIterator(list_i);
void obj_exist(OBJ_DATA *obj) { propertyTablePut(obj_table, obj); // also add all contents if(listSize(objGetContents(obj)) > 0) { LIST_ITERATOR *cont_i = newListIterator(objGetContents(obj)); OBJ_DATA *cont = NULL; ITERATE_LIST(cont, cont_i) obj_exist(cont); deleteListIterator(cont_i); } }
void obj_unexist(OBJ_DATA *obj) { // also unexist all contents if(listSize(objGetContents(obj)) > 0) { LIST_ITERATOR *cont_i = newListIterator(objGetContents(obj)); OBJ_DATA *cont = NULL; ITERATE_LIST(cont, cont_i) obj_unexist(cont); deleteListIterator(cont_i); } propertyTableRemove(obj_table, objGetUID(obj)); }
Iterator newDirectoryIterator(string dir) { Iterator iterator; string *names; int i; iterator = newListIterator(sizeof (string), NULL); names = listDirectory(dir); for (i = 0; names[i] != NULL; i++) { addToIteratorList(iterator, &names[i]); } return iterator; }
// // run all of the resets for a specified room void do_resets(ROOM_DATA *room) { // first apply all of our prototype resets LIST *protos = parse_keywords(roomGetPrototypes(room)); LIST_ITERATOR *proto_i = newListIterator(protos); char *proto = NULL; RESET_LIST *list = NULL; // try to run each parent reset, and finally our own ITERATE_LIST(proto, proto_i) { if((list = worldGetType(gameworld, "reset", proto)) != NULL) resetRunOn(resetListGetResets(list), room, INITIATOR_ROOM, get_key_locale(proto)); } deleteListIterator(proto_i); deleteListWith(protos, free); }
void output_handler() { LIST_ITERATOR *sock_i = newListIterator(socket_list); SOCKET_DATA *sock = NULL; ITERATE_LIST(sock, sock_i) { /* if the player quits or get's disconnected */ if(sock->closed) continue; /* Send all new data to the socket and close it if any errors occour */ if (!flush_output(sock)) close_socket(sock, FALSE); } deleteListIterator(sock_i); }
static PyObject * PyRoom_getobjs(PyRoom *self, PyObject *args) { ROOM_DATA *room = worldGetRoom(gameworld, self->vnum); if(room == NULL) return NULL; else { LIST_ITERATOR *obj_i = newListIterator(roomGetContents(room)); PyObject *list = PyList_New(0); OBJ_DATA *obj; // for each obj in the room list, add him to a Python list ITERATE_LIST(obj, obj_i) PyList_Append(list, newPyObj(obj)); deleteListIterator(obj_i); return Py_BuildValue("O", list); } }
static PyObject * PyRoom_getchars(PyRoom *self, PyObject *args) { ROOM_DATA *room = worldGetRoom(gameworld, self->vnum); if(room == NULL) return NULL; else { LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(room)); PyObject *list = PyList_New(0); CHAR_DATA *ch; // for each char in the room list, add him to a Python list ITERATE_LIST(ch, char_i) PyList_Append(list, newPyChar(ch)); deleteListIterator(char_i); return Py_BuildValue("O", list); } }
PyObject *PyAccount_characters(PyAccount *self, PyObject *args) { ACCOUNT_DATA *acc = PyAccount_AsAccount((PyObject *)self); if(acc == NULL) { PyErr_Format(PyExc_StandardError, "Tried to add character to a nonexistant account."); return NULL; } LIST_ITERATOR *name_i = newListIterator(accountGetChars(acc)); PyObject *list = PyList_New(0); const char *name = NULL; ITERATE_LIST(name, name_i) { PyObject *val = PyString_FromString(name); PyList_Append(list, val); Py_DECREF(val); } deleteListIterator(name_i);
// // zone reset hook. Whenever a zone is reset, apply all of its reset rules for // each room in the zone. void zone_reset_hook(const char *info) { char *zone_key = NULL; hookParseInfo(info, &zone_key); ZONE_DATA *zone = worldGetZone(gameworld, zone_key); LIST_ITERATOR *res_i = newListIterator(zoneGetResettable(zone)); char *name = NULL; const char *locale = zone_key; ROOM_DATA *room = NULL; ITERATE_LIST(name, res_i) { if((room = worldGetRoom(gameworld, get_fullkey(name, locale))) != NULL) { do_resets(room); } } deleteListIterator(res_i); // garbage collection free(zone_key); }
// // builds up a list of variables out of the token list, and arguments. If we // encounter an error and we need to show it to the looker, do so. LIST *compose_variable_list(CHAR_DATA *looker, LIST *tokens, char *args, char *err_buf) { LIST *variables = newList(); LIST_ITERATOR *tok_i = newListIterator(tokens); PARSE_TOKEN *tok = NULL; bool error = FALSE; bool optional_found = FALSE; // go through our list of tokens, and try dealing with the args ITERATE_LIST(tok, tok_i) { PARSE_VAR *var = NULL; // did we just encounter an optional value? if(tok->type == PARSE_TOKEN_OPTIONAL) { optional_found = TRUE; continue; } // can we still use tokens to process stuff? if(*args != '\0') var = use_one_parse_token(looker, tok, &args, &error, err_buf); // we haven't found an "optional" marker yet - this isn't allowed else if(optional_found == FALSE) error = TRUE; // we have found an "optional" marker. Just break out of the loop else break; // if use of the token returned a new variable, append it if(var != NULL) listQueue(variables, var); // if we enountered an error, tell the person if neccessary else if(error == TRUE) { deleteListWith(variables, deleteParseVar); variables = NULL; break; } } deleteListIterator(tok_i);
void recycle_sockets() { SOCKET_DATA *dsock; LIST_ITERATOR *sock_i = newListIterator(socket_list); ITERATE_LIST(dsock, sock_i) { if (dsock->lookup_status != TSTATE_CLOSED) continue; /* remove the socket from the main list */ listRemove(socket_list, dsock); propertyTableRemove(sock_table, dsock->uid); /* close the socket */ close(dsock->control); /* stop compression */ compressEnd(dsock, dsock->compressing, TRUE); /* delete the socket from memory */ deleteSocket(dsock); } deleteListIterator(sock_i); }
void obj_to_game(OBJ_DATA *obj) { if(setIn(object_set, obj)) return; // property table, for lookup by python if(!obj_exists(obj)) obj_exist(obj); // set and list storage, for objects physically 'in' the game listPut(object_list, obj); setPut(object_set, obj); // execute all of our to_game hooks hookRun("obj_to_game", hookBuildInfo("obj", obj)); // also add all contents if(listSize(objGetContents(obj)) > 0) { LIST_ITERATOR *cont_i = newListIterator(objGetContents(obj)); OBJ_DATA *cont = NULL; ITERATE_LIST(cont, cont_i) obj_to_game(cont); deleteListIterator(cont_i); } }
void input_handler() { LIST_ITERATOR *sock_i = newListIterator(socket_list); SOCKET_DATA *sock = NULL; ITERATE_LIST(sock, sock_i) { // Close sockects we are unable to read from, or if we have no handler // to take in input if ((FD_ISSET(sock->control, &rFd) && !read_from_socket(sock)) || listSize(sock->input_handlers) == 0) { close_socket(sock, FALSE); continue; } /* Ok, check for a new command */ next_cmd_from_buffer(sock); // are we idling? if(!sock->cmd_read) sock->idle += 1.0 / PULSES_PER_SECOND; /* Is there a new command pending ? */ else if (sock->cmd_read) { sock->idle = 0.0; IH_PAIR *pair = listGet(sock->input_handlers, 0); if(pair->python == FALSE) { void (* handler)(SOCKET_DATA *, char *) = pair->handler; char *cmddup = strdup(bufferString(sock->next_command)); handler(sock, cmddup); free(cmddup); } else { PyObject *arglist = Py_BuildValue("Os", socketGetPyFormBorrowed(sock), bufferString(sock->next_command)); PyObject *retval = PyEval_CallObject(pair->handler, arglist); // check for an error: if(retval == NULL) log_pyerr("Error with a Python input handler"); // garbage collection Py_XDECREF(retval); Py_XDECREF(arglist); } // append our last command to the command history. History buffer is // 100 commands, so pop off the earliest command if we're going over listPut(sock->command_hist, strdup(bufferString(sock->next_command))); if(listSize(sock->command_hist) > 100) free(listRemoveNum(sock->command_hist, 100)); bufferClear(sock->next_command); // we save whether or not we read a command until our next call to // input_handler(), at which time it is reset to FALSE if we didn't read // sock->cmd_read = FALSE; } #ifdef MODULE_ALIAS // ACK!! this is so yucky, but I can't think of a better way to do it... // if this command was put in place by an alias, decrement the alias_queue // counter by one. This counter is in place mainly so aliases do not end // up calling eachother and making us get stuck in an infinite loop. if(sock->player) { int alias_queue = charGetAliasesQueued(sock->player); if(alias_queue > 0) charSetAliasesQueued(sock->player, --alias_queue); } #endif } deleteListIterator(sock_i); }
// // Tries to apply a token to args, to parse something out. Returns a PARSE_VAR // if the token's usage resulted in the creation of a variable. If an error was // encountered, make this apparent by setting the value of the variable at error PARSE_VAR *use_one_parse_token(CHAR_DATA *looker, PARSE_TOKEN *tok, char **args, bool *error, char *err_buf) { char buf[SMALL_BUFFER]; PARSE_VAR *var = NULL; char *arg = *args; // skip over any leading spaces we might have while(isspace(*arg)) arg++; switch(tok->type) { case PARSE_TOKEN_MULTI: { // make a proxy error value and error buf so we don't accidentally fill // these up when it turns out we find something on a var past the first bool multi_err = FALSE; char multi_err_buf[SMALL_BUFFER] = ""; // go through all of our possible types until we find something LIST_ITERATOR *multi_i = newListIterator(tok->token_list); PARSE_TOKEN *mtok = NULL; bool multiple_possible = FALSE; ITERATE_LIST(mtok, multi_i) { if(mtok->all_ok) multiple_possible = TRUE; var = use_one_parse_token(looker, mtok, &arg, &multi_err, multi_err_buf); // reset our error value for the next pass at it... if(var == NULL) multi_err = FALSE; // found something! Disambiguate the type else { switch(mtok->type) { case PARSE_TOKEN_CHAR: var->disambiguated_type = PARSE_CHAR; break; case PARSE_TOKEN_ROOM: var->disambiguated_type = PARSE_ROOM; break; case PARSE_TOKEN_EXIT: var->disambiguated_type = PARSE_EXIT; break; case PARSE_TOKEN_OBJ: var->disambiguated_type = PARSE_OBJ; break; case PARSE_TOKEN_WORD: var->disambiguated_type = PARSE_STRING; break; case PARSE_TOKEN_STRING: var->disambiguated_type = PARSE_STRING; break; case PARSE_TOKEN_INT: var->disambiguated_type = PARSE_INT; break; case PARSE_TOKEN_DOUBLE: var->disambiguated_type = PARSE_DOUBLE; break; case PARSE_TOKEN_BOOL: var->disambiguated_type = PARSE_BOOL; break; } // break out of the loop... we found something break; } } deleteListIterator(multi_i); // did we manage not to find something? if(var != NULL) var->multiple_possible = multiple_possible; else { one_arg(arg, buf); // get the first arg, for reporting... sprintf(err_buf, "Your argument '%s' was invalid or could not be found.", buf); *error = TRUE; } break; } case PARSE_TOKEN_FLAVOR: { int len = strlen(tok->flavor); // have we found the flavor text? if(strncasecmp(tok->flavor, arg, len) == 0 && (arg[len] == '\0' || isspace(arg[len]))) arg = arg + len; // do we need to do something about it? else if(!tok->flavor_optional) *error = TRUE; break; } // parse out a char value case PARSE_TOKEN_CHAR: arg = one_arg(arg, buf); var = use_one_parse_token_char(looker, tok, buf); if(var == NULL) { sprintf(err_buf, "The person, %s, could not be found.", buf); *error = TRUE; } break; // parse out an obj value case PARSE_TOKEN_OBJ: arg = one_arg(arg, buf); var = use_one_parse_token_obj(looker, tok, buf); if(var == NULL) { sprintf(err_buf, "The object, %s, could not be found.", buf); *error = TRUE; } break; // parse out a room value case PARSE_TOKEN_ROOM: arg = one_arg(arg, buf); var = use_one_parse_token_room(looker, tok, buf); if(var == NULL) { sprintf(err_buf, "The room, %s, could not be found.", buf); *error = TRUE; } break; // parse out an exit value case PARSE_TOKEN_EXIT: arg = one_arg(arg, buf); var = use_one_parse_token_exit(looker, tok, buf); if(var == NULL) { sprintf(err_buf, "The direction, %s, could not be found.", buf); *error = TRUE; } break; // try to parse out a double value case PARSE_TOKEN_DOUBLE: arg = one_arg(arg, buf); var = use_one_parse_token_double(buf); if(var == NULL) { sprintf(err_buf, "'%s' is not a decimal value.", buf); *error = TRUE; } break; // try to parse out an integer value case PARSE_TOKEN_INT: arg = one_arg(arg, buf); var = use_one_parse_token_int(buf); if(var == NULL) { sprintf(err_buf, "'%s' is not a%s number.", buf, (string_is_double(buf) ? "n acceptable" : "")); *error = TRUE; } break; // try to parse out a boolean value case PARSE_TOKEN_BOOL: arg = one_arg(arg, buf); var = use_one_parse_token_bool(buf); if(var == NULL) { sprintf(err_buf, "'%s' is not a yes/no value.", buf); *error = TRUE; } break; // parse out a single word case PARSE_TOKEN_WORD: { var = newParseVar(PARSE_VAR_STRING); var->ptr_val = arg; bool multi_word = FALSE; char multi_mark = '"'; // are we using quotation marks to specify multiple words? if(*arg == '"' || *arg == '\'') { multi_word = TRUE; multi_mark = *arg; arg++; var->ptr_val = arg; } // go through arg to the next space, and delimit the word for(; *arg != '\0'; arg++) { if((multi_word && *arg == multi_mark) || (!multi_word && isspace(*arg))) { *arg = '\0'; arg++; break; } } break; } // copies whatever is left case PARSE_TOKEN_STRING: var = newParseVar(PARSE_VAR_STRING); var->ptr_val = arg; // skip up the place of the arg... while(*arg != '\0') arg++; break; // since this doesn't really parse a value... case PARSE_TOKEN_OPTIONAL: break; } // up the placement of our arg if we didn't encounter an error if(!*error) *args = arg; return var; }
case TRIGVAR_ROOM: pyopt = roomGetPyForm(opt->data); break; } PyDict_SetItemString(dict, opt->name, pyopt); listPut(varnames, strdup(opt->name)); Py_XDECREF(pyopt); } deleteListIterator(opt_i); } // run the script, then kill our dictionary triggerRun(trig, dict); // if triggers create methods, it increases the reference count on our // dictionary. This is a known memory leak. We'll try to mitigate it by // cleaning out some of the contents. A better solution is needed, that // makes sure the dictionary itself is not leaked LIST_ITERATOR *vname_i = newListIterator(varnames); char *vname = NULL; ITERATE_LIST(vname, vname_i) { PyDict_DelItemString(dict, vname); } deleteListIterator(vname_i); deleteListWith(varnames, free); Py_XDECREF(dict); } // // generalized function for running all triggers of a specified type. void gen_do_trigs(void *me, int me_type, const char *type, CHAR_DATA *ch,OBJ_DATA *obj, ROOM_DATA *room, EXIT_DATA *exit, const char *command, const char *arg, LIST *optional) { // find our list of triggers LIST *trig_keys = NULL;
// // generalized function for setting up a dictionary and running a trigger. The // common types of variables can be supplied in the function. Additional ones // can be added in the optional list, which must be deleted after use void gen_do_trig(TRIGGER_DATA *trig, void *me, int me_type, CHAR_DATA *ch, OBJ_DATA *obj, ROOM_DATA *room, EXIT_DATA *exit, const char *command, const char *arg, LIST *optional) { // make our basic dictionary, and fill it up with these new variables PyObject *dict = restricted_script_dict(); LIST *varnames = newList(); // now, import all of our variables if(command) { PyObject *pycmd = PyString_FromString(command); PyDict_SetItemString(dict, "cmd", pycmd); listPut(varnames, strdup("cmd")); Py_DECREF(pycmd); } if(arg) { PyObject *pyarg = PyString_FromString(arg); PyDict_SetItemString(dict, "arg", pyarg); listPut(varnames, strdup("arg")); Py_DECREF(pyarg); } if(ch) { PyObject *pych = charGetPyForm(ch); PyDict_SetItemString(dict, "ch", pych); listPut(varnames, strdup("ch")); Py_DECREF(pych); } if(room) { PyObject *pyroom = roomGetPyForm(room); PyDict_SetItemString(dict, "room", pyroom); listPut(varnames, strdup("room")); Py_DECREF(pyroom); } if(obj) { PyObject *pyobj = objGetPyForm(obj); PyDict_SetItemString(dict, "obj", pyobj); listPut(varnames, strdup("obj")); Py_DECREF(pyobj); } if(exit) { PyObject *pyexit = newPyExit(exit); PyDict_SetItemString(dict, "ex", pyexit); listPut(varnames, strdup("ex")); Py_DECREF(pyexit); } // add the thing the trigger is attached to if(me) { PyObject *pyme = NULL; switch(me_type) { case TRIGVAR_CHAR: pyme = charGetPyForm(me); break; case TRIGVAR_OBJ: pyme = objGetPyForm(me); break; case TRIGVAR_ROOM: pyme = roomGetPyForm(me); break; } PyDict_SetItemString(dict, "me", pyme); listPut(varnames, strdup("me")); Py_DECREF(pyme); } // now, add any optional variables if(optional) { LIST_ITERATOR *opt_i = newListIterator(optional); OPT_VAR *opt = NULL; PyObject *pyopt = NULL; ITERATE_LIST(opt, opt_i) { pyopt = NULL; switch(opt->type) { case TRIGVAR_CHAR: pyopt = charGetPyForm(opt->data); break; case TRIGVAR_OBJ: pyopt = objGetPyForm(opt->data); break; case TRIGVAR_ROOM: pyopt = roomGetPyForm(opt->data); break; } PyDict_SetItemString(dict, opt->name, pyopt); listPut(varnames, strdup(opt->name)); Py_XDECREF(pyopt); } deleteListIterator(opt_i); }