/* Note: Finds the next alphabetical property, regardless of the existence of the original property given. */ PropPtr propdir_next_elem(PropPtr root, char *path) { PropPtr p; char *n; if (!root) return (NULL); while (*path && *path == PROPDIR_DELIMITER) path++; if (!*path) return (NULL); n = index(path, PROPDIR_DELIMITER); while (n && *n == PROPDIR_DELIMITER) *(n++) = '\0'; if (n && *n) { /* just another propdir in the path */ p = locate_prop(root, path); if (p && PropDir(p)) { /* yup, found the propdir */ return (propdir_next_elem(PropDir(p), n)); } return (NULL); } else { /* aha, we are finally to the property subname itself. */ return (next_node(root, path)); } }
/* path is the name of the propdir to find the first node of */ PropPtr propdir_first_elem(PropPtr root, char *path) { PropPtr p; while (*path && *path == PROPDIR_DELIMITER) path++; if (!*path) return (first_node(root)); p = propdir_get_elem(root, path); if (p && PropDir(p)) { return (first_node(PropDir(p))); /* found the property! */ } return (NULL); /* nope, doesn't exist */ }
/** * Calculates the size of the given property directory AVL list. This * will iterate over the entire structure to give the entire size. It * is the low level equivalent of size_properties * * @see size_properties * * @param avl the Property directory AVL to check * @return the size of the loaded properties in memory -- this does NOT * do any diskbase loading. */ size_t size_proplist(PropPtr avl) { size_t bytes = 0; if (!avl) return 0; bytes += sizeof(struct plist); bytes += strlen(PropName(avl)); if (!(PropFlags(avl) & PROP_ISUNLOADED)) { switch (PropType(avl)) { case PROP_STRTYP: bytes += strlen(PropDataStr(avl)) + 1; break; case PROP_LOKTYP: bytes += size_boolexp(PropDataLok(avl)); break; default: break; } } bytes += size_proplist(avl->left); bytes += size_proplist(avl->right); bytes += size_proplist(PropDir(avl)); return bytes; }
int fetch_propvals(dbref obj, const char *dir) { PropPtr p, pptr; int cnt = 0; char buf[BUFFER_LEN]; char name[BUFFER_LEN]; p = first_prop_nofetch(obj, dir, &pptr, name, sizeof(name)); while (p) { cnt = (cnt || propfetch(obj, p)); if (PropDir(p) || (PropFlags(p) & PROP_DIRUNLOADED)) { strcpyn(buf, sizeof(buf), dir); strcatn(buf, sizeof(buf), name); strcatn(buf, sizeof(buf), "/"); if (PropFlags(p) & PROP_DIRUNLOADED) { SetPFlags(p, (PropFlags(p) & ~PROP_DIRUNLOADED)); getproperties(input_file, obj, buf); } fetch_propvals(obj, buf); } p = next_prop(pptr, p, name, sizeof(name)); } return cnt; }
/* return true if a property contains a propdir */ int propdir_check(PropPtr root, char *path) { PropPtr p; if ((p = propdir_get_elem(root, path))) return (PropDir(p) != NULL); return (0); }
void delete_proplist(PropPtr p) { if (!p) return; delete_proplist(AVL_LF(p)); delete_proplist(PropDir(p)); delete_proplist(AVL_RT(p)); free_propnode(p); }
void untouchprop_rec(PropPtr p) { if (!p) return; SetPFlags(p, (PropFlags(p) & ~PROP_TOUCHED)); untouchprop_rec(AVL_LF(p)); untouchprop_rec(AVL_RT(p)); untouchprop_rec(PropDir(p)); }
/* copies properties */ void copy_proplist(dbref obj, PropPtr * nu, PropPtr old) { PropPtr p; if (old) { #ifdef DISKBASE propfetch(obj, old); #endif p = new_prop(nu, PropName(old)); SetPFlagsRaw(p, PropFlagsRaw(old)); switch (PropType(old)) { case PROP_STRTYP: SetPDataStr(p, alloc_string(PropDataStr(old))); break; case PROP_LOKTYP: if (PropFlags(old) & PROP_ISUNLOADED) { SetPDataLok(p, TRUE_BOOLEXP); SetPFlags(p, (PropFlags(p) & ~PROP_ISUNLOADED)); } else { SetPDataLok(p, copy_bool(PropDataLok(old))); } break; case PROP_DIRTYP: SetPDataVal(p, 0); break; case PROP_FLTTYP: SetPDataFVal(p, PropDataFVal(old)); break; default: SetPDataVal(p, PropDataVal(old)); break; } copy_proplist(obj, &PropDir(p), PropDir(old)); copy_proplist(obj, &AVL_LF(p), AVL_LF(old)); copy_proplist(obj, &AVL_RT(p), AVL_RT(old)); /* copy_proplist(obj, nu, AVL_LF(old)); copy_proplist(obj, nu, AVL_RT(old)); */ } }
/** * Recursively deletes an entire proplist AVL with 'p' as the root, * and frees 'p' itself. * * @param p The proplist to delete. */ void delete_proplist(PropPtr p) { if (!p) return; delete_proplist(p->left); delete_proplist(PropDir(p)); delete_proplist(p->right); free_propnode(p); }
void db_dump_props_rec(dbref obj, FILE * f, const char *dir, PropPtr p) { char buf[BUFFER_LEN]; #ifdef DISKBASE int tpos = 0; int flg; short wastouched = 0; #endif if (!p) return; db_dump_props_rec(obj, f, dir, AVL_LF(p)); #ifdef DISKBASE if (tp_diskbase_propvals) { tpos = ftell(f); wastouched = (PropFlags(p) & PROP_TOUCHED); } if (propfetch(obj, p)) { fseek(f, 0L, 2); } #endif db_putprop(f, dir, p); #ifdef DISKBASE if (tp_diskbase_propvals && !wastouched) { if (PropType(p) == PROP_STRTYP || PropType(p) == PROP_LOKTYP) { flg = PropFlagsRaw(p) | PROP_ISUNLOADED; clear_propnode(p); SetPFlagsRaw(p, flg); SetPDataVal(p, tpos); } } #endif if (PropDir(p)) { sprintf(buf, "%s%s%c", dir, PropName(p), PROPDIR_DELIMITER); db_dump_props_rec(obj, f, buf, PropDir(p)); } db_dump_props_rec(obj, f, dir, AVL_RT(p)); }
/* return true if a property contains a propdir */ int is_propdir_nofetch(dbref player, const char *type) { PropPtr p; char w[BUFFER_LEN]; strcpy(w, type); p = propdir_get_elem(DBFETCH(player)->properties, w); if (!p) return 0; return (PropDir(p) != (PropPtr) NULL); }
char * displayprop(dbref player, dbref obj, const char *name, char *buf) { char mybuf[BUFFER_LEN], tbuf[BUFFER_LEN]; int pdflag; PropPtr p = get_property(obj, name); if (!p) { sprintf(buf, SYSGLOOM "%s: No such property.", name); return buf; } #ifdef DISKBASE propfetch(obj, p); #endif pdflag = (PropDir(p) != NULL); sprintf(tbuf, "%.*s%c", (BUFFER_LEN / 4), name, (pdflag) ? PROPDIR_DELIMITER : '\0'); tct(tbuf, mybuf); switch (PropType(p)) { case PROP_STRTYP: sprintf(buf, SYSAQUA "str " SYSGREEN "%s" SYSRED ":" SYSCYAN "%.*s", mybuf, (BUFFER_LEN / 2), tct(PropDataUNCStr(p), tbuf)); break; case PROP_REFTYP: sprintf(buf, SYSBROWN "ref " SYSGREEN "%s" SYSRED ":%s", mybuf, ansi_unparse_object(player, PropDataRef(p))); break; case PROP_INTTYP: sprintf(buf, SYSFOREST "int " SYSGREEN "%s" SYSRED ":" SYSYELLOW "%d", mybuf, PropDataVal(p)); break; case PROP_FLTTYP: sprintf(buf, SYSNAVY "flt " SYSGREEN "%s" SYSRED ":" SYSBROWN "%.15g", mybuf, PropDataFVal(p)); break; case PROP_LOKTYP: if (PropFlags(p) & PROP_ISUNLOADED) { sprintf(buf, SYSCRIMSON "lok " SYSGREEN "%s" SYSRED ":" SYSPURPLE "*UNLOCKED*", mybuf); } else { sprintf(buf, SYSCRIMSON "lok " SYSGREEN "%s" SYSRED ":" SYSPURPLE "%.*s", mybuf, (BUFFER_LEN / 2), tct(unparse_boolexp(player, PropDataLok(p), 1), tbuf)); } break; case PROP_DIRTYP: sprintf(buf, SYSWHITE "dir " SYSGREEN "%s" SYSRED ":", mybuf); break; } return buf; }
/* path is the name of the property to delete */ PropPtr propdir_delete_elem(PropPtr root, char *path) { PropPtr p; char *n; if (!root) return (NULL); while (*path && *path == PROPDIR_DELIMITER) path++; if (!*path) return (root); n = index(path, PROPDIR_DELIMITER); while (n && *n == PROPDIR_DELIMITER) *(n++) = '\0'; if (n && *n) { /* just another propdir in the path */ p = locate_prop(root, path); if (p && PropDir(p)) { /* yup, found the propdir */ SetPDir(p, propdir_delete_elem(PropDir(p), n)); if (!PropDir(p) && PropType(p) == PROP_DIRTYP) { root = delete_prop(&root, PropName(p)); } } /* return the updated root pntr */ return (root); } else { /* aha, we are finally to the property itself. */ p = locate_prop(root, path); if (p && PropDir(p)) { delete_proplist(PropDir(p)); } (void) delete_prop(&root, path); return (root); } }
/* return a pointer to the first property in a propdir and duplicates the property name into 'name'. returns 0 if the property list is empty or does not exist. */ PropPtr first_prop_nofetch(dbref player, const char *dir, PropPtr *list, char *name) { char buf[BUFFER_LEN]; PropPtr p; if (dir) { while (*dir && *dir == PROPDIR_DELIMITER) { dir++; } } if (!dir || !*dir) { *list = DBFETCH(player)->properties; p = first_node(*list); if (p) { strcpy(name, PropName(p)); } else { *name = '\0'; } return (p); } strcpy(buf, dir); *list = p = propdir_get_elem(DBFETCH(player)->properties, buf); if (!p) { *name = '\0'; return NULL; } *list = PropDir(p); p = first_node(*list); if (p) { strcpy(name, PropName(p)); } else { *name = '\0'; } return (p); }
/* * returns pointer to the new property node. Returns a pointer to an * existing elem of the given name, if one already exists. Returns * NULL if the name given is bad. * root is the pointer to the root propdir node. This is updated in this * routine to point to the new root node of the structure. * path is the name of the property to insert */ PropPtr propdir_new_elem(PropPtr * root, char *path) { PropPtr p; char *n; while (*path && *path == PROPDIR_DELIMITER) path++; if (!*path) return (NULL); n = index(path, PROPDIR_DELIMITER); while (n && *n == PROPDIR_DELIMITER) *(n++) = '\0'; if (n && *n) { /* just another propdir in the path */ p = new_prop(root, path); return (propdir_new_elem(&PropDir(p), n)); } else { /* aha, we are finally to the property itself. */ p = new_prop(root, path); return (p); } }
/* path is the name of the propdir to find */ const char * propdir_unloaded(PropPtr root, const char *path) { PropPtr p; const char *n; char *o, *l; static char buf[BUFFER_LEN]; if (!root) return NULL; n = path; o = buf; while (*n == PROPDIR_DELIMITER) n++; if (!*n) return NULL; while (*n) { *o++ = '/'; l = o; while (*n && *n != PROPDIR_DELIMITER) *o++ = *n++; while (*n == PROPDIR_DELIMITER) n++; *o = '\0'; p = locate_prop(root, l); if (!p) { return NULL; } if (PropFlags(p) & PROP_DIRUNLOADED) { SetPFlags(p, (PropFlags(p) & ~PROP_DIRUNLOADED)); return buf + 1; } root = PropDir(p); } return NULL; }
void set_property_nofetch(dbref object, const char *pname, PData * dat, bool pure) { char buf[BUFFER_LEN]; char *n; PropPtr p; /* Make sure that we are passed a valid property name */ if (!pname) return; while (*pname == PROPDIR_DELIMITER) pname++; strcpy(buf, pname); /* truncate propnames with a ':' in them at the ':' */ if ((n = index(buf, PROP_DELIMITER))) *n = '\0'; /* truncate propnames with a '\n' in them at the '\n' */ if ((n = index(buf, '\n'))) *n = '\0'; if (!*buf) return; if ((!(FLAGS(object) & LISTENER)) && (string_prefix(buf, "_listen") || string_prefix(buf, "~listen") || string_prefix(buf, "@listen") || string_prefix(buf, "_olisten") || string_prefix(buf, "~olisten") || string_prefix(buf, "@olisten") || string_prefix(buf, "_alisten") || string_prefix(buf, "~alisten") || string_prefix(buf, "@alisten") || string_prefix(buf, "_aolisten") || string_prefix(buf, "~aolisten") || string_prefix(buf, "@aolisten"))) { FLAGS(object) |= LISTENER; } if ((!(FLAG2(object) & F2COMMAND)) && (string_prefix(buf, "_command") || string_prefix(buf, "~command") || string_prefix(buf, "@command") || string_prefix(buf, "_ocommand") || string_prefix(buf, "~ocommand") || string_prefix(buf, "@ocommand"))) { FLAG2(object) |= F2COMMAND; } p = propdir_new_elem(&(DBFETCH(object)->properties), buf); /* free up any old values */ clear_propnode(p); SetPFlagsRaw(p, dat->flags); if (PropFlags(p) & PROP_ISUNLOADED) { SetPDataUnion(p, dat->data); return; } switch (PropType(p)) { case PROP_STRTYP: if (!dat->data.str || !*dat->data.str) { SetPType(p, PROP_DIRTYP); SetPDataStr(p, NULL); if (!PropDir(p)) { remove_property_nofetch(object, pname); } } else { #ifdef COMPRESS if (!pure) { if (!(dat->flags & PROP_NOCOMPRESS) && isascii_str(dat->data.str)) { SetPDataStr(p, alloc_compressed(dat->data.str)); } else { dat->flags |= PROP_NOCOMPRESS; SetPDataStr(p, alloc_string(dat->data.str)); } SetPFlagsRaw(p, (dat->flags | PROP_COMPRESSED)); } else #endif SetPDataStr(p, alloc_string(dat->data.str)); } break; case PROP_INTTYP: SetPDataVal(p, dat->data.val); if (!dat->data.val) { SetPType(p, PROP_DIRTYP); if (!PropDir(p)) remove_property_nofetch(object, pname); } break; case PROP_FLTTYP: SetPDataFVal(p, dat->data.fval); if (dat->data.fval == 0.0) { SetPType(p, PROP_DIRTYP); if (!PropDir(p)) remove_property_nofetch(object, pname); } break; case PROP_REFTYP: SetPDataRef(p, dat->data.ref); if (dat->data.ref == NOTHING) { SetPType(p, PROP_DIRTYP); SetPDataRef(p, 0); if (!PropDir(p)) remove_property_nofetch(object, pname); } break; case PROP_LOKTYP: SetPDataLok(p, dat->data.lok); break; case PROP_DIRTYP: SetPDataVal(p, 0); if (!PropDir(p)) remove_property_nofetch(object, pname); break; } }
void set_property_nofetch(dbref player, const char *type, int flags, PTYPE value) { PropPtr p; char buf[BUFFER_LEN]; char *n, *w; /* Make sure that we are passed a valid property name */ if (!type) return; /* if (tp_db_readonly) return; *//* Why did we remove this? */ while (*type == PROPDIR_DELIMITER) type++; if ((!(FLAGS(player) & LISTENER)) && (string_prefix(type, "_listen") || string_prefix(type, "~listen") || string_prefix(type, "@listen") || string_prefix(type, "_olisten") || string_prefix(type, "~olisten") || string_prefix(type, "@olisten") || string_prefix(type, "_alisten") || string_prefix(type, "~alisten") || string_prefix(type, "@alisten") || string_prefix(type, "_aolisten") || string_prefix(type, "~aolisten") || string_prefix(type, "@aolisten"))) { FLAGS(player) |= LISTENER; } if ((!(FLAG2(player) & F2COMMAND)) && (string_prefix(type, "_command") || string_prefix(type, "~command") || string_prefix(type, "@command") || string_prefix(type, "_ocommand") || string_prefix(type, "~ocommand") || string_prefix(type, "@ocommand"))) { FLAG2(player) |= F2COMMAND; } w = strcpy(buf, type); /* truncate propnames with a ':' in them at the ':' */ n = index(buf, PROP_DELIMITER); if (n) *n = '\0'; if (!*buf) return; p = propdir_new_elem(&(DBFETCH(player)->properties), w); /* free up any old values */ clear_propnode(p); SetPFlagsRaw(p, flags); if (PropFlags(p) & PROP_ISUNLOADED) { SetPDataVal(p, (int) value); return; } switch (PropType(p)) { case PROP_STRTYP: if (!value || !*((char *) value)) { SetPType(p, PROP_DIRTYP); SetPDataVal(p, 0); if (!PropDir(p)) remove_property_nofetch(player, type); } else { /* char *cptr = (char *) value; while (cptr) { if (*cptr == '\n') *cptr = '\r'; ++cptr; } */ SetPDataStr(p, alloc_compressed((char *) value)); #ifdef COMPRESS SetPFlagsRaw(p, (flags | PROP_COMPRESSED)); #endif } break; case PROP_INTTYP: SetPDataVal(p, (int) value); if (!value) { SetPType(p, PROP_DIRTYP); if (!PropDir(p)) remove_property_nofetch(player, type); } break; case PROP_FLTTYP: SetPDataFVal(p, strtod(value, NULL)); if (strtod(value, NULL) == 0) { SetPType(p, PROP_DIRTYP); if (!PropDir(p)) { remove_property_nofetch(player, type); } } break; case PROP_REFTYP: if (((dbref) value) == NOTHING) { SetPType(p, PROP_DIRTYP); SetPDataVal(p, 0); if (!PropDir(p)) remove_property_nofetch(player, type); } else { SetPDataRef(p, (dbref) value); } break; case PROP_LOKTYP: SetPDataLok(p, (struct boolexp *) value); /* * if ((struct boolexp *)value == TRUE_BOOLEXP) { * SetPType(p, PROP_DIRTYP); * SetPDataVal(p, 0); * if (!PropDir(p)) * remove_property_nofetch(player, type); * } else { * SetPDataLok(p, (struct boolexp *)value); * } */ break; case PROP_DIRTYP: SetPDataVal(p, 0); if (!PropDir(p)) remove_property_nofetch(player, type); break; } }