Fixes for gcc warnings - mostly WRT check of returns values
[yaz-moved-to-github.git] / util / yaziconv.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2008 Index Data
3  * See the file LICENSE for details.
4  */
5
6 #if HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <string.h>
13 #include <ctype.h>
14
15 #include <yaz/yaz-util.h>
16
17 #define CHUNK_IN 64
18 #define CHUNK_OUT 64
19
20 void write_out(const char *b0, const char *b1)
21 {
22     size_t sz = b1 - b0;
23     if (sz)
24     {
25         if (fwrite(b0, 1, sz, stdout) != sz)
26         {
27             fprintf(stderr, "yaz-iconv: write failed\n");
28             exit(8);
29         }
30     }
31 }
32
33 void convert(FILE *inf, yaz_iconv_t cd, int verbose)
34 {
35     char inbuf0[CHUNK_IN], *inbuf = inbuf0;
36     char outbuf0[CHUNK_OUT], *outbuf = outbuf0;
37     size_t inbytesleft = CHUNK_IN;
38     size_t outbytesleft = CHUNK_OUT;
39     int mustread = 1;
40
41     while (1)
42     {
43         size_t r;
44         if (mustread)
45         {
46             r = fread(inbuf, 1, inbytesleft, inf);
47             if (inbytesleft != r)
48             {
49                 if (ferror(inf))
50                 {
51                     fprintf(stderr, "yaz-iconv: error reading file\n");
52                     exit(6);
53                 }
54                 if (r == 0)
55                 {
56                     write_out(outbuf0, outbuf);
57                     outbuf = outbuf0;
58                     outbytesleft = CHUNK_OUT;
59                     r = yaz_iconv(cd, 0, 0, &outbuf, &outbytesleft);
60                     write_out(outbuf0, outbuf);
61                     break;
62                 }
63                 inbytesleft = r;
64             }
65         }
66         if (verbose > 1)
67         {
68             fprintf(stderr, "yaz_iconv: inbytesleft=%ld outbytesleft=%ld\n",
69                     (long) inbytesleft, (long) outbytesleft);
70
71         }
72         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
73         if (r == (size_t)(-1))
74         {
75             int e = yaz_iconv_error(cd);
76             if (e == YAZ_ICONV_EILSEQ)
77             {
78                 fprintf(stderr, "invalid sequence\n");
79                 return ;
80             }
81             else if (e == YAZ_ICONV_EINVAL) /* incomplete input */
82             { 
83                 size_t i;
84                 for (i = 0; i<inbytesleft; i++)
85                     inbuf0[i] = inbuf[i];
86
87                 r = fread(inbuf0 + i, 1, CHUNK_IN - i, inf);
88                 if (r != CHUNK_IN - i)
89                 {
90                     if (ferror(inf))
91                     {
92                         fprintf(stderr, "yaz-iconv: error reading file\n");
93                         exit(6);
94                     }
95                 }
96                 if (r == 0)
97                 {
98                     fprintf(stderr, "invalid sequence due to missing input\n");
99                     return ;
100                 }
101                 inbytesleft += r;
102                 inbuf = inbuf0;
103                 mustread = 0;
104             }
105             else if (e == YAZ_ICONV_E2BIG) /* no more output space */
106             {
107                 write_out(outbuf0, outbuf);
108                 outbuf = outbuf0;
109                 outbytesleft = CHUNK_OUT;
110                 mustread = 0;
111             }
112             else
113             {
114                 fprintf(stderr, "yaz-iconv: unknown error\n");
115                 exit(7);
116             }
117         }
118         else
119         {
120             inbuf = inbuf0;
121             inbytesleft = CHUNK_IN;
122
123             write_out(outbuf0, outbuf);
124             outbuf = outbuf0;
125             outbytesleft = CHUNK_OUT;
126
127             mustread = 1;
128         }
129     }
130 }
131
132 int main(int argc, char **argv)
133 {
134     int ret;
135     int verbose = 0;
136     char *from = 0;
137     char *to = 0;
138     char *arg;
139     yaz_iconv_t cd;
140     FILE *inf = stdin;
141
142     while ((ret = options("vf:t:", argv, argc, &arg)) != -2)
143     {
144         switch (ret)
145         {
146         case 0:
147             inf = fopen(arg, "rb");
148             if (!inf)
149             {
150                 fprintf(stderr, "yaz-iconv: cannot open %s", arg);
151                 exit(2);
152             }
153             break;
154         case 'f':
155             from = arg;
156             break;
157         case 't':
158             to = arg;
159             break;
160         case 'v':
161             verbose++;
162             break;
163         default:
164             fprintf(stderr, "yaz-iconv: Usage\n"
165                     "yaziconv -f encoding -t encoding [-v] [file]\n");
166             exit(1);
167         }
168     }
169     if (!to)
170     {
171         fprintf(stderr, "yaz-iconv: -t encoding missing\n");
172         exit(3);
173     }
174     if (!from)
175     {
176         fprintf(stderr, "yaz-iconv: -f encoding missing\n");
177         exit(4);
178     }
179     cd = yaz_iconv_open(to, from);
180     if (!cd)
181     {
182         fprintf(stderr, "yaz-iconv: unsupported encoding\n");
183         exit(5);
184     }
185     else
186     {
187         if (verbose)
188         {
189             fprintf(stderr, "yaz-iconv: using %s\n",
190                     yaz_iconv_isbuiltin(cd) ? "YAZ" : "iconv");
191         }
192     }
193     convert(inf, cd, verbose);
194     yaz_iconv_close(cd);
195     return 0;
196 }
197 /*
198  * Local variables:
199  * c-basic-offset: 4
200  * indent-tabs-mode: nil
201  * End:
202  * vim: shiftwidth=4 tabstop=8 expandtab
203  */
204