Fiddling with the variant stuff.
authorSebastian Hammer <quinn@indexdata.com>
Mon, 13 Nov 1995 09:27:22 +0000 (09:27 +0000)
committerSebastian Hammer <quinn@indexdata.com>
Mon, 13 Nov 1995 09:27:22 +0000 (09:27 +0000)
21 files changed:
client/client.c
include/data1.h
include/nmem.h [new file with mode: 0644]
include/oid.h
retrieval/d1_doespec.c
retrieval/d1_espec.c
retrieval/d1_grs.c
retrieval/d1_read.c
retrieval/d1_tagset.c
server/eventl.c
tab/generic.tag [new file with mode: 0644]
tab/gils-variant.est [new file with mode: 0644]
tab/gils.abs
tab/gils.att
tab/gils.tag
tab/var1.var
tab/wais-b.est [new file with mode: 0644]
tab/wais-variant.est [new file with mode: 0644]
tab/wais.abs [new file with mode: 0644]
util/nmem.c [new file with mode: 0644]
util/oid.c

index b92f15e..4ecfff2 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: client.c,v $
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: client.c,v $
- * Revision 1.24  1995-10-30 12:41:13  quinn
+ * Revision 1.25  1995-11-13 09:27:22  quinn
+ * Fiddling with the variant stuff.
+ *
+ * Revision 1.24  1995/10/30  12:41:13  quinn
  * Added hostname lookup for server.
  *
  * Revision 1.23  1995/10/18  16:12:30  quinn
  * Added hostname lookup for server.
  *
  * Revision 1.23  1995/10/18  16:12:30  quinn
@@ -298,7 +301,22 @@ int cmd_authentication(char *arg)
 
 /* SEARCH SERVICE ------------------------------ */
 
 
 /* SEARCH SERVICE ------------------------------ */
 
-void display_grs1(Z_GenericRecord *r, int level)
+static void display_variant(Z_Variant *v, int level)
+{
+    int i;
+
+    for (i = 0; i < v->num_triples; i++)
+    {
+       printf("%*sclass=%d,type=%d", level * 4, "", *v->triples[i]->class,
+           *v->triples[i]->type);
+       if (v->triples[i]->which == Z_Triple_internationalString)
+           printf(",value=%s\n", v->triples[i]->value.internationalString);
+       else
+           printf("\n");
+    }
+}
+
+static void display_grs1(Z_GenericRecord *r, int level)
 {
     int i;
 
 {
     int i;
 
@@ -328,12 +346,31 @@ void display_grs1(Z_GenericRecord *r, int level)
             printf("%s\n", t->content->u.string);
         else if (t->content->which == Z_ElementData_numeric)
            printf("%d\n", *t->content->u.numeric);
             printf("%s\n", t->content->u.string);
         else if (t->content->which == Z_ElementData_numeric)
            printf("%d\n", *t->content->u.numeric);
+       else if (t->content->which == Z_ElementData_noDataRequested)
+           printf("[No data requested]\n");
+       else if (t->content->which == Z_ElementData_elementEmpty)
+           printf("[Element empty]\n");
+       else if (t->content->which == Z_ElementData_elementNotThere)
+           printf("[Element not there]\n");
        else
             printf("??????\n");
        else
             printf("??????\n");
+       if (t->appliedVariant)
+           display_variant(t->appliedVariant, level+1);
+       if (t->metaData && t->metaData->supportedVariants)
+       {
+           int c;
+
+           printf("%*s---- variant list\n", (level+1)*4, "");
+           for (c = 0; c < t->metaData->num_supportedVariants; c++)
+           {
+               printf("%*svariant #%d\n", (level+1)*4, "", c);
+               display_variant(t->metaData->supportedVariants[c], level + 2);
+           }
+       }
     }
 }
 
     }
 }
 
-void display_record(Z_DatabaseRecord *p)
+static void display_record(Z_DatabaseRecord *p)
 {
     Z_External *r = (Z_External*) p;
     oident *ent = oid_getentbyoid(r->direct_reference);
 {
     Z_External *r = (Z_External*) p;
     oident *ent = oid_getentbyoid(r->direct_reference);
index 51fff44..8feeb71 100644 (file)
  * OF THIS SOFTWARE.
  *
  * $Log: data1.h,v $
  * OF THIS SOFTWARE.
  *
  * $Log: data1.h,v $
- * Revision 1.3  1995-11-01 16:34:52  quinn
+ * Revision 1.4  1995-11-13 09:27:29  quinn
+ * Fiddling with the variant stuff.
+ *
+ * Revision 1.3  1995/11/01  16:34:52  quinn
  * Making data1 look for tables in data1_tabpath
  *
  * Revision 1.2  1995/11/01  13:54:35  quinn
  * Making data1 look for tables in data1_tabpath
  *
  * Revision 1.2  1995/11/01  13:54:35  quinn
@@ -234,10 +237,10 @@ typedef struct data1_node
 {
     enum 
     {
 {
     enum 
     {
-       DATA1N_root,
+       DATA1N_root,        /* the root of a record (containing global data) */
        DATA1N_tag,         /* a tag */
        DATA1N_tag,         /* a tag */
-       DATA1N_data,        /* */
-       DATA1N_variant,     /* variant specification */
+       DATA1N_data,        /* some data under a leaf tag or variant */
+       DATA1N_variant,     /* variant specification (a triple, actually) */
        DATA1N_indicator    /* ISO2709 indicator */
     } which;
 
        DATA1N_indicator    /* ISO2709 indicator */
     } which;
 
@@ -254,6 +257,8 @@ typedef struct data1_node
            char *tag;
            data1_element *element;
            int node_selected;
            char *tag;
            data1_element *element;
            int node_selected;
+           int make_variantlist;
+           int no_data_requested;
        } tag;
 
        struct
        } tag;
 
        struct
diff --git a/include/nmem.h b/include/nmem.h
new file mode 100644 (file)
index 0000000..227d99f
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1995, Index Data.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation, in whole or in part, for any purpose, is hereby granted,
+ * provided that:
+ *
+ * 1. This copyright and permission notice appear in all copies of the
+ * software and its documentation. Notices of copyright or attribution
+ * which appear at the beginning of any file must remain unchanged.
+ *
+ * 2. The names of Index Data or the individual authors may not be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * IN NO EVENT SHALL INDEX DATA BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR
+ * NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * $log$
+ */
+
+#ifndef NMEM_H
+#define NMEM_H
+
+typedef struct nmem_control *NMEM;
+
+void nmem_reset(NMEM n);
+void *nmem_malloc(NMEM n, int size);
+int nmem_total(NMEM n);
+NMEM nmem_create(void);
+void nmem_destroy(NMEM n);
+
+#endif
index b681a9d..e38b8cc 100644 (file)
  * OF THIS SOFTWARE.
  *
  * $Log: oid.h,v $
  * OF THIS SOFTWARE.
  *
  * $Log: oid.h,v $
- * Revision 1.9  1995-10-12 10:34:45  quinn
+ * Revision 1.10  1995-11-13 09:27:31  quinn
+ * Fiddling with the variant stuff.
+ *
+ * Revision 1.9  1995/10/12  10:34:45  quinn
  * Added Espec-1.
  *
  * Revision 1.8  1995/10/10  16:27:08  quinn
  * Added Espec-1.
  *
  * Revision 1.8  1995/10/10  16:27:08  quinn
@@ -86,7 +89,7 @@ typedef struct oident
        CLASS_USERINFO,
        CLASS_ELEMSPEC,
        CLASS_VARSET,
        CLASS_USERINFO,
        CLASS_ELEMSPEC,
        CLASS_VARSET,
-       CLASS_DBSCHEMA,
+       CLASS_SCHEMA,
        CLASS_TAGSET
     } class;
     enum oid_value
        CLASS_TAGSET
     } class;
     enum oid_value
