diff --git a/include/QF/qfplist.h b/include/QF/qfplist.h index 68aedcd8c..ecc9ec01a 100644 --- a/include/QF/qfplist.h +++ b/include/QF/qfplist.h @@ -156,6 +156,17 @@ const char *PL_String (plitem_t *string); */ plitem_t *PL_ObjectForKey (plitem_t *dict, const char *key); +/** Remove a value from an array object. + The array items will be shuffled to fill the resulting hole. + + \param dict The Dictionary to remove the value from + \param key The unique key associated with the value to be removed + \return the value associated with the key, or NULL if not found or dict + isn't a dictionary. + \note You are responsible for freeing the returned object. +*/ +plitem_t *PL_RemoveObjectForKey (plitem_t *array, const char *key); + /** Retrieve a value from an array object. \param array The array to get the value from @@ -191,9 +202,9 @@ int PL_D_NumKeys (plitem_t *dict); \return true on success, false on failure - \note the dictionary becomes the owner of both the key and the value. + \note the dictionary becomes the owner of the value. */ -qboolean PL_D_AddObject (plitem_t *dict, plitem_t *key, plitem_t *value); +qboolean PL_D_AddObject (plitem_t *dict, const char *key, plitem_t *value); /** Add an item to an array. diff --git a/libs/gamecode/engine/pr_parse.c b/libs/gamecode/engine/pr_parse.c index 76755f9fa..ca45a7441 100644 --- a/libs/gamecode/engine/pr_parse.c +++ b/libs/gamecode/engine/pr_parse.c @@ -138,7 +138,7 @@ ED_EntityDict (progs_t *pr, edict_t *ed) continue; value = PR_UglyValueString (pr, type, v); - PL_D_AddObject (entity, PL_NewString (name), PL_NewString (value)); + PL_D_AddObject (entity, name, PL_NewString (value)); } } return entity; @@ -172,7 +172,7 @@ ED_GlobalsDict (progs_t *pr) name = PR_GetString (pr, def->s_name); value = PR_UglyValueString (pr, type, &pr->pr_globals[def->ofs]); - PL_D_AddObject (globals, PL_NewString (name), PL_NewString (value)); + PL_D_AddObject (globals, name, PL_NewString (value)); } return globals; } @@ -326,7 +326,8 @@ ED_ConvertToPlist (progs_t *pr, script_t *script) value = PL_NewString (va ("0 %s 0", token)); else value = PL_NewString (token); - PL_D_AddObject (ent, key, value); + PL_D_AddObject (ent, PL_String (key), value); + PL_Free (key); } PL_A_AddObject (plist, ent); } diff --git a/libs/ruamoko/rua_plist.c b/libs/ruamoko/rua_plist.c index 4a5775e7a..7eb896e29 100644 --- a/libs/ruamoko/rua_plist.c +++ b/libs/ruamoko/rua_plist.c @@ -141,8 +141,7 @@ bi_PL_D_NumKeys (progs_t *pr) static void bi_PL_D_AddObject (progs_t *pr) { - R_INT (pr) = PL_D_AddObject (p_plitem (pr, 0), - remove_plitem (pr, p_plitem (pr, 1)), + R_INT (pr) = PL_D_AddObject (p_plitem (pr, 0), P_GSTRING (pr, 1), remove_plitem (pr, p_plitem (pr, 2))); } diff --git a/libs/util/qfplist.c b/libs/util/qfplist.c index 114e932f4..5e3d2b929 100644 --- a/libs/util/qfplist.c +++ b/libs/util/qfplist.c @@ -83,7 +83,8 @@ dict_free (void *i, void *unused) { dictkey_t *item = (dictkey_t *) i; free (item->key); - PL_Free (item->value); // Make descended stuff get freed + if (item->value) // Make descended stuff get freed + PL_Free (item->value); free (item); } @@ -190,6 +191,25 @@ PL_ObjectForKey (plitem_t *dict, const char *key) return k ? k->value : NULL; } +plitem_t * +PL_RemoveObjectForKey (plitem_t *dict, const char *key) +{ + hashtab_t *table = (hashtab_t *) dict->data; + dictkey_t *k; + plitem_t *value; + + if (dict->type != QFDictionary) + return NULL; + + k = (dictkey_t *) Hash_Del (table, key); + if (!k) + return NULL; + value = k->value; + k->value = 0; + dict_free (k, 0); + return value; +} + plitem_t * PL_D_AllKeys (plitem_t *dict) { @@ -234,17 +254,14 @@ PL_ObjectAtIndex (plitem_t *array, int index) } qboolean -PL_D_AddObject (plitem_t *dict, plitem_t *key, plitem_t *value) +PL_D_AddObject (plitem_t *dict, const char *key, plitem_t *value) { dictkey_t *k; if (dict->type != QFDictionary) return false; - if (key->type != QFString) - return false; - - if ((k = Hash_Find ((hashtab_t *)dict->data, key->data))) { + if ((k = Hash_Find ((hashtab_t *)dict->data, key))) { PL_Free ((plitem_t *) k->value); k->value = value; } else { @@ -253,7 +270,7 @@ PL_D_AddObject (plitem_t *dict, plitem_t *key, plitem_t *value) if (!k) return false; - k->key = strdup ((char *) key->data); + k->key = strdup (key); k->value = value; Hash_Add ((hashtab_t *)dict->data, k); @@ -666,7 +683,7 @@ PL_ParsePropertyListItem (pldata_t *pl) } // Add the key/value pair to the dictionary - if (!PL_D_AddObject (item, key, value)) { + if (!PL_D_AddObject (item, PL_String (key), value)) { PL_Free (key); PL_Free (value); PL_Free (item); diff --git a/nq/source/host_cmd.c b/nq/source/host_cmd.c index 250fd2df6..55d385a46 100644 --- a/nq/source/host_cmd.c +++ b/nq/source/host_cmd.c @@ -457,24 +457,18 @@ game_dict (void) { plitem_t *game = PL_NewDictionary (); - PL_D_AddObject (game, - PL_NewString ("comment"), + PL_D_AddObject (game, "comment", PL_NewString (va ("%-21s kills:%3i/%3i", cl.levelname, cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]))); - PL_D_AddObject (game, PL_NewString ("spawn_parms"), spawn_parms_array ()); - PL_D_AddObject (game, - PL_NewString ("current_skill"), + PL_D_AddObject (game, "spawn_parms", spawn_parms_array ()); + PL_D_AddObject (game, "current_skill", PL_NewString (va ("%d", current_skill))); - PL_D_AddObject (game, PL_NewString ("name"), PL_NewString (sv.name)); - PL_D_AddObject (game, - PL_NewString ("time"), - PL_NewString (va ("%f", sv.time))); - PL_D_AddObject (game, PL_NewString ("lightstyles"), lightstyles_array ()); - PL_D_AddObject (game, - PL_NewString ("globals"), - ED_GlobalsDict (&sv_pr_state)); - PL_D_AddObject (game, PL_NewString ("entities"), entities_array ()); + PL_D_AddObject (game, "name", PL_NewString (sv.name)); + PL_D_AddObject (game, "time", PL_NewString (va ("%f", sv.time))); + PL_D_AddObject (game, "lightstyles", lightstyles_array ()); + PL_D_AddObject (game, "globals", ED_GlobalsDict (&sv_pr_state)); + PL_D_AddObject (game, "entities", entities_array ()); return game; } @@ -489,9 +483,7 @@ convert_to_game_dict (script_t *script) // savegame comment (ignored) Script_GetToken (script, 1); - PL_D_AddObject (game, - PL_NewString ("comment"), - PL_NewString (script->token->str)); + PL_D_AddObject (game, "comment", PL_NewString (script->token->str)); // spawn_parms item = PL_NewArray (); @@ -499,26 +491,20 @@ convert_to_game_dict (script_t *script) Script_GetToken (script, 1); PL_A_AddObject (item, PL_NewString (script->token->str)); } - PL_D_AddObject (game, PL_NewString ("spawn_parms"), item); + PL_D_AddObject (game, "spawn_parms", item); // this silliness is so we can load 1.06 save files, which have float skill // values Script_GetToken (script, 1); skill = (int) (atof (script->token->str) + 0.1); - PL_D_AddObject (game, - PL_NewString ("current_skill"), - PL_NewString (va ("%d", skill))); + PL_D_AddObject (game, "current_skill", PL_NewString (va ("%d", skill))); Script_GetToken (script, 1); - PL_D_AddObject (game, - PL_NewString ("name"), - PL_NewString (script->token->str)); + PL_D_AddObject (game, "name", PL_NewString (script->token->str)); Script_GetToken (script, 1); - PL_D_AddObject (game, - PL_NewString ("time"), - PL_NewString (script->token->str)); + PL_D_AddObject (game, "time", PL_NewString (script->token->str)); // load the light styles item = PL_NewArray (); @@ -531,13 +517,13 @@ convert_to_game_dict (script_t *script) //strcpy (s, script->token->str); //sv.lightstyles[i] = s; } - PL_D_AddObject (game, PL_NewString ("lightstyles"), item); + PL_D_AddObject (game, "lightstyles", item); // load the edicts out of the savegame file list = ED_ConvertToPlist (&sv_pr_state, script); item = PL_RemoveObjectAtIndex (list, 0); - PL_D_AddObject (game, PL_NewString ("globals"), item); - PL_D_AddObject (game, PL_NewString ("entities"), list); + PL_D_AddObject (game, "globals", item); + PL_D_AddObject (game, "entities", list); return game; } diff --git a/ruamoko/include/PropertyList.h b/ruamoko/include/PropertyList.h index 607038f1b..381efc53b 100644 --- a/ruamoko/include/PropertyList.h +++ b/ruamoko/include/PropertyList.h @@ -28,7 +28,7 @@ - (integer) numKeys; - (PLItem) getObjectForKey:(string) key; - (PLItem) allKeys; -- addKey:(PLItem) key value:(PLItem) value; +- addKey:(string) key value:(PLItem) value; @end @interface PLArray: PLItem diff --git a/ruamoko/include/plist.h b/ruamoko/include/plist.h index a220bb1df..4cb52ba1a 100644 --- a/ruamoko/include/plist.h +++ b/ruamoko/include/plist.h @@ -14,7 +14,7 @@ typedef enum {QFDictionary, QFArray, QFBinary, QFString} pltype_t; // possible t @extern plitem_t (plitem_t item, integer index) PL_ObjectAtIndex; @extern plitem_t (plitem_t item) PL_D_AllKeys; @extern integer (plitem_t item) PL_D_NumKeys; -@extern integer (plitem_t dict, plitem_t key, plitem_t value) PL_D_AddObject; +@extern integer (plitem_t dict, string key, plitem_t value) PL_D_AddObject; @extern integer (plitem_t array_item, plitem_t item) PL_A_AddObject; @extern integer (plitem_t item) PL_A_NumObjects; @extern integer (plitem_t array_item, plitem_t item, integer index) PL_A_InsertObjectAtIndex; diff --git a/ruamoko/lib/Entity.r b/ruamoko/lib/Entity.r index 15aaa563f..c1192c304 100644 --- a/ruamoko/lib/Entity.r +++ b/ruamoko/lib/Entity.r @@ -132,7 +132,8 @@ function PR_FindFunction (string func) = #0; value = PL_NewString ("0 " + token + " 0"); else value = PL_NewString (token); - PL_D_AddObject (ent, key, value); + PL_D_AddObject (ent, PL_String (key), value); + PL_Free (key); } PL_A_AddObject (plist, ent); } diff --git a/ruamoko/lib/PropertyList.r b/ruamoko/lib/PropertyList.r index 8a2b8d261..ebded2a73 100644 --- a/ruamoko/lib/PropertyList.r +++ b/ruamoko/lib/PropertyList.r @@ -119,15 +119,14 @@ return [PLItem itemClass: PL_D_AllKeys (item)]; } -- addKey:(PLItem) key value:(PLItem) value +- addKey:(string) key value:(PLItem) value { - if (!key.own || !value.own) { + if (!value.own) { obj_error (self, 0, "add of unowned key/value to PLDictionary"); return self; } - PL_D_AddObject (item, key.item, value.item); - key.own = value.own = 0; - [key release]; + PL_D_AddObject (item, key, value.item); + value.own = 0; [value release]; return self; } diff --git a/ruamoko/lib/plist.r b/ruamoko/lib/plist.r index b053c69b2..afaae7f92 100644 --- a/ruamoko/lib/plist.r +++ b/ruamoko/lib/plist.r @@ -8,7 +8,7 @@ plitem_t (plitem_t item, string key) PL_ObjectForKey = #0; plitem_t (plitem_t item, integer index) PL_ObjectAtIndex = #0; plitem_t (plitem_t item) PL_D_AllKeys = #0; integer (plitem_t item) PL_D_NumKeys = #0; -integer (plitem_t dict, plitem_t key, plitem_t value) PL_D_AddObject = #0; +integer (plitem_t dict, string key, plitem_t value) PL_D_AddObject = #0; integer (plitem_t array_item, plitem_t item) PL_A_AddObject = #0; integer (plitem_t item) PL_A_NumObjects = #0; integer (plitem_t array_item, plitem_t item, integer index) PL_A_InsertObjectAtIndex = #0; diff --git a/tools/qflight/source/entities.c b/tools/qflight/source/entities.c index 585760de5..3c0c94926 100644 --- a/tools/qflight/source/entities.c +++ b/tools/qflight/source/entities.c @@ -229,8 +229,7 @@ LoadEntities (void) epair->next = entity->epairs; entity->epairs = epair; - PL_D_AddObject (dict, PL_NewString (key), - PL_NewString (script->token->str)); + PL_D_AddObject (dict, key, PL_NewString (script->token->str)); if (!strcmp (key, "classname")) entity->classname = epair->value;