X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=marc.c;h=8bbb69c265f7e5a74f29397de2d056cbaa255d1b;hb=e7202ba8f70cdd61f90ad87619424b8b62ee2389;hp=04d497fb16a5159d12524958849f3fc4545b7cba;hpb=06c9c5c547ac216c72d12b0d9b3539b9038d8a05;p=ir-tcl-moved-to-github.git diff --git a/marc.c b/marc.c index 04d497f..8bbb69c 100644 --- a/marc.c +++ b/marc.c @@ -1,10 +1,46 @@ /* * IR toolkit for tcl/tk * (c) Index Data 1995 + * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * * $Log: marc.c,v $ - * Revision 1.1 1995-05-26 08:54:19 adam + * 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. + * New interactive script: shell.tcl. + * + * Revision 1.4 1995/06/22 13:15:09 adam + * Feature: SUTRS. Setting getSutrs implemented. + * Work on display formats. + * Preferred record syntax can be set by the user. + * + * Revision 1.3 1995/05/29 08:44:26 adam + * Work on delete of objects. + * + * Revision 1.2 1995/05/26 11:44:11 adam + * Bugs fixed. More work on MARC utilities and queries. Test + * client is up-to-date again. + * + * Revision 1.1 1995/05/26 08:54:19 adam * New MARC utilities. Uses prefix query. * */ @@ -20,10 +56,12 @@ #define ISO2709_FS 036 #define ISO2709_IDFS 037 -int atoi_n (const char *buf, int len) +static int atoi_n (const char *buf, int len) { int val = 0; + if (!isdigit (buf[len-1])) + return 0; while (--len >= 0) { if (isdigit (*buf)) @@ -35,22 +73,41 @@ 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; } -FILE *outf = stderr; - char *ir_tcl_fread_marc (FILE *inf, size_t *size) { char length[5]; @@ -61,11 +118,11 @@ char *ir_tcl_fread_marc (FILE *inf, size_t *size) *size = 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); @@ -84,17 +141,25 @@ int ir_tcl_get_marc (Tcl_Interp *interp, const char *buf, int length_data_entry; int length_starting; int length_implementation; + char ptag[4]; int mode = 0; if (!strcmp (argv[3], "field")) mode = 'f'; - else if (!strcmp (argv[3], "lines")) + 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); return TCL_ERROR; } + if (!buf) + { + Tcl_AppendResult (interp, "Not a MARC record", NULL); + return TCL_ERROR; + } record_length = atoi_n (buf, 5); if (record_length < 25) { @@ -122,6 +187,7 @@ 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'; @@ -142,9 +208,10 @@ int ir_tcl_get_marc (Tcl_Interp *interp, const char *buf, continue; while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset) { + int i0; + if (memcmp (tag, "00", 2) && identifier_length) { - int i0; i++; for (j = 1; j