Added a few comments - no code changed.
[idzebra-moved-to-github.git] / recctrl / regxread.c
index e65ce84..a90f02e 100644 (file)
@@ -1,10 +1,30 @@
 /*
- * Copyright (C) 1994-1996, Index Data I/S 
+ * Copyright (C) 1994-1997, Index Data I/S 
  * All rights reserved.
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: regxread.c,v $
- * Revision 1.7  1997-07-15 16:33:07  adam
+ * Revision 1.13  1997-12-12 06:33:58  adam
+ * Fixed bug that showed up when multiple filter where used.
+ * Made one routine thread-safe.
+ *
+ * Revision 1.12  1997/11/18 10:03:24  adam
+ * Member num_children removed from data1_node.
+ *
+ * Revision 1.11  1997/11/06 11:41:01  adam
+ * Implemented "begin variant" for the sgml.regx filter.
+ *
+ * Revision 1.10  1997/10/31 12:36:12  adam
+ * Minor change that avoids compiler warning.
+ *
+ * Revision 1.9  1997/09/29 09:02:49  adam
+ * Fixed small bug (introduced by previous commit).
+ *
+ * Revision 1.8  1997/09/17 12:19:22  adam
+ * Zebra version corresponds to YAZ version 1.4.
+ * Changed Zebra server so that it doesn't depend on global common_resource.
+ *
+ * Revision 1.7  1997/07/15 16:33:07  adam
  * Check for zero length in execData.
  *
  * Revision 1.6  1997/02/24 10:41:51  adam
@@ -165,6 +185,7 @@ struct lexSpec {
     struct lexTrans trans;
     int lineNo;
     NMEM m;
+    data1_handle dh;
     void *f_win_fh;
     void (*f_win_ef)(void *, off_t);
 
@@ -322,6 +343,7 @@ static void lexSpecDel (struct lexSpec **pp)
     xfree (p->trans.fastRule);
     for (rp = p->trans.rules; rp; rp = rp1)
     {
+       rp1 = rp->next;
         actionListDel (&rp->info.actionList);
         xfree (rp);
     }
@@ -504,7 +526,8 @@ int readFileSpec (struct lexSpec *spec)
     lineBuf = xmalloc (1+lineSize);
     logf (LOG_LOG, "reading regx filter %s.flt", spec->name);
     sprintf (lineBuf, "%s.flt", spec->name);
-    if (!(spec_inf = yaz_path_fopen (data1_get_tabpath(), lineBuf, "r")))
+    if (!(spec_inf = yaz_path_fopen (data1_get_tabpath(spec->dh),
+                                    lineBuf, "r")))
     {
         logf (LOG_ERRNO|LOG_WARN, "cannot read spec file %s", spec->name);
         xfree (lineBuf);
@@ -618,7 +641,7 @@ static void execData (struct lexSpec *spec,
     }
     else
     {
-        res = data1_mk_node (spec->m);
+        res = data1_mk_node (spec->dh, spec->m);
         res->parent = parent;
         res->which = DATA1N_data;
         res->u.data.what = DATA1I_text;
@@ -634,7 +657,6 @@ static void execData (struct lexSpec *spec,
         memcpy (res->u.data.data, ebuf, elen);
         res->root = parent->root;
         
-        parent->num_children++;
         parent->last_child = res;
         if (d1_stack[*d1_level])
             d1_stack[*d1_level]->next = res;
@@ -651,6 +673,91 @@ static void execDataP (struct lexSpec *spec,
     execData (spec, d1_stack, d1_level, ebuf, elen, formatted_text);
 }
 
+static void variantBegin (struct lexSpec *spec, 
+                         data1_node **d1_stack, int *d1_level,
+                         const char *class_str, int class_len,
+                         const char *type_str, int type_len,
+                         const char *value_str, int value_len)
+{
+    struct data1_node *parent = d1_stack[*d1_level -1];
+    char tclass[DATA1_MAX_SYMBOL], ttype[DATA1_MAX_SYMBOL];
+    data1_vartype *tp;
+    int i;
+    data1_node *res;
+
+    if (*d1_level == 0)
+    {
+        logf (LOG_WARN, "in variant begin. No record type defined");
+        return ;
+    }
+    if (class_len >= DATA1_MAX_SYMBOL)
+       class_len = DATA1_MAX_SYMBOL-1;
+    memcpy (tclass, class_str, class_len);
+    tclass[class_len] = '\0';
+
+    if (type_len >= DATA1_MAX_SYMBOL)
+       type_len = DATA1_MAX_SYMBOL-1;
+    memcpy (ttype, type_str, type_len);
+    ttype[type_len] = '\0';
+
+#if REGX_DEBUG 
+    logf (LOG_DEBUG, "variant begin %s %s (%d)", tclass, ttype, *d1_level);
+#endif
+
+    if (!(tp =
+         data1_getvartypebyct(spec->dh, parent->root->u.root.absyn->varset,
+                              tclass, ttype)))
+       return;
+    
+    if (parent->which != DATA1N_variant)
+    {
+       res = data1_mk_node (spec->dh, spec->m);
+       res->parent = parent;
+       res->which = DATA1N_variant;
+       res->u.variant.type = 0;
+       res->u.variant.value = 0;
+       res->root = parent->root;
+
+       parent->last_child = res;
+       if (d1_stack[*d1_level])
+           d1_stack[*d1_level]->next = res;
+       else
+           parent->child = res;
+       d1_stack[*d1_level] = res;
+       d1_stack[++(*d1_level)] = NULL;
+    }
+    for (i = *d1_level-1; d1_stack[i]->which == DATA1N_variant; i--)
+       if (d1_stack[i]->u.variant.type == tp)
+       {
+           *d1_level = i;
+           break;
+       }
+
+#if REGX_DEBUG 
+    logf (LOG_DEBUG, "variant node (%d)", *d1_level);
+#endif
+    parent = d1_stack[*d1_level-1];
+    res = data1_mk_node (spec->dh, spec->m);
+    res->parent = parent;
+    res->which = DATA1N_variant;
+    res->root = parent->root;
+    res->u.variant.type = tp;
+
+    if (value_len >= DATA1_LOCALDATA)
+       value_len =DATA1_LOCALDATA-1;
+    memcpy (res->lbuf, value_str, value_len);
+    res->lbuf[value_len] = '\0';
+
+    res->u.variant.value = res->lbuf;
+    
+    parent->last_child = res;
+    if (d1_stack[*d1_level])
+        d1_stack[*d1_level]->next = res;
+    else
+        parent->child = res;
+    d1_stack[*d1_level] = res;
+    d1_stack[++(*d1_level)] = NULL;
+}
 
 static void tagBegin (struct lexSpec *spec, 
                       data1_node **d1_stack, int *d1_level,
@@ -658,7 +765,7 @@ static void tagBegin (struct lexSpec *spec,
 {
     struct data1_node *parent = d1_stack[*d1_level -1];
     data1_element *elem = NULL;
-    data1_node *partag = get_parent_tag(parent);
+    data1_node *partag = get_parent_tag(spec->dh, parent);
     data1_node *res;
     data1_element *e = NULL;
     int localtag = 0;
@@ -669,17 +776,16 @@ static void tagBegin (struct lexSpec *spec,
         return ;
     }
     
-    res = data1_mk_node (spec->m);
+    res = data1_mk_node (spec->dh, spec->m);
     res->parent = parent;
     res->which = DATA1N_tag;
-    res->u.tag.tag = res->lbuf;
     res->u.tag.get_bytes = -1;
 
     if (len >= DATA1_LOCALDATA)
         len = DATA1_LOCALDATA-1;
-
-    memcpy (res->u.tag.tag, tag, len);
-    res->u.tag.tag[len] = '\0';
+    memcpy (res->lbuf, tag, len);
+    res->lbuf[len] = '\0';
+    res->u.tag.tag = res->lbuf;
    
 #if REGX_DEBUG 
     logf (LOG_DEBUG, "tag begin %s (%d)", res->u.tag.tag, *d1_level);
@@ -690,15 +796,14 @@ static void tagBegin (struct lexSpec *spec,
         if (!(e = partag->u.tag.element))
             localtag = 1;
     
-    elem = data1_getelementbytagname (d1_stack[0]->u.root.absyn, e,
-                                      res->u.tag.tag);
-    
+    elem = data1_getelementbytagname (spec->dh, d1_stack[0]->u.root.absyn,
+                                     e, res->u.tag.tag);
     res->u.tag.element = elem;
     res->u.tag.node_selected = 0;
     res->u.tag.make_variantlist = 0;
     res->u.tag.no_data_requested = 0;
     res->root = parent->root;
-    parent->num_children++;
+
     parent->last_child = res;
     if (d1_stack[*d1_level])
         d1_stack[*d1_level]->next = res;
@@ -715,9 +820,10 @@ static void tagEnd (struct lexSpec *spec,
     while (*d1_level > 1)
     {
         (*d1_level)--;
-        if (!tag ||
-            (strlen(d1_stack[*d1_level]->u.tag.tag) == len &&
-             !memcmp (d1_stack[*d1_level]->u.tag.tag, tag, len)))
+        if ((d1_stack[*d1_level]->which == DATA1N_tag) &&
+           (!tag ||
+            (strlen(d1_stack[*d1_level]->u.tag.tag) == (size_t) len &&
+             !memcmp (d1_stack[*d1_level]->u.tag.tag, tag, len))))
             break;
     }
 #if REGX_DEBUG
@@ -855,10 +961,8 @@ static int execTok (struct lexSpec *spec, const char **src,
     return 2;
 }
 
-static char *regxStrz (const char *src, int len)
+static char *regxStrz (const char *src, int len, char *str)
 {
-    static char str[64];
-    
     if (len > 63)
         len = 63;
     memcpy (str, src, len);
@@ -879,7 +983,7 @@ static int execCode (struct lexSpec *spec,
     r = execTok (spec, &s, arg_no, arg_start, arg_end, &cmd_str, &cmd_len);
     while (r)
     {
-        char *p;
+        char *p, ptmp[64];
         
         if (r == 1)
         {
@@ -887,14 +991,14 @@ static int execCode (struct lexSpec *spec,
                          &cmd_str, &cmd_len);
             continue;
         }
-        p = regxStrz (cmd_str, cmd_len);
+        p = regxStrz (cmd_str, cmd_len, ptmp);
         if (!strcmp (p, "begin"))
         {
             r = execTok (spec, &s, arg_no, arg_start, arg_end,
                          &cmd_str, &cmd_len);
             if (r < 2)
                 continue;
-            p = regxStrz (cmd_str, cmd_len);
+            p = regxStrz (cmd_str, cmd_len, ptmp);
             if (!strcmp (p, "record"))
             {
                 r = execTok (spec, &s, arg_no, arg_start, arg_end,
@@ -914,13 +1018,13 @@ static int execCode (struct lexSpec *spec,
 #if REGX_DEBUG
                     logf (LOG_DEBUG, "begin record %s", absynName);
 #endif
-                    if (!(absyn = data1_get_absyn (absynName)))
+                    if (!(absyn = data1_get_absyn (spec->dh, absynName)))
                         logf (LOG_WARN, "Unknown tagset: %s", absynName);
                     else
                     {
                         data1_node *res;
 
-                        res = data1_mk_node (spec->m);
+                        res = data1_mk_node (spec->dh, spec->m);
                         res->which = DATA1N_root;
                         res->u.root.type = absynName;
                         res->u.root.absyn = absyn;
@@ -942,7 +1046,42 @@ static int execCode (struct lexSpec *spec,
                 tagBegin (spec, d1_stack, d1_level, cmd_str, cmd_len);
                 r = execTok (spec, &s, arg_no, arg_start, arg_end,
                              &cmd_str, &cmd_len);
-            }
+            } 
+           else if (!strcmp (p, "variant"))
+           {
+               int class_len;
+               const char *class_str = NULL;
+               int type_len;
+               const char *type_str = NULL;
+               int value_len;
+               const char *value_str = NULL;
+               r = execTok (spec, &s, arg_no, arg_start, arg_end,
+                            &cmd_str, &cmd_len);
+               if (r < 2)
+                   continue;
+               class_str = cmd_str;
+               class_len = cmd_len;
+               r = execTok (spec, &s, arg_no, arg_start, arg_end,
+                            &cmd_str, &cmd_len);
+               if (r < 2)
+                   continue;
+               type_str = cmd_str;
+               type_len = cmd_len;
+
+               r = execTok (spec, &s, arg_no, arg_start, arg_end,
+                            &cmd_str, &cmd_len);
+               if (r < 2)
+                   continue;
+               value_str = cmd_str;
+               value_len = cmd_len;
+
+                variantBegin (spec, d1_stack, d1_level, class_str, class_len,
+                             type_str, type_len, value_str, value_len);
+               
+               
+               r = execTok (spec, &s, arg_no, arg_start, arg_end,
+                            &cmd_str, &cmd_len);
+           }
         }
         else if (!strcmp (p, "end"))
         {
@@ -950,7 +1089,7 @@ static int execCode (struct lexSpec *spec,
                          &cmd_str, &cmd_len);
             if (r > 1)
             {
-                p = regxStrz (cmd_str, cmd_len);
+                p = regxStrz (cmd_str, cmd_len, ptmp);
                 if (!strcmp (p, "record"))
                 {
                     *d1_level = 0;
@@ -1040,7 +1179,7 @@ static int execCode (struct lexSpec *spec,
                     logf (LOG_WARN, "missing number after -offset");
                     continue;
                 }
-                p = regxStrz (cmd_str, cmd_len);
+                p = regxStrz (cmd_str, cmd_len, ptmp);
                 offset = atoi (p);
                 r = execTok (spec, &s, arg_no, arg_start, arg_end,
                              &cmd_str, &cmd_len);
@@ -1294,7 +1433,6 @@ static data1_node *lexRoot (struct lexSpec *spec, off_t offset)
 data1_node *grs_read_regx (struct grs_read_info *p)
 {
     int res;
-    data1_node *n;
 
 #if REGX_DEBUG
     logf (LOG_DEBUG, "grs_read_regx");
@@ -1304,6 +1442,7 @@ data1_node *grs_read_regx (struct grs_read_info *p)
         if (curLexSpec)
             lexSpecDel (&curLexSpec);
         curLexSpec = lexSpecMk (p->type);
+       curLexSpec->dh = p->dh;
         res = readFileSpec (curLexSpec);
         if (res)
         {
@@ -1322,6 +1461,5 @@ data1_node *grs_read_regx (struct grs_read_info *p)
         curLexSpec->f_win_size = 500000;
     }
     curLexSpec->m = p->mem;
-    n = lexRoot (curLexSpec, p->offset);
-    return n;
+    return lexRoot (curLexSpec, p->offset);
 }