SRW, CQL, 2003
[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.20 2003-01-06 08:20:28 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                             int i;
148                             size_t outbytesleft = sizeof(outbuf);
149                             char *outp = outbuf;
150                             size_t r = yaz_iconv (cd, (char**) &inp,
151                                                   &inbytesleft, 
152                                                   &outp, &outbytesleft);
153                             if (r == (size_t) (-1))
154                             {
155                                 int e = yaz_iconv_error(cd);
156                                 if (e != YAZ_ICONV_E2BIG)
157                                     break;
158                             }
159                             fwrite (outbuf, outp - outbuf, 1, stdout);
160                         }
161                     }
162
163                     if (cfile)
164                     {
165                         char *p = buf;
166                         int i;
167                         if (count)
168                             fprintf (cfile, ",");
169                         fprintf (cfile, "\n");
170                         for (i = 0; i < r; i++)
171                         {
172                             if ((i & 15) == 0)
173                                 fprintf (cfile, "  \"");
174                             fprintf (cfile, "\\x%02X", p[i] & 255);
175                             
176                             if (i < r - 1 && (i & 15) == 15)
177                                 fprintf (cfile, "\"\n");
178                             
179                         }
180                         fprintf (cfile, "\"\n");
181                     }
182                 }
183                 count++;
184                 if (cd)
185                     yaz_iconv_close(cd);
186             }
187             if (cfile)
188                 fprintf (cfile, "};\n");
189             break;
190         case 'v':
191             verbose++;
192             break;
193         default:
194             usage(prog);
195             exit (1);
196         }
197     }
198     if (cfile)
199         fclose (cfile);
200     if (!no)
201     {
202         usage(prog);
203         exit (1);
204     }
205     exit (0);
206 }