1 /* $Id: recgrs.c,v 1.75 2003-03-08 14:27:58 pop Exp $
2 Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003
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 = xmalloc(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) {
286 logf(LOG_DEBUG,"Got it");
287 return xpe->termlists;
294 1 start element (tag)
296 3 start attr (and attr-exact)
304 Now, if there is a matching xelm described in abs, for the
305 indexed element or the attribute, then the data is handled according
306 to those definitions...
308 modified by pop, 2002-12-13
311 static void index_xpath (data1_node *n, struct recExtractCtrl *p,
312 int level, RecWord *wrd, int use)
315 char tag_path_full[1024];
322 wrd->string = n->u.data.data;
323 wrd->length = n->u.data.len;
324 if (p->flagShowRecords)
326 printf("%*s data=", (level + 1) * 4, "");
327 for (i = 0; i<wrd->length && i < 8; i++)
328 fputc (wrd->string[i], stdout);
336 /* we have to fetch the whole path to the data tag */
337 for (nn = n; nn; nn = nn->parent) {
338 if (nn->which == DATA1N_tag) {
339 size_t tlen = strlen(nn->u.tag.tag);
340 if (tlen + flen > (sizeof(tag_path_full)-2)) return;
341 memcpy (tag_path_full + flen, nn->u.tag.tag, tlen);
343 tag_path_full[flen++] = '/';
345 else if (nn->which == DATA1N_root) break;
348 tag_path_full[flen] = 0;
350 /* If we have a matching termlist... */
351 if ((tl = xpath_termlist_by_tagpath(tag_path_full, n))) {
352 for (; tl; tl = tl->next) {
353 wrd->reg_type = *tl->structure;
354 /* this is the ! case, so structure is for the xpath index */
356 wrd->attrSet = VAL_IDXPATH;
360 /* this is just the old fashioned attribute based index */
362 wrd->attrSet = (int) (tl->att->parent->reference);
363 wrd->attrUse = tl->att->locals->local;
368 /* xpath indexing is done, if there was no termlist given,
369 or no ! attribute... */
371 wrd->attrSet = VAL_IDXPATH;
380 for (nn = n; nn; nn = nn->parent)
382 if (nn->which == DATA1N_tag)
384 size_t tlen = strlen(nn->u.tag.tag);
385 if (tlen + flen > (sizeof(tag_path_full)-2))
387 memcpy (tag_path_full + flen, nn->u.tag.tag, tlen);
389 tag_path_full[flen++] = '/';
391 else if (nn->which == DATA1N_root)
397 wrd->string = tag_path_full;
399 wrd->attrSet = VAL_IDXPATH;
401 if (p->flagShowRecords)
403 printf("%*s tag=", (level + 1) * 4, "");
404 for (i = 0; i<wrd->length && i < 40; i++)
405 fputc (wrd->string[i], stdout);
413 (*p->tokenAdd)(wrd); /* index element pag (AKA tag path) */
416 for (xp = n->u.tag.attributes; xp; xp = xp->next)
419 /* attribute (no value) */
422 wrd->string = xp->name;
423 wrd->length = strlen(xp->name);
429 strlen(xp->name) + strlen(xp->value) < sizeof(comb)-2)
431 /* attribute value exact */
432 strcpy (comb, xp->name);
434 strcat (comb, xp->value);
439 wrd->length = strlen(comb);
445 for (xp = n->u.tag.attributes; xp; xp = xp->next)
447 char attr_tag_path_full[1024];
450 sprintf (attr_tag_path_full, "@%s/%.*s",
451 xp->name, int_len, tag_path_full);
454 wrd->string = attr_tag_path_full;
455 wrd->length = strlen(attr_tag_path_full);
460 /* the same jokes, as with the data nodes ... */
464 wrd->string = xp->value;
465 wrd->length = strlen(xp->value);
468 if ((tl = xpath_termlist_by_tagpath(attr_tag_path_full,
470 for (; tl; tl = tl->next) {
471 wrd->reg_type = *tl->structure;
473 wrd->attrSet = VAL_IDXPATH;
478 wrd->attrSet = (int) (tl->att->parent->reference);
479 wrd->attrUse = tl->att->locals->local;
486 wrd->attrSet = VAL_IDXPATH;
493 wrd->attrSet = VAL_IDXPATH;
496 wrd->string = attr_tag_path_full;
497 wrd->length = strlen(attr_tag_path_full);
505 static void index_termlist (data1_node *par, data1_node *n,
506 struct recExtractCtrl *p, int level, RecWord *wrd)
508 data1_termlist *tlist = 0;
509 data1_datatype dtype = DATA1K_string;
512 * cycle up towards the root until we find a tag with an att..
513 * this has the effect of indexing locally defined tags with
514 * the attribute of their ancestor in the record.
517 while (!par->u.tag.element)
518 if (!par->parent || !(par=get_parent_tag(p->dh, par->parent)))
520 if (!par || !(tlist = par->u.tag.element->termlists))
522 if (par->u.tag.element->tag)
523 dtype = par->u.tag.element->tag->kind;
525 for (; tlist; tlist = tlist->next)
529 /* consider source */
532 if (!strcmp (tlist->source, "data") && n->which == DATA1N_data)
534 wrd->string = n->u.data.data;
535 wrd->length = n->u.data.len;
537 else if (!strcmp (tlist->source, "tag") && n->which == DATA1N_tag)
539 wrd->string = n->u.tag.tag;
540 wrd->length = strlen(n->u.tag.tag);
542 else if (sscanf (tlist->source, "attr(%511[^)])", xattr) == 1 &&
543 n->which == DATA1N_tag)
545 data1_xattr *p = n->u.tag.attributes;
546 while (p && strcmp (p->name, xattr))
550 wrd->string = p->value;
551 wrd->length = strlen(p->value);
556 if (p->flagShowRecords)
559 printf("%*sIdx: [%s]", (level + 1) * 4, "",
561 printf("%s:%s [%d] %s",
562 tlist->att->parent->name,
563 tlist->att->name, tlist->att->value,
566 for (i = 0; i<wrd->length && i < 8; i++)
567 fputc (wrd->string[i], stdout);
571 fputc ('\n', stdout);
575 wrd->reg_type = *tlist->structure;
576 wrd->attrSet = (int) (tlist->att->parent->reference);
577 wrd->attrUse = tlist->att->locals->local;
584 static int dumpkeys(data1_node *n, struct recExtractCtrl *p, int level,
587 for (; n; n = n->next)
589 if (p->flagShowRecords) /* display element description to user */
591 if (n->which == DATA1N_root)
593 printf("%*s", level * 4, "");
594 printf("Record type: '%s'\n", n->u.root.type);
596 else if (n->which == DATA1N_tag)
600 printf("%*s", level * 4, "");
601 if (!(e = n->u.tag.element))
602 printf("Local tag: '%s'\n", n->u.tag.tag);
605 printf("Elm: '%s' ", e->name);
608 data1_tag *t = e->tag;
610 printf("TagNam: '%s' ", t->names->name);
613 printf("%s[%d],", t->tagset->name, t->tagset->type);
616 if (t->which == DATA1T_numeric)
617 printf("%d)", t->value.numeric);
619 printf("'%s')", t->value.string);
626 if (n->which == DATA1N_tag)
628 index_termlist (n, n, p, level, wrd);
629 /* index start tag */
630 assert (n->root->u.root.absyn);
632 if (!n->root->u.root.absyn)
633 index_xpath (n, p, level, wrd, 1);
634 else if (n->root->u.root.absyn->enable_xpath_indexing)
635 index_xpath (n, p, level, wrd, 1);
639 if (dumpkeys(n->child, p, level + 1, wrd) < 0)
643 if (n->which == DATA1N_data)
645 data1_node *par = get_parent_tag(p->dh, n);
647 if (p->flagShowRecords)
649 printf("%*s", level * 4, "");
651 if (n->u.data.len > 256)
652 printf("'%.240s ... %.6s'\n", n->u.data.data,
653 n->u.data.data + n->u.data.len-6);
654 else if (n->u.data.len > 0)
655 printf("'%.*s'\n", n->u.data.len, n->u.data.data);
661 index_termlist (par, n, p, level, wrd);
662 if (!n->root->u.root.absyn)
663 index_xpath (n, p, level, wrd, 1016);
664 else if (n->root->u.root.absyn->enable_xpath_indexing)
665 index_xpath (n, p, level, wrd, 1016);
668 if (n->which == DATA1N_tag)
671 if (!n->root->u.root.absyn)
672 index_xpath (n, p, level, wrd, 2);
673 else if (n->root->u.root.absyn->enable_xpath_indexing)
674 index_xpath (n, p, level, wrd, 2);
677 if (p->flagShowRecords && n->which == DATA1N_root)
679 printf("%*s-------------\n\n", level * 4, "");
685 int grs_extract_tree(struct recExtractCtrl *p, data1_node *n)
688 int oidtmp[OID_SIZE];
691 oe.proto = PROTO_Z3950;
692 oe.oclass = CLASS_SCHEMA;
695 oe.value = n->u.root.absyn->reference;
697 if ((oid_ent_to_oid (&oe, oidtmp)))
698 (*p->schemaAdd)(p, oidtmp);
702 return dumpkeys(n, p, 0, &wrd);
705 static int grs_extract_sub(struct grs_handlers *h, struct recExtractCtrl *p,
709 struct grs_read_info gri;
711 int oidtmp[OID_SIZE];
714 gri.readf = p->readf;
715 gri.seekf = p->seekf;
716 gri.tellf = p->tellf;
719 gri.offset = p->offset;
723 if (read_grs_type (h, &gri, p->subType, &n))
724 return RECCTRL_EXTRACT_ERROR_NO_SUCH_FILTER;
726 return RECCTRL_EXTRACT_EOF;
727 oe.proto = PROTO_Z3950;
728 oe.oclass = CLASS_SCHEMA;
730 if (!n->u.root.absyn)
731 return RECCTRL_EXTRACT_ERROR;
735 oe.value = n->u.root.absyn->reference;
736 if ((oid_ent_to_oid (&oe, oidtmp)))
737 (*p->schemaAdd)(p, oidtmp);
740 /* ensure our data1 tree is UTF-8 */
741 data1_iconv (p->dh, mem, n, "UTF-8", data1_get_encoding(p->dh, n));
744 data1_pr_tree (p->dh, n, stdout);
748 if (dumpkeys(n, p, 0, &wrd) < 0)
750 data1_free_tree(p->dh, n);
751 return RECCTRL_EXTRACT_ERROR_GENERIC;
753 data1_free_tree(p->dh, n);
754 return RECCTRL_EXTRACT_OK;
757 static int grs_extract(void *clientData, struct recExtractCtrl *p)
760 NMEM mem = nmem_create ();
761 struct grs_handlers *h = (struct grs_handlers *) clientData;
763 ret = grs_extract_sub(h, p, mem);
769 * Return: -1: Nothing done. 0: Ok. >0: Bib-1 diagnostic.
771 static int process_comp(data1_handle dh, data1_node *n, Z_RecordComposition *c)
773 data1_esetname *eset;
779 case Z_RecordComp_simple:
780 if (c->u.simple->which != Z_ElementSetNames_generic)
781 return 26; /* only generic form supported. Fix this later */
782 if (!(eset = data1_getesetbyname(dh, n->u.root.absyn,
783 c->u.simple->u.generic)))
785 logf(LOG_LOG, "Unknown esetname '%s'", c->u.simple->u.generic);
786 return 25; /* invalid esetname */
788 logf(LOG_DEBUG, "Esetname '%s' in simple compspec",
789 c->u.simple->u.generic);
792 case Z_RecordComp_complex:
793 if (c->u.complex->generic)
795 /* insert check for schema */
796 if ((p = c->u.complex->generic->elementSpec))
800 case Z_ElementSpec_elementSetName:
802 data1_getesetbyname(dh, n->u.root.absyn,
803 p->u.elementSetName)))
805 logf(LOG_LOG, "Unknown esetname '%s'",
806 p->u.elementSetName);
807 return 25; /* invalid esetname */
809 logf(LOG_DEBUG, "Esetname '%s' in complex compspec",
810 p->u.elementSetName);
813 case Z_ElementSpec_externalSpec:
814 if (p->u.externalSpec->which == Z_External_espec1)
816 logf(LOG_DEBUG, "Got Espec-1");
817 espec = p->u.externalSpec-> u.espec1;
821 logf(LOG_LOG, "Unknown external espec.");
822 return 25; /* bad. what is proper diagnostic? */
833 logf (LOG_DEBUG, "Element: Espec-1 match");
834 return data1_doespec1(dh, n, espec);
838 logf (LOG_DEBUG, "Element: all match");
843 /* Add Zebra info in separate namespace ...
846 <metadata xmlns="http://www.indexdata.dk/zebra/">
848 <localnumber>447</localnumber>
849 <filename>records/genera.xml</filename>
854 static void zebra_xml_metadata (struct recRetrieveCtrl *p, data1_node *top,
857 const char *idzebra_ns[3];
858 const char *i2 = "\n ";
859 const char *i4 = "\n ";
862 idzebra_ns[0] = "xmlns";
863 idzebra_ns[1] = "http://www.indexdata.dk/zebra/";
866 data1_mk_text (p->dh, mem, i2, top);
868 n = data1_mk_tag (p->dh, mem, "idzebra", idzebra_ns, top);
870 data1_mk_text (p->dh, mem, "\n", top);
872 data1_mk_text (p->dh, mem, i4, n);
874 data1_mk_tag_data_int (p->dh, n, "size", p->recordSize, mem);
878 data1_mk_text (p->dh, mem, i4, n);
879 data1_mk_tag_data_int (p->dh, n, "score", p->score, mem);
881 data1_mk_text (p->dh, mem, i4, n);
882 data1_mk_tag_data_int (p->dh, n, "localnumber", p->localno, mem);
885 data1_mk_text (p->dh, mem, i4, n);
886 data1_mk_tag_data_text(p->dh, n, "filename", p->fname, mem);
888 data1_mk_text (p->dh, mem, i2, n);
891 static int grs_retrieve(void *clientData, struct recRetrieveCtrl *p)
893 data1_node *node = 0, *onode = 0, *top;
896 int res, selected = 0;
898 struct grs_read_info gri;
900 struct grs_handlers *h = (struct grs_handlers *) clientData;
901 int requested_schema = VAL_NONE;
902 data1_marctab *marctab;
906 gri.readf = p->readf;
907 gri.seekf = p->seekf;
908 gri.tellf = p->tellf;
915 logf (LOG_DEBUG, "grs_retrieve");
916 if (read_grs_type (h, &gri, p->subType, &node))
928 /* ensure our data1 tree is UTF-8 */
929 data1_iconv (p->dh, mem, node, "UTF-8", data1_get_encoding(p->dh, node));
932 data1_pr_tree (p->dh, node, stdout);
934 top = data1_get_root_tag (p->dh, node);
936 logf (LOG_DEBUG, "grs_retrieve: size");
937 tagname = data1_systag_lookup(node->u.root.absyn, "size", "size");
939 (dnew = data1_mk_tag_data_wd(p->dh, top, tagname, mem)))
941 dnew->u.data.what = DATA1I_text;
942 dnew->u.data.data = dnew->lbuf;
943 sprintf(dnew->u.data.data, "%d", p->recordSize);
944 dnew->u.data.len = strlen(dnew->u.data.data);
947 tagname = data1_systag_lookup(node->u.root.absyn, "rank", "rank");
948 if (tagname && p->score >= 0 &&
949 (dnew = data1_mk_tag_data_wd(p->dh, top, tagname, mem)))
951 logf (LOG_DEBUG, "grs_retrieve: %s", tagname);
952 dnew->u.data.what = DATA1I_num;
953 dnew->u.data.data = dnew->lbuf;
954 sprintf(dnew->u.data.data, "%d", p->score);
955 dnew->u.data.len = strlen(dnew->u.data.data);
958 tagname = data1_systag_lookup(node->u.root.absyn, "sysno",
959 "localControlNumber");
960 if (tagname && p->localno > 0 &&
961 (dnew = data1_mk_tag_data_wd(p->dh, top, tagname, mem)))
963 logf (LOG_DEBUG, "grs_retrieve: %s", tagname);
964 dnew->u.data.what = DATA1I_text;
965 dnew->u.data.data = dnew->lbuf;
967 sprintf(dnew->u.data.data, "%d", p->localno);
968 dnew->u.data.len = strlen(dnew->u.data.data);
971 data1_pr_tree (p->dh, node, stdout);
973 #if YAZ_VERSIONL >= 0x010903L
974 if (p->comp && p->comp->which == Z_RecordComp_complex &&
975 p->comp->u.complex->generic &&
976 p->comp->u.complex->generic->which == Z_Schema_oid &&
977 p->comp->u.complex->generic->schema.oid)
979 oident *oe = oid_getentbyoid (p->comp->u.complex->generic->schema.oid);
981 requested_schema = oe->value;
984 if (p->comp && p->comp->which == Z_RecordComp_complex &&
985 p->comp->u.complex->generic && p->comp->u.complex->generic->schema)
987 oident *oe = oid_getentbyoid (p->comp->u.complex->generic->schema);
989 requested_schema = oe->value;
993 /* If schema has been specified, map if possible, then check that
994 * we got the right one
996 if (requested_schema != VAL_NONE)
998 logf (LOG_DEBUG, "grs_retrieve: schema mapping");
999 for (map = node->u.root.absyn->maptabs; map; map = map->next)
1001 if (map->target_absyn_ref == requested_schema)
1004 if (!(node = data1_map_record(p->dh, onode, map, mem)))
1013 if (node->u.root.absyn &&
1014 requested_schema != node->u.root.absyn->reference)
1016 p->diagnostic = 238;
1022 * Does the requested format match a known syntax-mapping? (this reflects
1023 * the overlap of schema and formatting which is inherent in the MARC
1026 yaz_log (LOG_DEBUG, "grs_retrieve: syntax mapping");
1027 if (node->u.root.absyn)
1028 for (map = node->u.root.absyn->maptabs; map; map = map->next)
1030 if (map->target_absyn_ref == p->input_format)
1033 if (!(node = data1_map_record(p->dh, onode, map, mem)))
1042 yaz_log (LOG_DEBUG, "grs_retrieve: schemaIdentifier");
1043 if (node->u.root.absyn &&
1044 node->u.root.absyn->reference != VAL_NONE &&
1045 p->input_format == VAL_GRS1)
1049 int oidtmp[OID_SIZE];
1051 oe.proto = PROTO_Z3950;
1052 oe.oclass = CLASS_SCHEMA;
1053 oe.value = node->u.root.absyn->reference;
1055 if ((oid = oid_ent_to_oid (&oe, oidtmp)))
1058 data1_handle dh = p->dh;
1062 for (ii = oid; *ii >= 0; ii++)
1066 sprintf(p, "%d", *ii);
1069 if ((dnew = data1_mk_tag_data_wd(dh, top,
1070 "schemaIdentifier", mem)))
1072 dnew->u.data.what = DATA1I_oid;
1073 dnew->u.data.data = (char *) nmem_malloc(mem, p - tmp);
1074 memcpy(dnew->u.data.data, tmp, p - tmp);
1075 dnew->u.data.len = p - tmp;
1080 logf (LOG_DEBUG, "grs_retrieve: element spec");
1081 if (p->comp && (res = process_comp(p->dh, node, p->comp)) > 0)
1083 p->diagnostic = res;
1085 data1_free_tree(p->dh, onode);
1086 data1_free_tree(p->dh, node);
1090 else if (p->comp && !res)
1094 data1_pr_tree (p->dh, node, stdout);
1096 logf (LOG_DEBUG, "grs_retrieve: transfer syntax mapping");
1097 switch (p->output_format = (p->input_format != VAL_NONE ?
1098 p->input_format : VAL_SUTRS))
1101 zebra_xml_metadata (p, top, mem);
1104 data1_pr_tree (p->dh, node, stdout);
1108 data1_iconv (p->dh, mem, node, p->encoding, "UTF-8");
1110 if (!(p->rec_buf = data1_nodetoidsgml(p->dh, node, selected,
1112 p->diagnostic = 238;
1115 char *new_buf = (char*) odr_malloc (p->odr, p->rec_len);
1116 memcpy (new_buf, p->rec_buf, p->rec_len);
1117 p->rec_buf = new_buf;
1122 if (!(p->rec_buf = data1_nodetogr(p->dh, node, selected,
1124 p->diagnostic = 238; /* not available in requested syntax */
1126 p->rec_len = (size_t) (-1);
1129 if (!(p->rec_buf = data1_nodetoexplain(p->dh, node, selected,
1131 p->diagnostic = 238;
1133 p->rec_len = (size_t) (-1);
1136 if (!(p->rec_buf = data1_nodetosummary(p->dh, node, selected,
1138 p->diagnostic = 238;
1140 p->rec_len = (size_t) (-1);
1144 data1_iconv (p->dh, mem, node, p->encoding, "UTF-8");
1145 if (!(p->rec_buf = data1_nodetobuf(p->dh, node, selected,
1147 p->diagnostic = 238;
1150 char *new_buf = (char*) odr_malloc (p->odr, p->rec_len);
1151 memcpy (new_buf, p->rec_buf, p->rec_len);
1152 p->rec_buf = new_buf;
1156 if (!(p->rec_buf = data1_nodetosoif(p->dh, node, selected,
1158 p->diagnostic = 238;
1161 char *new_buf = (char*) odr_malloc (p->odr, p->rec_len);
1162 memcpy (new_buf, p->rec_buf, p->rec_len);
1163 p->rec_buf = new_buf;
1167 if (!node->u.root.absyn)
1169 p->diagnostic = 238;
1172 for (marctab = node->u.root.absyn->marc; marctab;
1173 marctab = marctab->next)
1174 if (marctab->reference == p->input_format)
1178 p->diagnostic = 238;
1182 data1_iconv (p->dh, mem, node, p->encoding, "UTF-8");
1183 if (!(p->rec_buf = data1_nodetomarc(p->dh, marctab, node,
1184 selected, &p->rec_len)))
1185 p->diagnostic = 238;
1188 char *new_buf = (char*) odr_malloc (p->odr, p->rec_len);
1189 memcpy (new_buf, p->rec_buf, p->rec_len);
1190 p->rec_buf = new_buf;
1194 data1_free_tree(p->dh, node);
1196 data1_free_tree(p->dh, onode);
1201 static struct recType grs_type =
1210 RecType recTypeGrs = &grs_type;