Version 5.14.8
[yaz-moved-to-github.git] / util / marcdump.c
index f92204e..adfc015 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2013 Index Data
+ * Copyright (C) Index Data
  * See the file LICENSE for details.
  */
 
 #endif
 
 #include <yaz/marcdisp.h>
+#include <yaz/json.h>
 #include <yaz/yaz-util.h>
 #include <yaz/xmalloc.h>
 #include <yaz/options.h>
+#include <yaz/backtrace.h>
 
 #ifndef SEEK_SET
 #define SEEK_SET 0
@@ -117,6 +119,53 @@ static void marcdump_read_line(yaz_marc_t mt, const char *fname)
     fclose(inf);
 }
 
+static void marcdump_read_json(yaz_marc_t mt, const char *fname)
+{
+    FILE *inf = fopen(fname, "rb");
+    if (!inf)
+    {
+        fprintf(stderr, "%s: cannot open %s:%s\n",
+                prog, fname, strerror(errno));
+        exit(1);
+    }
+    else
+    {
+        const char *errmsg;
+        size_t errpos;
+        WRBUF w = wrbuf_alloc();
+        struct json_node *n;
+        int c;
+
+        while ((c = getc(inf)) != EOF)
+            wrbuf_putc(w, c);
+        n = json_parse2(wrbuf_cstr(w), &errmsg, &errpos);
+        if (n)
+        {
+            int r = yaz_marc_read_json_node(mt, n);
+            if (r == 0)
+            {
+                wrbuf_rewind(w);
+                yaz_marc_write_mode(mt, w);
+                fputs(wrbuf_cstr(w), stdout);
+                wrbuf_rewind(w);
+            }
+            else
+            {
+                fprintf(stderr, "%s: JSON MARC parsing failed ret=%d\n", fname,
+                        r);
+            }
+        }
+        else
+        {
+            fprintf(stderr, "%s: JSON parse error: %s . pos=%ld\n", fname,
+                    errmsg, (long) errpos);
+        }
+        wrbuf_destroy(w);
+        fclose(inf);
+    }
+}
+
+
 #if YAZ_HAVE_XML2
 static void marcdump_read_xml(yaz_marc_t mt, const char *fname)
 {
@@ -133,8 +182,7 @@ static void marcdump_read_xml(yaz_marc_t mt, const char *fname)
             int type = xmlTextReaderNodeType(reader);
             if (type == XML_READER_TYPE_ELEMENT)
             {
-                const char *name = (const char *)
-                    xmlTextReaderLocalName(reader);
+                char *name = (char *) xmlTextReaderLocalName(reader);
                 if (!strcmp(name, "record") || !strcmp(name, "r"))
                 {
                     xmlNodePtr ptr = xmlTextReaderExpand(reader);
@@ -158,8 +206,10 @@ static void marcdump_read_xml(yaz_marc_t mt, const char *fname)
                         wrbuf_rewind(wrbuf);
                     }
                 }
+                xmlFree(name);
             }
         }
+        xmlFreeTextReader(reader);
     }
 #else
     xmlDocPtr doc = xmlParseFile(fname);
@@ -244,6 +294,10 @@ static void dump(const char *fname, const char *from, const char *to,
     {
         marcdump_read_line(mt, fname);
     }
+    else if (input_format == YAZ_MARC_JSON)
+    {
+        marcdump_read_json(mt, fname);
+    }
     else if (input_format == YAZ_MARC_ISO2709)
     {
         FILE *inf = fopen(fname, "rb");
@@ -266,6 +320,7 @@ static void dump(const char *fname, const char *from, const char *to,
             size_t len_result;
             size_t r;
             char buf[100001];
+            yaz_iconv_t cd1 = 0;
 
             r = fread(buf, 1, 5, inf);
             if (r < 5)
@@ -375,7 +430,21 @@ static void dump(const char *fname, const char *from, const char *to,
                 }
             }
             len_result = rlen;
+
+            if (yaz_marc_check_marc21_coding(from, buf, 26))
+            {
+                cd1 = yaz_iconv_open(to, "utf-8");
+                if (cd1)
+                    yaz_marc_iconv(mt, cd1);
+            }
             r = yaz_marc_decode_buf(mt, buf, -1, &result, &len_result);
+
+            if (cd1)
+            {
+                yaz_iconv_close(cd1);
+                yaz_marc_iconv(mt, cd);
+            }
+
             if (r == -1)
                 no_errors++;
             if (r > 0 && result && len_result)
@@ -454,6 +523,7 @@ int main (int argc, char **argv)
 #endif
 
     prog = *argv;
+    yaz_enable_panic_backtrace(prog);
     while ((r = options("i:o:C:npc:xOeXIf:t:s:l:Vv", argv, argc, &arg)) != -2)
     {
         no++;