1f7cc78ecSespie /* winduni.c -- unicode support for the windres program.
2*cf2f2c56Smiod Copyright 1997, 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
3f7cc78ecSespie Written by Ian Lance Taylor, Cygnus Support.
4f7cc78ecSespie
5f7cc78ecSespie This file is part of GNU Binutils.
6f7cc78ecSespie
7f7cc78ecSespie This program is free software; you can redistribute it and/or modify
8f7cc78ecSespie it under the terms of the GNU General Public License as published by
9f7cc78ecSespie the Free Software Foundation; either version 2 of the License, or
10f7cc78ecSespie (at your option) any later version.
11f7cc78ecSespie
12f7cc78ecSespie This program is distributed in the hope that it will be useful,
13f7cc78ecSespie but WITHOUT ANY WARRANTY; without even the implied warranty of
14f7cc78ecSespie MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15f7cc78ecSespie GNU General Public License for more details.
16f7cc78ecSespie
17f7cc78ecSespie You should have received a copy of the GNU General Public License
18f7cc78ecSespie along with this program; if not, write to the Free Software
19f7cc78ecSespie Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20f7cc78ecSespie 02111-1307, USA. */
21f7cc78ecSespie
22f7cc78ecSespie /* This file contains unicode support routines for the windres
23f7cc78ecSespie program. Ideally, we would have generic unicode support which
24f7cc78ecSespie would work on all systems. However, we don't. Instead, on a
25f7cc78ecSespie Windows host, we are prepared to call some Windows routines. This
26f7cc78ecSespie means that we will generate different output on Windows and Unix
27f7cc78ecSespie hosts, but that seems better than not really supporting unicode at
28f7cc78ecSespie all. */
29f7cc78ecSespie
30f7cc78ecSespie #include "bfd.h"
31f7cc78ecSespie #include "bucomm.h"
32f7cc78ecSespie #include "winduni.h"
33d2201f2fSdrahn #include "safe-ctype.h"
34f7cc78ecSespie
35f7cc78ecSespie #ifdef _WIN32
36f7cc78ecSespie #include <windows.h>
37f7cc78ecSespie #endif
38f7cc78ecSespie
39f7cc78ecSespie /* Convert an ASCII string to a unicode string. We just copy it,
40f7cc78ecSespie expanding chars to shorts, rather than doing something intelligent. */
41f7cc78ecSespie
42f7cc78ecSespie void
unicode_from_ascii(int * length,unichar ** unicode,const char * ascii)43*cf2f2c56Smiod unicode_from_ascii (int *length, unichar **unicode, const char *ascii)
44f7cc78ecSespie {
45f7cc78ecSespie int len;
46f7cc78ecSespie const char *s;
47f7cc78ecSespie unsigned short *w;
48f7cc78ecSespie
49f7cc78ecSespie len = strlen (ascii);
50f7cc78ecSespie
51f7cc78ecSespie if (length != NULL)
52f7cc78ecSespie *length = len;
53f7cc78ecSespie
54f7cc78ecSespie *unicode = ((unichar *) res_alloc ((len + 1) * sizeof (unichar)));
55f7cc78ecSespie
56f7cc78ecSespie #ifdef _WIN32
57f7cc78ecSespie /* FIXME: On Windows, we should be using MultiByteToWideChar to set
58f7cc78ecSespie the length. */
59f7cc78ecSespie MultiByteToWideChar (CP_ACP, 0, ascii, len + 1, *unicode, len + 1);
60f7cc78ecSespie #else
61f7cc78ecSespie for (s = ascii, w = *unicode; *s != '\0'; s++, w++)
62f7cc78ecSespie *w = *s & 0xff;
63f7cc78ecSespie *w = 0;
64f7cc78ecSespie #endif
65f7cc78ecSespie }
66f7cc78ecSespie
67f7cc78ecSespie /* Print the unicode string UNICODE to the file E. LENGTH is the
68f7cc78ecSespie number of characters to print, or -1 if we should print until the
69f7cc78ecSespie end of the string. FIXME: On a Windows host, we should be calling
70f7cc78ecSespie some Windows function, probably WideCharToMultiByte. */
71f7cc78ecSespie
72f7cc78ecSespie void
unicode_print(FILE * e,const unichar * unicode,int length)73*cf2f2c56Smiod unicode_print (FILE *e, const unichar *unicode, int length)
74f7cc78ecSespie {
75f7cc78ecSespie while (1)
76f7cc78ecSespie {
77f7cc78ecSespie unichar ch;
78f7cc78ecSespie
79f7cc78ecSespie if (length == 0)
80f7cc78ecSespie return;
81f7cc78ecSespie if (length > 0)
82f7cc78ecSespie --length;
83f7cc78ecSespie
84f7cc78ecSespie ch = *unicode;
85f7cc78ecSespie
86f7cc78ecSespie if (ch == 0 && length < 0)
87f7cc78ecSespie return;
88f7cc78ecSespie
89f7cc78ecSespie ++unicode;
90f7cc78ecSespie
91f7cc78ecSespie if ((ch & 0x7f) == ch)
92f7cc78ecSespie {
93f7cc78ecSespie if (ch == '\\')
94f7cc78ecSespie fputs ("\\", e);
95d2201f2fSdrahn else if (ISPRINT (ch))
96f7cc78ecSespie putc (ch, e);
97f7cc78ecSespie else
98f7cc78ecSespie {
99f7cc78ecSespie switch (ch)
100f7cc78ecSespie {
101f7cc78ecSespie case ESCAPE_A:
102f7cc78ecSespie fputs ("\\a", e);
103f7cc78ecSespie break;
104f7cc78ecSespie
105f7cc78ecSespie case ESCAPE_B:
106f7cc78ecSespie fputs ("\\b", e);
107f7cc78ecSespie break;
108f7cc78ecSespie
109f7cc78ecSespie case ESCAPE_F:
110f7cc78ecSespie fputs ("\\f", e);
111f7cc78ecSespie break;
112f7cc78ecSespie
113f7cc78ecSespie case ESCAPE_N:
114f7cc78ecSespie fputs ("\\n", e);
115f7cc78ecSespie break;
116f7cc78ecSespie
117f7cc78ecSespie case ESCAPE_R:
118f7cc78ecSespie fputs ("\\r", e);
119f7cc78ecSespie break;
120f7cc78ecSespie
121f7cc78ecSespie case ESCAPE_T:
122f7cc78ecSespie fputs ("\\t", e);
123f7cc78ecSespie break;
124f7cc78ecSespie
125f7cc78ecSespie case ESCAPE_V:
126f7cc78ecSespie fputs ("\\v", e);
127f7cc78ecSespie break;
128f7cc78ecSespie
129f7cc78ecSespie default:
130f7cc78ecSespie fprintf (e, "\\%03o", (unsigned int) ch);
131f7cc78ecSespie break;
132f7cc78ecSespie }
133f7cc78ecSespie }
134f7cc78ecSespie }
135f7cc78ecSespie else if ((ch & 0xff) == ch)
136f7cc78ecSespie fprintf (e, "\\%03o", (unsigned int) ch);
137f7cc78ecSespie else
138f7cc78ecSespie fprintf (e, "\\x%x", (unsigned int) ch);
139f7cc78ecSespie }
140f7cc78ecSespie }
141