ISO2709 output for yaz_marc utility
[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.23 2003-12-11 00:37:23 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] [-I] [-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 #ifdef CODESET
62     to = nl_langinfo(CODESET);
63 #endif
64 #endif
65
66     while ((r = options("vc:xOXIf:t:", argv, argc, &arg)) != -2)
67     {
68         int count;
69         no++;
70         switch (r)
71         {
72         case 'f':
73             from = arg;
74             break;
75         case 't':
76             to = arg;
77             break;
78         case 'c':
79             if (cfile)
80                 fclose (cfile);
81             cfile = fopen (arg, "w");
82             break;
83         case 'x':
84             xml = YAZ_MARC_SIMPLEXML;
85             break;
86         case 'O':
87             xml = YAZ_MARC_OAIMARC;
88             break;
89         case 'X':
90             xml = YAZ_MARC_MARCXML;
91             break;
92         case 'I':
93             xml = YAZ_MARC_ISO2709;
94             break;
95         case 0:
96             inf = fopen (arg, "rb");
97             count = 0;
98             if (!inf)
99             {
100                 fprintf (stderr, "%s: cannot open %s:%s\n",
101                          prog, arg, strerror (errno));
102                 exit(1);
103             }
104             if (cfile)
105                 fprintf (cfile, "char *marc_records[] = {\n");
106             if (1)
107             {
108                 yaz_marc_t mt = yaz_marc_create();
109                 yaz_iconv_t cd = 0;
110
111                 if (from && to)
112                 {
113                     cd = yaz_iconv_open(to, from);
114                     if (!cd)
115                     {
116                         fprintf(stderr, "conversion from %s to %s "
117                                 "unsupported\n", from, to);
118                         exit(2);
119                     }
120                     yaz_marc_iconv(mt, cd);
121                 }
122                 yaz_marc_xml(mt, xml);
123                 yaz_marc_debug(mt, verbose);
124                 while (1)
125                 {
126                     int len;
127                     char *result;
128                     int rlen;
129                     
130                     r = fread (buf, 1, 5, inf);
131                     if (r < 5)
132                         break;
133                     len = atoi_n(buf, 5);
134                     if (len < 25 || len > 100000)
135                         break;
136                     len = len - 5;
137                     r = fread (buf + 5, 1, len, inf);
138                     if (r < len)
139                         break;
140                     r = yaz_marc_decode_buf (mt, buf, -1, &result, &rlen);
141                     if (r <= 0)
142                         break;
143 #if 1
144                     fwrite (result, rlen, 1, stdout);
145 #else
146                     if (!cd)
147                         fwrite (result, rlen, 1, stdout);
148                     else
149                     {
150                         char outbuf[12];
151                         size_t inbytesleft = rlen;
152                         const char *inp = result;
153                         
154                         while (inbytesleft)
155                         {
156                             size_t outbytesleft = sizeof(outbuf);
157                             char *outp = outbuf;
158                             size_t r = yaz_iconv (cd, (char**) &inp,
159                                                   &inbytesleft, 
160                                                   &outp, &outbytesleft);
161                             if (r == (size_t) (-1))
162                             {
163                                 int e = yaz_iconv_error(cd);
164                                 if (e != YAZ_ICONV_E2BIG)
165                                     break;
166                             }
167                             fwrite (outbuf, outp - outbuf, 1, stdout);
168                         }
169                     }
170 #endif
171                     if (cfile)
172                     {
173                         char *p = buf;
174                         int i;
175                         if (count)
176                             fprintf (cfile, ",");
177                         fprintf (cfile, "\n");
178                         for (i = 0; i < r; i++)
179                         {
180                             if ((i & 15) == 0)
181                                 fprintf (cfile, "  \"");
182                             fprintf (cfile, "\\x%02X", p[i] & 255);
183                             
184                             if (i < r - 1 && (i & 15) == 15)
185                                 fprintf (cfile, "\"\n");
186                             
187                         }
188                         fprintf (cfile, "\"\n");
189                     }
190                 }
191                 count++;
192                 if (cd)
193                     yaz_iconv_close(cd);
194                 yaz_marc_destroy(mt);
195             }
196             if (cfile)
197                 fprintf (cfile, "};\n");
198             fclose(inf);
199             break;
200         case 'v':
201             verbose++;
202             break;
203         default:
204             usage(prog);
205             exit (1);
206         }
207     }
208     if (cfile)
209         fclose (cfile);
210     if (!no)
211     {
212         usage(prog);
213         exit (1);
214     }
215     exit (0);
216 }