Fix broken xml entity.
[idzebra-moved-to-github.git] / index / mod_grs_marc.c
index 52b59e8..078cbb7 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of the Zebra server.
-   Copyright (C) 1995-2008 Index Data
+   Copyright (C) Index Data
 
 Zebra is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -17,6 +17,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 */
 
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
 #include <stdio.h>
 #include <ctype.h>
 #include <assert.h>
@@ -34,7 +37,7 @@ struct marc_info {
     char type[256];
 };
 
-static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
+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];
@@ -63,23 +66,23 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
 
        yaz_log(YLOG_WARN, "MARC: Skipping bad byte %d (0x%02X)",
                *buf & 0xff, *buf & 0xff);
-       for (i = 0; i<4; i++)
+       for (i = 0; i < 4; i++)
            buf[i] = buf[i+1];
 
        if (p->stream->readf(p->stream, buf+4, 1) != 1)
            return NULL;
     }
-    record_length = atoi_n (buf, 5);
+    record_length = atoi_n(buf, 5);
     if (record_length < 25)
     {
-        yaz_log (YLOG_WARN, "MARC record length < 25, is %d", record_length);
+        yaz_log(YLOG_WARN, "MARC record length < 25, is %d", record_length);
         return NULL;
     }
 
     read_bytes = p->stream->readf(p->stream, buf+5, record_length-5);
     if (read_bytes < record_length-5)
     {
-        yaz_log (YLOG_WARN, "Couldn't read whole MARC record");
+        yaz_log(YLOG_WARN, "Couldn't read whole MARC record");
         return NULL;
     }
     /* skip until we meet a record separator */
@@ -105,24 +108,24 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
     }
 
     absynName = mi->type;
-    res_root = data1_mk_root (p->dh, p->mem, absynName);
+    res_root = data1_mk_root(p->dh, p->mem, absynName);
     if (!res_root)
     {
-        yaz_log (YLOG_WARN, "cannot read MARC without an abstract syntax");
+        yaz_log(YLOG_WARN, "cannot read MARC without an abstract syntax");
         return 0;
     }
     if (marc_xml)
     {
        data1_node *lead;
        const char *attr[] = { "xmlns", "http://www.loc.gov/MARC21/slim", 0};
-                        
-       res_top = data1_mk_tag (p->dh, p->mem, "record", attr, res_root);
+
+       res_top = data1_mk_tag(p->dh, p->mem, "record", attr, res_root);
 
        lead = data1_mk_tag(p->dh, p->mem, "leader", 0, res_top);
        data1_mk_text_n(p->dh, p->mem, buf, 24, lead);
     }
     else
