xref: /openbsd-src/gnu/usr.bin/binutils/binutils/winduni.c (revision cf2f2c5620d6d9a4fd01930983c4b9a1f76d7aa3)
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