e46beab02cea854d0894a44708b4c84f52505bf1
[yaz-moved-to-github.git] / util / marcdump.c
1 /*
2  * Copyright (c) 1995-2003, Index Data
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Id: marcdump.c,v 1.21 2003-02-12 22:02:33 adam Exp $
7  */
8
9 #if HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17
18 #if HAVE_LOCALE_H
19 #include <locale.h>
20 #endif
21 #if HAVE_LANGINFO_H
22 #include <langinfo.h>
23 #endif
24
25 #include <yaz/marcdisp.h>
26 #include <yaz/yaz-util.h>
27 #include <yaz/xmalloc.h>
28 #include <yaz/options.h>
29
30 #ifndef SEEK_SET
31 #define SEEK_SET 0
32 #endif
33 #ifndef SEEK_END
34 #define SEEK_END 2
35 #endif
36
37 static void usage(const char *prog)
38 {
39     fprintf (stderr, "Usage: %s [-c cfile] [-f from] [-t to] [-x] [-O] [-X] [-v] file...\n",
40              prog);
41
42
43 int main (int argc, char **argv)
44 {
45     int r;
46     char *arg;
47     int verbose = 0;
48     FILE *inf;
49     char buf[100001];
50     char *prog = *argv;
51     int no = 0;
52     int xml = 0;
53     FILE *cfile = 0;
54     char *from = 0, *to = 0;
55
56     
57 #if HAVE_LOCALE_H
58     setlocale(LC_CTYPE, "");
59 #endif
60 #if HAVE_LANGINFO_H
61     to = nl_langinfo(CODESET);
62 #endif
63
64     while ((r = options("vc:xOXf:t:", argv, argc, &arg)) != -2)
65     {
66         int count;
67         no++;
68         switch (r)
69         {
70         case 'f':
71             from = arg;
72             break;
73         case 't':
74             to = arg;
75             break;
76         case 'c':
77             if (cfile)
78                 fclose (cfile);
79             cfile = fopen (arg, "w");
80             break;
81         case 'x':
82             xml = YAZ_MARC_SIMPLEXML;
83             break;
84         case 'O':
85             xml = YAZ_MARC_OAIMARC;
86             break;
87         case 'X':
88             xml = YAZ_MARC_MARCXML;
89             break;
90         case 0:
91             inf = fopen (arg, "r");
92             count = 0;
93             if (!inf)
94             {
95                 fprintf (stderr, "%s: cannot open %s:%s\n",
96                          prog, arg, strerror (errno));
97                 exit(1);
98             }
99             if (cfile)
100                 fprintf (cfile, "char *marc_records[] = {\n");
101             if (1)
102             {
103                 yaz_marc_t mt = yaz_marc_create();
104                 yaz_iconv_t cd = 0;
105
106                 if (from && to)
107                 {
108                     cd = yaz_iconv_open(to, from);
109                     if (!cd)
110                     {
111                         fprintf(stderr, "conversion from %s to %s "
112                                 "unsupported\n", from, to);
113                         exit(2);
114                     }
115                 }
116                 yaz_marc_xml(mt, xml);
117                 yaz_marc_debug(mt, verbose);
118                 while (1)
119                 {
120                     int len;
121                     char *result;
122                     int rlen;
123                     
124                     r = fread (buf, 1, 5, inf);
125                     if (r < 5)
126                         break;
127                     len = atoi_n(buf, 5);
128                     if (len < 25 || len > 100000)
129                         break;
130                     len = len - 5;
131                     r = fread (buf + 5, 1, len, inf);
132                     if (r < len)
133                         break;
134                     r = yaz_marc_decode_buf (mt, buf, -1, &result, &rlen);
135                     if (r <= 0)
136                         break;
137                     if (!cd)
138                         fwrite (result, rlen, 1, stdout);
139                     else
140                     {
141                         char outbuf[12];
142                         size_t inbytesleft = rlen;
143                         const char *inp = result;
144                         
145                         while (inbytesleft)
146                         {
147                             size_t outbytesleft = sizeof(outbuf);
148                             char *outp = outbuf;
149                             size_t r = yaz_iconv (cd, (char**) &inp,
150                                                   &inbytesleft, 
151                                                   &outp, &outbytesleft);
152                             if (r == (size_t) (-1))
153                             {
154                                 int e = yaz_iconv_error(cd);
155                                 if (e != YAZ_ICONV_E2BIG)
156                                     break;
157                             }
158                             fwrite (outbuf, outp - outbuf, 1, stdout);
159                         }
160                     }
161
162                     if (cfile)
163                     {
164                         char *p = buf;
165                         int i;
166                         if (count)
167                             fprintf (cfile, ",");
168                         fprintf (cfile, "\n");
169                         for (i = 0; i < r; i++)
170                         {
171                             if ((i & 15) == 0)
172                                 fprintf (cfile, "  \"");
173                             fprintf (cfile, "\\x%02X", p[i] & 255);
174                             
175                             if (i < r - 1 && (i & 15) == 15)
176                                 fprintf (cfile, "\"\n");
177                             
178                         }
179                         fprintf (cfile, "\"\n");
180                     }
181                 }
182                 count++;
183                 if (cd)
184                     yaz_iconv_close(cd);
185             }
186             if (cfile)
187                 fprintf (cfile, "};\n");
188             break;
189         case 'v':
190             verbose++;
191             break;
192         default:
193             usage(prog);
194             exit (1);
195         }
196     }
197     if (cfile)
198         fclose (cfile);
199     if (!no)
200     {
201         usage(prog);
202         exit (1);
203     }
204     exit (0);
205 }