Work on EXPLAIN schema. First implementation of sub-schema facility
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 9 Dec 1997 16:18:16 +0000 (16:18 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 9 Dec 1997 16:18:16 +0000 (16:18 +0000)
in the *.abs files.

CHANGELOG
include/data1.h
retrieval/d1_absyn.c
retrieval/d1_expout.c
tab/bib1.att
tab/explain.abs
tab/explain.tag

index 5e3121c..71cce43 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,13 @@
 Possible compatibility problems with earlier versions marked with '*'.
 
+Fixed bug in plain SGML reader in function data1_read_node:
+tags with prefix "var" was incorrectly interpreted as variants.
+
+Added feature "sub-schemas" to enable references to - and definitions
+of - group of elements.
+
+* Removed member parent from type data1_element (in data1.h).
+
 Implemented function odr_nullval() that returns the value of
 ODR_NULLVAL.
 
@@ -9,7 +17,6 @@ Made NT service interface part of the server library. The
 function statserv_main uses the NT service when required and
 calls the statserv_start / statserv_close routines.
 
-
 Routine zget_SearchRequest fills resultSetName member with "default"
 instead of "Default".
 
index e6e2584..54b4d3b 100644 (file)
  * OF THIS SOFTWARE.
  *
  * $Log: data1.h,v $
- * Revision 1.31  1997-11-18 09:51:08  adam
+ * Revision 1.32  1997-12-09 16:18:16  adam
+ * Work on EXPLAIN schema. First implementation of sub-schema facility
+ * in the *.abs files.
+ *
+ * Revision 1.31  1997/11/18 09:51:08  adam
  * Removed element num_children from data1_node. Minor changes in
  * data1 to Explain.
  *
@@ -314,11 +318,16 @@ typedef struct data1_element
     char *name;
     data1_tag *tag;
     data1_termlist *termlists;
-    struct data1_element *parent;
     struct data1_element *children;
     struct data1_element *next;
 } data1_element;
 
