annotate lib/unicodeio.c @ 2305:463a686cf218

New file from Bruno. One portability tweak: guard inclusion of stddef.h.
author Jim Meyering <jim@meyering.net>
date Wed, 01 Mar 2000 13:22:35 +0000
parents
children add6290501b6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2305
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
1 /* Unicode character output to streams with locale dependent encoding.
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
2
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
3 Copyright (C) 2000 Free Software Foundation, Inc.
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
4
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
5 This program is free software; you can redistribute it and/or modify it
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
6 under the terms of the GNU Library General Public License as published
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
7 by the Free Software Foundation; either version 2, or (at your option)
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
8 any later version.
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
9
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
13 Library General Public License for more details.
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
14
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
15 You should have received a copy of the GNU Library General Public
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
16 License along with this program; if not, write to the Free Software
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
18 USA. */
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
19
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
20 /* Written by Bruno Haible <haible@clisp.cons.org>. */
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
21
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
22 #ifdef HAVE_CONFIG_H
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
23 # include <config.h>
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
24 #endif
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
25
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
26 #if HAVE_STDDEF_H
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
27 # include <stddef.h>
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
28 #endif
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
29
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
30 #include <stdio.h>
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
31
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
32 #if HAVE_ICONV
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
33 # include <iconv.h>
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
34 /* Name of UCS-4 encoding with machine dependent endianness and alignment. */
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
35 # ifdef _LIBICONV_VERSION
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
36 # define UCS4_NAME "UCS-4-INTERNAL"
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
37 # else
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
38 # define UCS4_NAME "INTERNAL"
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
39 # endif
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
40 #endif
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
41
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
42 #include <error.h>
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
43
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
44 #if ENABLE_NLS
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
45 # include <libintl.h>
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
46 # define _(Text) gettext (Text)
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
47 #else
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
48 # define _(Text) Text
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
49 #endif
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
50
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
51 #include "unicodeio.h"
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
52
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
53 /* Use md5.h for its nice detection of unsigned 32-bit type. */
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
54 #include "md5.h"
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
55 #undef uint32_t
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
56 #define uint32_t md5_uint32
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
57
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
58 /* Outputs the Unicode character CODE to the output stream STREAM.
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
59 Assumes that the locale doesn't change between two calls. */
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
60 void
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
61 print_unicode_char (FILE *stream, unsigned int code)
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
62 {
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
63 #if HAVE_ICONV
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
64 static int initialized;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
65 static iconv_t ucs4_to_local;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
66
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
67 uint32_t in;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
68 char outbuf[25];
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
69 const char *inptr;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
70 size_t inbytesleft;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
71 char *outptr;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
72 size_t outbytesleft;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
73 size_t res;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
74
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
75 if (!initialized)
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
76 {
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
77 extern const char *locale_charset (void);
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
78 const char *charset = locale_charset ();
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
79
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
80 ucs4_to_local = (charset != NULL
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
81 ? iconv_open (charset, UCS4_NAME)
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
82 : (iconv_t)(-1));
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
83 if (ucs4_to_local == (iconv_t)(-1))
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
84 {
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
85 /* For an unknown encoding, assume ASCII. */
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
86 ucs4_to_local = iconv_open ("ASCII", UCS4_NAME);
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
87 if (ucs4_to_local == (iconv_t)(-1))
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
88 error (1, 0, _("cannot output U+%04X: iconv function not usable"),
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
89 code);
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
90 }
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
91 initialized = 1;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
92 }
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
93
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
94 in = code;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
95 inptr = (char *) &in;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
96 inbytesleft = sizeof (in);
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
97 outptr = outbuf;
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
98 outbytesleft = sizeof (outbuf);
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
99
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
100 /* Convert the character. */
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
101 res = iconv (ucs4_to_local, &inptr, &inbytesleft, &outptr, &outbytesleft);
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
102 if (inbytesleft > 0 || res == (size_t)(-1))
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
103 error (1, res == (size_t)(-1) ? errno : 0,
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
104 _("cannot convert U+%04X to local character set"), code);
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
105
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
106 /* Avoid glibc-2.1 bug. */
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
107 # if defined _LIBICONV_VERSION || !(__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1)
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
108
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
109 /* Get back to the initial shift state. */
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
110 res = iconv (ucs4_to_local, NULL, NULL, &outptr, &outbytesleft);
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
111 if (res == (size_t)(-1))
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
112 error (1, errno, _("cannot convert U+%04X to local character set"), code);
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
113
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
114 # endif
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
115
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
116 fwrite (outbuf, 1, outptr - outbuf, stream);
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
117
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
118 #else
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
119 error (1, 0, _("cannot output U+%04X: iconv function not available"), code);
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
120 #endif
463a686cf218 New file from Bruno.
Jim Meyering <jim@meyering.net>
parents:
diff changeset
121 }