@@ -99,6 +102,7 @@ typedef struct oident
        VAL_EXT1,
        VAL_CCL1,
        VAL_GILS,
        VAL_EXT1,
        VAL_CCL1,
        VAL_GILS,
+       VAL_WAIS,
        VAL_STAS,
        VAL_DIAG1,
        VAL_ISO2709,
        VAL_STAS,
        VAL_DIAG1,
        VAL_ISO2709,
index 538d567..4a1e002 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_doespec.c,v $
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_doespec.c,v $
- * Revision 1.2  1995-11-01 13:54:45  quinn
+ * Revision 1.3  1995-11-13 09:27:33  quinn
+ * Fiddling with the variant stuff.
+ *
+ * Revision 1.2  1995/11/01  13:54:45  quinn
  * Minor adjustments
  *
  * Revision 1.1  1995/11/01  11:56:07  quinn
  * Minor adjustments
  *
  * Revision 1.1  1995/11/01  11:56:07  quinn
 
 
 #include <assert.h>
 
 
 #include <assert.h>
+#include <oid.h>
 #include <log.h>
 #include <proto.h>
 #include <data1.h>
 
 #include <log.h>
 #include <proto.h>
 #include <data1.h>
 
-static int match_children(data1_node *n, Z_ETagUnit **t, int num);
+static int match_children(data1_node *n, Z_Espec1 *e, int i, Z_ETagUnit **t,
+    int num);
 
 
-static int match_children_wildpath(data1_node *n, Z_ETagUnit **t, int num)
+static int match_children_wildpath(data1_node *n, Z_Espec1 *e, int i,
+    Z_ETagUnit **t, int num)
 {return 0;}
 
 {return 0;}
 
