From 5ebe07935fedc4ce6b2a3bb0aa29425674ce7d08 Mon Sep 17 00:00:00 2001 From: ian Date: Tue, 21 Dec 1999 14:16:19 +0000 Subject: [PATCH] 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. --- CHANGELOG | 3 + include/yaz/data1.h | 12 ++- retrieval/Makefile.in | 4 +- retrieval/d1_absyn.c | 20 ++++- retrieval/d1_if.c | 239 +++++++++++++++++++++++++++++++++++++++++++++++++ retrieval/d1_read.c | 12 ++- win/makefile | 12 ++- 7 files changed, 291 insertions(+), 11 deletions(-) create mode 100644 retrieval/d1_if.c diff --git a/CHANGELOG b/CHANGELOG index 0d0669a..736a36f 100644 --- 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 diff --git a/include/yaz/data1.h b/include/yaz/data1.h index ff3c8d0..1831b5b 100644 --- a/include/yaz/data1.h +++ b/include/yaz/data1.h @@ -24,7 +24,12 @@ * 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 diff --git a/retrieval/Makefile.in b/retrieval/Makefile.in index bfa488d..cbec5f3 100644 --- a/retrieval/Makefile.in +++ b/retrieval/Makefile.in @@ -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) diff --git a/retrieval/d1_absyn.c b/retrieval/d1_absyn.c index 38843d2..9488626 100644 --- a/retrieval/d1_absyn.c +++ b/retrieval/d1_absyn.c @@ -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 index 0000000..65c3b13 --- /dev/null +++ b/retrieval/d1_if.c @@ -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 +#include +#include +#include + +#include +#include + +#include + + +/* + * 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; + } +} diff --git a/retrieval/d1_read.c b/retrieval/d1_read.c index e73f946..a5e9266 100644 --- a/retrieval/d1_read.c +++ b/retrieval/d1_read.c @@ -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; diff --git a/win/makefile b/win/makefile index 10db29e..9cbcb20 100644 --- a/win/makefile +++ b/win/makefile @@ -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 -- 1.7.10.4