Changed retrieval module to allow data1 trees with no associated absyn.
authorian <ian>
Tue, 21 Dec 1999 14:16:19 +0000 (14:16 +0000)
committerian <ian>
Tue, 21 Dec 1999 14:16:19 +0000 (14:16 +0000)
Also added a simple interface for extracting values from data1 trees using
a string based tagpath.

CHANGELOG
include/yaz/data1.h
retrieval/Makefile.in
retrieval/d1_absyn.c
retrieval/d1_if.c [new file with mode: 0644]
retrieval/d1_read.c
win/makefile

index 0d0669a..736a36f 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,8 @@
 Possible compatibility problems with earlier versions marked with '*'.
 
+Changed retrieval module so that we can load records with no abstract
+syntax defined. Tagpaths in these records are fully composed of string tags.
+
 Implemented ISO ILL protocol. Refer to stuff in sub directory ill.
 
 --- 1.5 1999/12/10
index ff3c8d0..1831b5b 100644 (file)
  * OF THIS SOFTWARE.
  *
  * $Log: data1.h,v $
- * Revision 1.1  1999-11-30 13:47:11  adam
+ * Revision 1.2  1999-12-21 14:16:19  ian
+ * Changed retrieval module to allow data1 trees with no associated absyn.
+ * Also added a simple interface for extracting values from data1 trees using
+ * a string based tagpath.
+ *
+ * Revision 1.1  1999/11/30 13:47:11  adam
  * Improved installation. Moved header files to include/yaz.
  *
  * Revision 1.42  1999/10/21 12:06:28  adam
@@ -561,6 +566,11 @@ YAZ_EXPORT data1_node
 *data1_add_insert_taggeddata(data1_handle dh, data1_node *root,
                              data1_node *at, const char *tagname, NMEM m,
                              int first_flag, int local_allowed);
+
+YAZ_EXPORT char *data1_getNodeValue(data1_node* node, char* pTagPath);
+
+YAZ_EXPORT data1_node *data1_LookupNode(data1_node* node, char* pTagPath);
+
 #ifdef __cplusplus
 }
 #endif
index bfa488d..cbec5f3 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.3 1999-06-09 09:43:31 adam Exp $
+# $Id: Makefile.in,v 1.4 1999-12-21 14:16:19 ian Exp $
 
 SHELL=/bin/sh
 
@@ -14,7 +14,7 @@ LIB=../lib/libret.a
 PO = d1_handle.o d1_read.o d1_attset.o d1_tagset.o d1_absyn.o d1_grs.o \
        d1_sutrs.o d1_varset.o d1_espec.o \
        d1_doespec.o d1_map.o d1_marc.o d1_write.o d1_expout.o d1_sumout.o \
-       d1_soif.o d1_prtree.o
+       d1_soif.o d1_prtree.o d1_if.o
 
 all: $(LIB)
 
index 38843d2..9488626 100644 (file)
@@ -4,7 +4,12 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_absyn.c,v $
- * Revision 1.26  1999-11-30 13:47:12  adam
+ * Revision 1.27  1999-12-21 14:16:19  ian
+ * Changed retrieval module to allow data1 trees with no associated absyn.
+ * Also added a simple interface for extracting values from data1 trees using
+ * a string based tagpath.
+ *
+ * Revision 1.26  1999/11/30 13:47:12  adam
  * Improved installation. Moved header files to include/yaz.
  *
  * Revision 1.25  1999/10/21 12:06:29  adam