-static int match_children_here(data1_node *n, Z_ETagUnit **t, int num)
+/*
+ * Locate a specific triple within a variant.
+ * set is the set to look for, universal set is the set that applies to a
+ * triple with an unknown set.
+ */
+static Z_Triple *find_triple(Z_Variant *var, oid_value universalset,
+    oid_value set, int class, int type)
+{
+    int i;
+    oident *defaultsetent = oid_getentbyoid(var->globalVariantSetId);
+    oid_value defaultset = defaultsetent ? defaultsetent->value :
+       universalset;
+
+    for (i = 0; i < var->num_triples; i++)
+    {
+       oident *cursetent =
+           oid_getentbyoid(var->triples[i]->variantSetId);
+       oid_value curset = cursetent ? cursetent->value : defaultset;
+
+       if (set == curset &&
+           *var->triples[i]->class == class &&
+           *var->triples[i]->type == type)
+           return var->triples[i];
+    }
+    return 0;
+}
+
+static void mark_subtree(data1_node *n, int make_variantlist, int no_data,
+    Z_Variant *vreq)
+{
+    data1_node *c;
+
+    if (n->which == DATA1N_tag && (!n->child || n->child->which != DATA1N_tag))
+    {
+       n->u.tag.node_selected = 1;
+       n->u.tag.make_variantlist = make_variantlist;
+       n->u.tag.no_data_requested = no_data;
+    }
+
+    for (c = n->child; c; c = c->next)
+    {
+       if (c->which == DATA1N_tag && (!n->child ||
+           n->child->which != DATA1N_tag))
+       {
+           c->u.tag.node_selected = 1;
+           c->u.tag.make_variantlist = make_variantlist;
+           c->u.tag.no_data_requested = no_data;
+       }
+       mark_subtree(c, make_variantlist, no_data, vreq);
+    }
+}
+
+static int match_children_here(data1_node *n, Z_Espec1 *e, int i,
+    Z_ETagUnit **t, int num)
 {
     int counter = 0, hits = 0;
     data1_node *c;
 {
     int counter = 0, hits = 0;
     data1_node *c;
@@ -79,9 +138,41 @@ static int match_children_here(data1_node *n, Z_ETagUnit **t, int num)
            (occur->which == Z_Occurrences_values && counter >=
            *occur->u.values->start))
        {
            (occur->which == Z_Occurrences_values && counter >=
            *occur->u.values->start))
        {
-           if (match_children(c, t + 1, num - 1))
+           if (match_children(c, e, i, t + 1, num - 1))
            {
                c->u.tag.node_selected = 1;
            {
                c->u.tag.node_selected = 1;
+               /*
+                * Consider the variant specification if this is a complete
+                * match.
+                */
+               if (num == 1)
+               {
+                   int show_variantlist = 0;
+                   int no_data = 0;
+                   Z_Variant *vreq =
+                       e->elements[i]->u.simpleElement->variantRequest;
+                   oident *defset = oid_getentbyoid(e->defaultVariantSetId);
+                   oid_value defsetval = defset ? defset->value : VAL_NONE;
+                   oid_value var1 = oid_getvalbyname("Variant-1");
+
+                   if (!vreq)
+                       vreq = e->defaultVariantRequest;
+
+                   if (vreq)
+                   {
+                       /*
+                        * 6,5: meta-data requested, variant list.
+                        */
+                       if (find_triple(vreq, defsetval, var1, 6, 5))
+                           show_variantlist = 1;
+                       /*
+                        * 9,1: Miscellaneous, no data requested.
+                        */
+                       if (find_triple(vreq, defsetval, var1, 9, 1))
+                           no_data = 1;
+                   }
+                   mark_subtree(c, show_variantlist, no_data, vreq);
+               }
                hits++;
                /*
                 * have we looked at enough children?
                hits++;
                /*
                 * have we looked at enough children?
@@ -96,34 +187,24 @@ static int match_children_here(data1_node *n, Z_ETagUnit **t, int num)
     return hits;
 }
 
     return hits;
 }
 
-static void mark_children(data1_node *n)
+static int match_children(data1_node *n, Z_Espec1 *e, int i, Z_ETagUnit **t,
+    int num)
 {
 {
-    data1_node *c;
-
-    for (c = n->child; c; c = c->next)
-    {
-       if (c->which != DATA1N_tag)
-           continue;
-       c->u.tag.node_selected = 1;
-       mark_children(c);
-    }
-}
+    int res;
 
 
-static int match_children(data1_node *n, Z_ETagUnit **t, int num)
-{
     if (!num)
     if (!num)
-    {
-       mark_children(n); /* Here there shall be variants, like, dude */
        return 1;
        return 1;
-    }
     switch (t[0]->which)
     {
        case Z_ETagUnit_wildThing:
     switch (t[0]->which)
     {
        case Z_ETagUnit_wildThing:
-       case Z_ETagUnit_specificTag: return match_children_here(n, t, num);
-       case Z_ETagUnit_wildPath: return match_children_wildpath(n, t, num);
+       case Z_ETagUnit_specificTag: res = match_children_here(n, e, i,
+           t, num); break;
+       case Z_ETagUnit_wildPath: res = match_children_wildpath(n, e, i,
+           t, num); break;
        default:
            abort();
     }
        default:
            abort();
     }
+    return res;
 }
 
 int data1_doespec1(data1_node *n, Z_Espec1 *e)
 }
 
 int data1_doespec1(data1_node *n, Z_Espec1 *e)
@@ -131,7 +212,11 @@ int data1_doespec1(data1_node *n, Z_Espec1 *e)
     int i;
 
     for (i = 0; i < e->num_elements; i++)
     int i;
 
     for (i = 0; i < e->num_elements; i++)
-       match_children(n,  e->elements[i]->u.simpleElement->path->tags,
+    {
+       if (e->elements[i]->which != Z_ERequest_simpleElement)
+           return 100;
+       match_children(n, e, i, e->elements[i]->u.simpleElement->path->tags,
            e->elements[i]->u.simpleElement->path->num_tags);
            e->elements[i]->u.simpleElement->path->num_tags);
+    }
     return 0;
 }
     return 0;
 }
index dd27c11..3c62d05 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_espec.c,v $
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_espec.c,v $
- * Revision 1.2  1995-11-01 16:34:56  quinn
+ * Revision 1.3  1995-11-13 09:27:34  quinn
+ * Fiddling with the variant stuff.
+ *
+ * Revision 1.2  1995/11/01  16:34:56  quinn
  * Making data1 look for tables in data1_tabpath
  *
  * Revision 1.1  1995/11/01  11:56:07  quinn
  * Making data1 look for tables in data1_tabpath
  *
  * Revision 1.1  1995/11/01  11:56:07  quinn
 #include <tpath.h>
 #include <data1.h>
 
 #include <tpath.h>
 #include <data1.h>
 
