Moved towards version 1.2.
[ir-tcl-moved-to-github.git] / marc.c
diff --git a/marc.c b/marc.c
index 6322dc6..5b546ab 100644 (file)
--- a/marc.c
+++ b/marc.c
@@ -5,7 +5,28 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: marc.c,v $
- * Revision 1.3  1995-05-29 08:44:26  adam
+ * 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
@@ -32,6 +53,8 @@ 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))
@@ -43,18 +66,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)
@@ -93,16 +137,20 @@ 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
     {
         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)
     {
@@ -130,6 +178,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';
@@ -203,13 +252,13 @@ int ir_tcl_get_marc (Tcl_Interp *interp, const char *buf,
                 free (data);
             }
        }
+        if (mode == 'l' && *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;
 }