@@ -261,6 +266,10 @@ data1_element *data1_getelementbytagname (data1_handle dh, data1_absyn *abs,
 {
     data1_element *r;
 
+    /* It's now possible to have a data1 tree with no abstract syntax */
+    if ( !abs )
+        return 0;
+
     if (!parent)
         r = abs->main_elements;
     else
@@ -281,6 +290,11 @@ data1_element *data1_getelementbyname (data1_handle dh, data1_absyn *absyn,
                                       const char *name)
 {
     data1_element *r;
+
+    /* It's now possible to have a data1 tree with no abstract syntax */
+    if ( !absyn )
+        return 0;
+    
     assert (absyn->main_elements);
     for (r = absyn->main_elements; r; r = r->next)
        if (!data1_matchstr(r->name, name))
@@ -291,6 +305,10 @@ data1_element *data1_getelementbyname (data1_handle dh, data1_absyn *absyn,
 
 void fix_element_ref (data1_handle dh, data1_absyn *absyn, data1_element *e)
 {
+    /* It's now possible to have a data1 tree with no abstract syntax */
+    if ( !absyn )
+        return;
+
     for (; e; e = e->next)
     {
        if (!e->sub_name)
diff --git a/retrieval/d1_if.c b/retrieval/d1_if.c
new file mode 100644 (file)
index 0000000..65c3b13
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 1995-1999, Index Data.
+ * See the file LICENSE for details.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * d1_if.c : A simple interface for extracting strings from data1_node tree structures
+ *
+ * $Log: d1_if.c,v $
+ * Revision 1.1  1999-12-21 14:16:19  ian
+ * Changed retrieval module to allow data1 trees with no associated absyn.
+ * Also added a simple interface for extracting values from data1 trees using
+ * a string based tagpath.
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <yaz/data1.h>
+#include <yaz/log.h>
+
+#include <string.h>
+
+
+/*
+ * Search for a token in the supplied string up to the supplied list of stop characters or EOL
+ * At the end, return the character causing the break and fill pTokenBuffer with the token string so far
+ * After the scan, *pPosInBuffer will point to the next character after the one causing the break and
+ *                 pTokenBuffer will contain the actual token
+ */
+char data1_ScanNextToken(char* pBuffer,
+                         char** pPosInBuffer,
+                         char* pBreakChars,
+                         char* pWhitespaceChars,
+                         char* pTokenBuffer)
+{
+    char* pBuff = pTokenBuffer;
+    *pBuff = '\0';
+
+    while ( **pPosInBuffer )
+    {
+        if ( strchr(pBreakChars,**pPosInBuffer) != NULL )
+        {
+            /* Current character is a break character */
+            *pBuff++ = '\0';
+            return *((*pPosInBuffer)++);
+        }
+        else
+        {
+            if ( strchr(pWhitespaceChars, **pPosInBuffer) != NULL )
+                *pPosInBuffer++;
+            else
+                *pBuff++ = *((*pPosInBuffer)++);
+        }
+    }
+
+    *pBuff++ = *((*pPosInBuffer)++);
+    return(**pPosInBuffer);
+}
+
+/* 
+ * Attempt to find a string value given the specified tagpath
+ * 
+ * Need to make this safe by passing in a buffer..... 
+ *
+ */
+char *data1_getNodeValue(data1_node* node, char* pTagPath)
+{
+    data1_node* n = NULL;
+
+    n = data1_LookupNode(node, pTagPath );
+
+    if ( n )
+    {
+        /* n should be a tag node with some data under it.... */
+        if ( n->child )
+        {
+            if ( n->child->which == DATA1N_data )
+            {
+                return n->child->u.data.data;
+            }
+            else
+            {
+                yaz_log(LOG_WARN,"Attempting to lookup data for tagpath: Child node is not a data node");
+            }
+        }
+        else
+        {
+            yaz_log(LOG_WARN,"Found a node matching the tagpath, but it has no child data nodes");
+        }
+    }
+    else
+    {
+        yaz_log(LOG_WARN,"Unable to lookup a node on the specified tag path");
+    }
+
+    return "";
+}
+
+
+/* 
+ * data1_LookupNode : Try and find a node as specified by a tagpath
+ */
+data1_node *data1_LookupNode(data1_node* node, char* pTagPath)
+{
+    /* Node matching the pattern in the tagpath */
+    data1_node* matched_node = NULL;
+
+    /* Current Child node as we search for nodes matching the pattern in the tagpath */
+    data1_node* current_child = node->child;
+
+    /* Max length of a tag */
+    int iMaxTagSize=50;
+
+    /* Current position in string */
+    char* pCurrCharInPath = pTagPath;
+
+    /* Work buffer */
+    char Buffer[iMaxTagSize];
+
+    /* The tag type of this node */
+    int iTagType = 0;
+
+    /* for non string tags, the tag value */
+    int iTagValue = 0;
+
+    /* for string tags, the tag value */
+    char StringTagVal[iMaxTagSize];
+
+    /* Which occurence of that tag under this node */
+    int iOccurences=0;
+
+    /* Character causing a break */
+    char sepchr = '\0';
+    Buffer[0] = '\0';
+    StringTagVal[0] = '\0';
+
+    sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ",[(."," ", Buffer);
+
+    if ( sepchr == '[' )
+    {
+        /* Next component in node value is [ TagType, TagVal, TagOccurence ] */
+        sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ","," ", Buffer);
+        iTagType = atoi(Buffer);
+
+        /* Occurence is optional... */
+        sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ",]."," ", Buffer);
+
+        if ( iTagType == 3 )
+            strcpy(StringTagVal,Buffer);
+        else
+            iTagValue = atoi(Buffer);
+
+        /* If sepchar was a ',' there should be an instance */
+        if ( sepchr == ',' )
+        {
+            sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "]."," ", Buffer);
+            iOccurences = atoi(Buffer);
+        }
+
+        if ( sepchr == ']' )
+        {
+            /* See if we can scan the . for the next component or the end of the line... */
+            sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "."," ", Buffer);
+        }
+        else
+        {
+            yaz_log(LOG_FATAL,"Node does not end with a ]");
+            /* Fatal Error */
+            return(NULL);
+        }
+    }
+    else
+    {
+        /* We have a TagName so Read up to ( or . or EOL */
+        iTagType = 3;
+        strcpy(StringTagVal,Buffer);
+
+        if ( sepchr == '(' )
+        {
+            /* Read the occurence */
+            sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ")"," ", Buffer);
+            iOccurences = atoi(Buffer);
+
+            /* See if we can find the . at the end of this clause */
+            sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "."," ", Buffer);
+        }
+        
+    }
+
+    yaz_log(LOG_DEBUG,"search node for child like [%d,%d,%s,%d]",iTagType,iTagValue,StringTagVal,iOccurences);
+    
+
+    /* OK.. We have extracted tagtype, Value and Occurence, see if we can find a node */
+    /* Under the current parent matching that description                             */
+
+    while ( ( current_child ) && ( matched_node == NULL ) )
+    {
+        if ( current_child->which == DATA1N_tag )
+        {
+            if ( iTagType == 3 )
+            {
+                if ( ( current_child->u.tag.element == NULL ) &&
+                     ( strcmp(current_child->u.tag.tag, StringTagVal) == 0 ) )
+                {
+                    if ( iOccurences )
+                    {
+                        // Everything matched, but not yet found the right occurence of the given tag
+                        iOccurences--;
+                    }
+                    else
+                    {
+                        /* We have matched a string tag... Is there more to process? */
+                        matched_node = current_child;
+                    }
+                }
+            }
+            else /* Attempt to match real element */
+            {
+                yaz_log(LOG_WARN,"Non string tag matching not yet implemented");
+            }
+        }
+        current_child = current_child->next;
+    }
+
+
+    /* If there is more... Continue */
+    if ( ( sepchr == '.' ) && ( matched_node ) )
+    {
+        return data1_LookupNode(matched_node, pCurrCharInPath);
+    }
+    else
+    {
+        return matched_node;
+    }
+}
index e73f946..a5e9266 100644 (file)
@@ -4,7 +4,12 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_read.c,v $
- * Revision 1.30  1999-11-30 13:47:12  adam
+ * Revision 1.31  1999-12-21 14:16:20  ian
+ * Changed retrieval module to allow data1 trees with no associated absyn.
+ * Also added a simple interface for extracting values from data1 trees using
+ * a string based tagpath.
+ *
+ * Revision 1.30  1999/11/30 13:47:12  adam
  * Improved installation. Moved header files to include/yaz.
  *
  * Revision 1.29  1999/10/21 12:06:29  adam