+static Z_Variant *read_variant(int argc, char **argv, ODR o)
+{
+    Z_Variant *r = odr_malloc(o, sizeof(*r));
+    oident var1;
+    int i;
+
+    var1.proto = PROTO_Z3950;
+    var1.class = CLASS_VARSET;
+    var1.value = VAL_VAR1;
+    r->globalVariantSetId = odr_oiddup(o, oid_getoidbyent(&var1));
+
+    r->triples = odr_malloc(o, sizeof(Z_Triple*) * argc);
+    r->num_triples = argc;
+    for (i = 0; i < argc; i++)
+    {
+       int class, type;
+       char value[512];
+       Z_Triple *t;
+
+       if (sscanf(argv[i], "(%d,%d,%[^)])", &class, &type, value) < 3)
+       {
+           logf(LOG_WARN, "Syntax error in variant component '%s'",
+               argv[i]);
+           return 0;
+       }
+       t = r->triples[i] = odr_malloc(o, sizeof(Z_Triple));
+       t->variantSetId = 0;
+       t->class = odr_malloc(o, sizeof(int));
+       *t->class = class;
+       t->type = odr_malloc(o, sizeof(int));
+       *t->type = type;
+       /*
+        * This is wrong.. we gotta look up the correct type for the
+        * variant, I guess... damn this stuff.
+        */
+       if (*value == '@')
+       {
+           t->which = Z_Triple_null;
+           t->value.null = ODR_NULLVAL;
+       }
+       else
+       {
+           t->which = Z_Triple_internationalString;
+           t->value.internationalString = odr_malloc(o, strlen(value)+1);
+           strcpy(t->value.internationalString, value);
+       }
+    }
+    return r;
+}
+
+static Z_Occurrences *read_occurrences(char *occ, ODR o)
+{
+    Z_Occurrences *op = odr_malloc(o, sizeof(*op));
+    char *p;
+
+    if (!occ)
+    {
+       op->which = Z_Occurrences_values;
+       op->u.values = odr_malloc(o, sizeof(Z_OccurValues));
+       op->u.values->start = odr_malloc(o, sizeof(int));
+       *op->u.values->start = 1;
+       op->u.values->howMany = 0;
+    }
+    else if (!strcmp(occ, "all"))
+    {
+       op->which = Z_Occurrences_all;
+       op->u.all = ODR_NULLVAL;
+    }
+    else if (!strcmp(occ, "last"))
+    {
+       op->which = Z_Occurrences_last;
+       op->u.all = ODR_NULLVAL;
+    }
+    else
+    {
+       Z_OccurValues *ov = odr_malloc(o, sizeof(*ov));
+
+       if (!isdigit(*occ))
+       {
+           logf(LOG_WARN, "Bad occurrences-spec in %s", occ);
+           return 0;
+       }
+       op->which = Z_Occurrences_values;
+       op->u.values = ov;
+       ov->start = odr_malloc(o, sizeof(*ov->start));
+       *ov->start = atoi(occ);
+       if ((p = strchr(occ, '+')))
+       {
+           ov->howMany = odr_malloc(o, sizeof(*ov->howMany));
+           *ov->howMany = atoi(p + 1);
+       }
+       else
+           ov->howMany = 0;
+    }
+    return op;
+}
+
+
+static Z_ETagUnit *read_tagunit(char *buf, ODR o)
+{
+    Z_ETagUnit *u = odr_malloc(o, sizeof(*u));
+    int terms;
+    int type;
+    char value[512], occ[512];
+
+    if (*buf == '*')
+    {
+       u->which = Z_ETagUnit_wildPath;
+       u->u.wildPath = ODR_NULLVAL;
+    }
+    else if (*buf == '?')
+    {
+       u->which = Z_ETagUnit_wildThing;
+       if (buf[1] == ':')
+           u->u.wildThing = read_occurrences(buf+2, o);
+       else
+           u->u.wildThing = read_occurrences(0, o);
+    }
+    else if ((terms = sscanf(buf, "(%d,%[^)]):%[a-z0-9+]", &type, value,
+       occ)) >= 2)
+    {
+       int numval;
+       Z_SpecificTag *t;
+       char *valp = value;
+       int force_string = 0;
+
+       if (*valp == '\'')
+       {
+           valp++;
+           force_string = 1;
+       }
+       u->which = Z_ETagUnit_specificTag;
+       u->u.specificTag = t = odr_malloc(o, sizeof(*t));
+       t->tagType = odr_malloc(o, sizeof(*t->tagType));
+       *t->tagType = type;
+       t->tagValue = odr_malloc(o, sizeof(*t->tagValue));
+       if (!force_string && (numval = atoi(valp)))
+       {
+           t->tagValue->which = Z_StringOrNumeric_numeric;
+           t->tagValue->u.numeric = odr_malloc(o, sizeof(int));
+           *t->tagValue->u.numeric = numval;
+       }
+       else
+       {
+           t->tagValue->which = Z_StringOrNumeric_string;
+           t->tagValue->u.string = odr_malloc(o, strlen(valp)+1);
+           strcpy(t->tagValue->u.string, valp);
+       }
+       if (terms > 2) /* an occurrences-spec exists */
+           t->occurrences = read_occurrences(occ, o);
+       else
+           t->occurrences = 0;
+    }
+    return u;
+}
+
 /*
 /*
- * Read an element-set specification from a file. If !o, use xmalloc for
- * memory allocation.
+ * Read an element-set specification from a file.
+ * NOTE: If !o, memory is allocated directly from the heap by odr_malloc().
  */
 Z_Espec1 *data1_read_espec1(char *file, ODR o)
 {
  */
 Z_Espec1 *data1_read_espec1(char *file, ODR o)
 {
@@ -92,7 +251,11 @@ Z_Espec1 *data1_read_espec1(char *file, ODR o)
        }
        else if (!strcmp(argv[0], "defaultvariantrequest"))
        {
        }
        else if (!strcmp(argv[0], "defaultvariantrequest"))
        {
-           abort();
+           if (!(res->defaultVariantRequest = read_variant(argc-1, argv+1, o)))
+           {
+               logf(LOG_WARN, "%s: Bad defaultvariantrequest", file);
+               continue;
+           }
        }
        else if (!strcmp(argv[0], "simpleelement"))
        {
        }
        else if (!strcmp(argv[0], "simpleelement"))
        {
@@ -116,6 +279,7 @@ Z_Espec1 *data1_read_espec1(char *file, ODR o)
                logf(LOG_WARN, "%s: Empty simpleelement directive", file);
                continue;
            }
                logf(LOG_WARN, "%s: Empty simpleelement directive", file);
                continue;
            }
+
            res->elements[res->num_elements++] = er =
                odr_malloc(o, sizeof(*er));
            er->which = Z_ERequest_simpleElement;
            res->elements[res->num_elements++] = er =
                odr_malloc(o, sizeof(*er));
            er->which = Z_ERequest_simpleElement;
@@ -123,53 +287,24 @@ Z_Espec1 *data1_read_espec1(char *file, ODR o)
            se->variantRequest = 0;
            se->path = tp = odr_malloc(o, sizeof(*tp));
            tp->num_tags = 0;
            se->variantRequest = 0;
            se->path = tp = odr_malloc(o, sizeof(*tp));
            tp->num_tags = 0;