+typedef struct data1_sub_elements {
+    char *name;
+    struct data1_sub_elements *next;
+    data1_element *elements;
+} data1_sub_elements;
+
 typedef struct data1_absyn
 {
     char *name;
@@ -329,7 +338,8 @@ typedef struct data1_absyn
     data1_esetname *esetnames;
     data1_maptab *maptabs;
     data1_marctab *marc;
-    data1_element *elements;
+    data1_sub_elements *sub_elements;
+    data1_element *main_elements;
 } data1_absyn;
 
 /*
index c8479a4..1b4b44b 100644 (file)
@@ -4,7 +4,11 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_absyn.c,v $
- * Revision 1.14  1997-10-31 12:20:09  adam
+ * Revision 1.15  1997-12-09 16:18:16  adam
+ * Work on EXPLAIN schema. First implementation of sub-schema facility
+ * in the *.abs files.
+ *
+ * Revision 1.14  1997/10/31 12:20:09  adam
  * Improved memory debugging for xmalloc/nmem.c. References to NMEM
  * instead of ODR in n ESPEC-1 handling in source d1_espec.c.
  * Bug fix: missing fclose in data1_read_espec1.
@@ -130,9 +134,10 @@ data1_element *data1_getelementbytagname (data1_handle dh, data1_absyn *abs,
     data1_element *r;
 
     if (!parent)
-       r = abs->elements;
+        r = abs->main_elements;
     else
        r = parent->children;
+    assert (abs->main_elements);
     for (; r; r = r->next)
     {
        data1_name *n;
@@ -148,8 +153,8 @@ data1_element *data1_getelementbyname (data1_handle dh, data1_absyn *absyn,
                                       char *name)
 {
     data1_element *r;
-
-    for (r = absyn->elements; r; r = r->next)
+    assert (absyn->main_elements);
+    for (r = absyn->main_elements; r; r = r->next)
        if (!data1_matchstr(r->name, name))
            return r;
     return 0;
@@ -158,19 +163,20 @@ data1_element *data1_getelementbyname (data1_handle dh, data1_absyn *absyn,
 data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
 {
     char line[512], *r, cmd[512], args[512];
+    data1_sub_elements *cur_elements = NULL;
     data1_absyn *res = 0;
     FILE *f;
-    data1_element **ppl[D1_MAX_NESTING], *cur[D1_MAX_NESTING];
+    data1_element **ppl[D1_MAX_NESTING];
     data1_esetname **esetpp;
     data1_maptab **maptabp;
     data1_marctab **marcp;
     data1_termlist *all = 0;
-    int level = 0;
+    int level;
 
     logf (LOG_DEBUG, "begin data1_read_absyn file=%s", file);
     if (!(f = yaz_path_fopen(data1_get_tabpath (dh), file, "r")))
     {
-       logf(LOG_WARN|LOG_ERRNO, "%s", file);
+       logf(LOG_WARN|LOG_ERRNO, "Couldn't open %s", file);
        return 0;
     }
 
@@ -181,14 +187,14 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
     res->attset = 0;
     res->varset = 0;
     res->esetnames = 0;
+    esetpp = &res->esetnames;
     res->maptabs = 0;
     maptabp = &res->maptabs;
     res->marc = 0;
     marcp = &res->marc;
-    res->elements = 0;
-    ppl[0] = &res->elements;
-    cur[0] = 0;
-    esetpp = &res->esetnames;
+
+    res->sub_elements = NULL;
+    res->main_elements = NULL;
 
     for (;;)
     {
@@ -211,6 +217,18 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
            int type, value;
            data1_termlist **tp;
 
+           if (!cur_elements)
+           {
+                cur_elements = nmem_malloc(data1_nmem_get(dh),
+                                          sizeof(*cur_elements));
+               cur_elements->next = res->sub_elements;
+               cur_elements->elements = NULL;
+               cur_elements->name = "main";
+               res->sub_elements = cur_elements;
+
+               level = 0;
+               ppl[level] = &cur_elements->elements;
+            }
            if (sscanf(args, "%511s %511s %511s", path, name, termlists) < 3)
            {
                logf(LOG_WARN, "Bad # of args to elm in %s: '%s'", 
@@ -235,12 +253,25 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
                return 0;
            }
            level = i;
-           new_element = cur[level] = *ppl[level] =
+           if (*p == '$' && level > 0)
+           {
+               data1_sub_elements *sub_e = res->sub_elements;
+
+               p++;
+               while (sub_e && strcmp (p, sub_e->name))
+                  sub_e = sub_e->next;
+               if (sub_e)
+                   *ppl[level] = sub_e->elements;
+               if (level)
+                   level--;
+               continue;
+            }
+           new_element = *ppl[level] =
                nmem_malloc(data1_nmem_get(dh), sizeof(*new_element));
            new_element->next = new_element->children = 0;
            new_element->tag = 0;
            new_element->termlists = 0;
-           new_element->parent = level ? cur[level - 1] : 0;
+
            tp = &new_element->termlists;
            ppl[level] = &new_element->next;
            ppl[level+1] = &new_element->children;
@@ -339,6 +370,25 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
 
            new_element->name = nmem_strdup(data1_nmem_get (dh), name);
        }
+       else if (!strcmp(cmd, "section"))
+       {
+           char name[512];
+           if (sscanf(args, "%511s", name) < 1)
+           {
+               logf(LOG_WARN, "Bad # of args to sub in %s: '%s'",
+                                file, args);
+               continue;
+           }
+            cur_elements = nmem_malloc(data1_nmem_get(dh),
+                                          sizeof(*cur_elements));
+           cur_elements->next = res->sub_elements;
+           cur_elements->elements = NULL;
+           cur_elements->name = nmem_strdup (data1_nmem_get(dh), name);
+           res->sub_elements = cur_elements;
+
+           level = 0;
+           ppl[level] = &cur_elements->elements;
+       }
        else if (!strcmp(cmd, "all"))
        {
            char *p;
@@ -397,13 +447,13 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
        {
            char name[512];
 
-           if (!sscanf(args, "%s", name))
+           if (!sscanf(args, "%511s", name))
            {
-               logf(LOG_WARN, "%s malformed name directive in %s", file);
+               logf(LOG_WARN, "Malformed name directive in %s", file);
                fclose(f);
                return 0;
            }
-           res->name = nmem_strdup(data1_nmem_get(dh), args);
+           res->name = nmem_strdup(data1_nmem_get(dh), name);
        }
        else if (!strcmp(cmd, "reference"))
        {
@@ -411,7 +461,7 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
 
            if (!sscanf(args, "%s", name))
            {
-               logf(LOG_WARN, "%s malformed reference directive in %s", file);
+               logf(LOG_WARN, "Malformed reference in %s", file);
                fclose(f);
                return 0;
            }
@@ -428,7 +478,7 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
 
            if (!sscanf(args, "%s", name))
            {
-               logf(LOG_WARN, "%s malformed attset directive in %s", file);
+               logf(LOG_WARN, "Malformed attset directive in %s", file);
                fclose(f);
                return 0;
            }
@@ -445,7 +495,7 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
 
            if (!sscanf(args, "%s", name))
            {
-               logf(LOG_WARN, "%s malformed tagset directive in %s", file);
+               logf(LOG_WARN, "Malformed tagset directive in %s", file);
                fclose(f);
                return 0;
            }
@@ -462,7 +512,7 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
 
            if (!sscanf(args, "%s", name))
            {
-               logf(LOG_WARN, "%s malformed varset directive in %s", file);
+               logf(LOG_WARN, "Malformed varset directive in %s", file);
                fclose(f);
                return 0;
            }
@@ -479,7 +529,8 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
 
            if (sscanf(args, "%s %s", name, fname) != 2)
            {
-               logf(LOG_WARN, "%s: Two arg's required for esetname directive");
+               logf(LOG_WARN, "Two arg's required for esetname in %s",
+                     file);
                fclose(f);
                return 0;
            }
@@ -502,13 +553,14 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
 
            if (sscanf(args, "%s", name) != 1)
            {
-               logf(LOG_WARN, "%s: One argument required for maptab directive",
-                   file);
+               logf(LOG_WARN, "One argument for maptab directive in %s",
+                     file);
                continue;
            }
            if (!(*maptabp = data1_read_maptab (dh, name)))
            {
-               logf(LOG_WARN, "%s: Failed to read maptab.");
+               logf(LOG_WARN, "Failed to read maptab %s in %s",
+                     name, file);
                continue;
            }
            maptabp = &(*maptabp)->next;
@@ -519,13 +571,14 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
 
            if (sscanf(args, "%s", name) != 1)
            {
-               logf(LOG_WARN, "%s: One argument required for marc directive",
+               logf(LOG_WARN, "One argument for marc directive in %s",
                    file);
                continue;
            }
            if (!(*marcp = data1_read_marctab (dh, name)))
            {
-               logf(LOG_WARN, "%s: Failed to read marctab.");
+               logf(LOG_WARN, "%Failed to read marctab %s in %s",
+                     name, file);
                continue;
            }
            marcp = &(*marcp)->next;
@@ -538,6 +591,13 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
        }
     }
     fclose(f);
+
+    cur_elements = res->sub_elements;
+    while (cur_elements && strcmp (cur_elements->name, "main"))
+       cur_elements = cur_elements->next;
+    if (cur_elements)
+        res->main_elements = cur_elements->elements;
+
     logf (LOG_DEBUG, "end data1_read_absyn file=%s", file);
     return res;
 }
index 1e6d587..4a45d0f 100644 (file)
@@ -1,10 +1,14 @@
 /*
- * Copyright (c) 1995, Index Data.
+ * Copyright (c) 1995-1997, Index Data.
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_expout.c,v $
- * Revision 1.6  1997-11-24 11:33:56  adam
+ * Revision 1.7  1997-12-09 16:18:16  adam
+ * Work on EXPLAIN schema. First implementation of sub-schema facility
+ * in the *.abs files.
+ *
+ * Revision 1.6  1997/11/24 11:33:56  adam
  * Using function odr_nullval() instead of global ODR_NULLVAL when
  * appropriate.
  *
@@ -39,6 +43,9 @@ typedef struct {
     data1_handle dh;
     ODR o;
     int select;
+
+    bool_t *false_value;
+    bool_t *true_value;
 } ExpHandle;
 
 static int is_numeric_tag (ExpHandle *eh, data1_node *c)
@@ -57,14 +64,14 @@ static int is_numeric_tag (ExpHandle *eh, data1_node *c)
     }
     if (eh->select && !c->u.tag.node_selected)
        return 0;
-    return 1;
+    return c->u.tag.element->tag->value.numeric;
 }
 
 static int is_data_tag (ExpHandle *eh, data1_node *c)
 {
     if (!c || c->which != DATA1N_data)
        return 0;
-    if (select && !c->u.tag.node_selected)
+    if (eh->select && !c->u.tag.node_selected)
        return 0;
     return 1;
 }
@@ -105,11 +112,37 @@ static bool_t *f_bool(ExpHandle *eh, data1_node *c)
     if (!is_data_tag (eh, c) || c->u.data.len > 63)
        return 0;
     tf = odr_malloc (eh->o, sizeof(*tf));
-    sprintf(intbuf, "%.*s", 63, c->u.data.data);
+    sprintf(intbuf, "%.*s", c->u.data.len, c->u.data.data);
     *tf = atoi(intbuf);
     return tf;
 }
 
+static Odr_oid *f_oid(ExpHandle *eh, data1_node *c, oid_class oclass)
+{
+    char oidstr[64];
+    int oid_this[20];
+    oid_value value_for_this;
+
+    c = c->child;
+    if (!is_data_tag (eh, c) || c->u.data.len > 63)
+       return 0;
+    sprintf(oidstr, "%.*s", c->u.data.len, c->u.data.data);
+    value_for_this = oid_getvalbyname(oidstr);
+    if (value_for_this == VAL_NONE)
+       return NULL; /* fix */
+    else
+    {
+       struct oident ident;
+
+       ident.oclass = oclass;
+       ident.proto = PROTO_Z3950;
+       ident.value = value_for_this;
+       
+       oid_ent_to_oid (&ident, oid_this);
+    }
+    return odr_oiddup (eh->o, oid_this);
+}
+
 static Z_IntUnit *f_intunit(ExpHandle *eh, data1_node *c)
 {
     /* fix */
@@ -148,18 +181,12 @@ static Z_CommonInfo *f_commonInfo(ExpHandle *eh, data1_node *n)
 
     for (c = n->child; c; c = c->next)
     {
-       if (!is_numeric_tag (eh, c))
-           continue;
-       switch (c->u.tag.element->tag->value.numeric)
+       switch (is_numeric_tag (eh, c))
        {
            case 601: res->dateAdded = f_string(eh, c); break;
            case 602: res->dateChanged = f_string(eh, c); break;
            case 603: res->expiry = f_string(eh, c); break;
            case 604: res->humanStringLanguage = f_string(eh, c); break;
-           /* otherInfo? */
-           default:
-               logf(LOG_WARN, "Bad child in commonInfo");
-               return 0;
        }
     }
     return res;
@@ -171,12 +198,31 @@ Z_QueryTypeDetails *f_queryTypeDetails (ExpHandle *eh, data1_node *n)
     return NULL;
 }
 
