1 /* $Id: recgrs.c,v 1.74 2003-02-20 21:13:37 adam 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 = 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 YAZ_VERSIONL >= 0x010903L
972 if (p->comp && p->comp->which == Z_RecordComp_complex &&
973 p->comp->u.complex->generic &&
974 p->comp->u.complex->generic->which == Z_Schema_oid &&
975 p->comp->u.complex->generic->schema.oid)
977 oident *oe = oid_getentbyoid (p->comp->u.complex->generic->schema.oid);
979 requested_schema = oe->value;
982 if (p->comp && p->comp->which == Z_RecordComp_complex &&
983 p->comp->u.complex->generic && p->comp->u.complex->generic->schema)
985 oident *oe = oid_getentbyoid (p->comp->u.complex->generic->schema);
987 requested_schema = oe->value;
991 /* If schema has been specified, map if possible, then check that
992 * we got the right one
994 if (requested_schema != VAL_NONE)
996 logf (LOG_DEBUG, "grs_retrieve: schema mapping");
997 for (map = node->u.root.absyn->maptabs; map; map = map->next)
999 if (map->target_absyn_ref == requested_schema)
1002 if (!(node = data1_map_record(p->dh, onode, map, mem)))
1011 if (node->u.root.absyn &&
1012 requested_schema != node->u.root.absyn->reference)
1014 p->diagnostic = 238;
1020 * Does the requested format match a known syntax-mapping? (this reflects
1021 * the overlap of schema and formatting which is inherent in the MARC
1024 yaz_log (LOG_DEBUG, "grs_retrieve: syntax mapping");
1025 if (node->u.root.absyn)
1026 for (map = node->u.root.absyn->maptabs; map; map = map->next)
1028 if (map->target_absyn_ref == p->input_format)
1031 if (!(node = data1_map_record(p->dh, onode, map, mem)))
1040 yaz_log (LOG_DEBUG, "grs_retrieve: schemaIdentifier");
1041 if (node->u.root.absyn &&
1042 node->u.root.absyn->reference != VAL_NONE &&
1043 p->input_format == VAL_GRS1)
1047 int oidtmp[OID_SIZE];
1049 oe.proto = PROTO_Z3950;
1050 oe.oclass = CLASS_SCHEMA;
1051 oe.value = node->u.root.absyn->reference;
1053 if ((oid = oid_ent_to_oid (&oe, oidtmp)))
1056 data1_handle dh = p->dh;
1060 for (ii = oid; *ii >= 0; ii++)
1064 sprintf(p, "%d", *ii);
1067 if ((dnew = data1_mk_tag_data_wd(dh, top,
1068 "schemaIdentifier", mem)))
1070 dnew->u.data.what = DATA1I_oid;
1071 dnew->u.data.data = (char *) nmem_malloc(mem, p - tmp);
1072 memcpy(dnew->u.data.data, tmp, p - tmp);
1073 dnew->u.data.len = p - tmp;
1078 logf (LOG_DEBUG, "grs_retrieve: element spec");
1079 if (p->comp && (res = process_comp(p->dh, node, p->comp)) > 0)
1081 p->diagnostic = res;
1083 data1_free_tree(p->dh, onode);
1084 data1_free_tree(p->dh, node);
1088 else if (p->comp && !res)
1092 data1_pr_tree (p->dh, node, stdout);
1094 logf (LOG_DEBUG, "grs_retrieve: transfer syntax mapping");
1095 switch (p->output_format = (p->input_format != VAL_NONE ?
1096 p->input_format : VAL_SUTRS))
1099 zebra_xml_metadata (p, top, mem);
1102 data1_pr_tree (p->dh, node, stdout);
1106 data1_iconv (p->dh, mem, node, p->encoding, "UTF-8");
1108 if (!(p->rec_buf = data1_nodetoidsgml(p->dh, node, selected,
1110 p->diagnostic = 238;
1113 char *new_buf = (char*) odr_malloc (p->odr, p->rec_len);
1114 memcpy (new_buf, p->rec_buf, p->rec_len);
1115 p->rec_buf = new_buf;
1120 if (!(p->rec_buf = data1_nodetogr(p->dh, node, selected,
1122 p->diagnostic = 238; /* not available in requested syntax */
1124 p->rec_len = (size_t) (-1);
1127 if (!(p->rec_buf = data1_nodetoexplain(p->dh, node, selected,
1129 p->diagnostic = 238;
1131 p->rec_len = (size_t) (-1);
1134 if (!(p->rec_buf = data1_nodetosummary(p->dh, node, selected,
1136 p->diagnostic = 238;
1138 p->rec_len = (size_t) (-1);
1142 data1_iconv (p->dh, mem, node, p->encoding, "UTF-8");
1143 if (!(p->rec_buf = data1_nodetobuf(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 (!(p->rec_buf = data1_nodetosoif(p->dh, node, selected,
1156 p->diagnostic = 238;
1159 char *new_buf = (char*) odr_malloc (p->odr, p->rec_len);
1160 memcpy (new_buf, p->rec_buf, p->rec_len);
1161 p->rec_buf = new_buf;
1165 if (!node->u.root.absyn)
1167 p->diagnostic = 238;
1170 for (marctab = node->u.root.absyn->marc; marctab;
1171 marctab = marctab->next)
1172 if (marctab->reference == p->input_format)
1176 p->diagnostic = 238;
1180 data1_iconv (p->dh, mem, node, p->encoding, "UTF-8");
1181 if (!(p->rec_buf = data1_nodetomarc(p->dh, marctab, node,
1182 selected, &p->rec_len)))
1183 p->diagnostic = 238;
1186 char *new_buf = (char*) odr_malloc (p->odr, p->rec_len);
1187 memcpy (new_buf, p->rec_buf, p->rec_len);
1188 p->rec_buf = new_buf;
1192 data1_free_tree(p->dh, node);
1194 data1_free_tree(p->dh, onode);
1199 static struct recType grs_type =
1208 RecType recTypeGrs = &grs_type;