X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=data1%2Fd1_marc.c;h=a04ef8949c9c0d3cbcaca9ce8b4f678d6880642a;hb=e63cb633d580e1a364de81d4f24fb2c9fa70e279;hp=d038d19cf4ee1a5114f28e77b73ae7cd7e20a76b;hpb=02266b68e2e2c86d8a8467ee56721926b365d2d0;p=idzebra-moved-to-github.git diff --git a/data1/d1_marc.c b/data1/d1_marc.c index d038d19..a04ef89 100644 --- a/data1/d1_marc.c +++ b/data1/d1_marc.c @@ -1,6 +1,6 @@ -/* $Id: d1_marc.c,v 1.2 2002-10-22 13:19:50 adam Exp $ - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 - Index Data Aps +/* $Id: d1_marc.c,v 1.12 2005-02-02 19:37:27 adam Exp $ + Copyright (C) 1995-2005 + Index Data ApS This file is part of the Zebra server. @@ -26,13 +26,13 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include -#include #include +#include #include #include #include #include -#include +#include data1_marctab *data1_read_marctab (data1_handle dh, const char *file) { @@ -45,7 +45,7 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) if (!(f = data1_path_fopen(dh, file, "r"))) { - yaz_log(LOG_WARN|LOG_ERRNO, "%s", file); + yaz_log(YLOG_WARN|YLOG_ERRNO, "%s", file); return 0; } @@ -70,7 +70,7 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) { if (argc != 2) { - yaz_log(LOG_WARN, "%s:%d:Missing arg for %s", file, lineno, + yaz_log(YLOG_WARN, "%s:%d:Missing arg for %s", file, lineno, *argv); continue; } @@ -80,13 +80,13 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) { if (argc != 2) { - yaz_log(LOG_WARN, "%s:%d: Missing arg for %s", file, lineno, + yaz_log(YLOG_WARN, "%s:%d: Missing arg for %s", file, lineno, *argv); continue; } if ((res->reference = oid_getvalbyname(argv[1])) == VAL_NONE) { - yaz_log(LOG_WARN, "%s:%d: Unknown tagset reference '%s'", + yaz_log(YLOG_WARN, "%s:%d: Unknown tagset reference '%s'", file, lineno, argv[1]); continue; } @@ -95,7 +95,7 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) { if (argc != 2) { - yaz_log(LOG_WARN, "%s:%d: Missing arg for %s", file, lineno, + yaz_log(YLOG_WARN, "%s:%d: Missing arg for %s", file, lineno, *argv); continue; } @@ -105,7 +105,7 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) { if (argc != 2) { - yaz_log(LOG_WARN, "%s:%d: Missing arg for %s", file, lineno, + yaz_log(YLOG_WARN, "%s:%d: Missing arg for %s", file, lineno, *argv); continue; } @@ -115,7 +115,7 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) { if (argc != 2) { - yaz_log(LOG_WARN, "%s:%d: Missing arg for %s", file, lineno, + yaz_log(YLOG_WARN, "%s:%d: Missing arg for %s", file, lineno, *argv); continue; } @@ -125,7 +125,7 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) { if (argc != 2) { - yaz_log(LOG_WARN, "%s:%d: Missing arg for %s", file, lineno, + yaz_log(YLOG_WARN, "%s:%d: Missing arg for %s", file, lineno, *argv); continue; } @@ -135,7 +135,7 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) { if (argc != 2) { - yaz_log(LOG_WARN, "%s:%d: Missing arg for %s", file, lineno, + yaz_log(YLOG_WARN, "%s:%d: Missing arg for %s", file, lineno, *argv); continue; } @@ -145,14 +145,14 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) { if (argc != 2) { - yaz_log(LOG_WARN, "%s:%d: Missing arg for %s", file, lineno, + yaz_log(YLOG_WARN, "%s:%d: Missing arg for %s", file, lineno, *argv); continue; } res->force_identifier_length = atoi(argv[1]); } else - yaz_log(LOG_WARN, "%s:%d: Unknown directive '%s'", file, lineno, + yaz_log(YLOG_WARN, "%s:%d: Unknown directive '%s'", file, lineno, *argv); fclose(f); @@ -164,7 +164,7 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) * Locate some data under this node. This routine should handle variants * prettily. */ -static char *get_data(data1_node *n, int *len) +static char *get_data(data1_node *n, int *len, int chop) { char *r; @@ -174,15 +174,21 @@ static char *get_data(data1_node *n, int *len) { int i; *len = n->u.data.len; - - for (i = 0; i<*len; i++) - if (!d1_isspace(n->u.data.data[i])) - break; - while (*len && d1_isspace(n->u.data.data[*len - 1])) - (*len)--; - *len = *len - i; - if (*len > 0) - return n->u.data.data + i; + + if (chop) + { + for (i = 0; i<*len; i++) + if (!d1_isspace(n->u.data.data[i])) + break; + while (*len && d1_isspace(n->u.data.data[*len - 1])) + (*len)--; + *len = *len - i; + if (*len > 0) + return n->u.data.data + i; + } + else + if (*len > 0) + return n->u.data.data; } if (n->which == DATA1N_tag) n = n->child; @@ -209,16 +215,12 @@ static void memint (char *p, int val, int len) } } +/* check for indicator. non MARCXML only */ static int is_indicator (data1_marctab *p, data1_node *subf) { -#if 1 if (p->indicator_length != 2 || (subf && subf->which == DATA1N_tag && strlen(subf->u.tag.tag) == 2)) return 1; -#else - if (subf && subf->which == DATA1N_tag && subf->child->which == DATA1N_tag) - return 1; -#endif return 0; } @@ -226,6 +228,8 @@ static int nodetomarc(data1_handle dh, data1_marctab *p, data1_node *n, int selected, char **buf, int *size) { + char leader[24]; + int len = 26; int dlen; int base_address = 25; @@ -233,49 +237,86 @@ static int nodetomarc(data1_handle dh, char *op; data1_node *field, *subf; - yaz_log (LOG_DEBUG, "nodetomarc"); +#if 0 + data1_pr_tree(dh, n, stdout); +#endif + yaz_log (YLOG_DEBUG, "nodetomarc"); + + memcpy (leader+5, p->record_status, 1); + memcpy (leader+6, p->implementation_codes, 4); + memint (leader+10, p->indicator_length, 1); + memint (leader+11, p->identifier_length, 1); + memcpy (leader+17, p->user_systems, 3); + memint (leader+20, p->length_data_entry, 1); + memint (leader+21, p->length_starting, 1); + memint (leader+22, p->length_implementation, 1); + memcpy (leader+23, p->future_use, 1); for (field = n->child; field; field = field->next) { - int is00X = 0; + int control_field = 0; /* 00X fields - usually! */ + int marc_xml = 0; if (field->which != DATA1N_tag) - { - yaz_log(LOG_WARN, "Malformed field composition for marc output."); - return -1; - } + continue; if (selected && !field->u.tag.node_selected) continue; - + subf = field->child; if (!subf) continue; + + if (!yaz_matchstr(field->u.tag.tag, "mc?")) + continue; + else if (!strcmp(field->u.tag.tag, "leader")) + { + int dlen = 0; + char *dbuf = get_data(subf, &dlen, 0); + if (dlen > 24) + dlen = 24; + if (dbuf && dlen > 0) + memcpy (leader, dbuf, dlen); + continue; + } + else if (!strcmp(field->u.tag.tag, "controlfield")) + { + control_field = 1; + marc_xml = 1; + } + else if (!strcmp(field->u.tag.tag, "datafield")) + { + control_field = 0; + marc_xml = 1; + } + else if (subf->which == DATA1N_data) + { + control_field = 1; + marc_xml = 0; + } + else + { + control_field = 0; + marc_xml = 0; + } len += 4 + p->length_data_entry + p->length_starting + p->length_implementation; base_address += 3 + p->length_data_entry + p->length_starting + p->length_implementation; - if (subf->which == DATA1N_data) - is00X = 1; - if (!data1_is_xmlmode(dh)) - { - if (subf->which == DATA1N_tag && !strcmp(subf->u.tag.tag, "@")) - is00X = 1; - } - - - if (!is00X) + if (!control_field) len += p->indicator_length; - /* we'll allow no indicator if length is not 2 */ - if (is_indicator (p, subf)) - subf = subf->child; + /* we'll allow no indicator if length is not 2 */ + /* select when old XML format, since indicator is an element */ + if (marc_xml == 0 && is_indicator (p, subf)) + subf = subf->child; + for (; subf; subf = subf->next) { - if (!is00X) + if (!control_field) len += p->identifier_length; - get_data(subf, &dlen); + get_data(subf, &dlen, control_field ? 0 : 1); len += dlen; } } @@ -286,74 +327,132 @@ static int nodetomarc(data1_handle dh, *buf = (char *)xrealloc(*buf, *size = len); op = *buf; + + /* we know the base address now */ + memint (leader+12, base_address, 5); + + /* copy temp leader to real output buf op */ + memcpy (op, leader, 24); memint (op, len, 5); - memcpy (op+5, p->record_status, 1); - memcpy (op+6, p->implementation_codes, 4); - memint (op+10, p->indicator_length, 1); - memint (op+11, p->identifier_length, 1); - memint (op+12, base_address, 5); - memcpy (op+17, p->user_systems, 3); - memint (op+20, p->length_data_entry, 1); - memint (op+21, p->length_starting, 1); - memint (op+22, p->length_implementation, 1); - memcpy (op+23, p->future_use, 1); entry_p = 24; data_p = base_address; for (field = n->child; field; field = field->next) { - int is00X = 0; + int control_field = 0; + int marc_xml = 0; + const char *tag = 0; int data_0 = data_p; - char *indicator_data = " "; + char indicator_data[6]; + + memset (indicator_data, ' ', sizeof(indicator_data)-1); + indicator_data[sizeof(indicator_data)-1] = '\0'; + + if (field->which != DATA1N_tag) + continue; + if (selected && !field->u.tag.node_selected) continue; subf = field->child; if (!subf) continue; - - if (subf->which == DATA1N_data) - is00X = 1; - if (!data1_is_xmlmode(dh)) - { - if (subf->which == DATA1N_tag && !strcmp(subf->u.tag.tag, "@")) - is00X = 1; - } - - if (is_indicator (p, subf)) + + if (!yaz_matchstr(field->u.tag.tag, "mc?")) + continue; + else if (!strcmp(field->u.tag.tag, "leader")) + continue; + else if (!strcmp(field->u.tag.tag, "controlfield")) + { + control_field = 1; + marc_xml = 1; + } + else if (!strcmp(field->u.tag.tag, "datafield")) { - indicator_data = subf->u.tag.tag; + control_field = 0; + marc_xml = 1; + } + else if (subf->which == DATA1N_data) + { + control_field = 1; + marc_xml = 0; + } + else + { + control_field = 0; + marc_xml = 0; + } + if (marc_xml == 0 && is_indicator (p, subf)) + { + strncpy(indicator_data, subf->u.tag.tag, sizeof(indicator_data)-1); subf = subf->child; } - if (!is00X) - { - memcpy (op + data_p, indicator_data, p->indicator_length); - data_p += p->indicator_length; - } - for (; subf; subf = subf->next) + else if (marc_xml == 1 && !control_field) + { + data1_xattr *xa; + for (xa = field->u.tag.attributes; xa; xa = xa->next) + { + if (!strcmp(xa->name, "ind1")) + indicator_data[0] = xa->value[0]; + if (!strcmp(xa->name, "ind2")) + indicator_data[1] = xa->value[0]; + if (!strcmp(xa->name, "ind3")) + indicator_data[2] = xa->value[0]; + } + } + if (!control_field) + { + memcpy (op + data_p, indicator_data, p->indicator_length); + data_p += p->indicator_length; + } + for (; subf; subf = subf->next) { char *data; - if (!is00X) + if (!control_field) { const char *identifier = "a"; - if (subf->which != DATA1N_tag) - yaz_log(LOG_WARN, "Malformed fields for marc output."); + if (marc_xml) + { + if (subf->which == DATA1N_tag && + !strcmp(subf->u.tag.tag, "subfield")) + { + data1_xattr *xa; + for (xa = subf->u.tag.attributes; xa; xa = xa->next) + if (!strcmp(xa->name, "code")) + identifier = xa->value; + } + } + else if (subf->which != DATA1N_tag) + yaz_log(YLOG_WARN, "Malformed fields for marc output."); else identifier = subf->u.tag.tag; op[data_p] = ISO2709_IDFS; memcpy (op + data_p+1, identifier, p->identifier_length-1); data_p += p->identifier_length; } - data = get_data(subf, &dlen); + data = get_data(subf, &dlen, control_field ? 0 : 1); memcpy (op + data_p, data, dlen); data_p += dlen; } op[data_p++] = ISO2709_FS; - memcpy (op + entry_p, field->u.tag.tag, 3); + if (marc_xml) + { + data1_xattr *xa; + for (xa = field->u.tag.attributes; xa; xa = xa->next) + if (!strcmp(xa->name, "tag")) + tag = xa->value; + } + else + tag = field->u.tag.tag; + + if (!tag || strlen(tag) != 3) + tag = "000"; + memcpy (op + entry_p, tag, 3); + entry_p += 3; memint (op + entry_p, data_p - data_0, p->length_data_entry); entry_p += p->length_data_entry;