-Odr_oid **f_oid_seq (ExpHandle *eh, data1_node *n, int *num)
+Odr_oid **f_oid_seq (ExpHandle *eh, data1_node *n, int *num, oid_class oclass)
 {
-    /* fix */
-    return NULL;
-}
+    Odr_oid **res;
+    data1_node *c;
+    int i;
 
+    *num = 0;
+    for (c = n->child ; c; c = c->next)
+    {
+       if (is_numeric_tag (eh, c) != 1000)
+           continue;
+       ++(*num);
+    }
+    if (!*num)
+       return NULL;
+    res = odr_malloc (eh->o, sizeof(*res) * (*num));
+    for (c = n->child, i = 0 ; c; c = c->next)
+    {
+       if (is_numeric_tag (eh, c) != 1000)
+           continue;
+       res[i++] = f_oid (eh, c, oclass);
+    }
+    return res;
+}
+    
 char **f_string_seq (ExpHandle *eh, data1_node *n, int *num)
 {
     char **res;
@@ -186,16 +232,19 @@ char **f_string_seq (ExpHandle *eh, data1_node *n, int *num)
     *num = 0;
     for (c = n->child ; c; c = c->next)
     {
-       if (!is_numeric_tag (eh, c))
-           break;
-       if (n->u.tag.element->tag->value.numeric != 1001)
-           break;
+       if (!is_numeric_tag (eh, c) != 1001)
+           continue;
        ++(*num);
     }
-    if (*num)
-       res = odr_malloc (eh->o, sizeof(*res) * (*num));
-    for (c = n->child, i = 0 ; i < *num; c = c->next, i++)
-       res[i] = f_string (eh, c);
+    if (!*num)
+       return NULL;
+    res = odr_malloc (eh->o, sizeof(*res) * (*num));
+    for (c = n->child, i = 0 ; c; c = c->next)
+    {
+       if (!is_numeric_tag (eh, c) != 1001)
+           continue;
+       res[i++] = f_string (eh, c);
+    }
     return res;
 }
 
@@ -205,6 +254,55 @@ char **f_humstring_seq (ExpHandle *eh, data1_node *n, int *num)
     return NULL;
 }
 
