PennMUSH Community

Changeset 813

Show
Ignore:
Timestamp:
05/05/07 13:12:57 (2 years ago)
Author:
shawnw
Message:

#6638: Empty attributes as roots.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 1.8.2/branches/devel/CHANGES.182

    r808 r813  
    5050 *  Clarification of attribute trees in HELP @WIPE. Suggested by 
    5151    Talvo. 
    52  
     52 *  Loading a db with empty attributes used as the roots of 
     53    attribute trees didn't work if empty_attrs is set to no. 
     54    Reported by Kevin. [SW] 
     55  
    5356Version 1.8.2 patchlevel 3                      March 11, 2007 
    5457 
  • 1.8.2/branches/devel/hdrs/attrib.h

    r527 r813  
     1/** 
     2 * \file attrib.h 
     3 * 
     4 * \brief Attribute-related prototypes and constants. 
     5 */ 
     6 
    17#ifndef _ATTRIB_H 
    28#define _ATTRIB_H 
     
    1117struct attr { 
    1218  char const *name;     /**< Name of attribute */ 
    13   int flags;          /**< Attribute flags */ 
     19  unsigned int flags;         /**< Attribute flags */ 
    1420  chunk_reference_t data;   /**< The attribute's value, compressed */ 
    1521  dbref creator;        /**< The attribute's creator's dbref */ 
     
    3541extern ATTR *atr_sub_branch(ATTR *branch); 
    3642extern void atr_new_add(dbref thing, char const *RESTRICT atr, 
    37             char const *RESTRICT s, dbref player, int flags, 
    38             unsigned char derefs); 
     43            char const *RESTRICT s, dbref player, 
     44            unsigned int flags, unsigned char derefs); 
    3945extern int atr_add(dbref thing, char const *RESTRICT atr, 
    40            char const *RESTRICT s, dbref player, int flags); 
     46           char const *RESTRICT s, dbref player, unsigned int flags); 
    4147extern int atr_clr(dbref thing, char const *atr, dbref player); 
    4248extern ATTR *atr_get(dbref thing, char const *atr); 
     
    7884 
    7985/* possible attribute flags */ 
    80 #define AF_ODARK        0x1 /* OBSOLETE! Leave here but don't use */ 
    81 #define AF_INTERNAL     0x2 /* no one can see it or set it */ 
    82 #define AF_WIZARD       0x4 /* Wizard only can change it */ 
    83 #define AF_NUKED        0x8 /* OBSOLETE! Leave here but don't use */ 
    84 #define AF_LOCKED       0x10    /* Only creator of attrib can change it. */ 
    85 #define AF_NOPROG       0x20    /* won't be searched for $ commands. */ 
    86 #define AF_MDARK        0x40    /* Only wizards can see it */ 
    87 #define AF_PRIVATE      0x80    /* Children don't inherit it */ 
    88 #define AF_NOCOPY       0x100   /* atr_cpy (for @clone) doesn't copy it */ 
    89 #define AF_VISUAL       0x200   /* Everyone can see this attribute */ 
    90 #define AF_REGEXP       0x400   /* Match $/^ patterns using regexps */ 
    91 #define AF_CASE         0x800   /* Match $/^ patterns case-sensitive */ 
    92 #define AF_SAFE         0x1000  /* This attribute may not be modified */ 
    93 #define AF_STATIC       0x10000 /* OBSOLETE! Leave here but don't use */ 
    94 #define AF_COMMAND      0x20000 /* INTERNAL: value starts with $ */ 
    95 #define AF_LISTEN       0x40000 /* INTERNAL: value starts with ^ */ 
    96 #define AF_NODUMP       0x80000 /* INTERNAL: attribute is not saved */ 
    97 #define AF_LISTED       0x100000    /* INTERNAL: Used in @list attribs */ 
    98 #define AF_PREFIXMATCH  0x200000    /* Subject to prefix-matching */ 
    99 #define AF_VEILED       0x400000    /* On ex, show presence, not value */ 
    100 #define AF_DEBUG        0x800000    /* Show debug when evaluated */ 
    101 #define AF_NEARBY       0x1000000   /* Override AF_VISUAL if remote */ 
    102 #define AF_PUBLIC       0x2000000   /* Override SAFER_UFUN */ 
    103 #define AF_ANON         0x4000000   /* INTERNAL: Attribute doesn't really 
     86#define AF_ODARK        0x1 /**< OBSOLETE! Leave here but don't use */ 
     87#define AF_INTERNAL     0x2 /**< no one can see it or set it */ 
     88#define AF_WIZARD       0x4 /**< Wizard only can change it */ 
     89#define AF_NUKED        0x8 /**< OBSOLETE! Leave here but don't use */ 
     90#define AF_LOCKED       0x10    /**< Only creator of attrib can change it. */ 
     91#define AF_NOPROG       0x20    /**< won't be searched for $ commands. */ 
     92#define AF_MDARK        0x40    /**< Only wizards can see it */ 
     93#define AF_PRIVATE      0x80    /**< Children don't inherit it */ 
     94#define AF_NOCOPY       0x100   /**< atr_cpy (for @clone) doesn't copy it */ 
     95#define AF_VISUAL       0x200   /**< Everyone can see this attribute */ 
     96#define AF_REGEXP       0x400   /**< Match $/^ patterns using regexps */ 
     97#define AF_CASE         0x800   /**< Match $/^ patterns case-sensitive */ 
     98#define AF_SAFE         0x1000  /**< This attribute may not be modified */ 
     99#define AF_ROOT         0x2000  /**< Root of an attribute tree */ 
     100#define AF_UNDEF1       0x4000  /**< Undefined; reserved for a future flag */ 
     101#define AF_UNDEF2       0x8000  /**< Undefined; reserved for a future flag */ 
     102#define AF_STATIC       0x10000 /**< OBSOLETE! Leave here but don't use */ 
     103#define AF_COMMAND      0x20000 /**< INTERNAL: value starts with $ */ 
     104#define AF_LISTEN       0x40000 /**< INTERNAL: value starts with ^ */ 
     105#define AF_NODUMP       0x80000 /**< INTERNAL: attribute is not saved */ 
     106#define AF_LISTED       0x100000    /**< INTERNAL: Used in @list attribs */ 
     107#define AF_PREFIXMATCH  0x200000    /**< Subject to prefix-matching */ 
     108#define AF_VEILED       0x400000    /**< On ex, show presence, not value */ 
     109#define AF_DEBUG        0x800000    /**< Show debug when evaluated */ 
     110#define AF_NEARBY       0x1000000   /**< Override AF_VISUAL if remote */ 
     111#define AF_PUBLIC       0x2000000   /**< Override SAFER_UFUN */ 
     112#define AF_ANON         0x4000000   /**< INTERNAL: Attribute doesn't really 
    104113                       exist in the database */ 
    105 #define AF_NONAME       0x8000000   /* No name in did_it */ 
    106 #define AF_NOSPACE      0x10000000  /* No space in did_it */ 
    107 #define AF_MHEAR        0x20000000  /* ^-listens can be triggered by %! */ 
    108 #define AF_AHEAR        0x40000000  /* ^-listens can be triggered by anyone */ 
     114#define AF_NONAME       0x8000000   /**< No name in did_it */ 
     115#define AF_NOSPACE      0x10000000  /**< No space in did_it */ 
     116#define AF_MHEAR        0x20000000  /**< ^-listens can be triggered by %! */ 
     117#define AF_AHEAR        0x40000000  /**< ^-listens can be triggered by anyone */ 
     118#define AF_UNDEF3       0x80000000      /**< Undefined; reserved for a future flag */ 
    109119 
    110 /* external predefined attributes. */ 
     120#define AF_MAXVAL       0x100000000     /**< Largest attribute flag value. */ 
     121 
     122/*** external predefined attributes. */ 
    111123    extern ATTR attr[]; 
    112124 
    113 /* external @wipe indicator (changes atr_clr() behaviour) */ 
     125/** external @wipe indicator (changes atr_clr() behaviour) */ 
    114126    extern int we_are_wiping; 
    115127 
     
    122134#define AL_DEREFS(alist)        ((alist)->data?chunk_derefs((alist)->data):0) 
    123135 
    124 /* Errors from ok_player_alias */ 
     136/** Errors from ok_player_alias */ 
     137/** Success */ 
    125138#define OPAE_SUCCESS    1 
     139/** Invalid alias */ 
    126140#define OPAE_INVALID    -1 
     141/** Too many aliases already set */ 
    127142#define OPAE_TOOMANY    -2 
     143/** Null alias */ 
    128144#define OPAE_NULL       -3 
    129145 
  • 1.8.2/branches/devel/src/atr_tab.c

    r527 r813  
    8585  {"amhear", 'M', AF_MHEAR, AF_MHEAR}, 
    8686  {"aahear", 'A', AF_AHEAR, AF_AHEAR}, 
     87  {"root", '`', AF_ROOT, AF_ROOT}, 
    8788  {NULL, '\0', 0, 0} 
    8889}; 
  • 1.8.2/branches/devel/src/attrib.c

    r701 r813  
    7676} ATTRPAGE; 
    7777 
    78 static ATTR *atr_free_list; 
    79 static ATTR *get_atr_free_list(void); 
     78static ATTR *atr_free_list = NULL; 
     79static ATTR *alloc_atr(void); 
     80static ATTR *pop_free_list(void); 
     81static void push_free_list(ATTR *); 
    8082static ATTR *find_atr_pos_in_list(ATTR ***pos, char const *name); 
    8183static int can_create_attr(dbref player, dbref obj, char const *atr_name, 
     
    415417      AL_FLAGS(atr) = AL_FLAGS(std); \ 
    416418    } else { \ 
    417       AL_FLAGS(atr) = 0; \ 
    418       if (flags != NOTHING) \ 
    419         AL_FLAGS(atr) |= flags; \ 
     419      AL_FLAGS(atr) = flags; \ 
    420420    } \ 
    421421  } while (0) 
     
    506506 
    507507  /* allocate a new page, if needed */ 
    508   ptr = get_atr_free_list(); 
    509   atr_free_list = AL_NEXT(ptr); 
     508  ptr = pop_free_list(); 
     509  if (ptr == NULL) { 
     510    st_delete(name, &atr_names); 
     511    return NULL; 
     512  } 
    510513 
    511514  /* initialize atr */ 
     
    537540void 
    538541atr_new_add(dbref thing, const char *RESTRICT atr, const char *RESTRICT s, 
    539         dbref player, int flags, unsigned char derefs) 
     542        dbref player, unsigned int flags, unsigned char derefs) 
    540543{ 
    541544  ATTR *ptr; 
    542  
    543   if (!EMPTY_ATTRS && !*s) 
     545  char *p, root_name[ATTRIBUTE_NAME_LIMIT + 1]; 
     546 
     547  if (!EMPTY_ATTRS && !*s && !(flags & AF_ROOT)) 
    544548    return; 
    545549 
     
    553557    return; 
    554558 
    555   AL_FLAGS(ptr) = (flags != NOTHING) ? flags : 0; 
     559  strcpy(root_name, atr); 
     560  if ((p = strrchr(root_name, '`'))) { 
     561    ATTR *root = NULL; 
     562    *p = '\0'; 
     563    root = find_atr_in_list(List(thing), root_name); 
     564    if (!root) { 
     565      do_rawlog(LT_ERR, T("Missing root attribute '%s' on object #%d!\n"), 
     566        root_name, thing); 
     567      root = create_atr(thing, root_name); 
     568      set_default_flags(root, 0); 
     569      AL_FLAGS(root) |= AF_ROOT; 
     570      AL_CREATOR(root) = player; 
     571      if (!EMPTY_ATTRS) { 
     572    unsigned char *t = compress(" "); 
     573    if (!t) { 
     574      mush_panic(T("Unable to allocate memory in atr_new_add()!")); 
     575    } 
     576    root->data = chunk_create(t, u_strlen(t), 0); 
     577    free(t); 
     578      }       
     579    } 
     580  } 
     581   
     582  AL_FLAGS(ptr) = flags; 
    556583  AL_FLAGS(ptr) &= ~AF_COMMAND & ~AF_LISTEN; 
    557584  AL_CREATOR(ptr) = player; 
     
    564591    if (!t) 
    565592      return; 
     593 
    566594    ptr->data = chunk_create(t, u_strlen(t), derefs); 
    567595    free(t); 
     
    592620int 
    593621atr_add(dbref thing, const char *RESTRICT atr, const char *RESTRICT s, 
    594     dbref player, int flags) 
    595 { 
    596   ATTR *ptr
     622    dbref player, unsigned int flags) 
     623{ 
     624  ATTR *ptr, *root = NULL
    597625  char *p; 
    598626 
     
    623651      *p = '\0'; 
    624652 
    625       ptr = find_atr_in_list(ptr, missing_name); 
    626  
    627       if (!ptr) { 
    628     ptr = create_atr(thing, missing_name); 
    629     if (!ptr
     653      root = find_atr_in_list(ptr, missing_name); 
     654 
     655      if (!root) { 
     656    root = create_atr(thing, missing_name); 
     657    if (!root
    630658      return AE_ERROR; 
    631659 
    632660    /* update modification time here, because from now on, 
    633661     * we modify even if we fail */ 
    634     if (!IsPlayer(thing) && !AF_Nodump(ptr)) 
     662    if (!IsPlayer(thing) && !AF_Nodump(root)) 
    635663      ModTime(thing) = mudtime; 
    636664 
    637     set_default_flags(ptr, flags); 
    638     AL_FLAGS(ptr) &= ~AF_COMMAND & ~AF_LISTEN; 
    639     AL_CREATOR(ptr) = Owner(player); 
     665    set_default_flags(root, flags); 
     666    AL_FLAGS(root) &= ~AF_COMMAND & ~AF_LISTEN; 
     667    AL_FLAGS(root) |= AF_ROOT; 
     668    AL_CREATOR(root) = Owner(player); 
    640669    if (!EMPTY_ATTRS) { 
    641670      unsigned char *t = compress(" "); 
    642       if (!t) 
     671      if (!t) { 
     672        push_free_list(root); 
    643673        return AE_ERROR; 
    644       ptr->data = chunk_create(t, u_strlen(t), 0); 
     674      } 
     675      root->data = chunk_create(t, u_strlen(t), 0); 
    645676      free(t); 
    646677    } 
    647       } 
     678      } else  
     679    AL_FLAGS(root) |= AF_ROOT; 
    648680 
    649681      *p = '`'; 
     
    704736  ATTR *ptr, **prev, *sub; 
    705737  size_t len; 
     738  char *p, root_name[ATTRIBUTE_NAME_LIMIT + 1]; 
    706739 
    707740  prev = &List(thing); 
     
    728761    chunk_delete(ptr->data); 
    729762 
     763  /* If this is the only child of a root attribute, clear the root's flag */ 
     764  strcpy(root_name, AL_NAME(ptr)); 
     765  if ((p = strrchr(root_name, '`'))) { 
     766    ATTR *x, *parent; 
     767    *p = '\0'; 
     768    parent = find_atr_in_list(List(thing), root_name); 
     769    if (parent) { 
     770      int children = 0; 
     771      for (x = AL_NEXT(parent); 
     772       string_prefix(AL_NAME(x), root_name); 
     773       x = AL_NEXT(x)) 
     774    children++; 
     775 
     776       
     777      if (children == 0) 
     778    AL_FLAGS(parent) &= ~AF_ROOT; 
     779       
     780    } else  
     781      do_rawlog(LT_ERR, 
     782        "Attribute '%s' in tree on object #%d without a root!\n", 
     783        AL_NAME(ptr), thing); 
     784  } 
     785   
     786 
    730787  len = strlen(AL_NAME(ptr)); 
    731788  st_delete(AL_NAME(ptr), &atr_names); 
    732789 
    733   AL_NEXT(ptr) = atr_free_list; 
    734   AL_FLAGS(ptr) = 0; 
    735   atr_free_list = ptr; 
     790  push_free_list(ptr); 
    736791  AttrCount(thing)--; 
    737792 
     
    747802      st_delete(AL_NAME(ptr), &atr_names); 
    748803 
    749       AL_NEXT(ptr) = atr_free_list; 
    750       AL_FLAGS(ptr) = 0; 
    751       atr_free_list = ptr; 
     804      push_free_list(ptr); 
    752805      AttrCount(thing)--; 
    753806 
     
    10741127    st_delete(AL_NAME(ptr), &atr_names); 
    10751128 
    1076     AL_NEXT(ptr) = atr_free_list; 
    1077     atr_free_list = ptr; 
     1129    push_free_list(ptr); 
    10781130  } 
    10791131} 
     
    18351887 */ 
    18361888static ATTR * 
    1837 get_atr_free_list(void) 
     1889alloc_atr(void) 
    18381890{ 
    18391891  if (!atr_free_list) { 
     
    18421894    page = (ATTRPAGE *) mush_malloc(sizeof(ATTRPAGE), "ATTRPAGE"); 
    18431895    if (!page) 
    1844       mush_panic("Couldn't allocate memory in get_atr_free_list"); 
     1896      mush_panic("Couldn't allocate memory in alloc_attr"); 
    18451897    for (j = 0; j < ATTRS_PER_PAGE - 1; j++) 
    18461898      AL_NEXT(page->atrs + j) = page->atrs + j + 1; 
     
    18491901  } 
    18501902  return atr_free_list; 
     1903} 
     1904 
     1905/** Pop an empty attribute off of the free list for use on 
     1906 * an object. 
     1907 * \return the pointer to an attribute, or NULL on error. 
     1908 */ 
     1909static ATTR* 
     1910pop_free_list(void) 
     1911{ 
     1912  ATTR *ptr; 
     1913  ptr = alloc_atr(); 
     1914  if (!ptr) 
     1915    return NULL; 
     1916  atr_free_list = AL_NEXT(ptr); 
     1917  AL_NEXT(ptr) = NULL; 
     1918  return ptr; 
     1919} 
     1920 
     1921/** Push a now-unused attribute onto the free list 
     1922 * \param An attribute that's been deleted from an object and 
     1923 * had its chunk reference deleted. 
     1924 */ 
     1925static void 
     1926push_free_list(ATTR *a)  
     1927{ 
     1928  memset(a, 0, sizeof(*a)); 
     1929  AL_NEXT(a) = atr_free_list; 
     1930  atr_free_list = a; 
    18511931} 
    18521932 
  • 1.8.2/branches/devel/src/look.c

    r793 r813  
    337337    parent = NOTHING; 
    338338  strcpy(fbuf, privs_to_letters(attr_privs_view, AL_FLAGS(atr))); 
    339   if (atr_sub_branch(atr)) 
    340     strcat(fbuf, "`"); 
    341339  if (AF_Veiled(atr)) { 
    342340    if (ShowAnsi(player)) { 
     
    399397    parent = NOTHING; 
    400398  strcpy(fbuf, privs_to_letters(attr_privs_view, AL_FLAGS(atr))); 
    401   if (atr_sub_branch(atr)) 
    402     strcat(fbuf, "`"); 
    403399  r = safe_atr_value(atr); 
    404400  if (ShowAnsi(player)) { 
     
    17031699      /* Standard attribute. Get the default perms, if any. */ 
    17041700      /* Are we different? If so, do as usual */ 
    1705       int npmflags = AL_FLAGS(ptr) & (~AF_PREFIXMATCH); 
     1701      unsigned int npmflags = AL_FLAGS(ptr) & (~AF_PREFIXMATCH); 
    17061702      if (AL_FLAGS(atr) != AL_FLAGS(ptr) && AL_FLAGS(atr) != npmflags) 
    17071703    privs = privs_to_string(attr_privs_view, AL_FLAGS(atr));