1 /* Copyright (C) 2000-2001 Free Software Foundation, Inc.
2 This file is part of the GNU LIBICONV Library.
4 The GNU LIBICONV Library is free software; you can redistribute it
5 and/or modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 The GNU LIBICONV Library is distributed in the hope that it will be
10 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU LIBICONV Library; see the file COPYING.LIB.
16 If not, write to the Free Software Foundation, Inc., 59 Temple Place -
17 Suite 330, Boston, MA 02111-1307, USA. */
31 /* For systems that distinguish between text and binary I/O.
32 O_BINARY is usually declared in <fcntl.h>. */
33 #if !defined O_BINARY && defined _O_BINARY
34 /* For MSC-compatible compilers. */
35 # define O_BINARY _O_BINARY
36 # define O_TEXT _O_TEXT
39 /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */
44 # if !(defined(__EMX__) || defined(__DJGPP__))
45 # define setmode _setmode
46 # define fileno _fileno
49 # include <io.h> /* declares setmode() */
50 # include <unistd.h> /* declares isatty() */
51 # /* Avoid putting stdin/stdout in binary mode if it is connected to the
52 # console, because that would make it impossible for the user to
53 # interrupt the program through Ctrl-C or Ctrl-Break. */
54 # define SET_BINARY(fd) (!isatty(fd) ? (setmode(fd,O_BINARY), 0) : 0)
56 # define SET_BINARY(fd) setmode(fd,O_BINARY)
61 static int force_binary
= 0;
64 static void usage (int exitcode
)
66 const char* helpstring
=
68 "Usage: iconv [--binary] [-f fromcode] [-t tocode] [file ...]\n";
70 "Usage: iconv [-f fromcode] [-t tocode] [file ...]\n";
72 fprintf(exitcode
? stderr
: stdout
, helpstring
);
76 static void print_version (void)
78 printf("iconv (GNU libiconv %d.%d)\n",
79 _libiconv_version
>> 8, _libiconv_version
& 0xff);
81 Copyright (C) 2000-2001 Free Software Foundation, Inc.\n\
82 This is free software; see the source for copying conditions. There is NO\n\
83 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
84 Written by Bruno Haible.\n");
88 static int convert (iconv_t cd
, FILE* infile
, const char* infilename
)
90 char inbuf
[4096+4096];
96 SET_BINARY(fileno(infile
));
98 iconv(cd
,NULL
,NULL
,NULL
,NULL
);
100 size_t inbufsize
= fread(inbuf
+4096,1,4096,infile
);
101 if (inbufsize
== 0) {
105 fprintf(stderr
,"iconv: %s: incomplete character or shift sequence\n",infilename
);
109 const char* inptr
= inbuf
+4096-inbufrest
;
110 size_t insize
= inbufrest
+inbufsize
;
113 char* outptr
= outbuf
;
114 size_t outsize
= sizeof(outbuf
);
115 size_t res
= iconv(cd
,(ICONV_CONST
char**)&inptr
,&insize
,&outptr
,&outsize
);
116 if (outptr
!= outbuf
) {
117 int saved_errno
= errno
;
118 if (fwrite(outbuf
,1,outptr
-outbuf
,stdout
) < outptr
-outbuf
)
122 if (res
== (size_t)(-1)) {
123 if (errno
== EILSEQ
) {
124 fprintf(stderr
,"iconv: %s: cannot convert\n",infilename
);
126 } else if (errno
== EINVAL
) {
127 if (inbufsize
== 0 || insize
> 4096) {
128 fprintf(stderr
,"iconv: %s: incomplete character or shift sequence\n",infilename
);
133 /* Like memcpy(inbuf+4096-insize,inptr,insize), except that
134 we cannot use memcpy here, because source and destination
135 regions may overlap. */
136 char* restptr
= inbuf
+4096-insize
;
137 do { *restptr
++ = *inptr
++; } while (--insize
> 0);
141 } else if (errno
!= E2BIG
) {
142 int saved_errno
= errno
;
143 fprintf(stderr
,"iconv: %s: ",infilename
);
153 char* outptr
= outbuf
;
154 size_t outsize
= sizeof(outbuf
);
155 size_t res
= iconv(cd
,NULL
,NULL
,&outptr
,&outsize
);
156 if (outptr
!= outbuf
) {
157 int saved_errno
= errno
;
158 if (fwrite(outbuf
,1,outptr
-outbuf
,stdout
) < outptr
-outbuf
)
162 if (res
== (size_t)(-1)) {
163 if (errno
== EILSEQ
) {
164 fprintf(stderr
,"iconv: %s: cannot convert\n",infilename
);
166 } else if (errno
== EINVAL
) {
167 fprintf(stderr
,"iconv: %s: incomplete character or shift sequence\n",infilename
);
170 int saved_errno
= errno
;
171 fprintf(stderr
,"iconv: %s: ",infilename
);
178 if (ferror(infile
)) {
179 fprintf(stderr
,"iconv: %s: I/O error\n",infilename
);
185 int main (int argc
, char* argv
[])
187 const char* fromcode
= NULL
;
188 const char* tocode
= NULL
;
194 /* Needed for the locale dependent encodings, "char" and "wchar_t". */
195 setlocale(LC_CTYPE
,"");
197 for (i
= 1; i
< argc
;) {
198 if (!strcmp(argv
[i
],"-f")) {
199 if (i
== argc
-1) usage(1);
200 if (fromcode
!= NULL
) usage(1);
201 fromcode
= argv
[i
+1];
205 if (!strcmp(argv
[i
],"-t")) {
206 if (i
== argc
-1) usage(1);
207 if (tocode
!= NULL
) usage(1);
212 if (!strcmp(argv
[i
],"--help")) {
215 if (!strcmp(argv
[i
],"--version")) {
219 if (!strcmp(argv
[i
],"--binary")) {
225 if (argv
[i
][0] == '-')
231 SET_BINARY(fileno(stdout
));
233 if (fromcode
== NULL
)
237 cd
= iconv_open(tocode
,fromcode
);
238 if (cd
== (iconv_t
)(-1)) {
239 if (iconv_open("UCS-4",fromcode
) == (iconv_t
)(-1))
240 fprintf(stderr
,"iconv: conversion from %s unsupported\n",fromcode
);
241 else if (iconv_open(tocode
,"UCS-4") == (iconv_t
)(-1))
242 fprintf(stderr
,"iconv: conversion to %s unsupported\n",tocode
);
244 fprintf(stderr
,"iconv: conversion from %s to %s unsupported\n",fromcode
,tocode
);
248 status
= convert(cd
,stdin
,"(stdin)");
251 for (; i
< argc
; i
++) {
252 const char* infilename
= argv
[i
];
253 FILE* infile
= fopen(infilename
,"r");
254 if (infile
== NULL
) {
255 int saved_errno
= errno
;
256 fprintf(stderr
,"iconv: %s: ",infilename
);
261 status
|= convert(cd
,infile
,infilename
);
267 if (ferror(stdout
)) {
268 fprintf(stderr
,"iconv: I/O error\n");