X-Git-Url: http://git.indexdata.com/?p=idzebra-moved-to-github.git;a=blobdiff_plain;f=recctrl%2Fmarcread.c;h=a0fdcac574eab2aca457fe0c81f78e27a8f196c3;hp=86993736649018f1fef5ae29894bae1a9c99299e;hb=5437b50633032595afe6f87dc0f989bc92a5aea8;hpb=df9a3a9811db8c6ad09feeb94d66b429d98d8fde diff --git a/recctrl/marcread.c b/recctrl/marcread.c index 8699373..a0fdcac 100644 --- a/recctrl/marcread.c +++ b/recctrl/marcread.c @@ -1,5 +1,5 @@ -/* $Id: marcread.c,v 1.23 2003-12-10 23:30:15 adam Exp $ - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003 +/* $Id: marcread.c,v 1.27 2004-11-19 10:27:12 heikki Exp $ + Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004 Index Data Aps This file is part of the Zebra server. @@ -24,18 +24,23 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include -#include +#include #include #include -#include "grsread.h" +#include #include "marcomp.h" #include "inline.h" #define MARC_DEBUG 0 #define MARCOMP_DEBUG 0 +struct marc_info { + char type[256]; +}; + static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml) { + struct marc_info *mi = (struct marc_info*) p->clientData; char buf[100000]; int entry_p; int record_length; @@ -58,14 +63,14 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml) record_length = atoi_n (buf, 5); if (record_length < 25) { - logf (LOG_WARN, "MARC record length < 25, is %d", record_length); + yaz_log (YLOG_WARN, "MARC record length < 25, is %d", record_length); return NULL; } /* read remaining part - attempt to read one byte furhter... */ read_bytes = (*p->readf)(p->fh, buf+5, record_length-4); if (read_bytes < record_length-5) { - logf (LOG_WARN, "Couldn't read whole MARC record"); + yaz_log (YLOG_WARN, "Couldn't read whole MARC record"); return NULL; } if (read_bytes == record_length - 4) @@ -76,11 +81,11 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml) if (p->endf) (*p->endf)(p->fh, cur_offset - 1); } - absynName = p->type; + absynName = mi->type; res_root = data1_mk_root (p->dh, p->mem, absynName); if (!res_root) { - yaz_log (LOG_WARN, "cannot read MARC without an abstract syntax"); + yaz_log (YLOG_WARN, "cannot read MARC without an abstract syntax"); return 0; } if (marc_xml) @@ -96,7 +101,7 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml) else res_top = data1_mk_tag (p->dh, p->mem, absynName, 0, res_root); - if ((marctab = res_root->u.root.absyn->marc)) + if ((marctab = data1_absyn_getmarctab(p->dh, res_root->u.root.absyn))) { memcpy(marctab->leader, buf, 24); memcpy(marctab->implementation_codes, buf+6, 4); @@ -275,6 +280,7 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml) } return res_root; } + /* * Locate some data under this node. This routine should handle variants * prettily. @@ -310,6 +316,7 @@ static char *get_data(data1_node *n, int *len) *len = strlen(r); return r; } + static data1_node *lookup_subfield(data1_node *node, const char *name) { data1_node *p; @@ -321,7 +328,9 @@ static data1_node *lookup_subfield(data1_node *node, const char *name) } return 0; } -static inline_subfield *lookup_inline_subfield(inline_subfield *pisf, const char *name) + +static inline_subfield *lookup_inline_subfield(inline_subfield *pisf, + const char *name) { inline_subfield *p; @@ -332,7 +341,9 @@ static inline_subfield *lookup_inline_subfield(inline_subfield *pisf, const char } return 0; } -static inline_subfield *cat_inline_subfield(mc_subfield *psf, char *buf, inline_subfield *pisf) + +static inline_subfield *cat_inline_subfield(mc_subfield *psf, WRBUF buf, + inline_subfield *pisf) { mc_subfield *p; @@ -346,23 +357,26 @@ static inline_subfield *cat_inline_subfield(mc_subfield *psf, char *buf, inline_ { if (strcmp(p->prefix, "_")) { - strcat(strcat(buf, " "), p->prefix); + wrbuf_puts(buf, " "); + wrbuf_puts(buf, p->prefix); } if (p->interval.start == -1) { - strcat(buf, found->data); + wrbuf_puts(buf, found->data); } else { - strncat(buf, found->data+p->interval.start, - p->interval.end-p->interval.start+1); + wrbuf_write(buf, found->data+p->interval.start, + p->interval.end-p->interval.start); + wrbuf_puts(buf, ""); } if (strcmp(p->suffix, "_")) { - strcat(strcat(buf, p->suffix), " "); + wrbuf_puts(buf, p->suffix); + wrbuf_puts(buf, " "); } #if MARCOMP_DEBUG - logf(LOG_LOG, "cat_inline_subfield(): add subfield $%s", found->name); + yaz_log(YLOG_LOG, "cat_inline_subfield(): add subfield $%s", found->name); #endif pisf = found->next; } @@ -393,15 +407,16 @@ static inline_subfield *cat_inline_subfield(mc_subfield *psf, char *buf, inline_ } if (found) { - strcat(buf, " ("); + wrbuf_puts(buf, " ("); pisf = cat_inline_subfield(p->u.child, buf, pisf); - strcat(buf, ") "); + wrbuf_puts(buf, ") "); } } } return pisf; } -static void cat_inline_field(mc_field *pf, char *buf, data1_node *subfield) + +static void cat_inline_field(mc_field *pf, WRBUF buf, data1_node *subfield) { if (!pf || !subfield) return; @@ -425,7 +440,7 @@ static void cat_inline_field(mc_field *pf, char *buf, data1_node *subfield) int i; if ((i=inline_parse(pif, psubf->u.tag.tag, get_data(psubf, &len)))<0) { - logf(LOG_WARN, "inline subfield ($%s): parse error", + yaz_log(YLOG_WARN, "inline subfield ($%s): parse error", psubf->u.tag.tag); inline_destroy_field(pif); return; @@ -439,7 +454,7 @@ static void cat_inline_field(mc_field *pf, char *buf, data1_node *subfield) { if (!pf->list && pif->list) { - strcat(buf, pif->list->data); + wrbuf_puts(buf, pif->list->data); } else { @@ -460,24 +475,26 @@ static void cat_inline_field(mc_field *pf, char *buf, data1_node *subfield) /* add separator for inline fields */ - if (strlen(buf)) + if (wrbuf_len(buf)) { - strcat(buf, "\n"); + wrbuf_puts(buf, "\n"); } } else { - logf(LOG_WARN, "In-line field %s missed -- indicators does not match", pif->name); + yaz_log(YLOG_WARN, "In-line field %s missed -- indicators do not match", pif->name); } } } inline_destroy_field(pif); } #if MARCOMP_DEBUG - logf(LOG_LOG, "cat_inline_field(): got buffer {%s}", buf); + yaz_log(YLOG_LOG, "cat_inline_field(): got buffer {%s}", buf); #endif } -static data1_node *cat_subfield(mc_subfield *psf, char *buf, data1_node *subfield) + +static data1_node *cat_subfield(mc_subfield *psf, WRBUF buf, + data1_node *subfield) { mc_subfield *p; @@ -493,7 +510,8 @@ static data1_node *cat_subfield(mc_subfield *psf, char *buf, data1_node *subfiel if (strcmp(p->prefix, "_")) { - strcat(strcat(buf, " "), p->prefix); + wrbuf_puts(buf, " "); + wrbuf_puts(buf, p->prefix); } if (p->u.in_line) @@ -502,19 +520,21 @@ static data1_node *cat_subfield(mc_subfield *psf, char *buf, data1_node *subfiel } else if (p->interval.start == -1) { - strcat(buf, get_data(found, &len)); + wrbuf_puts(buf, get_data(found, &len)); } else { - strncat(buf, get_data(found, &len)+p->interval.start, - p->interval.end-p->interval.start+1); + wrbuf_write(buf, get_data(found, &len)+p->interval.start, + p->interval.end-p->interval.start); + wrbuf_puts(buf, ""); } if (strcmp(p->suffix, "_")) { - strcat(strcat(buf, p->suffix), " "); + wrbuf_puts(buf, p->suffix); + wrbuf_puts(buf, " "); } #if MARCOMP_DEBUG - logf(LOG_LOG, "cat_subfield(): add subfield $%s", found->u.tag.tag); + yaz_log(YLOG_LOG, "cat_subfield(): add subfield $%s", found->u.tag.tag); #endif subfield = found->next; } @@ -544,15 +564,17 @@ static data1_node *cat_subfield(mc_subfield *psf, char *buf, data1_node *subfiel } if (found) { - strcat(buf, " ("); + wrbuf_puts(buf, " ("); subfield = cat_subfield(p->u.child, buf, subfield); - strcat(buf, ") "); + wrbuf_puts(buf, ") "); } } } return subfield; } -static data1_node *cat_field(struct grs_read_info *p, mc_field *pf, char *buf, data1_node *field) + +static data1_node *cat_field(struct grs_read_info *p, mc_field *pf, + WRBUF buf, data1_node *field) { data1_node *subfield; int ind1, ind2; @@ -579,15 +601,16 @@ static data1_node *cat_field(struct grs_read_info *p, mc_field *pf, char *buf, d if (pf->interval.start == -1) { - strcat(buf, get_data(field, &len)); + wrbuf_puts(buf, get_data(field, &len)); } else { - strncat(buf, get_data(field, &len)+pf->interval.start, - pf->interval.end-pf->interval.start+1); + wrbuf_write(buf, get_data(field, &len)+pf->interval.start, + pf->interval.end-pf->interval.start); + wrbuf_puts(buf, ""); } #if MARCOMP_DEBUG - logf(LOG_LOG, "cat_field(): got buffer {%s}", buf); + yaz_log(YLOG_LOG, "cat_field(): got buffer {%s}", buf); #endif return field->next; } @@ -605,7 +628,7 @@ static data1_node *cat_field(struct grs_read_info *p, mc_field *pf, char *buf, d )) { #if MARCOMP_DEBUG - logf(LOG_WARN, "Field %s missed -- does not match indicators", field->u.tag.tag); + yaz_log(YLOG_WARN, "Field %s missed -- does not match indicators", field->u.tag.tag); #endif return field->next; } @@ -618,11 +641,12 @@ static data1_node *cat_field(struct grs_read_info *p, mc_field *pf, char *buf, d cat_subfield(pf->list, buf, subfield); #if MARCOMP_DEBUG - logf(LOG_LOG, "cat_field(): got buffer {%s}", buf); + yaz_log(YLOG_LOG, "cat_field(): got buffer {%s}", buf); #endif return field->next; } + static int is_empty(char *s) { char *p = s; @@ -634,14 +658,16 @@ static int is_empty(char *s) } return 1; } -static void parse_data1_tree(struct grs_read_info *p, const char *mc_stmnt, data1_node *root) + +static void parse_data1_tree(struct grs_read_info *p, const char *mc_stmnt, + data1_node *root) { - data1_marctab *marctab = root->u.root.absyn->marc; + data1_marctab *marctab = data1_absyn_getmarctab(p->dh, root->u.root.absyn); data1_node *top = root->child; data1_node *field; mc_context *c; mc_field *pf; - char buf[1000000]; + WRBUF buf; c = mc_mk_context(mc_stmnt+3); @@ -655,14 +681,15 @@ static void parse_data1_tree(struct grs_read_info *p, const char *mc_stmnt, data mc_destroy_context(c); return; } + buf = wrbuf_alloc(); #if MARCOMP_DEBUG - logf(LOG_LOG, "parse_data1_tree(): statement -{%s}", mc_stmnt); + yaz_log(YLOG_LOG, "parse_data1_tree(): statement -{%s}", mc_stmnt); #endif if (!yaz_matchstr(pf->name, "ldr")) { data1_node *new; #if MARCOMP_DEBUG - logf(LOG_LOG,"parse_data1_tree(): try LEADER from {%d} to {%d} positions", + yaz_log(YLOG_LOG,"parse_data1_tree(): try LEADER from {%d} to {%d} positions", pf->interval.start, pf->interval.end); #endif new = data1_mk_tag_n(p->dh, p->mem, mc_stmnt, strlen(mc_stmnt), 0, top); @@ -678,13 +705,16 @@ static void parse_data1_tree(struct grs_read_info *p, const char *mc_stmnt, data if (!yaz_matchstr(field->u.tag.tag, pf->name)) { data1_node *new; - char *pb = buf; + char *pb; #if MARCOMP_DEBUG - logf(LOG_LOG, "parse_data1_tree(): try field {%s}", field->u.tag.tag); + yaz_log(YLOG_LOG, "parse_data1_tree(): try field {%s}", field->u.tag.tag); #endif - *buf = '\0'; + wrbuf_rewind(buf); + wrbuf_puts(buf, ""); + field = cat_field(p, pf, buf, field); + pb = wrbuf_buf(buf); for (pb = strtok(pb, "\n"); pb; pb = strtok(NULL, "\n")) { if (!is_empty(pb)) @@ -702,6 +732,7 @@ static void parse_data1_tree(struct grs_read_info *p, const char *mc_stmnt, data } mc_destroy_field(pf); mc_destroy_context(c); + wrbuf_free(buf, 1); } data1_node *grs_read_marcxml(struct grs_read_info *p) @@ -712,7 +743,7 @@ data1_node *grs_read_marcxml(struct grs_read_info *p) if (!root) return 0; - for (e=root->u.root.absyn->main_elements; e; e=e->next) + for (e = data1_absyn_getelements(p->dh, root->u.root.absyn); e; e=e->next) { data1_tag *tag = e->tag; @@ -723,7 +754,6 @@ data1_node *grs_read_marcxml(struct grs_read_info *p) return root; } - data1_node *grs_read_marc(struct grs_read_info *p) { data1_node *root = grs_read_iso2709(p, 0); @@ -732,7 +762,7 @@ data1_node *grs_read_marc(struct grs_read_info *p) if (!root) return 0; - for (e=root->u.root.absyn->main_elements; e; e=e->next) + for (e = data1_absyn_getelements(p->dh, root->u.root.absyn); e; e=e->next) { data1_tag *tag = e->tag; @@ -742,29 +772,76 @@ data1_node *grs_read_marc(struct grs_read_info *p) } return root; } -static void *grs_init_marc(void) + +static void *init_marc(Res res, RecType rt) { - return 0; + struct marc_info *p = xmalloc(sizeof(*p)); + strcpy(p->type, ""); + return p; +} + +static void config_marc(void *clientData, Res res, const char *args) +{ + struct marc_info *p = (struct marc_info*) clientData; + if (strlen(args) < sizeof(p->type)) + strcpy(p->type, args); } -static void grs_destroy_marc(void *clientData) +static void destroy_marc(void *clientData) +{ + struct marc_info *p = (struct marc_info*) clientData; + xfree (p); +} + + +static int extract_marc(void *clientData, struct recExtractCtrl *ctrl) { + return zebra_grs_extract(clientData, ctrl, grs_read_marc); } -static struct recTypeGrs marc_type = { - "marc", - grs_init_marc, - grs_destroy_marc, - grs_read_marc +static int retrieve_marc(void *clientData, struct recRetrieveCtrl *ctrl) +{ + return zebra_grs_retrieve(clientData, ctrl, grs_read_marc); +} + +static struct recType marc_type = { + "grs.marc", + init_marc, + config_marc, + destroy_marc, + extract_marc, + retrieve_marc, }; -RecTypeGrs recTypeGrs_marc = &marc_type; +static int extract_marcxml(void *clientData, struct recExtractCtrl *ctrl) +{ + return zebra_grs_extract(clientData, ctrl, grs_read_marcxml); +} + +static int retrieve_marcxml(void *clientData, struct recRetrieveCtrl *ctrl) +{ + return zebra_grs_retrieve(clientData, ctrl, grs_read_marcxml); +} -static struct recTypeGrs marcxml_type = { - "marcxml", - grs_init_marc, - grs_destroy_marc, - grs_read_marcxml +static struct recType marcxml_type = { + "grs.marcxml", + init_marc, + config_marc, + destroy_marc, + extract_marcxml, + retrieve_marcxml, }; -RecTypeGrs recTypeGrs_marcxml = &marcxml_type; +RecType +#ifdef IDZEBRA_STATIC_GRS_MARC +idzebra_filter_grs_marc +#else +idzebra_filter +#endif + +[] = { + &marc_type, + &marcxml_type, + 0, +}; +