+           /*
+            * Parse the element selector.
+            */
            for (num = 1, ep = path; (ep = strchr(ep, '/')); num++, ep++);
            tp->tags = odr_malloc(o, sizeof(Z_ETagUnit*)*num);
 
            for ((ep = strchr(path, '/')) ; path ; (void)((path = ep) &&
                (ep = strchr(path, '/'))))
            {
            for (num = 1, ep = path; (ep = strchr(ep, '/')); num++, ep++);
            tp->tags = odr_malloc(o, sizeof(Z_ETagUnit*)*num);
 
            for ((ep = strchr(path, '/')) ; path ; (void)((path = ep) &&
                (ep = strchr(path, '/'))))
            {
-               int type;
-               char value[512];
-               Z_ETagUnit *u;
-
                if (ep)
                    ep++;
 
                assert(i<num);
                if (ep)
                    ep++;
 
                assert(i<num);
-               tp->tags[tp->num_tags++] = u = odr_malloc(o, sizeof(*u));
-               if (sscanf(path, "(%d,%[^)])", &type, value) == 2)
-               {
-                   int numval;
-                   Z_SpecificTag *t;
-                   char *valp = value;
-                   int force_string = 0;
-
-                   if (*valp == '\'')
-                   {
-                       valp++;
-                       force_string = 1;
-                   }
-                   u->which = Z_ETagUnit_specificTag;
-                   u->u.specificTag = t = odr_malloc(o, sizeof(*t));
-                   t->tagType = odr_malloc(o, sizeof(*t->tagType));
-                   *t->tagType = type;
-                   t->tagValue = odr_malloc(o, sizeof(*t->tagValue));
-                   if (!force_string && (numval = atoi(valp)))
-                   {
-                       t->tagValue->which = Z_StringOrNumeric_numeric;
-                       t->tagValue->u.numeric = odr_malloc(o, sizeof(int));
-                       *t->tagValue->u.numeric = numval;
-                   }
-                   else
-                   {
-                       t->tagValue->which = Z_StringOrNumeric_string;
-                       t->tagValue->u.string = odr_malloc(o, strlen(valp)+1);
-                       strcpy(t->tagValue->u.string, valp);
-                   }
-                   t->occurrences = 0; /* for later */
-               }
+               tp->tags[tp->num_tags++] = read_tagunit(path, o);
            }
            }
+
+           if (argc > 2 && !strcmp(argv[2], "variant"))
+               se->variantRequest= read_variant(argc-3, argv+3, o);
        }
        else
        {
        }
        else
        {
index a3ea519..7c863b0 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_grs.c,v $
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_grs.c,v $
- * Revision 1.2  1995-11-01 13:54:46  quinn
+ * Revision 1.3  1995-11-13 09:27:35  quinn
+ * Fiddling with the variant stuff.
+ *
+ * Revision 1.2  1995/11/01  13:54:46  quinn
  * Minor adjustments
  *
  * Revision 1.1  1995/11/01  11:56:07  quinn
  * Minor adjustments
  *
  * Revision 1.1  1995/11/01  11:56:07  quinn
@@ -177,6 +180,10 @@ static Z_TaggedElement *nodetotaggedelement(data1_node *n, int select, ODR o)
        data = n->child;
        leaf = 0;
     }
        data = n->child;
        leaf = 0;
     }