@@ -371,9 +376,8 @@ data1_node *data1_read_nodex (data1_handle dh, NMEM m,
            {
                if (!(absyn = data1_get_absyn (dh, tag)))
                {
-                   yaz_log(LOG_WARN, "Unable to acquire abstract syntax "
-                           "for '%s'", tag);
-                   return 0;
+                   yaz_log(LOG_WARN, "Unable to acquire abstract syntax " "for '%s'", tag); 
+                    /* It's now OK for a record not to have an absyn */
                }
                res = data1_mk_node (dh, m);
                res->which = DATA1N_root;
index 10db29e..9cbcb20 100644 (file)
@@ -1,5 +1,5 @@
 # Makefile.mak - makefile for MS NMAKE 
-# $Id: makefile,v 1.10 1999-12-08 13:10:48 adam Exp $
+# $Id: makefile,v 1.11 1999-12-21 14:16:20 ian Exp $
 #
 # Programmed by
 #  HL: Heikki Levanto, Index Data
@@ -286,7 +286,8 @@ YAZ_RET_OBJS= \
    $(OBJDIR)\d1_sutrs.obj\
    $(OBJDIR)\d1_tagset.obj\
    $(OBJDIR)\d1_varset.obj\
-   $(OBJDIR)\d1_write.obj
+   $(OBJDIR)\d1_write.obj\
+   $(OBJDIR)\d1_if.obj
 
 Z3950_OBJS= \
    $(OBJDIR)\z-date.obj\
@@ -611,7 +612,12 @@ $(PROTOH): $(GENERATED_C_FILES) $(GENERATED_H_FILES)
 ###########################################################
 #
 # $Log: makefile,v $
-# Revision 1.10  1999-12-08 13:10:48  adam
+# Revision 1.11  1999-12-21 14:16:20  ian
+# Changed retrieval module to allow data1 trees with no associated absyn.
+# Also added a simple interface for extracting values from data1 trees using
+# a string based tagpath.
+#
+# Revision 1.10  1999/12/08 13:10:48  adam
 # New version.
 #
 # Revision 1.9  1999/11/30 13:47:12  adam