+
+Z_RpnCapabilities *f_rpnCapabilities (ExpHandle *eh, data1_node *c)
+{
+    Z_RpnCapabilities *res = odr_malloc (eh->o, sizeof(*res));
+
+    res->num_operators = 0;
+    res->operators = NULL;
+    res->resultSetAsOperandSupported = eh->false_value;
+    res->restrictionOperandSupported = eh->false_value;
+    res->proximity = NULL;
+    /* fix */ /* 550 - 560 */
+    return res;
+}
+
+Z_QueryTypeDetails **f_queryTypesSupported (ExpHandle *eh, data1_node *c,
+                                           int *num)
+{
+    data1_node *n;
+    Z_QueryTypeDetails **res;
+    int i;
+
+    *num = 0;
+    for (n = c->child; n; n = n->next)
+    {
+       if (is_numeric_tag(eh, n) != 519)
+           continue;
+       /* fix */ /* 518 and 520 */
+       (*num)++;
+    }
+    if (!*num)
+       return NULL;
+    res = odr_malloc (eh->o, *num * sizeof(*res));
+    i = 0;
+    for (n = c->child; n; n = n->next)
+    {
+       if (is_numeric_tag(eh, n) == 519)
+       {
+           res[i] = odr_malloc (eh->o, sizeof(**res));
+           res[i]->which = Z_QueryTypeDetails_rpn;
+           res[i]->u.rpn = f_rpnCapabilities (eh, n);
+           i++;
+       }
+       else
+           continue;
+       /* fix */ /* 518 and 520 */
+    }
+    return res;
+}
+
 static Z_AccessInfo *f_accessInfo(ExpHandle *eh, data1_node *n)
 {
     Z_AccessInfo *res = odr_malloc(eh->o, sizeof(*res));
@@ -233,48 +331,37 @@ static Z_AccessInfo *f_accessInfo(ExpHandle *eh, data1_node *n)
 
     for (c = n->child; c; c = c->next)
     {
-       int i;
-       if (!is_numeric_tag (eh, c))
-           continue;
-       switch (c->u.tag.element->tag->value.numeric)
+       switch (is_numeric_tag (eh, c))
        {
        case 501:
-           res->num_queryTypesSupported = 0;
-           for (n = c->child; n; n = n->next)
-           {
-               if (!is_numeric_tag(eh, n))
-                   break;
-               (res->num_queryTypesSupported)++;
-           }
-           if (res->num_queryTypesSupported)
-               res->queryTypesSupported =
-                   odr_malloc (eh->o, res->num_queryTypesSupported
-                               * sizeof(*res->queryTypesSupported));
-           i = 0;
-           for (n = c->child; i < res->num_queryTypesSupported; n = n->next)
-               res->queryTypesSupported[i++] = f_queryTypeDetails (eh, n);
+           res->queryTypesSupported =
+               f_queryTypesSupported (eh, c, &res->num_queryTypesSupported);
            break;
        case 503:
-           res->diagnosticsSets = f_oid_seq(eh, c, &res->num_diagnosticsSets);
+           res->diagnosticsSets =
+               f_oid_seq(eh, c, &res->num_diagnosticsSets, CLASS_DIAGSET);
            break;
        case 505:
-           res->attributeSetIds = f_oid_seq(eh, c, &res->num_attributeSetIds);
+           res->attributeSetIds =
+               f_oid_seq(eh, c, &res->num_attributeSetIds, CLASS_ATTSET);
            break;
        case 507:
-           res->schemas = f_oid_seq(eh, c, &res->num_schemas);
+           res->schemas =
+               f_oid_seq(eh, c, &res->num_schemas, CLASS_SCHEMA);
            break;
        case 509:
-           res->recordSyntaxes = f_oid_seq (eh, c, &res->num_recordSyntaxes);
+           res->recordSyntaxes =
+               f_oid_seq (eh, c, &res->num_recordSyntaxes, CLASS_RECSYN);
            break;
        case 511:
-           res->resourceChallenges = f_oid_seq (eh, c,
-                                                &res->num_resourceChallenges);
+           res->resourceChallenges =
+               f_oid_seq (eh, c, &res->num_resourceChallenges, CLASS_RESFORM);
            break;
        case 513: res->restrictedAccess = NULL; break; /* fix */
        case 514: res->costInfo = NULL; break; /* fix */
        case 515:
-           res->variantSets = f_oid_seq (eh, c, 
-                                         &res->num_variantSets);
+           res->variantSets =
+               f_oid_seq (eh, c, &res->num_variantSets, CLASS_VARSET);
            break;
        case 516:
            res->elementSetNames =
@@ -283,9 +370,6 @@ static Z_AccessInfo *f_accessInfo(ExpHandle *eh, data1_node *n)
        case 517:
            res->unitSystems = f_string_seq (eh, c, &res->num_unitSystems);
            break;
-       default:
-           logf(LOG_WARN, "Bad child in accessInfo");
-           return 0;
        }
     }
     return res;
@@ -322,24 +406,29 @@ static Z_ContactInfo *f_contactInfo(ExpHandle *eh, data1_node *n)
 static Z_DatabaseList *f_databaseList(ExpHandle *eh, data1_node *n)
 {
     data1_node *c;
-    Z_DatabaseList *res = odr_malloc (eh->o, sizeof(*res));
-    int i;
+    Z_DatabaseList *res;
+    int i = 0;
+    
+    for (c = n->child; c; c = c->next)
+    {
+       if (!is_numeric_tag (eh, c) != 102) 
+           continue;
+       ++i;
+    }
+    if (!i)
+       return NULL;
 
-    res->num_databases = 0;
-    res->databases = NULL;
-    for (c = n->child ; c; c = c->next)
+    res = odr_malloc (eh->o, sizeof(*res));
+    
+    res->num_databases = i;
+    res->databases = odr_malloc (eh->o, sizeof(*res->databases) * i);
+    i = 0;
+    for (c = n->child; c; c = c->next)
     {
-       if (!is_numeric_tag (eh, c))
-           break;
-       if (n->u.tag.element->tag->value.numeric != 102)
-           break;
-       ++(res->num_databases);
+       if (!is_numeric_tag (eh, c) != 102)
+           continue;
+       res->databases[i++] = f_string (eh, c);
     }
-    if (res->num_databases)
-       res->databases =
-           odr_malloc (eh->o, sizeof(*res->databases)*res->num_databases);
-    for (c = n->child, i = 0 ; i < res->num_databases; c = c->next, i++)
-       res->databases[i] = f_string (eh, c);
     return res;
 }
 
@@ -347,10 +436,7 @@ static Z_TargetInfo *f_targetInfo(ExpHandle *eh, data1_node *n)
 {
     Z_TargetInfo *res = odr_malloc(eh->o, sizeof(*res));
     data1_node *c;
-    bool_t *fl = odr_malloc(eh->o,sizeof(*fl));
-    int i;
 
-    *fl = 0;
     res->commonInfo = 0;
     res->name = 0;
     res->recentNews = 0;
@@ -377,6 +463,8 @@ static Z_TargetInfo *f_targetInfo(ExpHandle *eh, data1_node *n)
     
     for (c = n->child; c; c = c->next)
     {
+       int i = 0;
+
        if (!is_numeric_tag (eh, c))
            continue;
        switch (c->u.tag.element->tag->value.numeric)
@@ -398,19 +486,20 @@ static Z_TargetInfo *f_targetInfo(ExpHandle *eh, data1_node *n)
            res->num_nicknames = 0;
            for (n = c->child; n; n = n->next)
            {
-               if (!is_numeric_tag(eh, n))
-                   break;
-               if (n->u.tag.element->tag->value.numeric != 102)
-                   break;
+               if (is_numeric_tag(eh, n) != 102)
+                   continue;
                (res->num_nicknames)++;
            }
            if (res->num_nicknames)
                res->nicknames =
                    odr_malloc (eh->o, res->num_nicknames 
                                * sizeof(*res->nicknames));
-           i = 0;
-           for (n = c->child; i < res->num_nicknames; n = n->next)
+           for (n = c->child; n; n = n->next)
+           {
+               if (is_numeric_tag(eh, n) != 102)
+                   continue;
                res->nicknames[i++] = f_string (eh, n);
+           }
            break;
        case 115: res->usageRest = f_humstring(eh, c); break;
        case 116: res->paymentAddr = f_humstring(eh, c); break;
@@ -419,30 +508,29 @@ static Z_TargetInfo *f_targetInfo(ExpHandle *eh, data1_node *n)
            res->num_dbCombinations = 0;
            for (n = c->child; n; n = n->next)
            {
-               if (!is_numeric_tag(eh, n))
-                   break;
-               if (n->u.tag.element->tag->value.numeric != 605)
-                   break;
+               if (!is_numeric_tag(eh, n) != 605)
+                   continue;
                (res->num_dbCombinations)++;
            }
            if (res->num_dbCombinations)
                res->dbCombinations =
                    odr_malloc (eh->o, res->num_dbCombinations
                                * sizeof(*res->dbCombinations));
-           i = 0;
-           for (n = c->child; i < res->num_dbCombinations; n = n->next)
+           for (n = c->child; n; n = n->next)
+           {
+               if (!is_numeric_tag(eh, n) != 605)
+                   continue;
                res->dbCombinations[i++] = f_databaseList (eh, n);
+           }
            break;
-       case 119: break; /* addresses */
+       case 119: res->addresses = 0; break; /* fix */
        case 500: res->commonAccessInfo = f_accessInfo(eh, c); break;
-       default:
-           logf(LOG_WARN, "Unknown target-info element");
        }
     }
     if (!res->namedResultSets)
-       res->namedResultSets = fl;
+       res->namedResultSets = eh->false_value;
     if (!res->multipleDbSearch)
-       res->multipleDbSearch = fl;
+       res->multipleDbSearch = eh->false_value;
     return res;
 }
 