-       res_top = data1_mk_tag (p->dh, p->mem, absynName, 0, res_root);
+       res_top = data1_mk_tag(p->dh, p->mem, absynName, 0, res_root);
 
     if ((marctab = data1_absyn_getmarctab(p->dh, res_root)))
     {
@@ -136,16 +139,16 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
     if (marctab && marctab->force_indicator_length >= 0)
        indicator_length = marctab->force_indicator_length;
     else
-       indicator_length = atoi_n (buf+10, 1);
+       indicator_length = atoi_n(buf+10, 1);
     if (marctab && marctab->force_identifier_length >= 0)
        identifier_length = marctab->force_identifier_length;
     else
-       identifier_length = atoi_n (buf+11, 1);
-    base_address = atoi_n (buf+12, 5);
+       identifier_length = atoi_n(buf+11, 1);
+    base_address = atoi_n(buf+12, 5);
 
-    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 = atoi_n(buf+20, 1);
+    length_starting = atoi_n(buf+21, 1);
+    length_implementation = atoi_n(buf+22, 1);
 
     for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
     {
@@ -183,21 +186,21 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
         data1_node *res;
         data1_node *parent = res_top;
 
-        memcpy (tag, buf+entry_p, 3);
+        memcpy(tag, buf+entry_p, 3);
         entry_p += 3;
         tag[3] = '\0';
 
        if (marc_xml)
            res = parent;
        else
-           res = data1_mk_tag_n (p->dh, p->mem, tag, 3, 0 /* attr */, parent);
-       
+           res = data1_mk_tag_n(p->dh, p->mem, tag, 3, 0 /* attr */, parent);
+
 #if MARC_DEBUG
-        fprintf (outf, "%s ", tag);
+        fprintf(outf, "%s ", tag);
 #endif
-        data_length = atoi_n (buf+entry_p, length_data_entry);
+        data_length = atoi_n(buf+entry_p, length_data_entry);
         entry_p += length_data_entry;
-        data_offset = atoi_n (buf+entry_p, length_starting);
+        data_offset = atoi_n(buf+entry_p, length_starting);
         entry_p += length_starting;
         i = data_offset + base_address;
         end_offset = i+data_length-1;
@@ -207,8 +210,8 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
            yaz_log(YLOG_WARN, "MARC: Bad offsets in data. Skipping rest");
            break;
        }
-       
-        if (memcmp (tag, "00", 2) && indicator_length)
+
+        if (memcmp(tag, "00", 2) && indicator_length)
         {
             /* generate indicator node */
            if (marc_xml)
@@ -222,7 +225,7 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
 
                res = data1_mk_tag(p->dh, p->mem, "datafield", attr, res);
 
-               for (j = 0; j<indicator_length; j++)
+               for (j = 0; j < indicator_length; j++)
                {
                    char str1[18], str2[2];
                    sprintf (str1, "ind%d", j+1);
@@ -231,8 +234,8 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
 
                    attr[0] = str1;
                    attr[1] = str2;
-                   
-                   data1_tag_add_attr (p->dh, p->mem, res, attr);
+
+                   data1_tag_add_attr(p->dh, p->mem, res, attr);
                }
            }
            else
@@ -240,25 +243,25 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
 #if MARC_DEBUG
                int j;
 #endif
-               res = data1_mk_tag_n (p->dh, p->mem, 
-                                     buf+i, indicator_length, 0 /* attr */, res);
+               res = data1_mk_tag_n(p->dh, p->mem, buf+i,
+                                     indicator_length, 0 /* attr */, res);
 #if MARC_DEBUG
-               for (j = 0; j<indicator_length; j++)
-                   fprintf (outf, "%c", buf[j+i]);
+               for (j = 0; j < indicator_length; j++)
+                   fprintf(outf, "%c", buf[j+i]);
 #endif
            }
            i += indicator_length;
-        } 
+        }
        else
        {
            if (marc_xml)
            {
                const char *attr[10];
-               
+
                attr[0] = "tag";
                attr[1] = tag;
                attr[2] = 0;
-               
+
                res = data1_mk_tag(p->dh, p->mem, "controlfield", attr, res);
            }
        }
@@ -269,14 +272,14 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
         {
            if (memcmp (tag, "00", 2) && identifier_length)
             {
+                int j;
                data1_node *res;
                if (marc_xml)
                {
-                   int j;
                    const char *attr[3];
                    char code[10];
-                   
-                   for (j = 1; j<identifier_length && j < 9; j++)
+
+                   for (j = 1; j < identifier_length && j < 9; j++)
                        code[j-1] = buf[i+j];
                    code[j-1] = 0;
                    attr[0] = "code";
@@ -287,15 +290,15 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
                }
                else
                {
-                   res = data1_mk_tag_n (p->dh, p->mem,
-                                          buf+i+1, identifier_length-1, 
-                                          0 /* attr */, parent);
+                   res = data1_mk_tag_n(p->dh, p->mem,
+                                         buf+i+1, identifier_length-1,
+                                         0 /* attr */, parent);
                }
 #if MARC_DEBUG
-                fprintf (outf, " $"); 
-                for (j = 1; j<identifier_length; j++)
-                    fprintf (outf, "%c", buf[j+i]);
-                fprintf (outf, " ");
+                fprintf (outf, " $");
+                for (j = 1; j < identifier_length; j++)
+                    fprintf(outf, "%c", buf[j+i]);
+                fprintf(outf, " ");
 #endif
                 i += identifier_length;
                 i0 = i;
@@ -303,31 +306,31 @@ static data1_node *grs_read_iso2709 (struct grs_read_info *p, int marc_xml)
                     buf[i] != ISO2709_FS && i < end_offset)
                {
 #if MARC_DEBUG
-                   fprintf (outf, "%c", buf[i]);
+                   fprintf(outf, "%c", buf[i]);
 #endif
                    i++;
                }
-               data1_mk_text_n (p->dh, p->mem, buf + i0, i - i0, res);
+               data1_mk_text_n(p->dh, p->mem, buf + i0, i - i0, res);
                i0 = i;
             }
             else
             {
 #if MARC_DEBUG
-                fprintf (outf, "%c", buf[i]);
+                fprintf(outf, "%c", buf[i]);
 #endif
                 i++;
             }
         }
         if (i > i0)
        {
-            data1_mk_text_n (p->dh, p->mem, buf + i0, i - i0, parent);
+            data1_mk_text_n(p->dh, p->mem, buf + i0, i - i0, parent);
        }
 #if MARC_DEBUG
         fprintf (outf, "\n");
         if (i < end_offset)
