* config/tc-spu.c (spu_cons): Use deferred_expression. Handle
[deliverable/binutils-gdb.git] / binutils / winduni.c
CommitLineData
252b5132 1/* winduni.c -- unicode support for the windres program.
3db64b00
AM
2 Copyright 1997, 1998, 2000, 2001, 2003, 2007
3 Free Software Foundation, Inc.
252b5132 4 Written by Ian Lance Taylor, Cygnus Support.
4a594fce 5 Rewritten by Kai Tietz, Onevision.
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132
RH
23
24/* This file contains unicode support routines for the windres
25 program. Ideally, we would have generic unicode support which
26 would work on all systems. However, we don't. Instead, on a
27 Windows host, we are prepared to call some Windows routines. This
28 means that we will generate different output on Windows and Unix
29 hosts, but that seems better than not really supporting unicode at
30 all. */
31
3db64b00 32#include "sysdep.h"
252b5132 33#include "bfd.h"
4a594fce 34#include "bucomm.h"
252b5132 35#include "winduni.h"
3882b010 36#include "safe-ctype.h"
252b5132
RH
37
38#ifdef _WIN32
39#include <windows.h>
40#endif
41
4a594fce
NC
42/* Prototypes. */
43static int unichar_isascii (const unichar *, rc_uint_type);
44
252b5132
RH
45/* Convert an ASCII string to a unicode string. We just copy it,
46 expanding chars to shorts, rather than doing something intelligent. */
47
48void
4a594fce 49unicode_from_ascii (rc_uint_type *length, unichar **unicode, const char *ascii)
252b5132 50{
4a594fce 51 rc_uint_type len;
bcfb5d77 52#ifndef _WIN32
252b5132
RH
53 const char *s;
54 unsigned short *w;
55
56 len = strlen (ascii);
252b5132 57 *unicode = ((unichar *) res_alloc ((len + 1) * sizeof (unichar)));
252b5132
RH
58 for (s = ascii, w = *unicode; *s != '\0'; s++, w++)
59 *w = *s & 0xff;
60 *w = 0;
bcfb5d77
DS
61#else
62 /* We use MultiByteToWideChar rather than strlen to get the unicode
63 string length to allow multibyte "ascii" chars. The value returned
64 by this function includes the trailing '\0'. */
4a594fce 65 len = (rc_uint_type) MultiByteToWideChar (CP_ACP, 0, ascii, -1, NULL, 0);
bcfb5d77
DS
66 if (len)
67 {
68 *unicode = ((unichar *) res_alloc (len * sizeof (unichar)));
4a594fce
NC
69 MultiByteToWideChar (CP_ACP, 0, ascii, -1, *unicode, (int) len);
70 }
71 /* Discount the trailing '/0'. If MultiByteToWideChar failed,
72 this will set *length to -1. */
73 len--;
74#endif
75
76 if (length != NULL)
77 *length = len;
78}
79
80/* Convert an unicode string to an ASCII string. We just copy it,
81 shrink shorts to chars, rather than doing something intelligent.
82 Shorts with not within the char range are replaced by '_'. */
83
84void
85ascii_from_unicode (rc_uint_type *length, const unichar *unicode, char **ascii)
86{
87 rc_uint_type len;
88#ifndef _WIN32
89 char *s;
90 const unsigned short *w;
91
92 len = 0;
93 while (unicode[len] != 0)
94 ++len;
95 *ascii = ((char *) res_alloc (len + 1));
96 for (s = *ascii, w = unicode; *w != '\0'; w++, s++)
97 {
98 if(w[0]==(w[0]&0xff))
99 *s = (char) w[0];
100 else
101 *s = '_';
102 }
103 *s = 0;
104#else
105 WINBOOL used_def = FALSE;
106 /* We use MultiByteToWideChar rather than strlen to get the unicode
107 string length to allow multibyte "ascii" chars. The value returned
108 by this function includes the trailing '\0'. */
109 len = (rc_uint_type) WideCharToMultiByte (CP_ACP, WC_DEFAULTCHAR, unicode, -1, NULL,
110 0, "_", &used_def);
111 if (len)
112 {
113 *ascii = (char *) res_alloc (len * sizeof (char));
114 WideCharToMultiByte (CP_ACP, WC_DEFAULTCHAR, unicode, -1, *ascii, (int) len,
115 "_", &used_def);
bcfb5d77
DS
116 }
117 /* Discount the trailing '/0'. If MultiByteToWideChar failed,
118 this will set *length to -1. */
119 len--;
252b5132 120#endif
bcfb5d77
DS
121
122 if (length != NULL)
123 *length = len;
252b5132
RH
124}
125
126/* Print the unicode string UNICODE to the file E. LENGTH is the
127 number of characters to print, or -1 if we should print until the
128 end of the string. FIXME: On a Windows host, we should be calling
129 some Windows function, probably WideCharToMultiByte. */
130
131void
4a594fce 132unicode_print (FILE *e, const unichar *unicode, rc_uint_type length)
252b5132
RH
133{
134 while (1)
135 {
136 unichar ch;
137
138 if (length == 0)
139 return;
4a594fce 140 if ((bfd_signed_vma) length > 0)
252b5132
RH
141 --length;
142
143 ch = *unicode;
144
4a594fce 145 if (ch == 0 && (bfd_signed_vma) length < 0)
252b5132
RH
146 return;
147
148 ++unicode;
149
150 if ((ch & 0x7f) == ch)
151 {
152 if (ch == '\\')
4a594fce
NC
153 fputs ("\\\\", e);
154 else if (ch == '"')
155 fputs ("\"\"", e);
3882b010 156 else if (ISPRINT (ch))
252b5132
RH
157 putc (ch, e);
158 else
159 {
160 switch (ch)
161 {
162 case ESCAPE_A:
163 fputs ("\\a", e);
164 break;
165
166 case ESCAPE_B:
167 fputs ("\\b", e);
168 break;
169
170 case ESCAPE_F:
171 fputs ("\\f", e);
172 break;
173
174 case ESCAPE_N:
175 fputs ("\\n", e);
176 break;
177
178 case ESCAPE_R:
179 fputs ("\\r", e);
180 break;
181
182 case ESCAPE_T:
183 fputs ("\\t", e);
184 break;
185
186 case ESCAPE_V:
187 fputs ("\\v", e);
188 break;
189
190 default:
191 fprintf (e, "\\%03o", (unsigned int) ch);
192 break;
193 }
194 }
195 }
196 else if ((ch & 0xff) == ch)
197 fprintf (e, "\\%03o", (unsigned int) ch);
198 else
199 fprintf (e, "\\x%x", (unsigned int) ch);
200 }
201}
4a594fce
NC
202
203/* Print a unicode string to a file. */
204void
205ascii_print (FILE *e, const char *s, rc_uint_type length)
206{
207 while (1)
208 {
209 char ch;
210
211 if (length == 0)
212 return;
213 if ((bfd_signed_vma) length > 0)
214 --length;
215
216 ch = *s;
217
218 if (ch == 0 && (bfd_signed_vma) length < 0)
219 return;
220
221 ++s;
222
223 if ((ch & 0x7f) == ch)
224 {
225 if (ch == '\\')
226 fputs ("\\\\", e);
227 else if (ch == '"')
228 fputs ("\"\"", e);
229 else if (ISPRINT (ch))
230 putc (ch, e);
231 else
232 {
233 switch (ch)
234 {
235 case ESCAPE_A:
236 fputs ("\\a", e);
237 break;
238
239 case ESCAPE_B:
240 fputs ("\\b", e);
241 break;
242
243 case ESCAPE_F:
244 fputs ("\\f", e);
245 break;
246
247 case ESCAPE_N:
248 fputs ("\\n", e);
249 break;
250
251 case ESCAPE_R:
252 fputs ("\\r", e);
253 break;
254
255 case ESCAPE_T:
256 fputs ("\\t", e);
257 break;
258
259 case ESCAPE_V:
260 fputs ("\\v", e);
261 break;
262
263 default:
264 fprintf (e, "\\%03o", (unsigned int) ch);
265 break;
266 }
267 }
268 }
269 else
270 fprintf (e, "\\%03o", (unsigned int) ch & 0xff);
271 }
272}
273
274rc_uint_type
275unichar_len (const unichar *unicode)
276{
277 rc_uint_type r = 0;
278 if (unicode)
279 while (unicode[r] != 0)
280 r++;
281 else
282 --r;
283 return r;
284}
285
286unichar *
287unichar_dup (const unichar *unicode)
288{
289 unichar *r;
290 int len;
291
292 if (! unicode)
293 return NULL;
294 for (len = 0; unicode[len] != 0; ++len)
295 ;
296 ++len;
297 r = ((unichar *) res_alloc (len * sizeof (unichar)));
298 memcpy (r, unicode, len * sizeof (unichar));
299 return r;
300}
301
302unichar *
303unichar_dup_uppercase (const unichar *u)
304{
305 unichar *r = unichar_dup (u);
306 int i;
307
308 if (! r)
309 return NULL;
310
311 for (i = 0; r[i] != 0; ++i)
312 {
313 if (r[i] >= 'a' && r[i] <= 'z')
314 r[i] &= 0xdf;
315 }
316 return r;
317}
318
319static int
320unichar_isascii (const unichar *u, rc_uint_type len)
321{
322 rc_uint_type i;
323 if ((bfd_signed_vma) len < 0)
324 {
325 if (u)
326 len = (rc_uint_type) unichar_len (u);
327 else
328 len = 0;
329 }
330
331 for (i = 0; i < len; i++)
332 if ((u[i] & 0xff80) != 0)
333 return 0;
334 return 1;
335}
336
337void
338unicode_print_quoted (FILE *e, const unichar *u, rc_uint_type len)
339{
340 if (! unichar_isascii (u, len))
341 fputc ('L', e);
342 fputc ('"', e);
343 unicode_print (e, u, len);
344 fputc ('"', e);
345}
This page took 0.390725 seconds and 4 git commands to generate.