X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=marc.c;h=f04316be8e40da68d59ce1bf14bebd0a453d2e70;hb=d026c3e06f6e19e5ed4174ab1a504a4b5af79183;hp=9320d407522f59188eba2890a03b12fd4f999d29;hpb=b7bac2322e7a6855f60d167509108eff3d21bd65;p=ir-tcl-moved-to-github.git diff --git a/marc.c b/marc.c index 9320d40..f04316b 100644 --- a/marc.c +++ b/marc.c @@ -5,7 +5,27 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: marc.c,v $ - * Revision 1.5 1995-06-30 12:39:26 adam + * Revision 1.11 2005-03-10 13:54:38 adam + * Define irtcl_atoi_n rather than the YAZ function atoi_n + * + * Revision 1.10 1999/02/08 09:22:31 franck + * Added a grs mode for ir_tcl_get_marc which returns MARC records in a TCL + * structure similar to that of ir_tcl_get_grs. + * + * Revision 1.9 1996/07/03 13:31:13 adam + * The xmalloc/xfree functions from YAZ are used to manage memory. + * + * Revision 1.8 1995/11/14 16:48:00 adam + * Bug fix: record extraction in line mode merged lines with same tag. + * + * Revision 1.7 1995/11/09 15:24:02 adam + * Allow charsets [..] in record match. + * + * Revision 1.6 1995/08/28 12:21:22 adam + * Removed lines and list as synonyms of list in MARC extractron. + * Configure searches also for tk4.0 / tcl7.4. + * + * Revision 1.5 1995/06/30 12:39:26 adam * Bug fix: loadFile didn't set record type. * The MARC routines are a little less strict in the interpretation. * Script display.tcl replaces the old marc.tcl. @@ -39,7 +59,7 @@ #define ISO2709_FS 036 #define ISO2709_IDFS 037 -static int atoi_n (const char *buf, int len) +static int irtcl_atoi_n (const char *buf, int len) { int val = 0; @@ -56,18 +76,39 @@ static int atoi_n (const char *buf, int len) static int marc_compare (const char *f, const char *p) { + int ch; + if (*p == '*') return 0; if (!f) return -*p; - for (; *f && *p; f++, p++) - { - if (*p == '?') - continue; - if (*p != *f) - break; - } - return *f - *p; + for (; (ch = *p) && *f; f++, p++) + switch (*p) + { + case '*': + return 0; + case '?': + ch = *f; + break; + case '[': + while (1) + if (!*++p) + break; + else if (*p == ']') + { + p++; + break; + } + else if (*p == *f) + ch = *p; + if (ch != *p) + return *f - ch; + break; + default: + if (ch != *f) + return *f - ch; + } + return *f - ch; } char *ir_tcl_fread_marc (FILE *inf, size_t *size) @@ -77,14 +118,14 @@ char *ir_tcl_fread_marc (FILE *inf, size_t *size) if (fread (length, 1, 5, inf) != 5) return NULL; - *size = atoi_n (length, 5); + *size = irtcl_atoi_n (length, 5); if (*size <= 6) return NULL; - if (!(buf = malloc (*size+1))) + if (!(buf = xmalloc (*size+1))) return NULL; if (fread (buf+5, 1, *size-5, inf) != (*size-5)) { - free (buf); + xfree (buf); return NULL; } memcpy (buf, length, 5); @@ -106,11 +147,12 @@ int ir_tcl_get_marc (Tcl_Interp *interp, const char *buf, char ptag[4]; int mode = 0; - *ptag = '\0'; if (!strcmp (argv[3], "field")) mode = 'f'; - else if (!strcmp (argv[3], "lines") || !strcmp (argv[3], "list")) + else if (!strcmp (argv[3], "line")) mode = 'l'; + else if (!strcmp (argv[3], "grs")) + mode = 'g'; else { Tcl_AppendResult (interp, "Unknown MARC extract mode", NULL); @@ -121,19 +163,19 @@ int ir_tcl_get_marc (Tcl_Interp *interp, const char *buf, Tcl_AppendResult (interp, "Not a MARC record", NULL); return TCL_ERROR; } - record_length = atoi_n (buf, 5); + record_length = irtcl_atoi_n (buf, 5); if (record_length < 25) { Tcl_AppendResult (interp, "Not a MARC record", NULL); return TCL_ERROR; } - indicator_length = atoi_n (buf+10, 1); - identifier_length = atoi_n (buf+11, 1); - base_address = atoi_n (buf+12, 4); + indicator_length = irtcl_atoi_n (buf+10, 1); + identifier_length = irtcl_atoi_n (buf+11, 1); + base_address = irtcl_atoi_n (buf+12, 4); - length_data_entry = atoi_n (buf+20, 1); - length_starting = atoi_n (buf+21, 1); - length_implementation = atoi_n (buf+22, 1); + length_data_entry = irtcl_atoi_n (buf+20, 1); + length_starting = irtcl_atoi_n (buf+21, 1); + length_implementation = irtcl_atoi_n (buf+22, 1); for (entry_p = 24; buf[entry_p] != ISO2709_FS; ) entry_p += 3+length_data_entry+length_starting; @@ -148,12 +190,13 @@ int ir_tcl_get_marc (Tcl_Interp *interp, const char *buf, char indicator[128]; char identifier[128]; + *ptag = '\0'; memcpy (tag, buf+entry_p, 3); entry_p += 3; tag[3] = '\0'; - data_length = atoi_n (buf+entry_p, length_data_entry); + data_length = irtcl_atoi_n (buf+entry_p, length_data_entry); entry_p += length_data_entry; - data_offset = atoi_n (buf+entry_p, length_starting); + data_offset = irtcl_atoi_n (buf+entry_p, length_starting); entry_p += length_starting; i = data_offset + base_address; end_offset = i+data_length-1; @@ -192,7 +235,7 @@ int ir_tcl_get_marc (Tcl_Interp *interp, const char *buf, } if (marc_compare (identifier, argv[6])==0) { - char *data = malloc (i-i0+1); + char *data = xmalloc (i-i0+1); memcpy (data, buf+i0, i-i0); data[i-i0] = '\0'; @@ -216,18 +259,41 @@ int ir_tcl_get_marc (Tcl_Interp *interp, const char *buf, Tcl_AppendElement (interp, data); Tcl_AppendResult (interp, "} ", NULL); } + else if (mode == 'g') + { + if (strcmp (tag, ptag)) + { + if (*ptag) + Tcl_AppendResult (interp, "}} ", NULL); + if (*indicator) + Tcl_AppendResult (interp, "{ 0 numeric {", tag, + indicator, "} subtree {", NULL); + else + Tcl_AppendResult (interp, "{ 0 numeric ", tag, + " subtree {", NULL); + strcpy (ptag, tag); + } + if (*identifier) + Tcl_AppendResult (interp, "{3 string ", identifier, + " string ", NULL); + else + Tcl_AppendResult (interp, "{1 numeric 19 string ", + NULL); + Tcl_AppendElement (interp, data); + Tcl_AppendResult (interp, "} ", NULL); + } else Tcl_AppendElement (interp, data); - free (data); + xfree (data); } } + if (((mode == 'l') || (mode == 'g')) && *ptag) + Tcl_AppendResult (interp, "}} ", NULL); if (i < end_offset) logf (LOG_WARN, "MARC: separator but not at end of field"); if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS) logf (LOG_WARN, "MARC: no separator at end of field"); } - if (mode == 'l' && *ptag) - Tcl_AppendResult (interp, "}} ", NULL); return TCL_OK; }