-            fprintf (outf, "-- separator but not at end of field\n");
+            fprintf(outf, "-- separator but not at end of field\n");
         if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
-            fprintf (outf, "-- no separator at end of field\n");
+            fprintf(outf, "-- no separator at end of field\n");
 #endif
     }
     return res_root;
@@ -348,7 +351,7 @@ static char *get_data(data1_node *n, int *len)
             int i;
             *len = n->u.data.len;
 
-            for (i = 0; i<*len; i++)
+            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]))
@@ -362,7 +365,7 @@ static char *get_data(data1_node *n, int *len)
        else if (n->which == DATA1N_data)
             n = n->next;
        else
-            break;     
+            break;
     }
     r = "";
     *len = strlen(r);
@@ -372,8 +375,8 @@ static char *get_data(data1_node *n, int *len)
 static data1_node *lookup_subfield(data1_node *node, const char *name)
 {
     data1_node *p;
-    
-    for (p=node; p; p=p->next)
+
+    for (p = node; p; p = p->next)
     {
        if (!yaz_matchstr(p->u.tag.tag, name))
            return p;
@@ -385,8 +388,8 @@ static inline_subfield *lookup_inline_subfield(inline_subfield *pisf,
                                               const char *name)
 {
     inline_subfield *p;
-    
-    for (p=pisf; p; p=p->next)
+
+    for (p = pisf; p; p = p->next)
     {
        if (!yaz_matchstr(p->name, name))
            return p;
@@ -398,13 +401,13 @@ static inline_subfield *cat_inline_subfield(mc_subfield *psf, WRBUF buf,
                                            inline_subfield *pisf)
 {
     mc_subfield *p;
-    
+
     for (p = psf; p && pisf; p = p->next)
     {
        if (p->which == MC_SF)
        {
            inline_subfield *found = lookup_inline_subfield(pisf, p->name);
-           
+
            if (found)
            {
                if (strcmp(p->prefix, "_"))
@@ -429,14 +432,14 @@ static inline_subfield *cat_inline_subfield(mc_subfield *psf, WRBUF buf,
                }
 #if MARCOMP_DEBUG
                yaz_log(YLOG_LOG, "cat_inline_subfield(): add subfield $%s", found->name);
-#endif         
+#endif
                pisf = found->next;
            }
        }
        else if (p->which == MC_SFVARIANT)
        {
            inline_subfield *next;
-           
+
            do {
                next = cat_inline_subfield(p->u.child, buf, pisf);
                if (next == pisf)
@@ -448,7 +451,7 @@ static inline_subfield *cat_inline_subfield(mc_subfield *psf, WRBUF buf,
        {
            mc_subfield *pp;
            int found;
-           
+
            for (pp = p->u.child, found = 0; pp; pp = pp->next)
            {
                if (!yaz_matchstr(pisf->name, p->name))
@@ -465,11 +468,11 @@ static inline_subfield *cat_inline_subfield(mc_subfield *psf, WRBUF buf,
            }
        }
     }
-    return pisf; 
+    return pisf;
 }
 
 static void cat_inline_field(mc_field *pf, WRBUF buf, data1_node *subfield)
-{    
+{
     if (!pf || !subfield)
        return;
 
@@ -478,13 +481,13 @@ static void cat_inline_field(mc_field *pf, WRBUF buf, data1_node *subfield)
        int len;
        inline_field *pif=NULL;
        data1_node *psubf;
-       
+
        if (yaz_matchstr(subfield->u.tag.tag, "1"))
        {
            subfield = subfield->next;
            continue;
        }
-       
+
        psubf = subfield;
        pif = inline_mk_field();
        do
@@ -495,13 +498,13 @@ static void cat_inline_field(mc_field *pf, WRBUF buf, data1_node *subfield)
                yaz_log(YLOG_WARN, "inline subfield ($%s): parse error",
                    psubf->u.tag.tag);
                inline_destroy_field(pif);
-               return; 
+               return;
            }
            psubf = psubf->next;
        } while (psubf && yaz_matchstr(psubf->u.tag.tag, "1"));
-       
+
        subfield = psubf;
-       
+
        if (pif && !yaz_matchstr(pif->name, pf->name))
        {
            if (!pf->list && pif->list)
@@ -518,12 +521,12 @@ static void cat_inline_field(mc_field *pf, WRBUF buf, data1_node *subfield)
 
                ind1 = (pif->ind1[0] == ' ') ? '_':pif->ind1[0];
                ind2 = (pif->ind2[0] == ' ') ? '_':pif->ind2[0];
-    
+
                if (((pf->ind1[0] == '.') || (ind1 == pf->ind1[0])) &&
                    ((pf->ind2[0] == '.') || (ind2 == pf->ind2[0])))
                {
                    cat_inline_subfield(pf->list, buf, pif->list);
-                   
+
                    /*
                        add separator for inline fields
                    */
@@ -540,8 +543,8 @@ static void cat_inline_field(mc_field *pf, WRBUF buf, data1_node *subfield)
        }
        inline_destroy_field(pif);
     }
-#if MARCOMP_DEBUG    
-    yaz_log(YLOG_LOG, "cat_inline_field(): got buffer {%s}", buf);
+#if MARCOMP_DEBUG
+    yaz_log(YLOG_LOG, "cat_inline_field(): got buffer {%s}", wrbuf_cstr(buf));
 #endif
 }
 
@@ -549,23 +552,23 @@ static data1_node *cat_subfield(mc_subfield *psf, WRBUF buf,
                                data1_node *subfield)
 {
     mc_subfield *p;
-    
+
     for (p = psf; p && subfield; p = p->next)
     {
        if (p->which == MC_SF)
        {
            data1_node *found = lookup_subfield(subfield, p->name);
-           
+
            if (found)
            {
                int len;
-               
+
                if (strcmp(p->prefix, "_"))
                {
                    wrbuf_puts(buf, " ");
                    wrbuf_puts(buf, p->prefix);
                }
-               
+
                if (p->u.in_line)
                {
                    cat_inline_field(p->u.in_line, buf, found);
@@ -585,9 +588,9 @@ static data1_node *cat_subfield(mc_subfield *psf, WRBUF buf,
                    wrbuf_puts(buf, p->suffix);
                    wrbuf_puts(buf, " ");
                }
-#if MARCOMP_DEBUG              
+#if MARCOMP_DEBUG
                yaz_log(YLOG_LOG, "cat_subfield(): add subfield $%s", found->u.tag.tag);
-#endif         
+#endif
                subfield = found->next;
            }
        }
@@ -605,7 +608,7 @@ static data1_node *cat_subfield(mc_subfield *psf, WRBUF buf,
        {
            mc_subfield *pp;
            int found;
-           
+
            for (pp = p->u.child, found = 0; pp; pp = pp->next)
            {
                if (!yaz_matchstr(subfield->u.tag.tag, pp->name))
@@ -630,27 +633,27 @@ static data1_node *cat_field(struct grs_read_info *p, mc_field *pf,
 {
     data1_node *subfield;
     int ind1, ind2;
-    
+
     if (!pf || !field)
        return 0;
 
-    
+
     if (yaz_matchstr(field->u.tag.tag, pf->name))
        return field->next;
 
     subfield = field->child;
-    
+
     if (!subfield)
        return field->next;
 
     /*
        check subfield without indicators
     */
-    
+
     if (!pf->list && subfield->which == DATA1N_data)
     {
        int len;
-       
+
        if (pf->interval.start == -1)
        {
            wrbuf_puts(buf, get_data(field, &len));
@@ -662,18 +665,18 @@ static data1_node *cat_field(struct grs_read_info *p, mc_field *pf,
            wrbuf_puts(buf, "");
        }
 #if MARCOMP_DEBUG
-        yaz_log(YLOG_LOG, "cat_field(): got buffer {%s}", buf);
+        yaz_log(YLOG_LOG, "cat_field(): got buffer {%s}", wrbuf_cstr(buf));
 #endif
        return field->next;
     }
-    
+
     /*
        check indicators
     */
 
     ind1 = (subfield->u.tag.tag[0] == ' ') ? '_':subfield->u.tag.tag[0];
     ind2 = (subfield->u.tag.tag[1] == ' ') ? '_':subfield->u.tag.tag[1];
-    
+
     if (!(
        ((pf->ind1[0] == '.') || (ind1 == pf->ind1[0])) &&
        ((pf->ind2[0] == '.') || (ind2 == pf->ind2[0]))
@@ -684,25 +687,25 @@ static data1_node *cat_field(struct grs_read_info *p, mc_field *pf,
 #endif
        return field->next;
     }
-    
+
     subfield = subfield->child;
-    
+
     if (!subfield)
        return field->next;
 
     cat_subfield(pf->list, buf, subfield);
 
-#if MARCOMP_DEBUG    
-    yaz_log(YLOG_LOG, "cat_field(): got buffer {%s}", buf);
+#if MARCOMP_DEBUG
+    yaz_log(YLOG_LOG, "cat_field(): got buffer {%s}", wrbuf_cstr(buf));
 #endif
-    
-    return field->next;    
+
+    return field->next;
 }
 
 static int is_empty(char *s)
 {
     char *p = s;
-    
+
     for (p = s; *p; p++)
     {
        if (!isspace(*(unsigned char *)p))
@@ -720,21 +723,21 @@ static void parse_data1_tree(struct grs_read_info *p, const char *mc_stmnt,
     mc_context *c;
     mc_field *pf;
     WRBUF buf;
-    
+
     c = mc_mk_context(mc_stmnt+3);
-    
+
     if (!c)
        return;
-       
+
     pf = mc_getfield(c);
-    
+
     if (!pf)
     {
        mc_destroy_context(c);
        return;
     }
     buf = wrbuf_alloc();
-#if MARCOMP_DEBUG    
+#if MARCOMP_DEBUG
     yaz_log(YLOG_LOG, "parse_data1_tree(): statement -{%s}", mc_stmnt);
 #endif
     if (!yaz_matchstr(pf->name, "ldr"))
@@ -743,7 +746,7 @@ static void parse_data1_tree(struct grs_read_info *p, const char *mc_stmnt,
 #if MARCOMP_DEBUG
        yaz_log(YLOG_LOG,"parse_data1_tree(): try LEADER from {%d} to {%d} positions",
            pf->interval.start, pf->interval.end);
-#endif 
+#endif
         if (marctab)
         {
             new = data1_mk_tag_n(p->dh, p->mem, mc_stmnt, strlen(mc_stmnt), 0, top);
@@ -754,21 +757,21 @@ static void parse_data1_tree(struct grs_read_info *p, const char *mc_stmnt,
     else
     {
        field=top->child;
-       
-       while(field)
+
+       while (field)
        {
            if (!yaz_matchstr(field->u.tag.tag, pf->name))
            {
                data1_node *new;
                char *pb;
-#if MARCOMP_DEBUG              
+#if MARCOMP_DEBUG
                yaz_log(YLOG_LOG, "parse_data1_tree(): try field {%s}", field->u.tag.tag);
-#endif         
+#endif
                wrbuf_rewind(buf);
                wrbuf_puts(buf, "");
 
                field = cat_field(p, pf, buf, field);
-               
+
                wrbuf_cstr(buf);
                 pb = wrbuf_buf(buf);
                for (pb = strtok(pb, "\n"); pb; pb = strtok(NULL, "\n"))
@@ -798,11 +801,11 @@ data1_node *grs_read_marcxml(struct grs_read_info *p)
 
     if (!root)
        return 0;
-       
+
     for (e = data1_absyn_getelements(p->dh, root); e; e=e->next)
     {
        data1_tag *tag = e->tag;
-       
+
        if (tag && tag->which == DATA1T_string &&
            !yaz_matchstr(tag->value.string, "mc?"))
                parse_data1_tree(p, tag->value.string, root);
@@ -817,11 +820,11 @@ data1_node *grs_read_marc(struct grs_read_info *p)
 
     if (!root)
        return 0;
-       
+
     for (e = data1_absyn_getelements(p->dh, root); e; e=e->next)
     {
        data1_tag *tag = e->tag;
-       
+
        if (tag && tag->which == DATA1T_string &&
            !yaz_matchstr(tag->value.string, "mc?"))
                parse_data1_tree(p, tag->value.string, root);
@@ -892,7 +895,7 @@ static struct recType marcxml_type = {
 };
 
 RecType
-#ifdef IDZEBRA_STATIC_GRS_MARC
+#if IDZEBRA_STATIC_GRS_MARC
 idzebra_filter_grs_marc
 #else
 idzebra_filter
@@ -903,10 +906,11 @@ idzebra_filter
     &marcxml_type,
     0,
 };
-    
+
 /*
  * Local variables:
  * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
  * indent-tabs-mode: nil
  * End:
  * vim: shiftwidth=4 tabstop=8 expandtab