1 /* $Id: recgrs.c,v 1.72 2003-02-04 12:06:47 pop Exp $
2 Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 #include <sys/types.h>
36 #define GRS_MAX_WORD 512
42 struct grs_handler *next;
46 struct grs_handler *handlers;
49 static int read_grs_type (struct grs_handlers *h,
50 struct grs_read_info *p, const char *type,
53 struct grs_handler *gh = h->handlers;
54 const char *cp = strchr (type, '.');
56 if (cp == NULL || cp == type)
58 cp = strlen(type) + type;
62 strcpy (p->type, cp+1);
63 for (gh = h->handlers; gh; gh = gh->next)
65 if (!memcmp (type, gh->type->type, cp-type))
70 gh->clientData = (*gh->type->init)();
72 p->clientData = gh->clientData;
73 *root = (gh->type->read)(p);
74 gh->clientData = p->clientData;
81 static void grs_add_handler (struct grs_handlers *h, RecTypeGrs t)
83 struct grs_handler *gh = (struct grs_handler *) xmalloc (sizeof(*gh));
84 gh->next = h->handlers;
91 static void *grs_init(RecType recType)
93 struct grs_handlers *h = (struct grs_handlers *) xmalloc (sizeof(*h));
96 grs_add_handler (h, recTypeGrs_sgml);
97 grs_add_handler (h, recTypeGrs_regx);
99 grs_add_handler (h, recTypeGrs_tcl);
101 grs_add_handler (h, recTypeGrs_marc);
103 grs_add_handler (h, recTypeGrs_xml);
106 grs_add_handler (h, recTypeGrs_perl);
111 static void grs_destroy(void *clientData)
113 struct grs_handlers *h = (struct grs_handlers *) clientData;
114 struct grs_handler *gh = h->handlers, *gh_next;
119 (*gh->type->destroy)(gh->clientData);
126 int d1_check_xpath_predicate(data1_node *n, struct xpath_predicate *p) {
134 if (p->which == XPATH_PREDICATE_RELATION) {
135 if (p->u.relation.name[0]) {
136 if (*p->u.relation.name != '@') {
138 " Only attributes (@) are supported in xelm xpath predicates");
139 logf(LOG_WARN, "predicate %s ignored", p->u.relation.name);
142 attname = p->u.relation.name + 1;
144 /* looking for the attribute with a specified name */
145 for (attr = n->u.tag.attributes; attr; attr = attr->next) {
146 logf(LOG_DEBUG," - attribute %s <-> %s", attname, attr->name );
148 if (!strcmp(attr->name, attname)) {
149 if (p->u.relation.op[0]) {
150 if (*p->u.relation.op != '=') {
152 "Only '=' relation is supported (%s)",p->u.relation.op);
153 logf(LOG_WARN, "predicate %s ignored", p->u.relation.name);
156 logf(LOG_DEBUG," - value %s <-> %s",
157 p->u.relation.value, attr->value );
158 if (!strcmp(attr->value, p->u.relation.value)) {
163 /* attribute exists, no value specified */
173 else if (p->which == XPATH_PREDICATE_BOOLEAN) {
174 if (!strcmp(p->u.boolean.op,"and")) {
175 return (d1_check_xpath_predicate(n, p->u.boolean.left)
176 && d1_check_xpath_predicate(n, p->u.boolean.right));
178 else if (!strcmp(p->u.boolean.op,"or")) {
179 return (d1_check_xpath_predicate(n, p->u.boolean.left)
180 || d1_check_xpath_predicate(n, p->u.boolean.right));
182 logf(LOG_WARN, "Unknown boolean relation %s, ignored",p->u.boolean.op);
193 New function, looking for xpath "element" definitions in abs, by
194 tagpath, using a kind of ugly regxp search.The DFA was built while
195 parsing abs, so here we just go trough them and try to match
196 against the given tagpath. The first matching entry is returned.
200 Added support for enhanced xelm. Now [] predicates are considered
201 as well, when selecting indexing rules... (why the hell it's called
208 data1_termlist *xpath_termlist_by_tagpath(char *tagpath, data1_node *n)
210 data1_absyn *abs = n->root->u.root.absyn;
211 data1_xpelement *xpe = abs->xp_elements;
214 struct xpath_location_step *xp;
217 char *pexpr = malloc(strlen(tagpath)+2);
220 sprintf (pexpr, "%s\n", tagpath);
223 struct DFA_state **dfaar = xpe->dfa->states;
224 struct DFA_state *s=dfaar[0];
231 c = *pexpr++; t = s->trans; i = s->tran_no;
232 if (c >= t->ch[0] && c <= t->ch[1]) {
235 if ((s = dfaar[t->to])->rule_no &&
236 (start_line || s->rule_nno)) {
240 for (t=s->trans, i=s->tran_no; --i >= 0; t++) {
241 if ((unsigned) *p >= t->ch[0] && (unsigned) *p <= t->ch[1])
250 /* we have to check the perdicates up to the root node */
253 /* find the first tag up in the node structure */
254 nn = n; while (nn && nn->which != DATA1N_tag) {
258 /* go from inside out in the node structure, while going
259 backwards trough xpath location steps ... */
260 for (i=xpe->xpath_len - 1; i>0; i--) {
262 logf(LOG_DEBUG,"Checking step %d: %s on tag %s",
263 i,xp[i].part,nn->u.tag.tag);
265 if (!d1_check_xpath_predicate(nn, xp[i].predicate)) {
266 logf(LOG_DEBUG," Predicates didn't match");
271 if (nn->which == DATA1N_tag) {
284 logf(LOG_DEBUG,"Got it");
285 return xpe->termlists;
292 1 start element (tag)
294 3 start attr (and attr-exact)
302 Now, if there is a matching xelm described in abs, for the
303 indexed element or the attribute, then the data is handled according
304 to those definitions...
306 modified by pop, 2002-12-13
309 static void index_xpath (data1_node *n, struct recExtractCtrl *p,
310 int level, RecWord *wrd, int use)
313 char tag_path_full[1024];
320 wrd->string = n->u.data.data;
321 wrd->length = n->u.data.len;
322 if (p->flagShowRecords)
324 printf("%*s data=", (level + 1) * 4, "");
325 for (i = 0; i<wrd->length && i < 8; i++)
326 fputc (wrd->string[i], stdout);
334 /* we have to fetch the whole path to the data tag */
335 for (nn = n; nn; nn = nn->parent) {
336 if (nn->which == DATA1N_tag) {
337 size_t tlen = strlen(nn->u.tag.tag);
338 if (tlen + flen > (sizeof(tag_path_full)-2)) return;
339 memcpy (tag_path_full + flen, nn->u.tag.tag, tlen);
341 tag_path_full[flen++] = '/';
343 else if (nn->which == DATA1N_root) break;
346 tag_path_full[flen] = 0;
348 /* If we have a matching termlist... */
349 if ((tl = xpath_termlist_by_tagpath(tag_path_full, n))) {
350 for (; tl; tl = tl->next) {
351 wrd->reg_type = *tl->structure;
352 /* this is the ! case, so structure is for the xpath index */
354 wrd->attrSet = VAL_IDXPATH;
358 /* this is just the old fashioned attribute based index */
360 wrd->attrSet = (int) (tl->att->parent->reference);
361 wrd->attrUse = tl->att->locals->local;
366 /* xpath indexing is done, if there was no termlist given,
367 or no ! attribute... */
369 wrd->attrSet = VAL_IDXPATH;
378 for (nn = n; nn; nn = nn->parent)
380 if (nn->which == DATA1N_tag)
382 size_t tlen = strlen(nn->u.tag.tag);
383 if (tlen + flen > (sizeof(tag_path_full)-2))
385 memcpy (tag_path_full + flen, nn->u.tag.tag, tlen);
387 tag_path_full[flen++] = '/';
389 else if (nn->which == DATA1N_root)
395 wrd->string = tag_path_full;
397 wrd->attrSet = VAL_IDXPATH;
399 if (p->flagShowRecords)
401 printf("%*s tag=", (level + 1) * 4, "");
402 for (i = 0; i<wrd->length && i < 40; i++)
403 fputc (wrd->string[i], stdout);
411 (*p->tokenAdd)(wrd); /* index element pag (AKA tag path) */
414 for (xp = n->u.tag.attributes; xp; xp = xp->next)
417 /* attribute (no value) */
420 wrd->string = xp->name;
421 wrd->length = strlen(xp->name);
427 strlen(xp->name) + strlen(xp->value) < sizeof(comb)-2)
429 /* attribute value exact */
430 strcpy (comb, xp->name);
432 strcat (comb, xp->value);
437 wrd->length = strlen(comb);
443 for (xp = n->u.tag.attributes; xp; xp = xp->next)
445 char attr_tag_path_full[1024];
448 sprintf (attr_tag_path_full, "@%s/%.*s",
449 xp->name, int_len, tag_path_full);
452 wrd->string = attr_tag_path_full;
453 wrd->length = strlen(attr_tag_path_full);
458 /* the same jokes, as with the data nodes ... */
462 wrd->string = xp->value;
463 wrd->length = strlen(xp->value);
466 if ((tl = xpath_termlist_by_tagpath(attr_tag_path_full,
468 for (; tl; tl = tl->next) {
469 wrd->reg_type = *tl->structure;
471 wrd->attrSet = VAL_IDXPATH;
476 wrd->attrSet = (int) (tl->att->parent->reference);
477 wrd->attrUse = tl->att->locals->local;
484 wrd->attrSet = VAL_IDXPATH;
491 wrd->attrSet = VAL_IDXPATH;
494 wrd->string = attr_tag_path_full;
495 wrd->length = strlen(attr_tag_path_full);
503 static void index_termlist (data1_node *par, data1_node *n,
504 struct recExtractCtrl *p, int level, RecWord *wrd)
506 data1_termlist *tlist = 0;
507 data1_datatype dtype = DATA1K_string;
510 * cycle up towards the root until we find a tag with an att..
511 * this has the effect of indexing locally defined tags with
512 * the attribute of their ancestor in the record.
515 while (!par->u.tag.element)
516 if (!par->parent || !(par=get_parent_tag(p->dh, par->parent)))
518 if (!par || !(tlist = par->u.tag.element->termlists))
520 if (par->u.tag.element->tag)
521 dtype = par->u.tag.element->tag->kind;
523 for (; tlist; tlist = tlist->next)
527 /* consider source */
530 if (!strcmp (tlist->source, "data") && n->which == DATA1N_data)
532 wrd->string = n->u.data.data;
533 wrd->length = n->u.data.len;
535 else if (!strcmp (tlist->source, "tag") && n->which == DATA1N_tag)
537 wrd->string = n->u.tag.tag;
538 wrd->length = strlen(n->u.tag.tag);
540 else if (sscanf (tlist->source, "attr(%511[^)])", xattr) == 1 &&
541 n->which == DATA1N_tag)
543 data1_xattr *p = n->u.tag.attributes;
544 while (p && strcmp (p->name, xattr))
548 wrd->string = p->value;
549 wrd->length = strlen(p->value);
554 if (p->flagShowRecords)
557 printf("%*sIdx: [%s]", (level + 1) * 4, "",
559 printf("%s:%s [%d] %s",
560 tlist->att->parent->name,
561 tlist->att->name, tlist->att->value,
564 for (i = 0; i<wrd->length && i < 8; i++)
565 fputc (wrd->string[i], stdout);
569 fputc ('\n', stdout);
573 wrd->reg_type = *tlist->structure;
574 wrd->attrSet = (int) (tlist->att->parent->reference);
575 wrd->attrUse = tlist->att->locals->local;
582 static int dumpkeys(data1_node *n, struct recExtractCtrl *p, int level,
585 for (; n; n = n->next)
587 if (p->flagShowRecords) /* display element description to user */
589 if (n->which == DATA1N_root)
591 printf("%*s", level * 4, "");
592 printf("Record type: '%s'\n", n->u.root.type);
594 else if (n->which == DATA1N_tag)
598 printf("%*s", level * 4, "");
599 if (!(e = n->u.tag.element))
600 printf("Local tag: '%s'\n", n->u.tag.tag);
603 printf("Elm: '%s' ", e->name);
606 data1_tag *t = e->tag;
608 printf("TagNam: '%s' ", t->names->name);
611 printf("%s[%d],", t->tagset->name, t->tagset->type);
614 if (t->which == DATA1T_numeric)
615 printf("%d)", t->value.numeric);
617 printf("'%s')", t->value.string);
624 if (n->which == DATA1N_tag)
626 index_termlist (n, n, p, level, wrd);
627 /* index start tag */
628 assert (n->root->u.root.absyn);
630 if (!n->root->u.root.absyn)
631 index_xpath (n, p, level, wrd, 1);
632 else if (n->root->u.root.absyn->enable_xpath_indexing)
633 index_xpath (n, p, level, wrd, 1);
637 if (dumpkeys(n->child, p, level + 1, wrd) < 0)
641 if (n->which == DATA1N_data)
643 data1_node *par = get_parent_tag(p->dh, n);
645 if (p->flagShowRecords)
647 printf("%*s", level * 4, "");
649 if (n->u.data.len > 256)
650 printf("'%.240s ... %.6s'\n", n->u.data.data,
651 n->u.data.data + n->u.data.len-6);
652 else if (n->u.data.len > 0)
653 printf("'%.*s'\n", n->u.data.len, n->u.data.data);
659 index_termlist (par, n, p, level, wrd);
660 if (!n->root->u.root.absyn)
661 index_xpath (n, p, level, wrd, 1016);
662 else if (n->root->u.root.absyn->enable_xpath_indexing)
663 index_xpath (n, p, level, wrd, 1016);
666 if (n->which == DATA1N_tag)
669 if (!n->root->u.root.absyn)
670 index_xpath (n, p, level, wrd, 2);
671 else if (n->root->u.root.absyn->enable_xpath_indexing)
672 index_xpath (n, p, level, wrd, 2);
675 if (p->flagShowRecords && n->which == DATA1N_root)
677 printf("%*s-------------\n\n", level * 4, "");
683 int grs_extract_tree(struct recExtractCtrl *p, data1_node *n)
686 int oidtmp[OID_SIZE];
689 oe.proto = PROTO_Z3950;
690 oe.oclass = CLASS_SCHEMA;
693 oe.value = n->u.root.absyn->reference;
695 if ((oid_ent_to_oid (&oe, oidtmp)))
696 (*p->schemaAdd)(p, oidtmp);
700 return dumpkeys(n, p, 0, &wrd);
703 static int grs_extract_sub(struct grs_handlers *h, struct recExtractCtrl *p,
707 struct grs_read_info gri;
709 int oidtmp[OID_SIZE];
712 gri.readf = p->readf;
713 gri.seekf = p->seekf;
714 gri.tellf = p->tellf;
717 gri.offset = p->offset;
721 if (read_grs_type (h, &gri, p->subType, &n))
722 return RECCTRL_EXTRACT_ERROR_NO_SUCH_FILTER;
724 return RECCTRL_EXTRACT_EOF;
725 oe.proto = PROTO_Z3950;
726 oe.oclass = CLASS_SCHEMA;
728 if (!n->u.root.absyn)
729 return RECCTRL_EXTRACT_ERROR;
733 oe.value = n->u.root.absyn->reference;
734 if ((oid_ent_to_oid (&oe, oidtmp)))
735 (*p->schemaAdd)(p, oidtmp);
738 /* ensure our data1 tree is UTF-8 */
739 data1_iconv (p->dh, mem, n, "UTF-8", data1_get_encoding(p->dh, n));
742 data1_pr_tree (p->dh, n, stdout);
746 if (dumpkeys(n, p, 0, &wrd) < 0)
748 data1_free_tree(p->dh, n);
749 return RECCTRL_EXTRACT_ERROR_GENERIC;
751 data1_free_tree(p->dh, n);
752 return RECCTRL_EXTRACT_OK;
755 static int grs_extract(void *clientData, struct recExtractCtrl *p)
758 NMEM mem = nmem_create ();
759 struct grs_handlers *h = (struct grs_handlers *) clientData;
761 ret = grs_extract_sub(h, p, mem);
767 * Return: -1: Nothing done. 0: Ok. >0: Bib-1 diagnostic.
769 static int process_comp(data1_handle dh, data1_node *n, Z_RecordComposition *c)
771 data1_esetname *eset;
777 case Z_RecordComp_simple:
778 if (c->u.simple->which != Z_ElementSetNames_generic)
779 return 26; /* only generic form supported. Fix this later */
780 if (!(eset = data1_getesetbyname(dh, n->u.root.absyn,
781 c->u.simple->u.generic)))
783 logf(LOG_LOG, "Unknown esetname '%s'", c->u.simple->u.generic);
784 return 25; /* invalid esetname */
786 logf(LOG_DEBUG, "Esetname '%s' in simple compspec",
787 c->u.simple->u.generic);
790 case Z_RecordComp_complex:
791 if (c->u.complex->generic)
793 /* insert check for schema */
794 if ((p = c->u.complex->generic->elementSpec))
798 case Z_ElementSpec_elementSetName:
800 data1_getesetbyname(dh, n->u.root.absyn,
801 p->u.elementSetName)))
803 logf(LOG_LOG, "Unknown esetname '%s'",
804 p->u.elementSetName);
805 return 25; /* invalid esetname */
807 logf(LOG_DEBUG, "Esetname '%s' in complex compspec",
808 p->u.elementSetName);
811 case Z_ElementSpec_externalSpec:
812 if (p->u.externalSpec->which == Z_External_espec1)
814 logf(LOG_DEBUG, "Got Espec-1");
815 espec = p->u.externalSpec-> u.espec1;
819 logf(LOG_LOG, "Unknown external espec.");
820 return 25; /* bad. what is proper diagnostic? */
831 logf (LOG_DEBUG, "Element: Espec-1 match");
832 return data1_doespec1(dh, n, espec);
836 logf (LOG_DEBUG, "Element: all match");
841 /* Add Zebra info in separate namespace ...
844 <metadata xmlns="http://www.indexdata.dk/zebra/">
846 <localnumber>447</localnumber>
847 <filename>records/genera.xml</filename>
852 static void zebra_xml_metadata (struct recRetrieveCtrl *p, data1_node *top,
855 const char *idzebra_ns[3];
856 const char *i2 = "\n ";
857 const char *i4 = "\n ";
860 idzebra_ns[0] = "xmlns";
861 idzebra_ns[1] = "http://www.indexdata.dk/zebra/";
864 data1_mk_text (p->dh, mem, i2, top);
866 n = data1_mk_tag (p->dh, mem, "idzebra", idzebra_ns, top);
868 data1_mk_text (p->dh, mem, "\n", top);
870 data1_mk_text (p->dh, mem, i4, n);
872 data1_mk_tag_data_int (p->dh, n, "size", p->recordSize, mem);
876 data1_mk_text (p->dh, mem, i4, n);
877 data1_mk_tag_data_int (p->dh, n, "score", p->score, mem);
879 data1_mk_text (p->dh, mem, i4, n);
880 data1_mk_tag_data_int (p->dh, n, "localnumber", p->localno, mem);
883 data1_mk_text (p->dh, mem, i4, n);
884 data1_mk_tag_data_text(p->dh, n, "filename", p->fname, mem);
886 data1_mk_text (p->dh, mem, i2, n);
889 static int grs_retrieve(void *clientData, struct recRetrieveCtrl *p)
891 data1_node *node = 0, *onode = 0, *top;
894 int res, selected = 0;
896 struct grs_read_info gri;
898 struct grs_handlers *h = (struct grs_handlers *) clientData;
899 int requested_schema = VAL_NONE;
900 data1_marctab *marctab;
904 gri.readf = p->readf;
905 gri.seekf = p->seekf;
906 gri.tellf = p->tellf;
913 logf (LOG_DEBUG, "grs_retrieve");
914 if (read_grs_type (h, &gri, p->subType, &node))
926 /* ensure our data1 tree is UTF-8 */
927 data1_iconv (p->dh, mem, node, "UTF-8", data1_get_encoding(p->dh, node));
930 data1_pr_tree (p->dh, node, stdout);
932 top = data1_get_root_tag (p->dh, node);
934 logf (LOG_DEBUG, "grs_retrieve: size");
935 tagname = data1_systag_lookup(node->u.root.absyn, "size", "size");
937 (dnew = data1_mk_tag_data_wd(p->dh, top, tagname, mem)))
939 dnew->u.data.what = DATA1I_text;
940 dnew->u.data.data = dnew->lbuf;
941 sprintf(dnew->u.data.data, "%d", p->recordSize);
942 dnew->u.data.len = strlen(dnew->u.data.data);
945 tagname = data1_systag_lookup(node->u.root.absyn, "rank", "rank");
946 if (tagname && p->score >= 0 &&
947 (dnew = data1_mk_tag_data_wd(p->dh, top, tagname, mem)))
949 logf (LOG_DEBUG, "grs_retrieve: %s", tagname);
950 dnew->u.data.what = DATA1I_num;
951 dnew->u.data.data = dnew->lbuf;
952 sprintf(dnew->u.data.data, "%d", p->score);
953 dnew->u.data.len = strlen(dnew->u.data.data);
956 tagname = data1_systag_lookup(node->u.root.absyn, "sysno",
957 "localControlNumber");
958 if (tagname && p->localno > 0 &&
959 (dnew = data1_mk_tag_data_wd(p->dh, top, tagname, mem)))
961 logf (LOG_DEBUG, "grs_retrieve: %s", tagname);
962 dnew->u.data.what = DATA1I_text;
963 dnew->u.data.data = dnew->lbuf;
965 sprintf(dnew->u.data.data, "%d", p->localno);
966 dnew->u.data.len = strlen(dnew->u.data.data);
969 data1_pr_tree (p->dh, node, stdout);
971 if (p->comp && p->comp->which == Z_RecordComp_complex &&
972 p->comp->u.complex->generic &&
973 p->comp->u.complex->generic->schema)
975 oident *oe = oid_getentbyoid (p->comp->u.complex->generic->schema);
977 requested_schema = oe->value;
980 /* If schema has been specified, map if possible, then check that
981 * we got the right one
983 if (requested_schema != VAL_NONE)
985 logf (LOG_DEBUG, "grs_retrieve: schema mapping");
986 for (map = node->u.root.absyn->maptabs; map; map = map->next)
988 if (map->target_absyn_ref == requested_schema)
991 if (!(node = data1_map_record(p->dh, onode, map, mem)))
1000 if (node->u.root.absyn &&
1001 requested_schema != node->u.root.absyn->reference)
1003 p->diagnostic = 238;
1009 * Does the requested format match a known syntax-mapping? (this reflects
1010 * the overlap of schema and formatting which is inherent in the MARC
1013 yaz_log (LOG_DEBUG, "grs_retrieve: syntax mapping");
1014 if (node->u.root.absyn)
1015 for (map = node->u.root.absyn->maptabs; map; map = map->next)
1017 if (map->target_absyn_ref == p->input_format)
1020 if (!(node = data1_map_record(p->dh, onode, map, mem)))
1029 yaz_log (LOG_DEBUG, "grs_retrieve: schemaIdentifier");
1030 if (node->u.root.absyn &&
1031 node->u.root.absyn->reference != VAL_NONE &&
1032 p->input_format == VAL_GRS1)
1036 int oidtmp[OID_SIZE];
1038 oe.proto = PROTO_Z3950;
1039 oe.oclass = CLASS_SCHEMA;
1040 oe.value = node->u.root.absyn->reference;
1042 if ((oid = oid_ent_to_oid (&oe, oidtmp)))
1045 data1_handle dh = p->dh;
1049 for (ii = oid; *ii >= 0; ii++)
1053 sprintf(p, "%d", *ii);
1056 if ((dnew = data1_mk_tag_data_wd(dh, top,
1057 "schemaIdentifier", mem)))
1059 dnew->u.data.what = DATA1I_oid;
1060 dnew->u.data.data = (char *) nmem_malloc(mem, p - tmp);
1061 memcpy(dnew->u.data.data, tmp, p - tmp);
1062 dnew->u.data.len = p - tmp;
1067 logf (LOG_DEBUG, "grs_retrieve: element spec");
1068 if (p->comp && (res = process_comp(p->dh, node, p->comp)) > 0)
1070 p->diagnostic = res;
1072 data1_free_tree(p->dh, onode);
1073 data1_free_tree(p->dh, node);
1077 else if (p->comp && !res)
1081 data1_pr_tree (p->dh, node, stdout);
1083 logf (LOG_DEBUG, "grs_retrieve: transfer syntax mapping");
1084 switch (p->output_format = (p->input_format != VAL_NONE ?
1085 p->input_format : VAL_SUTRS))
1088 zebra_xml_metadata (p, top, mem);
1091 data1_pr_tree (p->dh, node, stdout);
1095 data1_iconv (p->dh, mem, node, p->encoding, "UTF-8");
1097 if (!(p->rec_buf = data1_nodetoidsgml(p->dh, node, selected,
1099 p->diagnostic = 238;
1102 char *new_buf = (char*) odr_malloc (p->odr, p->rec_len);
1103 memcpy (new_buf, p->rec_buf, p->rec_len);
1104 p->rec_buf = new_buf;
1109 if (!(p->rec_buf = data1_nodetogr(p->dh, node, selected,
1111 p->diagnostic = 238; /* not available in requested syntax */
1113 p->rec_len = (size_t) (-1);
1116 if (!(p->rec_buf = data1_nodetoexplain(p->dh, node, selected,
1118 p->diagnostic = 238;
1120 p->rec_len = (size_t) (-1);
1123 if (!(p->rec_buf = data1_nodetosummary(p->dh, node, selected,
1125 p->diagnostic = 238;
1127 p->rec_len = (size_t) (-1);
1131 data1_iconv (p->dh, mem, node, p->encoding, "UTF-8");
1132 if (!(p->rec_buf = data1_nodetobuf(p->dh, node, selected,
1134 p->diagnostic = 238;
1137 char *new_buf = (char*) odr_malloc (p->odr, p->rec_len);
1138 memcpy (new_buf, p->rec_buf, p->rec_len);
1139 p->rec_buf = new_buf;
1143 if (!(p->rec_buf = data1_nodetosoif(p->dh, node, selected,
1145 p->diagnostic = 238;
1148 char *new_buf = (char*) odr_malloc (p->odr, p->rec_len);
1149 memcpy (new_buf, p->rec_buf, p->rec_len);
1150 p->rec_buf = new_buf;
1154 if (!node->u.root.absyn)
1156 p->diagnostic = 238;
1159 for (marctab = node->u.root.absyn->marc; marctab;
1160 marctab = marctab->next)
1161 if (marctab->reference == p->input_format)
1165 p->diagnostic = 238;
1169 data1_iconv (p->dh, mem, node, p->encoding, "UTF-8");
1170 if (!(p->rec_buf = data1_nodetomarc(p->dh, marctab, node,
1171 selected, &p->rec_len)))
1172 p->diagnostic = 238;
1175 char *new_buf = (char*) odr_malloc (p->odr, p->rec_len);
1176 memcpy (new_buf, p->rec_buf, p->rec_len);
1177 p->rec_buf = new_buf;
1181 data1_free_tree(p->dh, node);
1183 data1_free_tree(p->dh, onode);
1188 static struct recType grs_type =
1197 RecType recTypeGrs = &grs_type;