@@ -450,12 +538,7 @@ static Z_DatabaseInfo *f_databaseInfo(ExpHandle *eh, data1_node *n)
 {
     Z_DatabaseInfo *res = odr_malloc(eh->o, sizeof(*res));
     data1_node *c;
-    bool_t *fl = odr_malloc(eh->o,sizeof(*fl));
-    bool_t *tr = odr_malloc(eh->o,sizeof(*tr));
-    int i;
 
-    *fl = 0;
-    *tr = 1;
     res->commonInfo = 0;
     res->name = 0;
     res->explainDatabase = 0;
@@ -491,11 +574,9 @@ static Z_DatabaseInfo *f_databaseInfo(ExpHandle *eh, data1_node *n)
     
     for (c = n->child; c; c = c->next)
     {
-       Z_DatabaseList *zdb;
+       int i = 0;
 
-       if (!is_numeric_tag (eh, c))
-           continue;
-       switch (c->u.tag.element->tag->value.numeric)
+       switch (is_numeric_tag (eh, c))
        {
        case 600: res->commonInfo = f_commonInfo(eh, c); break;
        case 102: res->name = f_string(eh, c); break;
@@ -504,19 +585,22 @@ static Z_DatabaseInfo *f_databaseInfo(ExpHandle *eh, data1_node *n)
            res->num_nicknames = 0;
            for (n = c->child; n; n = n->next)
            {
-               if (!is_numeric_tag(eh, n))
-                   break;
-               if (n->u.tag.element->tag->value.numeric != 102)
-                   break;
+               if (!is_numeric_tag(eh, n) ||
+                   n->u.tag.element->tag->value.numeric != 102)
+                   continue;
                (res->num_nicknames)++;
            }
            if (res->num_nicknames)
                res->nicknames =
                    odr_malloc (eh->o, res->num_nicknames 
                                * sizeof(*res->nicknames));
-           i = 0;
-           for (n = c->child; i < res->num_nicknames; n = n->next)
+           for (n = c->child; n; n = n->next)
+           {
+               if (!is_numeric_tag(eh, n) ||
+                   n->u.tag.element->tag->value.numeric != 102)
+                   continue;
                res->nicknames[i++] = f_string (eh, n);
+           }
            break;
        case 104: res->icon = 0; break;      /* fix */
        case 201: res->userFee = f_bool(eh, c); break;
@@ -526,19 +610,20 @@ static Z_DatabaseInfo *f_databaseInfo(ExpHandle *eh, data1_node *n)
            res->num_keywords = 0;
            for (n = c->child; n; n = n->next)
            {
-               if (!is_numeric_tag(eh, n))
-                   break;
-               if (n->u.tag.element->tag->value.numeric != 1000)
-                   break;
+               if (!is_numeric_tag(eh, n) != 1000)
+                   continue;
                (res->num_keywords)++;
            }
            if (res->num_keywords)
                res->keywords =
                    odr_malloc (eh->o, res->num_keywords 
                                * sizeof(*res->keywords));
-           i = 0;
-           for (n = c->child; i < res->num_keywords; n = n->next)
+           for (n = c->child; n; n = n->next)
+           {
+               if (!is_numeric_tag(eh, n) != 1000)
+                   continue;
                res->keywords[i++] = f_humstring (eh, n);
+           }
            break;
        case 113: res->description = f_humstring(eh, c); break;
        case 205:
@@ -566,14 +651,12 @@ static Z_DatabaseInfo *f_databaseInfo(ExpHandle *eh, data1_node *n)
        case 224: res->supplierContactInfo = f_contactInfo(eh, c); break;
        case 225: res->submissionContactInfo = f_contactInfo(eh, c); break;
        case 500: res->accessInfo = f_accessInfo(eh, c); break;
-       default:
-           logf(LOG_WARN, "Unknown element in databaseInfo");
        }
     }
     if (!res->userFee)
-       res->userFee = fl;
+       res->userFee = eh->false_value;
     if (!res->available)
-       res->available = tr;
+       res->available = eh->true_value;
     return res;
 }
 
