Update dict_attrbyname() to accept
authoraland <aland>
Tue, 14 Dec 2004 20:04:59 +0000 (20:04 +0000)
committeraland <aland>
Tue, 14 Dec 2004 20:04:59 +0000 (20:04 +0000)
Attr-%d
Vendor-%d-Attr-%d
VendorName-Attr-%d
VendorName-Attribute-Name

which should be a little more generic than what we had previously.

See recent comments to src/lib/valuepair.c, on how these changes
affect pairmake(), and pairparsevalue()

src/lib/dict.c

index 2a19fbc..1a56d95 100644 (file)
@@ -196,6 +196,7 @@ int dict_addattr(const char *name, int vendor, int type, int value,
        attr->attr = value;
        attr->type = type;
        attr->flags = flags;
+       attr->vendor = vendor;
 
        if (vendor) attr->attr |= (vendor << 16);
 
@@ -748,7 +749,7 @@ static int valuename_cmp(const void *a, const void *b)
                 ((const DICT_VALUE *)b)->attr);
        if (rcode != 0) return rcode;
 
-return strcasecmp(((const DICT_VALUE *)a)->name,
+       return strcasecmp(((const DICT_VALUE *)a)->name,
                          ((const DICT_VALUE *)b)->name);
 }
 
@@ -880,13 +881,93 @@ DICT_ATTR *dict_attrbyvalue(int val)
 
 /*
  *     Get an attribute by its name.
+ *
+ *     We can refer to an attribute by it's name, or by
+ *     canonical reference:
+ *
+ *     Attribute-Name
+ *     Attr-%d
+ *     VendorName-Attr-%d
+ *     Vendor-%d-Attr-%d
+ *     VendorName-Attribute-Name
  */
 DICT_ATTR *dict_attrbyname(const char *name)
 {
-       DICT_ATTR myattr;
+       DICT_ATTR myattr, *da;
 
        strNcpy(myattr.name, name, sizeof(myattr.name));
+       da = rbtree_finddata(attributes_byname, &myattr);
+       if (da) return da;
+
+       {
+               int value, attr;
+               const char *p = name;
+               char *q;
+               
+               /*
+                *      Look for:
+                *
+                *      Vendor-%d-Attr-%d
+                *      VendorName-Attr-%d
+                *      Attr-%d         %d = 1-65535
+                */
+
+               attr = 0;
+
+               if (strncasecmp(p, "Vendor-", 7) == 0) {
+                       p += 7;
+                       value = (int) strtol(p, &q, 10);
 
+                       /*
+                        *      Validate the parsed data.
+                        */
+                       if ((value <= 0) || (value > 65535)) {
+                               return NULL;
+                       }
+                       p = q + 1; /* skip the '-' */
+                       attr = value << 16; /* FIXME: horrid hack */
+
+               } else if (((q = strchr(name, '-')) != NULL) &&
+                          (strncasecmp(q, "-Attr-", 6) == 0)) {
+                       /*
+                        *      myattr.name is a temporary buffer
+                        */
+                       if ((q - name) >= sizeof(myattr.name)) return NULL;
+                       
+                       memcpy(myattr.name, name, q - name);
+                       myattr.name[q - name] = '\0';
+
+                       value = dict_vendorbyname(myattr.name);
+                       if (!value) return NULL;
+
+                       p = q + 1; /* skip the '-' */
+                       attr = value << 16;
+               }
+
+               /*
+                *      Accept only certain names.
+                */
+               if (strncasecmp(p, "Attr-", 5) == 0) {
+                       value = (int) strtol(p + 5, &q, 10);
+                       if (*q) return NULL; /* characters after the digits */
+                       if ((value <= 0) || (value > 65535)) return NULL; /* bad value */
+                       attr |= value;
+                       return dict_attrbyvalue(attr);
+               }
+
+               /*
+                *      If there's no leading Vendor-%d, or Vendorname,
+                *      and the attribute is not Attr-%d, then don't
+                *      bother looking it up again.
+                */
+               if (attr == 0) return NULL;
+               
+               /*
+                *      Else maybe it's Vendor-%d-Attribute-Name
+                */
+               strNcpy(myattr.name, p, sizeof(myattr.name));
+       }
+       
        return rbtree_finddata(attributes_byname, &myattr);
 }