+    /*
+     * If we're a data element at this point, we need to insert a
+     * wellKnown tag to wrap us up.
+     */
     else if (n->which == DATA1N_data || n->which == DATA1N_variant)
     {
        if (!(tag = data1_gettagbyname(n->root->u.root.absyn->tagset,
     else if (n->which == DATA1N_data || n->which == DATA1N_variant)
     {
        if (!(tag = data1_gettagbyname(n->root->u.root.absyn->tagset,
@@ -225,16 +232,24 @@ static Z_TaggedElement *nodetotaggedelement(data1_node *n, int select, ODR o)
        int nvars = 0;
 
        res->metaData = get_ElementMetaData(o);
        int nvars = 0;
 
        res->metaData = get_ElementMetaData(o);
-       if (traverse_triples(data, 0, res->metaData, o) < 0)
-           return 0;
+       if (n->which == DATA1N_tag && n->u.tag.make_variantlist)
+           if (traverse_triples(data, 0, res->metaData, o) < 0)
+               return 0;
        while (data && data->which == DATA1N_variant)
        {
            nvars++;
            data = data->child;
        }
        while (data && data->which == DATA1N_variant)
        {
            nvars++;
            data = data->child;
        }
-       res->appliedVariant = make_variant(data->parent, nvars-1, o);
+       if (n->which != DATA1N_tag || !n->u.tag.no_data_requested)
+           res->appliedVariant = make_variant(data->parent, nvars-1, o);
+    }
+    if (n->which == DATA1N_tag && n->u.tag.no_data_requested)
+    {
+       res->content = odr_malloc(o, sizeof(*res->content));
+       res->content->which = Z_ElementData_noDataRequested;
+       res->content->u.noDataRequested = ODR_NULLVAL;
     }
     }
-    if (!(res->content = nodetoelementdata(data, select, leaf, o)))
+    else if (!(res->content = nodetoelementdata(data, select, leaf, o)))
        return 0;
     return res;
 }
        return 0;
     return res;
 }
index 01b1a09..910fa0e 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_read.c,v $
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_read.c,v $
- * Revision 1.3  1995-11-01 16:34:57  quinn
+ * Revision 1.4  1995-11-13 09:27:36  quinn
+ * Fiddling with the variant stuff.
+ *
+ * Revision 1.3  1995/11/01  16:34:57  quinn
  * Making data1 look for tables in data1_tabpath
  *
  * Revision 1.2  1995/11/01  13:54:48  quinn
  * Making data1 look for tables in data1_tabpath
  *
  * Revision 1.2  1995/11/01  13:54:48  quinn
@@ -133,6 +136,8 @@ data1_node *data1_insert_taggeddata(data1_node *root, data1_node *at,
     tagn->line = -1;
     tagn->u.tag.tag = 0;
     tagn->u.tag.node_selected = 0;
     tagn->line = -1;
     tagn->u.tag.tag = 0;
     tagn->u.tag.node_selected = 0;
+    tagn->u.tag.make_variantlist = 0;
+    tagn->u.tag.no_data_requested = 0;
     if (!(tagn->u.tag.element = data1_getelementbytagname(root->u.root.absyn,
        0, tagname)))
     {
     if (!(tagn->u.tag.element = data1_getelementbytagname(root->u.root.absyn,
        0, tagname)))
     {
@@ -291,7 +296,7 @@ data1_node *data1_read_node(char **buf, data1_node *parent, int *line,
                *buf = t + 1;
            }
        }
                *buf = t + 1;
            }
        }
-       else /* acquire our element in the abstract syntax */
+       else /* tag.. acquire our element in the abstract syntax */
        {
            data1_node *partag = get_parent_tag(parent);
            data1_element *e = 0;
        {
            data1_node *partag = get_parent_tag(parent);
            data1_element *e = 0;
@@ -323,6 +328,8 @@ data1_node *data1_read_node(char **buf, data1_node *parent, int *line,
            res->u.tag.element = elem;
            res->u.tag.tag = tag;
            res->u.tag.node_selected = 0;
            res->u.tag.element = elem;
            res->u.tag.tag = tag;
            res->u.tag.node_selected = 0;
+           res->u.tag.make_variantlist = 0;
+           res->u.tag.no_data_requested = 0;
            res->root = parent->root;
            *buf = t + 1;
        }
            res->root = parent->root;
            *buf = t + 1;
        }
index b3a8439..97fdad8 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_tagset.c,v $
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_tagset.c,v $
- * Revision 1.3  1995-11-01 16:34:58  quinn
+ * Revision 1.4  1995-11-13 09:27:38  quinn
+ * Fiddling with the variant stuff.
+ *
+ * Revision 1.3  1995/11/01  16:34:58  quinn
  * Making data1 look for tables in data1_tabpath
  *
  * Revision 1.2  1995/11/01  13:54:49  quinn
  * Making data1 look for tables in data1_tabpath
  *
  * Revision 1.2  1995/11/01  13:54:49  quinn
@@ -49,6 +52,7 @@ data1_datatype data1_maptype(char *t)
        {"intunit", DATA1K_intunit},
        {"int", DATA1K_int},
        {"octetstring", DATA1K_octetstring},
        {"intunit", DATA1K_intunit},
        {"int", DATA1K_int},
        {"octetstring", DATA1K_octetstring},
+       {"null", DATA1K_null},
        {0, -1}
     };
     int i;
        {0, -1}
     };
     int i;
index b1c8bb8..46b2da0 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: eventl.c,v $
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: eventl.c,v $
- * Revision 1.17  1995-11-07 12:37:44  quinn
+ * Revision 1.18  1995-11-13 09:27:41  quinn
+ * Fiddling with the variant stuff.
+ *
+ * Revision 1.17  1995/11/07  12:37:44  quinn
  * Added support for forcing TIMEOUT event.
  *
  * Revision 1.16  1995/11/01  13:54:56  quinn
  * Added support for forcing TIMEOUT event.
  *
  * Revision 1.16  1995/11/01  13:54:56  quinn
@@ -100,7 +103,7 @@ IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags)
 
 int event_loop()
 {
 
 int event_loop()
 {
-    do
+    do /* loop as long as there are active associations to process */
     {
        IOCHAN p, nextp;
        fd_set in, out, except;
     {
        IOCHAN p, nextp;
        fd_set in, out, except;
diff --git a/tab/generic.tag b/tab/generic.tag
new file mode 100644 (file)
index 0000000..c58c50b
--- /dev/null
@@ -0,0 +1,4 @@
+name generic
+
+include tagsetm.tag
+include tagsetg.tag
diff --git a/tab/gils-variant.est b/tab/gils-variant.est
new file mode 100644 (file)
index 0000000..d2d2504
--- /dev/null
@@ -0,0 +1,13 @@
+#
+# This is the WAIS VARIANT element set description.
+#
+
+defaultvariantrequest (9,1,@) (6,5,@)  # No data; variant list.
+
+simpleelement (1,10)
+simpleelement (1,12)
+simpleelement (2,1) variant
+simpleelement (2,6)
+simpleelement (1,14) variant
+simpleelement (4,1)
+simpleelement (4,52)
index 7226c3c..4753b21 100644 (file)
@@ -4,7 +4,7 @@
 #
 
 name gils
 #
 
 name gils
-reference GILS
+reference GILS-schema
 attset gils.att
 tagset gils.tag
 varset var1.var
 attset gils.att
 tagset gils.tag
 varset var1.var
@@ -13,11 +13,11 @@ maptab gils-usmarc.map
 
 # Element set names
 
 
 # Element set names
 
+esetname VARIANT gils-variant.est  # for WAIS-compliance
 esetname B gils-b.est
 esetname G gils-g.est
 esetname W gils-b.est   # We don't really do bodyOfDisplay yet.
 esetname F @
 esetname B gils-b.est
 esetname G gils-g.est
 esetname W gils-b.est   # We don't really do bodyOfDisplay yet.
 esetname F @
-esetname VARIANT @
 
 elm (1,10)                  rank                          -
 elm (1,12)                  url                           -
 
 elm (1,10)                  rank                          -
 elm (1,12)                  url                           -
index 9952534..0484bf6 100644 (file)
@@ -1,5 +1,5 @@
 name gils\r
 name gils\r
-reference GILS\r
+reference GILS-attset\r
 include bib1.att\r
 ordinal 2\r
 \r
 include bib1.att\r
 ordinal 2\r
 \r
index 70679d3..7670eee 100644 (file)
@@ -1,5 +1,5 @@
 name gils
 name gils
-reference GILS
+reference GILS-tagset
 type 4
 include tagsetm.tag
 include tagsetg.tag
 type 4
 include tagsetm.tag
 include tagsetg.tag
index 1f784f8..eddcf8f 100644 (file)
@@ -44,9 +44,16 @@ class 5 piece
 
 class 6 metadata-requested
 
 
 class 6 metadata-requested
 
-  type 1       cost                    int
-
-  # More to follow....
+  type 1       cost                    intunit
+  type 2       size                    intunit
+  type 3       hitsvar                 null
+  type 4       hitsnonvar              null
+  type 5       variantlist             null
+  type 6       isvariantsupported      null
+  type 7       documentdescriptor      null
+  type 8       surrogateinformation    null
+  type 998     allmetadata             null
+  type 999     othermetadata           oid
 
 class 7        metadata-returned
 
 
 class 7        metadata-returned
 
diff --git a/tab/wais-b.est b/tab/wais-b.est
new file mode 100644 (file)
index 0000000..4100a20
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# WAIS eset.
+#
+
+simpleelement (2,1)
+simpleelement (2,7)
+simpleelement (1,16)
+simpleelement (1,18)
+simpleelement (1,14)
diff --git a/tab/wais-variant.est b/tab/wais-variant.est
new file mode 100644 (file)
index 0000000..9e17d26
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# WAIS variant eset.
+#
+
+#
+# Default is no data, variant-list, please.
+#
+
+simpleelement ?:all variant (9,1,@) (6,5,@)
+
+#
+# Empty variant-requests for the well-known elements to override default.
+#
+
+simpleelement (2,1) variant
+simpleelement (2,7) variant
+simpleelement (1,16) variant
+simpleelement (1,18) variant
+simpleelement (1,14) variant
diff --git a/tab/wais.abs b/tab/wais.abs
new file mode 100644 (file)
index 0000000..649d45c
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# WAIS profile
+#
+
+name wais
+reference WAIS-schema
+attset bib1.att
+tagset generic.tag
+
+varset var1.var
+
+esetname B wais-b.est
+esetname F @
+esetname VARIANT wais-variant.est
+
+elm (2,1)              Title                   !
+elm (2,7)              Name                    !
+elm (1,16)             Date                    !
+elm (1,18)             Score                   -
+elm (1,14)             RecordId                Local-number
diff --git a/util/nmem.c b/util/nmem.c
new file mode 100644 (file)
index 0000000..8fbfd84
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 1995, Index Data.
+ * See the file LICENSE for details.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: nmem.c,v $
+ * Revision 1.1  1995-11-13 09:27:52  quinn
+ * Fiddling with the variant stuff.
+ *
+ *
+ */
+
+/*
+ * This is a simple and fairly wasteful little module for nibble memory
+ * allocation. Evemtually we'll put in something better.
+ */
+
+#include <xmalloc.h>
+#include <nmem.h>
+
+#define NMEM_CHUNK (10*1024)
+
+typedef struct nmem_block
+{
+    char *buf;              /* memory allocated in this block */
+    int size;               /* size of buf */
+    int top;                /* top of buffer */
+    struct nmem_block *next;
+} nmem_block;
+
+typedef struct nmem_control
+{
+    int total;
+    nmem_block *blocks;
+} nmem_control;
+
+static nmem_block *freelist = 0; /* global freelist */
+
+static void free_block(nmem_block *p)
+{
+    p->next = freelist;
+    freelist = p;
+}
+
+/*
+ * acquire a block with a minimum of size free bytes.
+ */
+static nmem_block *get_block(int size)
+{
+    nmem_block *r, *l;
+
+    for (r = freelist, l = 0; r; l = r, r = r->next)
+       if (r->size >= size)
+           break;
+    if (r)
+       if (l)
+           l->next = r->next;
+       else
+           freelist = r->next;
+    else
+    {
+       int get = NMEM_CHUNK;
+
+       if (get < size)
+           get = size;
+       r = xmalloc(sizeof(*r));
+       r->buf = xmalloc(r->size = get);
+    }
+    r->top = 0;
+    return r;
+}
+
+void nmem_reset(NMEM n)
+{
+    nmem_block *t;
+
+    if (!n)
+       return;
+    while (n->blocks)
+    {
+       t = n->blocks;
+       n->blocks = n->blocks->next;
+       free_block(t);
+    }
+    n->total = 0;
+}
+
+void *nmem_malloc(NMEM n, int size)
+{
+    struct nmem_block *p;
+    char *r;
+
+    if (!n)
+       return xmalloc(size);
+    p = n->blocks;
+    if (!p || p->size - p->top < size)
+    {
+       p = get_block(size);
+       p->next = n->blocks;
+       n->blocks = p;
+    }
+    r = p->buf + p->top;
+    /* align size */
+    p->top += (size + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
+    n->total += size;
+    return r;
+}
+
+int nmem_total(NMEM n)
+{
+    return n->total;
+}
+
+NMEM nmem_create(void)
+{
+    NMEM r = xmalloc(sizeof(*r));
+    
+    r->blocks = 0;
+    r->total = 0;
+    return r;
+}
+
+void nmem_destroy(NMEM n)
+{
+    if (!n)
+       return;
+    nmem_reset(n);
+    xfree(n);
+}
index b373809..ba6027e 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: oid.c,v $
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: oid.c,v $
- * Revision 1.8  1995-10-12 10:34:56  quinn
+ * Revision 1.9  1995-11-13 09:27:53  quinn
+ * Fiddling with the variant stuff.
+ *
+ * Revision 1.8  1995/10/12  10:34:56  quinn
  * Added Espec-1.
  *
  * Revision 1.7  1995/10/10  16:27:12  quinn
  * Added Espec-1.
  *
  * Revision 1.7  1995/10/10  16:27:12  quinn
@@ -73,8 +76,8 @@ static oident oids[] =
     {PROTO_Z3950,   CLASS_ATTSET,  VAL_EXP1,      {3,2,-1},    "Exp-1"       },
     {PROTO_Z3950,   CLASS_ATTSET,  VAL_EXT1,      {3,3,-1},    "Ext-1"       },
     {PROTO_Z3950,   CLASS_ATTSET,  VAL_CCL1,      {3,4,-1},    "CCL-1"       },
     {PROTO_Z3950,   CLASS_ATTSET,  VAL_EXP1,      {3,2,-1},    "Exp-1"       },
     {PROTO_Z3950,   CLASS_ATTSET,  VAL_EXT1,      {3,3,-1},    "Ext-1"       },
     {PROTO_Z3950,   CLASS_ATTSET,  VAL_CCL1,      {3,4,-1},    "CCL-1"       },
-    {PROTO_Z3950,   CLASS_ATTSET,  VAL_GILS,      {3,5,-1},    "GILS"        },
-    {PROTO_Z3950,   CLASS_ATTSET,  VAL_STAS,      {3,6,-1},    "STAS",       },
+    {PROTO_Z3950,   CLASS_ATTSET,  VAL_GILS,      {3,5,-1},    "GILS-attset" },
+    {PROTO_Z3950,   CLASS_ATTSET,  VAL_STAS,      {3,6,-1},    "STAS-attset" },
     {PROTO_Z3950,   CLASS_DIAGSET, VAL_BIB1,      {4,1,-1},    "Bib-1"       },
     {PROTO_Z3950,   CLASS_DIAGSET, VAL_DIAG1,     {4,2,-1},    "Diag-1"      },
     {PROTO_Z3950,   CLASS_RECSYN,  VAL_UNIMARC,   {5,1,-1},    "Unimarc"     },
     {PROTO_Z3950,   CLASS_DIAGSET, VAL_BIB1,      {4,1,-1},    "Bib-1"       },
     {PROTO_Z3950,   CLASS_DIAGSET, VAL_DIAG1,     {4,2,-1},    "Diag-1"      },
     {PROTO_Z3950,   CLASS_RECSYN,  VAL_UNIMARC,   {5,1,-1},    "Unimarc"     },
@@ -114,9 +117,12 @@ static oident oids[] =
     {PROTO_Z3950,   CLASS_ELEMSPEC,VAL_ESPEC1,    {11,1,-1},   "Espec-1"     },
     {PROTO_Z3950,   CLASS_VARSET,  VAL_VAR1,      {12,1,-1},   "Variant-1"   },
 
     {PROTO_Z3950,   CLASS_ELEMSPEC,VAL_ESPEC1,    {11,1,-1},   "Espec-1"     },
     {PROTO_Z3950,   CLASS_VARSET,  VAL_VAR1,      {12,1,-1},   "Variant-1"   },
 
+    {PROTO_Z3950,   CLASS_SCHEMA,  VAL_WAIS,      {13,1,-1},   "WAIS-schema" },
+    {PROTO_Z3950,   CLASS_SCHEMA,  VAL_GILS,      {13,2,-1},   "GILS-schema" },
+
     {PROTO_Z3950,   CLASS_TAGSET,  VAL_SETM,      {14,1,-1},   "TagsetM"     },
     {PROTO_Z3950,   CLASS_TAGSET,  VAL_SETG,      {14,2,-1},   "TagsetG"     },
     {PROTO_Z3950,   CLASS_TAGSET,  VAL_SETM,      {14,1,-1},   "TagsetM"     },
     {PROTO_Z3950,   CLASS_TAGSET,  VAL_SETG,      {14,2,-1},   "TagsetG"     },
-    {PROTO_Z3950,   CLASS_TAGSET,  VAL_GILS,      {14,3,-1},   "GILS"        },
+    {PROTO_Z3950,   CLASS_TAGSET,  VAL_GILS,      {14,3,-1},   "GILS-tagset" },
 
     /* SR definitions. Note that some of them aren't defined by the
         standard (yet), but are borrowed from Z3950v3 */
 
     /* SR definitions. Note that some of them aren't defined by the
         standard (yet), but are borrowed from Z3950v3 */
@@ -169,8 +175,12 @@ static oident oids[] =
     {PROTO_SR,      CLASS_ELEMSPEC,VAL_ESPEC1,    {11,1,-1},   "Espec-1"     },
     {PROTO_SR,      CLASS_VARSET,  VAL_VAR1,      {12,1,-1},   "Variant-1"   },
 
     {PROTO_SR,      CLASS_ELEMSPEC,VAL_ESPEC1,    {11,1,-1},   "Espec-1"     },
     {PROTO_SR,      CLASS_VARSET,  VAL_VAR1,      {12,1,-1},   "Variant-1"   },
 
+    {PROTO_SR,      CLASS_SCHEMA,  VAL_WAIS,      {13,1,-1},   "WAIS-schema" },
+    {PROTO_SR,      CLASS_SCHEMA,  VAL_GILS,      {13,2,-1},   "GILS-schema" },
+
     {PROTO_SR,      CLASS_TAGSET,  VAL_SETM,      {14,1,-1},   "TagsetM"     },
     {PROTO_SR,      CLASS_TAGSET,  VAL_SETG,      {14,2,-1},   "TagsetG"     },
     {PROTO_SR,      CLASS_TAGSET,  VAL_SETM,      {14,1,-1},   "TagsetM"     },
     {PROTO_SR,      CLASS_TAGSET,  VAL_SETG,      {14,2,-1},   "TagsetG"     },
+    {PROTO_SR,      CLASS_TAGSET,  VAL_GILS,      {14,3,-1},   "GILS-tagset" },
 
     {0,             0,             0,             {-1},        0          }
 };
 
     {0,             0,             0,             {-1},        0          }
 };