@@ -586,6 +669,10 @@ Z_ExplainRecord *data1_nodetoexplain (data1_handle dh, data1_node *n,
     eh.dh = dh;
     eh.select = select;
     eh.o = o;
+    eh.false_value = odr_malloc(eh.o, sizeof(eh.false_value));
+    *eh.false_value = 0;
+    eh.true_value = odr_malloc(eh.o, sizeof(eh.true_value));
+    *eh.true_value = 1;
 
     assert(n->which == DATA1N_root);
     if (strcmp(n->u.root.type, "explain"))
@@ -599,16 +686,14 @@ Z_ExplainRecord *data1_nodetoexplain (data1_handle dh, data1_node *n,
        logf(LOG_WARN, "Explain record should have one exactly one child");
        return 0;
     }
-    if (!is_numeric_tag (&eh, n))
-       return 0;
-    switch (n->u.tag.element->tag->value.numeric)
+    switch (is_numeric_tag (&eh, n))
     {
-    case 0:
+    case 1:
        res->which = Z_Explain_targetInfo;
        if (!(res->u.targetInfo = f_targetInfo(&eh, n)))
            return 0;
        break;
-    case 1:
+    case 2:
        res->which = Z_Explain_databaseInfo;
        if (!(res->u.databaseInfo = f_databaseInfo(&eh, n)))
            return 0;
index 2883303..8393f3b 100644 (file)
@@ -81,7 +81,7 @@ att 1012            Date/time-last-modified
 att 1013            Authority/format-id
 att 1014            Concept-text
 att 1015            Concept-reference
-att 1016            Any                4,1005,62
+att 1016            Any                1016,4,1005,62
 att 1017            Server-choice
 att 1018            Publisher
 att 1019            Record-source
index 3036445..f146f45 100644 (file)
@@ -11,122 +11,114 @@ tagset explain.tag
 esetname B @
 esetname F @
 
-elm (4,0)                      targetInfo              ExplainCategory
+section accessInfo
+elm (4,501)                    queryTypesSupported             -
+elm (4,501)/(4,518)            privateCapabilities             -
+elm (4,501)/(4,519)            rpnCapabilities                 -
+elm (4,501)/(4,519)/(4,550)    rpnOperators                    -
+elm (4,501)/(4,519)/(4,550)/(4,551)    rpnOperator             -
+elm (4,501)/(4,519)/(4,552)    resultSetAsOperandSupported     -
+elm (4,501)/(4,519)/(4,553)    restrictionOperandSupported     -
+elm (4,501)/(4,519)/(4,554)    proximitySupport                -
+elm (4,501)/(4,519)/(4,554)/(4,555)    anySupport              -
+elm (4,501)/(4,519)/(4,554)/(4,556)    unitsSupported          -
+elm (4,501)/(4,519)/(4,554)/(4,556)/(4,557) unitSupported      -
+elm (4,501)/(4,519)/(4,554)/(4,556)/(4,557)/(4,558) known      -
+elm (4,501)/(4,519)/(4,554)/(4,556)/(4,557)/(4,559) private    -
+elm (4,501)/(4,519)/(4,554)/(4,556)/(4,557)/(4,559)/(4,558) privateUnit -
+elm (4,501)/(4,519)/(4,554)/(4,556)/(4,557)/(4,559)/(4,560) description -
+elm (4,501)/(4,520)            iso8777Capabilities             -
+elm (4,503)                    diagnosticSets                  -
+elm (4,503)/(4,1000)           diagnosticSet                   -
+elm (4,505)                    attributeSetIds                 -
+elm (4,505)/(4,1000)           attributeSetId                  -
+elm (4,507)                    schemas                         -
+elm (4,507)/(4,1000)           schema                          -
+elm (4,509)                    recordSyntaxes                  -
+elm (4,509/(4,1000)            recordSyntax                    -
+elm (4,511)                    resourceChallenges              -
+elm (4,511)/(4,1000)           resourceChallenge               -
+elm (4,513)                    restrictedAccess                -
+elm (4,514)                    costInfo                        -
+elm (4,515)                    variantSets                     -
+elm (4,515)/(4,1000)           variantSets                     -
+elm (4,516)                    elementSetNames                 -
+elm (4,516)/(4,1001)           elementSetName                  -
+elm (4,517)                    unitSystems                     -
+elm (4,517)/(4,1001)           unitSystem                      -
 
-elm (4,0)/(4,600)              targetCommonInfo                        -
-elm (4,0)/(4,600)/(4,601)      dateAdded                               !
-elm (4,0)/(4,600)/(4,602)      dateChanged                             !
-elm (4,0)/(4,600)/(4,603)      expiry                  DateExpired
-elm (4,0)/(4,600)/(4,604)      languageCode            HumanStringLanguage
+section commonInfo
+elm (4,601)                            dateAdded                       !
+elm (4,602)                            dateChanged                     !
+elm (4,603)                            expiry          DateExpired
+elm (4,604)                            languageCode    HumanStringLanguage
 
-elm (4,0)/(4,102)              targetName              TargetName
-elm (4,0)/(4,103)              recentNews                              -
-elm (4,0)/(4,104)              icon                                    -
-elm (4,0)/(4,105)              namedResultSets                         -
-elm (4,0)/(4,106)              multipleDbSearch                        -
-elm (4,0)/(4,107)              maxResultSets                           -
-elm (4,0)/(4,108)              maxResultSize                           -
-elm (4,0)/(4,109)              maxTerms                                -
-elm (4,0)/(4,110)              timeoutInterval                         -
-elm (4,0)/(4,111)              welcomeMessage                          -
-elm (4,0)/(4,112)              contactInfo                             -
-elm (4,0)/(4,113)              description                             -
-elm (4,0)/(4,114)              nicknames                               -
-elm (4,0)/(4,114)/(4,102)      nickname                                -
-elm (4,0)/(4,115)              usageRestrictions                       -
-elm (4,0)/(4,116)              paymentAddr                             -
-elm (4,0)/(4,117)              hours                                   -
-elm (4,0)/(4,118)              dbCombinations                          -
-elm (4,0)/(4,118)/(4,605)      databaseList                            -
-elm (4,0)/(4,118)/(4,605)/(4,102)      databaseName                    -
-elm (4,0)/(4,119)              addresses                               -
-
-elm (4,0)/(4,500)              commonAccessInfo                        -
-elm (4,0)/(4,500)/(4,501)      queryTypesSupported                     -
-elm (4,0)/(4,500)/(4,501)/(4,518)      privateCapabilities             -
-elm (4,0)/(4,500)/(4,501)/(4,519)      RpnCapabilities                 -
-elm (4,0)/(4,500)/(4,501)/(4,520)      Iso8777Capabilities             -
-elm (4,0)/(4,500)/(4,503)      diagnosticSets                          -
-elm (4,0)/(4,500)/(4,503)/(4,1000)     diagnosticSet                   -
-elm (4,0)/(4,500)/(4,505)      attributeSetIds                         -
-elm (4,0)/(4,500)/(4,505)/(4,1000)     attributeSetId                  -
-elm (4,0)/(4,500)/(4,507)      schemas                                 -
-elm (4,0)/(4,500)/(4,507)/(4,1000)     schema                          -
-elm (4,0)/(4,500)/(4,509)      recordSyntaxes                          -
-elm (4,0)/(4,500)/(4,509/(4,1000)      recordSyntax                    -
-elm (4,0)/(4,500)/(4,511)      resourceChallenges                      -
-elm (4,0)/(4,500)/(4,511)/(4,1000)     resourceChallenge               -
-elm (4,0)/(4,500)/(4,513)      restrictedAccess                        -
-elm (4,0)/(4,500)/(4,514)      costInfo                                -
-elm (4,0)/(4,500)/(4,515)      variantSets                             -
-elm (4,0)/(4,500)/(4,515)/(4,1000)     variantSets                     -
-elm (4,0)/(4,500)/(4,516)      elementSetNames                         -
-elm (4,0)/(4,500)/(4,516)/(4,1001)     elementSetName                  -
-elm (4,0)/(4,500)/(4,517)      unitSystems                             -
-elm (4,0)/(4,500)/(4,517)/(4,1001)     unitSystem                      -
-
-elm (4,1)                      databaseInfo            ExplainCategory
-elm (4,1)/(4,600)              databaseCommonInfo                      -
-elm (4,1)/(4,600)/(4,601)      dateAdded                               !
-elm (4,1)/(4,600)/(4,602)      dateChanged                             !
-elm (4,1)/(4,600)/(4,603)      expiry                  DateExpired
-elm (4,1)/(4,600)/(4,604)      languageCode            HumanStringLanguage
-elm (4,1)/(4,102)              databaseName            DatabaseName
-elm (4,1)/(4,226)              explainDatabase                         -
-elm (4,1)/(4,114)              nicknames                               -
-elm (4,1)/(4,114)/(4,102)      nickname                                -
+section main
+elm (4,1)                      targetInfo              ExplainCategory
+elm (4,1)/(4,600)              targetCommonInfo                        -
+elm (4,1)/(4,600)/$commonInfo  x                                       -
+elm (4,1)/(4,102)              targetName              TargetName
+elm (4,1)/(4,103)              recentNews                              -
 elm (4,1)/(4,104)              icon                                    -
-elm (4,1)/(4,201)              userFee                                 -
-elm (4,1)/(4,202)              available               Availability
-elm (4,1)/(4,203)              titleString                             -
-elm (4,1)/(4,227)              keywords                                -
-elm (4,1)/(4,227)/(4,1000)     keyword                                 -
+elm (4,1)/(4,105)              namedResultSets                         -
+elm (4,1)/(4,106)              multipleDbSearch                        -
+elm (4,1)/(4,107)              maxResultSets                           -
+elm (4,1)/(4,108)              maxResultSize                           -
+elm (4,1)/(4,109)              maxTerms                                -
+elm (4,1)/(4,110)              timeoutInterval                         -
+elm (4,1)/(4,111)              welcomeMessage                          -
+elm (4,1)/(4,112)              contactInfo                             -
 elm (4,1)/(4,113)              description                             -
-elm (4,1)/(4,205)              associatedDbs                           -
-elm (4,1)/(4,205)/(4,605)      databaseList                            -
-elm (4,1)/(4,205)/(4,605)/(4,102)      databaseName                    -
-elm (4,1)/(4,206)              subDbs                                  -
-elm (4,1)/(4,206)/(4,605)      databaseList                            -
-elm (4,1)/(4,206)/(4,605)/(4,102)      databaseName                    -
-elm (4,1)/(4,207)              disclaimers                             -
-elm (4,1)/(4,103)              recentNews                              -
-elm (4,1)/(4,209)              recordCount                             -
-elm (4,1)/(4,209)/(4,210)      recordCountActual                       -
-elm (4,1)/(4,209)/(4,211)      recordCountApprox                       -
-elm (4,1)/(4,212)              defaultOrder                            -
-elm (4,1)/(4,213)              avRecordSize                            -
-elm (4,1)/(4,214)              maxRecordSize                           -
-elm (4,1)/(4,215)              hours                                   -
-elm (4,1)/(4,216)              bestTime                                -
-elm (4,1)/(4,217)              lastUpdate                              -
-elm (4,1)/(4,218)              updateInterval                          -
-elm (4,1)/(4,219)              coverage                                -
-elm (4,1)/(4,220)              proprietary                             !
-elm (4,1)/(4,221)              copyrightText                           -
-elm (4,1)/(4,222)              copyrightNotice                         -
-elm (4,1)/(4,223)              producerContactInfo                     -
-elm (4,1)/(4,224)              supplierContactInfo                     -
-elm (4,1)/(4,225)              submissionContactInfo                   -
-elm (4,1)/(4,500)              databaseAccessInfo                      -
-elm (4,1)/(4,500)/(4,501)      queryTypesSupported                     -
-elm (4,1)/(4,500)/(4,501)/(4,518)      privateCapabilities             -
-elm (4,1)/(4,500)/(4,501)/(4,519)      RpnCapabilities                 -
-elm (4,1)/(4,500)/(4,501)/(4,520)      Iso8777Capabilities             -
-elm (4,1)/(4,500)/(4,503)      diagnosticSets                          -
-elm (4,1)/(4,500)/(4,503)/(4,1000)     diagnosticSet                   -
-elm (4,1)/(4,500)/(4,505)      attributeSetIds                         -
-elm (4,1)/(4,500)/(4,505)/(4,1000)     attributeSetId                  -
-elm (4,1)/(4,500)/(4,507)      schemas                                 -
-elm (4,1)/(4,500)/(4,507)/(4,1000)     schema                          -
-elm (4,1)/(4,500)/(4,509)      recordSyntaxes                          -
-elm (4,1)/(4,500)/(4,509/(4,1000)      recordSyntax                    -
-elm (4,1)/(4,500)/(4,511)      resourceChallenges                      -
-elm (4,1)/(4,500)/(4,511)/(4,1000)     resourceChallenge               -
-elm (4,1)/(4,500)/(4,513)      restrictedAccess                        -
-elm (4,1)/(4,500)/(4,514)      costInfo                                -
-elm (4,1)/(4,500)/(4,515)      variantSets                             -
-elm (4,1)/(4,500)/(4,515)/(4,1000)     variantSets                     -
-elm (4,1)/(4,500)/(4,516)      elementSetNames                         -
-elm (4,1)/(4,500)/(4,516)/(4,1001)     elementSetName                  -
-elm (4,1)/(4,500)/(4,517)      unitSystems                             -
-elm (4,1)/(4,500)/(4,517)/(4,1001)     unitSystem                      -
+elm (4,1)/(4,114)              nicknames                               -
+elm (4,1)/(4,114)/(4,102)      nickname                                -
+elm (4,1)/(4,115)              usageRestrictions                       -
+elm (4,1)/(4,116)              paymentAddr                             -
+elm (4,1)/(4,117)              hours                                   -
+elm (4,1)/(4,118)              dbCombinations                          -
+elm (4,1)/(4,118)/(4,605)      databaseList                            -
+elm (4,1)/(4,118)/(4,605)/(4,102)      databaseName                    -
+elm (4,1)/(4,119)              addresses                               -
+elm (4,1)/(4,500)              commonAccessInfo                        -
+elm (4,1)/(4,500)/$accessInfo  x                                       -
+
+elm (4,2)                      databaseInfo            ExplainCategory
+elm (4,2)/(4,600)              databaseCommonInfo                      -
+elm (4,2)/(4,600)/$commonInfo  x                                       -
+elm (4,2)/(4,102)              databaseName            DatabaseName
+elm (4,2)/(4,226)              explainDatabase                         -
+elm (4,2)/(4,114)              nicknames                               -
+elm (4,2)/(4,114)/(4,102)      nickname                                -
+elm (4,2)/(4,104)              icon                                    -
+elm (4,2)/(4,201)              userFee                                 -
+elm (4,2)/(4,202)              available               Availability
+elm (4,2)/(4,203)              titleString                             -
+elm (4,2)/(4,227)              keywords                                -
+elm (4,2)/(4,227)/(4,1000)     keyword                                 -
+elm (4,2)/(4,113)              description                             -
+elm (4,2)/(4,205)              associatedDbs                           -
+elm (4,2)/(4,205)/(4,605)      databaseList                            -
+elm (4,2)/(4,205)/(4,605)/(4,102)      databaseName                    -
+elm (4,2)/(4,206)              subDbs                                  -
+elm (4,2)/(4,206)/(4,605)      databaseList                            -
+elm (4,2)/(4,206)/(4,605)/(4,102)      databaseName                    -
+elm (4,2)/(4,207)              disclaimers                             -
+elm (4,2)/(4,103)              recentNews                              -
+elm (4,2)/(4,209)              recordCount                             -
+elm (4,2)/(4,209)/(4,210)      recordCountActual                       -
+elm (4,2)/(4,209)/(4,211)      recordCountApprox                       -
+elm (4,2)/(4,212)              defaultOrder                            -
+elm (4,2)/(4,213)              avRecordSize                            -
+elm (4,2)/(4,214)              maxRecordSize                           -
+elm (4,2)/(4,215)              hours                                   -
+elm (4,2)/(4,216)              bestTime                                -
+elm (4,2)/(4,217)              lastUpdate                              -
+elm (4,2)/(4,218)              updateInterval                          -
+elm (4,2)/(4,219)              coverage                                -
+elm (4,2)/(4,220)              proprietary                             !
+elm (4,2)/(4,221)              copyrightText                           -
+elm (4,2)/(4,222)              copyrightNotice                         -
+elm (4,2)/(4,223)              producerContactInfo                     -
+elm (4,2)/(4,224)              supplierContactInfo                     -
+elm (4,2)/(4,225)              submissionContactInfo                   -
+elm (4,2)/(4,500)              databaseAccessInfo                      -
+elm (4,2)/(4,500)/$accessInfo  x                                       -
index 6c781a0..b62f3c6 100644 (file)
@@ -9,11 +9,11 @@ include tagsetm.tag
 #
 # Explain categories
 #
-tag 0          targetInfo                                      structured
-tag 1          databaseInfo                                    structured
-tag 2          schemaInfo                                      structured
-tag 3          tagSetInfo                                      structured
-tag 4          recordSyntaxInfo                                structured
+tag 1          targetInfo                                      structured
+tag 2          databaseInfo                                    structured
+tag 3          schemaInfo                                      structured
+tag 4          tagSetInfo                                      structured
+tag 5          recordSyntaxInfo                                structured
 # ....
 
 #
@@ -86,6 +86,18 @@ tag 518         privateCapabilities                          structured
 tag 519                RpnCapabilities                                 structured
 tag 520                Iso8777Capabilities                             structured
 
+tag 550                rpnOperators                                    structured
+tag 551                rpnOperator                                     numeric
+tag 552                resultSetAsOperandSupported                     bool
+tag 553                restrictionOperandSupported                     bool
+tag 554                proximitySupport                                structured
+tag 555                anySupport                                      bool
+tag 556        proximityUnitsSupported                         structured
+tag 557                proximityUnitSupported                          structured
+tag 558                proximityUnitVal                                numeric
+tag 559                proximityUnitPrivate                            structured
+tag 560                proximityUnitDescription                        string
+
 tag 600                commonInfo                                      structured
 tag 601                dateAdded                                       generalizedtime
 tag 602                dateChanged                                     generalizedtime