xref: /openbsd-src/gnu/usr.bin/binutils/gdb/charset.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Character set conversion support for GDB.
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 2001, 2003 Free Software Foundation, Inc.
4b725ae77Skettenis 
5b725ae77Skettenis    This file is part of GDB.
6b725ae77Skettenis 
7b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis    it under the terms of the GNU General Public License as published by
9b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis    (at your option) any later version.
11b725ae77Skettenis 
12b725ae77Skettenis    This program is distributed in the hope that it will be useful,
13b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15b725ae77Skettenis    GNU General Public License for more details.
16b725ae77Skettenis 
17b725ae77Skettenis    You should have received a copy of the GNU General Public License
18b725ae77Skettenis    along with this program; if not, write to the Free Software
19b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
21b725ae77Skettenis 
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "charset.h"
24b725ae77Skettenis #include "gdbcmd.h"
25b725ae77Skettenis #include "gdb_assert.h"
26b725ae77Skettenis 
27b725ae77Skettenis #include <stddef.h>
28b725ae77Skettenis #include "gdb_string.h"
29b725ae77Skettenis #include <ctype.h>
30b725ae77Skettenis 
31b725ae77Skettenis #ifdef HAVE_ICONV
32b725ae77Skettenis #include <iconv.h>
33b725ae77Skettenis #endif
34b725ae77Skettenis 
35b725ae77Skettenis 
36b725ae77Skettenis /* How GDB's character set support works
37b725ae77Skettenis 
38b725ae77Skettenis    GDB has two global settings:
39b725ae77Skettenis 
40b725ae77Skettenis    - The `current host character set' is the character set GDB should
41b725ae77Skettenis      use in talking to the user, and which (hopefully) the user's
42b725ae77Skettenis      terminal knows how to display properly.
43b725ae77Skettenis 
44b725ae77Skettenis    - The `current target character set' is the character set the
45b725ae77Skettenis      program being debugged uses.
46b725ae77Skettenis 
47b725ae77Skettenis    There are commands to set each of these, and mechanisms for
48b725ae77Skettenis    choosing reasonable default values.  GDB has a global list of
49b725ae77Skettenis    character sets that it can use as its host or target character
50b725ae77Skettenis    sets.
51b725ae77Skettenis 
52b725ae77Skettenis    The header file `charset.h' declares various functions that
53b725ae77Skettenis    different pieces of GDB need to perform tasks like:
54b725ae77Skettenis 
55b725ae77Skettenis    - printing target strings and characters to the user's terminal
56b725ae77Skettenis      (mostly target->host conversions),
57b725ae77Skettenis 
58b725ae77Skettenis    - building target-appropriate representations of strings and
59b725ae77Skettenis      characters the user enters in expressions (mostly host->target
60b725ae77Skettenis      conversions),
61b725ae77Skettenis 
62b725ae77Skettenis    and so on.
63b725ae77Skettenis 
64b725ae77Skettenis    Now, many of these operations are specific to a particular
65b725ae77Skettenis    host/target character set pair.  If GDB supports N character sets,
66b725ae77Skettenis    there are N^2 possible pairs.  This means that, the larger GDB's
67b725ae77Skettenis    repertoire of character sets gets, the more expensive it gets to add
68b725ae77Skettenis    new character sets.
69b725ae77Skettenis 
70b725ae77Skettenis    To make sure that GDB can do the right thing for every possible
71b725ae77Skettenis    pairing of host and target character set, while still allowing
72b725ae77Skettenis    GDB's repertoire to scale, we use a two-tiered approach:
73b725ae77Skettenis 
74b725ae77Skettenis    - We maintain a global table of "translations" --- groups of
75b725ae77Skettenis      functions specific to a particular pair of character sets.
76b725ae77Skettenis 
77b725ae77Skettenis    - However, a translation can be incomplete: some functions can be
78b725ae77Skettenis      omitted.  Where there is not a translation to specify exactly
79b725ae77Skettenis      what function to use, we provide reasonable defaults.  The
80b725ae77Skettenis      default behaviors try to use the "iconv" library functions, which
81b725ae77Skettenis      support a wide range of character sets.  However, even if iconv
82b725ae77Skettenis      is not available, there are fallbacks to support trivial
83b725ae77Skettenis      translations: when the host and target character sets are the
84b725ae77Skettenis      same.  */
85b725ae77Skettenis 
86b725ae77Skettenis 
87b725ae77Skettenis /* The character set and translation structures.  */
88b725ae77Skettenis 
89b725ae77Skettenis 
90b725ae77Skettenis /* A character set GDB knows about.  GDB only supports character sets
91b725ae77Skettenis    with stateless encodings, in which every character is one byte
92b725ae77Skettenis    long.  */
93b725ae77Skettenis struct charset {
94b725ae77Skettenis 
95b725ae77Skettenis   /* A singly-linked list of all known charsets.  */
96b725ae77Skettenis   struct charset *next;
97b725ae77Skettenis 
98b725ae77Skettenis   /* The name of the character set.  Comparisons on character set
99b725ae77Skettenis      names are case-sensitive.  */
100b725ae77Skettenis   const char *name;
101b725ae77Skettenis 
102b725ae77Skettenis   /* Non-zero iff this character set can be used as a host character
103b725ae77Skettenis      set.  At present, GDB basically assumes that the host character
104b725ae77Skettenis      set is a superset of ASCII.  */
105b725ae77Skettenis   int valid_host_charset;
106b725ae77Skettenis 
107b725ae77Skettenis   /* Pointers to charset-specific functions that depend only on a
108b725ae77Skettenis      single character set, and data pointers to pass to them.  */
109b725ae77Skettenis   int (*host_char_print_literally) (void *baton,
110b725ae77Skettenis                                     int host_char);
111b725ae77Skettenis   void *host_char_print_literally_baton;
112b725ae77Skettenis 
113b725ae77Skettenis   int (*target_char_to_control_char) (void *baton,
114b725ae77Skettenis                                       int target_char,
115b725ae77Skettenis                                       int *target_ctrl_char);
116b725ae77Skettenis   void *target_char_to_control_char_baton;
117b725ae77Skettenis };
118b725ae77Skettenis 
119b725ae77Skettenis 
120b725ae77Skettenis /* A translation from one character set to another.  */
121b725ae77Skettenis struct translation {
122b725ae77Skettenis 
123b725ae77Skettenis   /* A singly-linked list of all known translations.  */
124b725ae77Skettenis   struct translation *next;
125b725ae77Skettenis 
126b725ae77Skettenis   /* This structure describes functions going from the FROM character
127b725ae77Skettenis      set to the TO character set.  Comparisons on character set names
128b725ae77Skettenis      are case-sensitive.  */
129b725ae77Skettenis   const char *from, *to;
130b725ae77Skettenis 
131b725ae77Skettenis   /* Pointers to translation-specific functions, and data pointers to
132b725ae77Skettenis      pass to them.  These pointers can be zero, indicating that GDB
133b725ae77Skettenis      should fall back on the default behavior.  We hope the default
134b725ae77Skettenis      behavior will be correct for many from/to pairs, reducing the
135b725ae77Skettenis      number of translations that need to be registered explicitly.  */
136b725ae77Skettenis 
137b725ae77Skettenis   /* TARGET_CHAR is in the `from' charset.
138b725ae77Skettenis      Returns a string in the `to' charset.  */
139b725ae77Skettenis   const char *(*c_target_char_has_backslash_escape) (void *baton,
140b725ae77Skettenis                                                      int target_char);
141b725ae77Skettenis   void *c_target_char_has_backslash_escape_baton;
142b725ae77Skettenis 
143b725ae77Skettenis   /* HOST_CHAR is in the `from' charset.
144b725ae77Skettenis      TARGET_CHAR points to a char in the `to' charset.  */
145b725ae77Skettenis   int (*c_parse_backslash) (void *baton, int host_char, int *target_char);
146b725ae77Skettenis   void *c_parse_backslash_baton;
147b725ae77Skettenis 
148b725ae77Skettenis   /* This is used for the host_char_to_target and target_char_to_host
149b725ae77Skettenis      functions.  */
150b725ae77Skettenis   int (*convert_char) (void *baton, int from, int *to);
151b725ae77Skettenis   void *convert_char_baton;
152b725ae77Skettenis };
153b725ae77Skettenis 
154b725ae77Skettenis 
155b725ae77Skettenis 
156b725ae77Skettenis /* The global lists of character sets and translations.  */
157b725ae77Skettenis 
158b725ae77Skettenis 
159b725ae77Skettenis #ifndef GDB_DEFAULT_HOST_CHARSET
160b725ae77Skettenis #define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1"
161b725ae77Skettenis #endif
162b725ae77Skettenis 
163b725ae77Skettenis #ifndef GDB_DEFAULT_TARGET_CHARSET
164b725ae77Skettenis #define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1"
165b725ae77Skettenis #endif
166b725ae77Skettenis 
167b725ae77Skettenis static const char *host_charset_name = GDB_DEFAULT_HOST_CHARSET;
168b725ae77Skettenis static const char *target_charset_name = GDB_DEFAULT_TARGET_CHARSET;
169b725ae77Skettenis 
170b725ae77Skettenis static const char *host_charset_enum[] =
171b725ae77Skettenis {
172b725ae77Skettenis   "ASCII",
173b725ae77Skettenis   "ISO-8859-1",
174b725ae77Skettenis   0
175b725ae77Skettenis };
176b725ae77Skettenis 
177b725ae77Skettenis static const char *target_charset_enum[] =
178b725ae77Skettenis {
179b725ae77Skettenis   "ASCII",
180b725ae77Skettenis   "ISO-8859-1",
181b725ae77Skettenis   "EBCDIC-US",
182b725ae77Skettenis   "IBM1047",
183b725ae77Skettenis   0
184b725ae77Skettenis };
185b725ae77Skettenis 
186b725ae77Skettenis /* The global list of all the charsets GDB knows about.  */
187b725ae77Skettenis static struct charset *all_charsets;
188b725ae77Skettenis 
189b725ae77Skettenis 
190b725ae77Skettenis static void
register_charset(struct charset * cs)191b725ae77Skettenis register_charset (struct charset *cs)
192b725ae77Skettenis {
193b725ae77Skettenis   struct charset **ptr;
194b725ae77Skettenis 
195b725ae77Skettenis   /* Put the new charset on the end, so that the list ends up in the
196b725ae77Skettenis      same order as the registrations in the _initialize function.  */
197b725ae77Skettenis   for (ptr = &all_charsets; *ptr; ptr = &(*ptr)->next)
198b725ae77Skettenis     ;
199b725ae77Skettenis 
200b725ae77Skettenis   cs->next = 0;
201b725ae77Skettenis   *ptr = cs;
202b725ae77Skettenis }
203b725ae77Skettenis 
204b725ae77Skettenis 
205b725ae77Skettenis static struct charset *
lookup_charset(const char * name)206b725ae77Skettenis lookup_charset (const char *name)
207b725ae77Skettenis {
208b725ae77Skettenis   struct charset *cs;
209b725ae77Skettenis 
210b725ae77Skettenis   for (cs = all_charsets; cs; cs = cs->next)
211b725ae77Skettenis     if (! strcmp (name, cs->name))
212b725ae77Skettenis       return cs;
213b725ae77Skettenis 
214b725ae77Skettenis   return NULL;
215b725ae77Skettenis }
216b725ae77Skettenis 
217b725ae77Skettenis 
218b725ae77Skettenis /* The global list of translations.  */
219b725ae77Skettenis static struct translation *all_translations;
220b725ae77Skettenis 
221b725ae77Skettenis 
222b725ae77Skettenis static void
register_translation(struct translation * t)223b725ae77Skettenis register_translation (struct translation *t)
224b725ae77Skettenis {
225b725ae77Skettenis   t->next = all_translations;
226b725ae77Skettenis   all_translations = t;
227b725ae77Skettenis }
228b725ae77Skettenis 
229b725ae77Skettenis 
230b725ae77Skettenis static struct translation *
lookup_translation(const char * from,const char * to)231b725ae77Skettenis lookup_translation (const char *from, const char *to)
232b725ae77Skettenis {
233b725ae77Skettenis   struct translation *t;
234b725ae77Skettenis 
235b725ae77Skettenis   for (t = all_translations; t; t = t->next)
236b725ae77Skettenis     if (! strcmp (from, t->from)
237b725ae77Skettenis         && ! strcmp (to, t->to))
238b725ae77Skettenis       return t;
239b725ae77Skettenis 
240b725ae77Skettenis   return 0;
241b725ae77Skettenis }
242b725ae77Skettenis 
243b725ae77Skettenis 
244b725ae77Skettenis 
245b725ae77Skettenis /* Constructing charsets.  */
246b725ae77Skettenis 
247b725ae77Skettenis /* Allocate, initialize and return a straightforward charset.
248b725ae77Skettenis    Use this function, rather than creating the structures yourself,
249b725ae77Skettenis    so that we can add new fields to the structure in the future without
250b725ae77Skettenis    having to tweak all the old charset descriptions.  */
251b725ae77Skettenis static struct charset *
simple_charset(const char * name,int valid_host_charset,int (* host_char_print_literally)(void * baton,int host_char),void * host_char_print_literally_baton,int (* target_char_to_control_char)(void * baton,int target_char,int * target_ctrl_char),void * target_char_to_control_char_baton)252b725ae77Skettenis simple_charset (const char *name,
253b725ae77Skettenis                 int valid_host_charset,
254b725ae77Skettenis                 int (*host_char_print_literally) (void *baton, int host_char),
255b725ae77Skettenis                 void *host_char_print_literally_baton,
256b725ae77Skettenis                 int (*target_char_to_control_char) (void *baton,
257b725ae77Skettenis                                                     int target_char,
258b725ae77Skettenis                                                     int *target_ctrl_char),
259b725ae77Skettenis                 void *target_char_to_control_char_baton)
260b725ae77Skettenis {
261b725ae77Skettenis   struct charset *cs = xmalloc (sizeof (*cs));
262b725ae77Skettenis 
263b725ae77Skettenis   memset (cs, 0, sizeof (*cs));
264b725ae77Skettenis   cs->name = name;
265b725ae77Skettenis   cs->valid_host_charset = valid_host_charset;
266b725ae77Skettenis   cs->host_char_print_literally = host_char_print_literally;
267b725ae77Skettenis   cs->host_char_print_literally_baton = host_char_print_literally_baton;
268b725ae77Skettenis   cs->target_char_to_control_char = target_char_to_control_char;
269b725ae77Skettenis   cs->target_char_to_control_char_baton = target_char_to_control_char_baton;
270b725ae77Skettenis 
271b725ae77Skettenis   return cs;
272b725ae77Skettenis }
273b725ae77Skettenis 
274b725ae77Skettenis 
275b725ae77Skettenis 
276b725ae77Skettenis /* ASCII functions.  */
277b725ae77Skettenis 
278b725ae77Skettenis static int
ascii_print_literally(void * baton,int c)279b725ae77Skettenis ascii_print_literally (void *baton, int c)
280b725ae77Skettenis {
281b725ae77Skettenis   c &= 0xff;
282b725ae77Skettenis 
283b725ae77Skettenis   return (0x20 <= c && c <= 0x7e);
284b725ae77Skettenis }
285b725ae77Skettenis 
286b725ae77Skettenis 
287b725ae77Skettenis static int
ascii_to_control(void * baton,int c,int * ctrl_char)288b725ae77Skettenis ascii_to_control (void *baton, int c, int *ctrl_char)
289b725ae77Skettenis {
290b725ae77Skettenis   *ctrl_char = (c & 037);
291b725ae77Skettenis   return 1;
292b725ae77Skettenis }
293b725ae77Skettenis 
294b725ae77Skettenis 
295b725ae77Skettenis /* ISO-8859 family functions.  */
296b725ae77Skettenis 
297b725ae77Skettenis 
298b725ae77Skettenis static int
iso_8859_print_literally(void * baton,int c)299b725ae77Skettenis iso_8859_print_literally (void *baton, int c)
300b725ae77Skettenis {
301b725ae77Skettenis   c &= 0xff;
302b725ae77Skettenis 
303b725ae77Skettenis   return ((0x20 <= c && c <= 0x7e) /* ascii printables */
304b725ae77Skettenis           || (! sevenbit_strings && 0xA0 <= c)); /* iso 8859 printables */
305b725ae77Skettenis }
306b725ae77Skettenis 
307b725ae77Skettenis 
308b725ae77Skettenis static int
iso_8859_to_control(void * baton,int c,int * ctrl_char)309b725ae77Skettenis iso_8859_to_control (void *baton, int c, int *ctrl_char)
310b725ae77Skettenis {
311b725ae77Skettenis   *ctrl_char = (c & 0200) | (c & 037);
312b725ae77Skettenis   return 1;
313b725ae77Skettenis }
314b725ae77Skettenis 
315b725ae77Skettenis 
316b725ae77Skettenis /* Construct an ISO-8859-like character set.  */
317b725ae77Skettenis static struct charset *
iso_8859_family_charset(const char * name)318b725ae77Skettenis iso_8859_family_charset (const char *name)
319b725ae77Skettenis {
320b725ae77Skettenis   return simple_charset (name, 1,
321b725ae77Skettenis                          iso_8859_print_literally, 0,
322b725ae77Skettenis                          iso_8859_to_control, 0);
323b725ae77Skettenis }
324b725ae77Skettenis 
325b725ae77Skettenis 
326b725ae77Skettenis 
327b725ae77Skettenis /* EBCDIC family functions.  */
328b725ae77Skettenis 
329b725ae77Skettenis 
330b725ae77Skettenis static int
ebcdic_print_literally(void * baton,int c)331b725ae77Skettenis ebcdic_print_literally (void *baton, int c)
332b725ae77Skettenis {
333b725ae77Skettenis   c &= 0xff;
334b725ae77Skettenis 
335b725ae77Skettenis   return (64 <= c && c <= 254);
336b725ae77Skettenis }
337b725ae77Skettenis 
338b725ae77Skettenis 
339b725ae77Skettenis static int
ebcdic_to_control(void * baton,int c,int * ctrl_char)340b725ae77Skettenis ebcdic_to_control (void *baton, int c, int *ctrl_char)
341b725ae77Skettenis {
342b725ae77Skettenis   /* There are no control character equivalents in EBCDIC.  Use
343b725ae77Skettenis      numeric escapes.  */
344b725ae77Skettenis   return 0;
345b725ae77Skettenis }
346b725ae77Skettenis 
347b725ae77Skettenis 
348b725ae77Skettenis /* Construct an EBCDIC-like character set.  */
349b725ae77Skettenis static struct charset *
ebcdic_family_charset(const char * name)350b725ae77Skettenis ebcdic_family_charset (const char *name)
351b725ae77Skettenis {
352b725ae77Skettenis   return simple_charset (name, 0,
353b725ae77Skettenis                          ebcdic_print_literally, 0,
354b725ae77Skettenis                          ebcdic_to_control, 0);
355b725ae77Skettenis }
356b725ae77Skettenis 
357b725ae77Skettenis 
358b725ae77Skettenis 
359b725ae77Skettenis 
360b725ae77Skettenis 
361b725ae77Skettenis /* Fallback functions using iconv.  */
362b725ae77Skettenis 
363b725ae77Skettenis #if defined(HAVE_ICONV)
364b725ae77Skettenis 
365b725ae77Skettenis struct cached_iconv {
366b725ae77Skettenis   struct charset *from, *to;
367b725ae77Skettenis   iconv_t i;
368b725ae77Skettenis };
369b725ae77Skettenis 
370b725ae77Skettenis 
371b725ae77Skettenis /* Make sure the iconv cache *CI contains an iconv descriptor
372b725ae77Skettenis    translating from FROM to TO.  If it already does, fine; otherwise,
373b725ae77Skettenis    close any existing descriptor, and open up a new one.  On success,
374b725ae77Skettenis    return zero; on failure, return -1 and set errno.  */
375b725ae77Skettenis static int
check_iconv_cache(struct cached_iconv * ci,struct charset * from,struct charset * to)376b725ae77Skettenis check_iconv_cache (struct cached_iconv *ci,
377b725ae77Skettenis                    struct charset *from,
378b725ae77Skettenis                    struct charset *to)
379b725ae77Skettenis {
380b725ae77Skettenis   iconv_t i;
381b725ae77Skettenis 
382b725ae77Skettenis   /* Does the cached iconv descriptor match the conversion we're trying
383b725ae77Skettenis      to do now?  */
384b725ae77Skettenis   if (ci->from == from
385b725ae77Skettenis       && ci->to == to
386b725ae77Skettenis       && ci->i != (iconv_t) 0)
387b725ae77Skettenis     return 0;
388b725ae77Skettenis 
389b725ae77Skettenis   /* It doesn't.  If we actually had any iconv descriptor open at
390b725ae77Skettenis      all, close it now.  */
391b725ae77Skettenis   if (ci->i != (iconv_t) 0)
392b725ae77Skettenis     {
393b725ae77Skettenis       i = ci->i;
394b725ae77Skettenis       ci->i = (iconv_t) 0;
395b725ae77Skettenis 
396b725ae77Skettenis       if (iconv_close (i) == -1)
397b725ae77Skettenis         error ("Error closing `iconv' descriptor for "
398b725ae77Skettenis                "`%s'-to-`%s' character conversion: %s",
399b725ae77Skettenis                ci->from->name, ci->to->name, safe_strerror (errno));
400b725ae77Skettenis     }
401b725ae77Skettenis 
402b725ae77Skettenis   /* Open a new iconv descriptor for the required conversion.  */
403b725ae77Skettenis   i = iconv_open (to->name, from->name);
404b725ae77Skettenis   if (i == (iconv_t) -1)
405b725ae77Skettenis     return -1;
406b725ae77Skettenis 
407b725ae77Skettenis   ci->i = i;
408b725ae77Skettenis   ci->from = from;
409b725ae77Skettenis   ci->to = to;
410b725ae77Skettenis 
411b725ae77Skettenis   return 0;
412b725ae77Skettenis }
413b725ae77Skettenis 
414b725ae77Skettenis 
415b725ae77Skettenis /* Convert FROM_CHAR using the cached iconv conversion *CI.  Return
416b725ae77Skettenis    non-zero if the conversion was successful, zero otherwise.  */
417b725ae77Skettenis static int
cached_iconv_convert(struct cached_iconv * ci,int from_char,int * to_char)418b725ae77Skettenis cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char)
419b725ae77Skettenis {
420b725ae77Skettenis   char from;
421b725ae77Skettenis   ICONV_CONST char *from_ptr = &from;
422b725ae77Skettenis   char to, *to_ptr = &to;
423b725ae77Skettenis   size_t from_left = sizeof (from), to_left = sizeof (to);
424b725ae77Skettenis 
425b725ae77Skettenis   gdb_assert (ci->i != (iconv_t) 0);
426b725ae77Skettenis 
427b725ae77Skettenis   from = from_char;
428b725ae77Skettenis   if (iconv (ci->i, &from_ptr, &from_left, &to_ptr, &to_left)
429b725ae77Skettenis       == (size_t) -1)
430b725ae77Skettenis     {
431b725ae77Skettenis       /* These all suggest that the input or output character sets
432b725ae77Skettenis          have multi-byte encodings of some characters, which means
433b725ae77Skettenis          it's unsuitable for use as a GDB character set.  We should
434b725ae77Skettenis          never have selected it.  */
435b725ae77Skettenis       gdb_assert (errno != E2BIG && errno != EINVAL);
436b725ae77Skettenis 
437b725ae77Skettenis       /* This suggests a bug in the code managing *CI.  */
438b725ae77Skettenis       gdb_assert (errno != EBADF);
439b725ae77Skettenis 
440b725ae77Skettenis       /* This seems to mean that there is no equivalent character in
441b725ae77Skettenis          the `to' character set.  */
442b725ae77Skettenis       if (errno == EILSEQ)
443b725ae77Skettenis         return 0;
444b725ae77Skettenis 
445b725ae77Skettenis       /* Anything else is mysterious.  */
446b725ae77Skettenis       internal_error (__FILE__, __LINE__,
447b725ae77Skettenis 		      "Error converting character `%d' from `%s' to `%s' "
448b725ae77Skettenis                       "character set: %s",
449b725ae77Skettenis                       from_char, ci->from->name, ci->to->name,
450b725ae77Skettenis                       safe_strerror (errno));
451b725ae77Skettenis     }
452b725ae77Skettenis 
453b725ae77Skettenis   /* If the pointers weren't advanced across the input, that also
454b725ae77Skettenis      suggests something was wrong.  */
455b725ae77Skettenis   gdb_assert (from_left == 0 && to_left == 0);
456b725ae77Skettenis 
457b725ae77Skettenis   *to_char = (unsigned char) to;
458b725ae77Skettenis   return 1;
459b725ae77Skettenis }
460b725ae77Skettenis 
461b725ae77Skettenis 
462b725ae77Skettenis static void
register_iconv_charsets(void)463b725ae77Skettenis register_iconv_charsets (void)
464b725ae77Skettenis {
465b725ae77Skettenis   /* Here we should check whether various character sets were
466b725ae77Skettenis      recognized by the local iconv implementation.
467b725ae77Skettenis 
468b725ae77Skettenis      The first implementation registered a bunch of character sets
469b725ae77Skettenis      recognized by iconv, but then we discovered that iconv on Solaris
470b725ae77Skettenis      and iconv on GNU/Linux had no character sets in common.  So we
471b725ae77Skettenis      replaced them with the hard-coded tables that appear later in the
472b725ae77Skettenis      file.  */
473b725ae77Skettenis }
474b725ae77Skettenis 
475b725ae77Skettenis #endif /* defined (HAVE_ICONV) */
476b725ae77Skettenis 
477b725ae77Skettenis 
478b725ae77Skettenis /* Fallback routines for systems without iconv.  */
479b725ae77Skettenis 
480b725ae77Skettenis #if ! defined (HAVE_ICONV)
481b725ae77Skettenis struct cached_iconv { char nothing; };
482b725ae77Skettenis 
483b725ae77Skettenis static int
check_iconv_cache(struct cached_iconv * ci,struct charset * from,struct charset * to)484b725ae77Skettenis check_iconv_cache (struct cached_iconv *ci,
485b725ae77Skettenis                    struct charset *from,
486b725ae77Skettenis                    struct charset *to)
487b725ae77Skettenis {
488b725ae77Skettenis   errno = EINVAL;
489b725ae77Skettenis   return -1;
490b725ae77Skettenis }
491b725ae77Skettenis 
492b725ae77Skettenis static int
cached_iconv_convert(struct cached_iconv * ci,int from_char,int * to_char)493b725ae77Skettenis cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char)
494b725ae77Skettenis {
495b725ae77Skettenis   /* This function should never be called.  */
496b725ae77Skettenis   gdb_assert (0);
497b725ae77Skettenis }
498b725ae77Skettenis 
499b725ae77Skettenis static void
register_iconv_charsets(void)500b725ae77Skettenis register_iconv_charsets (void)
501b725ae77Skettenis {
502b725ae77Skettenis }
503b725ae77Skettenis 
504b725ae77Skettenis #endif /* ! defined(HAVE_ICONV) */
505b725ae77Skettenis 
506b725ae77Skettenis 
507b725ae77Skettenis /* Default trivial conversion functions.  */
508b725ae77Skettenis 
509b725ae77Skettenis static int
identity_either_char_to_other(void * baton,int either_char,int * other_char)510b725ae77Skettenis identity_either_char_to_other (void *baton, int either_char, int *other_char)
511b725ae77Skettenis {
512b725ae77Skettenis   *other_char = either_char;
513b725ae77Skettenis   return 1;
514b725ae77Skettenis }
515b725ae77Skettenis 
516b725ae77Skettenis 
517b725ae77Skettenis 
518b725ae77Skettenis /* Default non-trivial conversion functions.  */
519b725ae77Skettenis 
520b725ae77Skettenis 
521b725ae77Skettenis static char backslashable[] = "abfnrtv";
522b725ae77Skettenis static char *backslashed[] = {"a", "b", "f", "n", "r", "t", "v", "0"};
523b725ae77Skettenis static char represented[] = "\a\b\f\n\r\t\v";
524b725ae77Skettenis 
525b725ae77Skettenis 
526b725ae77Skettenis /* Translate TARGET_CHAR into the host character set, and see if it
527b725ae77Skettenis    matches any of our standard escape sequences.  */
528b725ae77Skettenis static const char *
default_c_target_char_has_backslash_escape(void * baton,int target_char)529b725ae77Skettenis default_c_target_char_has_backslash_escape (void *baton, int target_char)
530b725ae77Skettenis {
531b725ae77Skettenis   int host_char;
532b725ae77Skettenis   const char *ix;
533b725ae77Skettenis 
534b725ae77Skettenis   /* If target_char has no equivalent in the host character set,
535b725ae77Skettenis      assume it doesn't have a backslashed form.  */
536b725ae77Skettenis   if (! target_char_to_host (target_char, &host_char))
537b725ae77Skettenis     return NULL;
538b725ae77Skettenis 
539b725ae77Skettenis   ix = strchr (represented, host_char);
540b725ae77Skettenis   if (ix)
541b725ae77Skettenis     return backslashed[ix - represented];
542b725ae77Skettenis   else
543b725ae77Skettenis     return NULL;
544b725ae77Skettenis }
545b725ae77Skettenis 
546b725ae77Skettenis 
547b725ae77Skettenis /* Translate the backslash the way we would in the host character set,
548b725ae77Skettenis    and then try to translate that into the target character set.  */
549b725ae77Skettenis static int
default_c_parse_backslash(void * baton,int host_char,int * target_char)550b725ae77Skettenis default_c_parse_backslash (void *baton, int host_char, int *target_char)
551b725ae77Skettenis {
552b725ae77Skettenis   const char *ix;
553b725ae77Skettenis 
554b725ae77Skettenis   ix = strchr (backslashable, host_char);
555b725ae77Skettenis 
556b725ae77Skettenis   if (! ix)
557b725ae77Skettenis     return 0;
558b725ae77Skettenis   else
559b725ae77Skettenis     return host_char_to_target (represented[ix - backslashable],
560b725ae77Skettenis                                 target_char);
561b725ae77Skettenis }
562b725ae77Skettenis 
563b725ae77Skettenis 
564b725ae77Skettenis /* Convert using a cached iconv descriptor.  */
565b725ae77Skettenis static int
iconv_convert(void * baton,int from_char,int * to_char)566b725ae77Skettenis iconv_convert (void *baton, int from_char, int *to_char)
567b725ae77Skettenis {
568b725ae77Skettenis   struct cached_iconv *ci = baton;
569b725ae77Skettenis   return cached_iconv_convert (ci, from_char, to_char);
570b725ae77Skettenis }
571b725ae77Skettenis 
572b725ae77Skettenis 
573b725ae77Skettenis 
574b725ae77Skettenis /* Conversion tables.  */
575b725ae77Skettenis 
576b725ae77Skettenis 
577b725ae77Skettenis /* I'd much rather fall back on iconv whenever possible.  But the
578b725ae77Skettenis    character set names you use with iconv aren't standardized at all,
579b725ae77Skettenis    a lot of platforms have really meager character set coverage, etc.
580b725ae77Skettenis    I wanted to have at least something we could use to exercise the
581b725ae77Skettenis    test suite on all platforms.
582b725ae77Skettenis 
583b725ae77Skettenis    In the long run, we should have a configure-time process explore
584b725ae77Skettenis    somehow which character sets the host platform supports, and some
585b725ae77Skettenis    arrangement that allows GDB users to use platform-indepedent names
586b725ae77Skettenis    for character sets.  */
587b725ae77Skettenis 
588b725ae77Skettenis 
589b725ae77Skettenis /* We generated these tables using iconv on a GNU/Linux machine.  */
590b725ae77Skettenis 
591b725ae77Skettenis 
592b725ae77Skettenis static int ascii_to_iso_8859_1_table[] = {
593b725ae77Skettenis     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 16 */
594b725ae77Skettenis    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
595b725ae77Skettenis    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
596b725ae77Skettenis    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
597b725ae77Skettenis    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 80 */
598b725ae77Skettenis    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 96 */
599b725ae77Skettenis    96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 112 */
600b725ae77Skettenis   112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 128 */
601b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
602b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
603b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
604b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
605b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
606b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
607b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
608b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  /* 256 */
609b725ae77Skettenis };
610b725ae77Skettenis 
611b725ae77Skettenis 
612b725ae77Skettenis static int ascii_to_ebcdic_us_table[] = {
613b725ae77Skettenis     0,  1,  2,  3, 55, 45, 46, 47, 22,  5, 37, 11, 12, 13, 14, 15, /* 16 */
614b725ae77Skettenis    16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
615b725ae77Skettenis    64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
616b725ae77Skettenis   240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
617b725ae77Skettenis   124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
618b725ae77Skettenis   215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109, /* 96 */
619b725ae77Skettenis   121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
620b725ae77Skettenis   151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161,  7, /* 128 */
621b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
622b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
623b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
624b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
625b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
626b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
627b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
628b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  /* 256 */
629b725ae77Skettenis };
630b725ae77Skettenis 
631b725ae77Skettenis 
632b725ae77Skettenis static int ascii_to_ibm1047_table[] = {
633b725ae77Skettenis     0,  1,  2,  3, 55, 45, 46, 47, 22,  5, 37, 11, 12, 13, 14, 15, /* 16 */
634b725ae77Skettenis    16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
635b725ae77Skettenis    64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
636b725ae77Skettenis   240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
637b725ae77Skettenis   124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
638b725ae77Skettenis   215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109, /* 96 */
639b725ae77Skettenis   121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
640b725ae77Skettenis   151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161,  7, /* 128 */
641b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
642b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
643b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
644b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
645b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
646b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
647b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
648b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  /* 256 */
649b725ae77Skettenis };
650b725ae77Skettenis 
651b725ae77Skettenis 
652b725ae77Skettenis static int iso_8859_1_to_ascii_table[] = {
653b725ae77Skettenis     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 16 */
654b725ae77Skettenis    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
655b725ae77Skettenis    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
656b725ae77Skettenis    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
657b725ae77Skettenis    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 80 */
658b725ae77Skettenis    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 96 */
659b725ae77Skettenis    96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 112 */
660b725ae77Skettenis   112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 128 */
661b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
662b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
663b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
664b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
665b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
666b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
667b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
668b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  /* 256 */
669b725ae77Skettenis };
670b725ae77Skettenis 
671b725ae77Skettenis 
672b725ae77Skettenis static int iso_8859_1_to_ebcdic_us_table[] = {
673b725ae77Skettenis     0,  1,  2,  3, 55, 45, 46, 47, 22,  5, 37, 11, 12, 13, 14, 15, /* 16 */
674b725ae77Skettenis    16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
675b725ae77Skettenis    64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
676b725ae77Skettenis   240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
677b725ae77Skettenis   124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
678b725ae77Skettenis   215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109, /* 96 */
679b725ae77Skettenis   121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
680b725ae77Skettenis   151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161,  7, /* 128 */
681b725ae77Skettenis    32, 33, 34, 35, 36, 21,  6, 23, 40, 41, 42, 43, 44,  9, 10, 27, /* 144 */
682b725ae77Skettenis    48, 49, 26, 51, 52, 53, 54,  8, 56, 57, 58, 59,  4, 20, 62,255, /* 160 */
683b725ae77Skettenis    -1, -1, 74, -1, -1, -1,106, -1, -1, -1, -1, -1, 95, -1, -1, -1, /* 176 */
684b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
685b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
686b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
687b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
688b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  /* 256 */
689b725ae77Skettenis };
690b725ae77Skettenis 
691b725ae77Skettenis 
692b725ae77Skettenis static int iso_8859_1_to_ibm1047_table[] = {
693b725ae77Skettenis     0,  1,  2,  3, 55, 45, 46, 47, 22,  5, 37, 11, 12, 13, 14, 15, /* 16 */
694b725ae77Skettenis    16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
695b725ae77Skettenis    64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
696b725ae77Skettenis   240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
697b725ae77Skettenis   124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
698b725ae77Skettenis   215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109, /* 96 */
699b725ae77Skettenis   121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
700b725ae77Skettenis   151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161,  7, /* 128 */
701b725ae77Skettenis    32, 33, 34, 35, 36, 21,  6, 23, 40, 41, 42, 43, 44,  9, 10, 27, /* 144 */
702b725ae77Skettenis    48, 49, 26, 51, 52, 53, 54,  8, 56, 57, 58, 59,  4, 20, 62,255, /* 160 */
703b725ae77Skettenis    65,170, 74,177,159,178,106,181,187,180,154,138,176,202,175,188, /* 176 */
704b725ae77Skettenis   144,143,234,250,190,160,182,179,157,218,155,139,183,184,185,171, /* 192 */
705b725ae77Skettenis   100,101, 98,102, 99,103,158,104,116,113,114,115,120,117,118,119, /* 208 */
706b725ae77Skettenis   172,105,237,238,235,239,236,191,128,253,254,251,252,186,174, 89, /* 224 */
707b725ae77Skettenis    68, 69, 66, 70, 67, 71,156, 72, 84, 81, 82, 83, 88, 85, 86, 87, /* 240 */
708b725ae77Skettenis   140, 73,205,206,203,207,204,225,112,221,222,219,220,141,142,223  /* 256 */
709b725ae77Skettenis };
710b725ae77Skettenis 
711b725ae77Skettenis 
712b725ae77Skettenis static int ebcdic_us_to_ascii_table[] = {
713b725ae77Skettenis     0,  1,  2,  3, -1,  9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15, /* 16 */
714b725ae77Skettenis    16, 17, 18, 19, -1, -1,  8, -1, 24, 25, -1, -1, 28, 29, 30, 31, /* 32 */
715b725ae77Skettenis    -1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1,  5,  6,  7, /* 48 */
716b725ae77Skettenis    -1, -1, 22, -1, -1, -1, -1,  4, -1, -1, -1, -1, 20, 21, -1, 26, /* 64 */
717b725ae77Skettenis    32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124, /* 80 */
718b725ae77Skettenis    38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, -1, /* 96 */
719b725ae77Skettenis    45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63, /* 112 */
720b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */
721b725ae77Skettenis    -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */
722b725ae77Skettenis    -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */
723b725ae77Skettenis    -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1, /* 176 */
724b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
725b725ae77Skettenis   123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */
726b725ae77Skettenis   125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */
727b725ae77Skettenis    92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */
728b725ae77Skettenis    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1  /* 256 */
729b725ae77Skettenis };
730b725ae77Skettenis 
731b725ae77Skettenis 
732b725ae77Skettenis static int ebcdic_us_to_iso_8859_1_table[] = {
733b725ae77Skettenis     0,  1,  2,  3,156,  9,134,127,151,141,142, 11, 12, 13, 14, 15, /* 16 */
734b725ae77Skettenis    16, 17, 18, 19,157,133,  8,135, 24, 25,146,143, 28, 29, 30, 31, /* 32 */
735b725ae77Skettenis   128,129,130,131,132, 10, 23, 27,136,137,138,139,140,  5,  6,  7, /* 48 */
736b725ae77Skettenis   144,145, 22,147,148,149,150,  4,152,153,154,155, 20, 21,158, 26, /* 64 */
737b725ae77Skettenis    32, -1, -1, -1, -1, -1, -1, -1, -1, -1,162, 46, 60, 40, 43,124, /* 80 */
738b725ae77Skettenis    38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59,172, /* 96 */
739b725ae77Skettenis    45, 47, -1, -1, -1, -1, -1, -1, -1, -1,166, 44, 37, 95, 62, 63, /* 112 */
740b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */
741b725ae77Skettenis    -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */
742b725ae77Skettenis    -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */
743b725ae77Skettenis    -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1, /* 176 */
744b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
745b725ae77Skettenis   123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */
746b725ae77Skettenis   125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */
747b725ae77Skettenis    92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */
748b725ae77Skettenis    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,159  /* 256 */
749b725ae77Skettenis };
750b725ae77Skettenis 
751b725ae77Skettenis 
752b725ae77Skettenis static int ebcdic_us_to_ibm1047_table[] = {
753b725ae77Skettenis     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 16 */
754b725ae77Skettenis    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
755b725ae77Skettenis    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
756b725ae77Skettenis    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
757b725ae77Skettenis    64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79, /* 80 */
758b725ae77Skettenis    80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94,176, /* 96 */
759b725ae77Skettenis    96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111, /* 112 */
760b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127, /* 128 */
761b725ae77Skettenis    -1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1, /* 144 */
762b725ae77Skettenis    -1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1, /* 160 */
763b725ae77Skettenis    -1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1, /* 176 */
764b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
765b725ae77Skettenis   192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1, /* 208 */
766b725ae77Skettenis   208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1, /* 224 */
767b725ae77Skettenis   224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1, /* 240 */
768b725ae77Skettenis   240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255  /* 256 */
769b725ae77Skettenis };
770b725ae77Skettenis 
771b725ae77Skettenis 
772b725ae77Skettenis static int ibm1047_to_ascii_table[] = {
773b725ae77Skettenis     0,  1,  2,  3, -1,  9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15, /* 16 */
774b725ae77Skettenis    16, 17, 18, 19, -1, -1,  8, -1, 24, 25, -1, -1, 28, 29, 30, 31, /* 32 */
775b725ae77Skettenis    -1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1,  5,  6,  7, /* 48 */
776b725ae77Skettenis    -1, -1, 22, -1, -1, -1, -1,  4, -1, -1, -1, -1, 20, 21, -1, 26, /* 64 */
777b725ae77Skettenis    32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124, /* 80 */
778b725ae77Skettenis    38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, 94, /* 96 */
779b725ae77Skettenis    45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63, /* 112 */
780b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */
781b725ae77Skettenis    -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */
782b725ae77Skettenis    -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */
783b725ae77Skettenis    -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, 91, -1, -1, /* 176 */
784b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, /* 192 */
785b725ae77Skettenis   123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */
786b725ae77Skettenis   125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */
787b725ae77Skettenis    92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */
788b725ae77Skettenis    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1  /* 256 */
789b725ae77Skettenis };
790b725ae77Skettenis 
791b725ae77Skettenis 
792b725ae77Skettenis static int ibm1047_to_iso_8859_1_table[] = {
793b725ae77Skettenis     0,  1,  2,  3,156,  9,134,127,151,141,142, 11, 12, 13, 14, 15, /* 16 */
794b725ae77Skettenis    16, 17, 18, 19,157,133,  8,135, 24, 25,146,143, 28, 29, 30, 31, /* 32 */
795b725ae77Skettenis   128,129,130,131,132, 10, 23, 27,136,137,138,139,140,  5,  6,  7, /* 48 */
796b725ae77Skettenis   144,145, 22,147,148,149,150,  4,152,153,154,155, 20, 21,158, 26, /* 64 */
797b725ae77Skettenis    32,160,226,228,224,225,227,229,231,241,162, 46, 60, 40, 43,124, /* 80 */
798b725ae77Skettenis    38,233,234,235,232,237,238,239,236,223, 33, 36, 42, 41, 59, 94, /* 96 */
799b725ae77Skettenis    45, 47,194,196,192,193,195,197,199,209,166, 44, 37, 95, 62, 63, /* 112 */
800b725ae77Skettenis   248,201,202,203,200,205,206,207,204, 96, 58, 35, 64, 39, 61, 34, /* 128 */
801b725ae77Skettenis   216, 97, 98, 99,100,101,102,103,104,105,171,187,240,253,254,177, /* 144 */
802b725ae77Skettenis   176,106,107,108,109,110,111,112,113,114,170,186,230,184,198,164, /* 160 */
803b725ae77Skettenis   181,126,115,116,117,118,119,120,121,122,161,191,208, 91,222,174, /* 176 */
804b725ae77Skettenis   172,163,165,183,169,167,182,188,189,190,221,168,175, 93,180,215, /* 192 */
805b725ae77Skettenis   123, 65, 66, 67, 68, 69, 70, 71, 72, 73,173,244,246,242,243,245, /* 208 */
806b725ae77Skettenis   125, 74, 75, 76, 77, 78, 79, 80, 81, 82,185,251,252,249,250,255, /* 224 */
807b725ae77Skettenis    92,247, 83, 84, 85, 86, 87, 88, 89, 90,178,212,214,210,211,213, /* 240 */
808b725ae77Skettenis    48, 49, 50, 51, 52, 53, 54, 55, 56, 57,179,219,220,217,218,159  /* 256 */
809b725ae77Skettenis };
810b725ae77Skettenis 
811b725ae77Skettenis 
812b725ae77Skettenis static int ibm1047_to_ebcdic_us_table[] = {
813b725ae77Skettenis     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 16 */
814b725ae77Skettenis    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
815b725ae77Skettenis    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
816b725ae77Skettenis    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
817b725ae77Skettenis    64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79, /* 80 */
818b725ae77Skettenis    80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94, -1, /* 96 */
819b725ae77Skettenis    96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111, /* 112 */
820b725ae77Skettenis    -1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127, /* 128 */
821b725ae77Skettenis    -1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1, /* 144 */
822b725ae77Skettenis    -1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1, /* 160 */
823b725ae77Skettenis    -1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1, /* 176 */
824b725ae77Skettenis    95, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
825b725ae77Skettenis   192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1, /* 208 */
826b725ae77Skettenis   208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1, /* 224 */
827b725ae77Skettenis   224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1, /* 240 */
828b725ae77Skettenis   240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255  /* 256 */
829b725ae77Skettenis };
830b725ae77Skettenis 
831b725ae77Skettenis 
832b725ae77Skettenis static int
table_convert_char(void * baton,int from,int * to)833b725ae77Skettenis table_convert_char (void *baton, int from, int *to)
834b725ae77Skettenis {
835b725ae77Skettenis   int *table = (int *) baton;
836b725ae77Skettenis 
837b725ae77Skettenis   if (0 <= from && from <= 255
838b725ae77Skettenis       && table[from] != -1)
839b725ae77Skettenis     {
840b725ae77Skettenis       *to = table[from];
841b725ae77Skettenis       return 1;
842b725ae77Skettenis     }
843b725ae77Skettenis   else
844b725ae77Skettenis     return 0;
845b725ae77Skettenis }
846b725ae77Skettenis 
847b725ae77Skettenis 
848b725ae77Skettenis static struct translation *
table_translation(const char * from,const char * to,int * table,const char * (* c_target_char_has_backslash_escape)(void * baton,int target_char),void * c_target_char_has_backslash_escape_baton,int (* c_parse_backslash)(void * baton,int host_char,int * target_char),void * c_parse_backslash_baton)849b725ae77Skettenis table_translation (const char *from, const char *to, int *table,
850b725ae77Skettenis                    const char *(*c_target_char_has_backslash_escape)
851b725ae77Skettenis                    (void *baton, int target_char),
852b725ae77Skettenis                    void *c_target_char_has_backslash_escape_baton,
853b725ae77Skettenis                    int (*c_parse_backslash) (void *baton,
854b725ae77Skettenis                                              int host_char,
855b725ae77Skettenis                                              int *target_char),
856b725ae77Skettenis                    void *c_parse_backslash_baton)
857b725ae77Skettenis {
858b725ae77Skettenis   struct translation *t = xmalloc (sizeof (*t));
859b725ae77Skettenis 
860b725ae77Skettenis   memset (t, 0, sizeof (*t));
861b725ae77Skettenis   t->from = from;
862b725ae77Skettenis   t->to = to;
863b725ae77Skettenis   t->c_target_char_has_backslash_escape = c_target_char_has_backslash_escape;
864b725ae77Skettenis   t->c_target_char_has_backslash_escape_baton
865b725ae77Skettenis     = c_target_char_has_backslash_escape_baton;
866b725ae77Skettenis   t->c_parse_backslash = c_parse_backslash;
867b725ae77Skettenis   t->c_parse_backslash_baton = c_parse_backslash_baton;
868b725ae77Skettenis   t->convert_char = table_convert_char;
869b725ae77Skettenis   t->convert_char_baton = (void *) table;
870b725ae77Skettenis 
871b725ae77Skettenis   return t;
872b725ae77Skettenis }
873b725ae77Skettenis 
874b725ae77Skettenis 
875b725ae77Skettenis static struct translation *
simple_table_translation(const char * from,const char * to,int * table)876b725ae77Skettenis simple_table_translation (const char *from, const char *to, int *table)
877b725ae77Skettenis {
878b725ae77Skettenis   return table_translation (from, to, table, 0, 0, 0, 0);
879b725ae77Skettenis }
880b725ae77Skettenis 
881b725ae77Skettenis 
882b725ae77Skettenis 
883b725ae77Skettenis /* Setting and retrieving the host and target charsets.  */
884b725ae77Skettenis 
885b725ae77Skettenis 
886b725ae77Skettenis /* The current host and target character sets.  */
887b725ae77Skettenis static struct charset *current_host_charset, *current_target_charset;
888b725ae77Skettenis 
889b725ae77Skettenis /* The current functions and batons we should use for the functions in
890b725ae77Skettenis    charset.h.  */
891b725ae77Skettenis 
892b725ae77Skettenis static const char *(*c_target_char_has_backslash_escape_func)
893b725ae77Skettenis      (void *baton, int target_char);
894b725ae77Skettenis static void *c_target_char_has_backslash_escape_baton;
895b725ae77Skettenis 
896b725ae77Skettenis static int (*c_parse_backslash_func) (void *baton,
897b725ae77Skettenis                                       int host_char,
898b725ae77Skettenis                                       int *target_char);
899b725ae77Skettenis static void *c_parse_backslash_baton;
900b725ae77Skettenis 
901b725ae77Skettenis static int (*host_char_to_target_func) (void *baton,
902b725ae77Skettenis                                         int host_char,
903b725ae77Skettenis                                         int *target_char);
904b725ae77Skettenis static void *host_char_to_target_baton;
905b725ae77Skettenis 
906b725ae77Skettenis static int (*target_char_to_host_func) (void *baton,
907b725ae77Skettenis                                         int target_char,
908b725ae77Skettenis                                         int *host_char);
909b725ae77Skettenis static void *target_char_to_host_baton;
910b725ae77Skettenis 
911b725ae77Skettenis 
912b725ae77Skettenis /* Cached iconv conversions, that might be useful to fallback
913b725ae77Skettenis    routines.  */
914b725ae77Skettenis static struct cached_iconv cached_iconv_host_to_target;
915b725ae77Skettenis static struct cached_iconv cached_iconv_target_to_host;
916b725ae77Skettenis 
917b725ae77Skettenis 
918b725ae77Skettenis /* Charset structures manipulation functions.  */
919b725ae77Skettenis 
920b725ae77Skettenis static struct charset *
lookup_charset_or_error(const char * name)921b725ae77Skettenis lookup_charset_or_error (const char *name)
922b725ae77Skettenis {
923b725ae77Skettenis   struct charset *cs = lookup_charset (name);
924b725ae77Skettenis 
925b725ae77Skettenis   if (! cs)
926b725ae77Skettenis     error ("GDB doesn't know of any character set named `%s'.", name);
927b725ae77Skettenis 
928b725ae77Skettenis   return cs;
929b725ae77Skettenis }
930b725ae77Skettenis 
931b725ae77Skettenis static void
check_valid_host_charset(struct charset * cs)932b725ae77Skettenis check_valid_host_charset (struct charset *cs)
933b725ae77Skettenis {
934b725ae77Skettenis   if (! cs->valid_host_charset)
935b725ae77Skettenis     error ("GDB can't use `%s' as its host character set.", cs->name);
936b725ae77Skettenis }
937b725ae77Skettenis 
938b725ae77Skettenis /* Set the host and target character sets to HOST and TARGET.  */
939b725ae77Skettenis static void
set_host_and_target_charsets(struct charset * host,struct charset * target)940b725ae77Skettenis set_host_and_target_charsets (struct charset *host, struct charset *target)
941b725ae77Skettenis {
942b725ae77Skettenis   struct translation *h2t, *t2h;
943b725ae77Skettenis 
944b725ae77Skettenis   /* If they're not both initialized yet, then just do nothing for
945b725ae77Skettenis      now.  As soon as we're done running our initialize function,
946b725ae77Skettenis      everything will be initialized.  */
947b725ae77Skettenis   if (! host || ! target)
948b725ae77Skettenis     {
949b725ae77Skettenis       current_host_charset = host;
950b725ae77Skettenis       current_target_charset = target;
951b725ae77Skettenis       return;
952b725ae77Skettenis     }
953b725ae77Skettenis 
954b725ae77Skettenis   h2t = lookup_translation (host->name, target->name);
955b725ae77Skettenis   t2h = lookup_translation (target->name, host->name);
956b725ae77Skettenis 
957b725ae77Skettenis   /* If the translations don't provide conversion functions, make sure
958b725ae77Skettenis      iconv can back them up.  Do this *before* modifying any state.  */
959b725ae77Skettenis   if (host != target)
960b725ae77Skettenis     {
961b725ae77Skettenis       if (! h2t || ! h2t->convert_char)
962b725ae77Skettenis         {
963b725ae77Skettenis           if (check_iconv_cache (&cached_iconv_host_to_target, host, target)
964b725ae77Skettenis               < 0)
965b725ae77Skettenis             error ("GDB can't convert from the `%s' character set to `%s'.",
966b725ae77Skettenis                    host->name, target->name);
967b725ae77Skettenis         }
968b725ae77Skettenis       if (! t2h || ! t2h->convert_char)
969b725ae77Skettenis         {
970b725ae77Skettenis           if (check_iconv_cache (&cached_iconv_target_to_host, target, host)
971b725ae77Skettenis               < 0)
972b725ae77Skettenis             error ("GDB can't convert from the `%s' character set to `%s'.",
973b725ae77Skettenis                    target->name, host->name);
974b725ae77Skettenis         }
975b725ae77Skettenis     }
976b725ae77Skettenis 
977b725ae77Skettenis   if (t2h && t2h->c_target_char_has_backslash_escape)
978b725ae77Skettenis     {
979b725ae77Skettenis       c_target_char_has_backslash_escape_func
980b725ae77Skettenis         = t2h->c_target_char_has_backslash_escape;
981b725ae77Skettenis       c_target_char_has_backslash_escape_baton
982b725ae77Skettenis         = t2h->c_target_char_has_backslash_escape_baton;
983b725ae77Skettenis     }
984b725ae77Skettenis   else
985b725ae77Skettenis     c_target_char_has_backslash_escape_func
986b725ae77Skettenis       = default_c_target_char_has_backslash_escape;
987b725ae77Skettenis 
988b725ae77Skettenis   if (h2t && h2t->c_parse_backslash)
989b725ae77Skettenis     {
990b725ae77Skettenis       c_parse_backslash_func = h2t->c_parse_backslash;
991b725ae77Skettenis       c_parse_backslash_baton = h2t->c_parse_backslash_baton;
992b725ae77Skettenis     }
993b725ae77Skettenis   else
994b725ae77Skettenis     c_parse_backslash_func = default_c_parse_backslash;
995b725ae77Skettenis 
996b725ae77Skettenis   if (h2t && h2t->convert_char)
997b725ae77Skettenis     {
998b725ae77Skettenis       host_char_to_target_func = h2t->convert_char;
999b725ae77Skettenis       host_char_to_target_baton = h2t->convert_char_baton;
1000b725ae77Skettenis     }
1001b725ae77Skettenis   else if (host == target)
1002b725ae77Skettenis     host_char_to_target_func = identity_either_char_to_other;
1003b725ae77Skettenis   else
1004b725ae77Skettenis     {
1005b725ae77Skettenis       host_char_to_target_func = iconv_convert;
1006b725ae77Skettenis       host_char_to_target_baton = &cached_iconv_host_to_target;
1007b725ae77Skettenis     }
1008b725ae77Skettenis 
1009b725ae77Skettenis   if (t2h && t2h->convert_char)
1010b725ae77Skettenis     {
1011b725ae77Skettenis       target_char_to_host_func = t2h->convert_char;
1012b725ae77Skettenis       target_char_to_host_baton = t2h->convert_char_baton;
1013b725ae77Skettenis     }
1014b725ae77Skettenis   else if (host == target)
1015b725ae77Skettenis     target_char_to_host_func = identity_either_char_to_other;
1016b725ae77Skettenis   else
1017b725ae77Skettenis     {
1018b725ae77Skettenis       target_char_to_host_func = iconv_convert;
1019b725ae77Skettenis       target_char_to_host_baton = &cached_iconv_target_to_host;
1020b725ae77Skettenis     }
1021b725ae77Skettenis 
1022b725ae77Skettenis   current_host_charset = host;
1023b725ae77Skettenis   current_target_charset = target;
1024b725ae77Skettenis }
1025b725ae77Skettenis 
1026b725ae77Skettenis /* Do the real work of setting the host charset.  */
1027b725ae77Skettenis static void
set_host_charset(const char * charset)1028b725ae77Skettenis set_host_charset (const char *charset)
1029b725ae77Skettenis {
1030b725ae77Skettenis   struct charset *cs = lookup_charset_or_error (charset);
1031b725ae77Skettenis   check_valid_host_charset (cs);
1032b725ae77Skettenis   set_host_and_target_charsets (cs, current_target_charset);
1033b725ae77Skettenis }
1034b725ae77Skettenis 
1035b725ae77Skettenis /* Do the real work of setting the target charset.  */
1036b725ae77Skettenis static void
set_target_charset(const char * charset)1037b725ae77Skettenis set_target_charset (const char *charset)
1038b725ae77Skettenis {
1039b725ae77Skettenis   struct charset *cs = lookup_charset_or_error (charset);
1040b725ae77Skettenis 
1041b725ae77Skettenis   set_host_and_target_charsets (current_host_charset, cs);
1042b725ae77Skettenis }
1043b725ae77Skettenis 
1044b725ae77Skettenis 
1045b725ae77Skettenis /* 'Set charset', 'set host-charset', 'set target-charset', 'show
1046b725ae77Skettenis    charset' sfunc's.  */
1047b725ae77Skettenis 
1048b725ae77Skettenis /* This is the sfunc for the 'set charset' command.  */
1049b725ae77Skettenis static void
set_charset_sfunc(char * charset,int from_tty,struct cmd_list_element * c)1050b725ae77Skettenis set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c)
1051b725ae77Skettenis {
1052b725ae77Skettenis   struct charset *cs = lookup_charset_or_error (host_charset_name);
1053b725ae77Skettenis   check_valid_host_charset (cs);
1054b725ae77Skettenis   /* CAREFUL: set the target charset here as well. */
1055b725ae77Skettenis   target_charset_name = host_charset_name;
1056b725ae77Skettenis   set_host_and_target_charsets (cs, cs);
1057b725ae77Skettenis }
1058b725ae77Skettenis 
1059b725ae77Skettenis /* 'set host-charset' command sfunc.  We need a wrapper here because
1060b725ae77Skettenis    the function needs to have a specific signature.  */
1061b725ae77Skettenis static void
set_host_charset_sfunc(char * charset,int from_tty,struct cmd_list_element * c)1062b725ae77Skettenis set_host_charset_sfunc (char *charset, int from_tty,
1063b725ae77Skettenis 			  struct cmd_list_element *c)
1064b725ae77Skettenis {
1065b725ae77Skettenis   set_host_charset (host_charset_name);
1066b725ae77Skettenis }
1067b725ae77Skettenis 
1068b725ae77Skettenis /* Wrapper for the 'set target-charset' command.  */
1069b725ae77Skettenis static void
set_target_charset_sfunc(char * charset,int from_tty,struct cmd_list_element * c)1070b725ae77Skettenis set_target_charset_sfunc (char *charset, int from_tty,
1071b725ae77Skettenis 			    struct cmd_list_element *c)
1072b725ae77Skettenis {
1073b725ae77Skettenis   set_target_charset (target_charset_name);
1074b725ae77Skettenis }
1075b725ae77Skettenis 
1076b725ae77Skettenis /* sfunc for the 'show charset' command.  */
1077b725ae77Skettenis static void
show_charset(char * arg,int from_tty)1078b725ae77Skettenis show_charset (char *arg, int from_tty)
1079b725ae77Skettenis {
1080b725ae77Skettenis   if (current_host_charset == current_target_charset)
1081b725ae77Skettenis     {
1082b725ae77Skettenis       printf_filtered ("The current host and target character set is `%s'.\n",
1083b725ae77Skettenis                        host_charset ());
1084b725ae77Skettenis     }
1085b725ae77Skettenis   else
1086b725ae77Skettenis     {
1087b725ae77Skettenis       printf_filtered ("The current host character set is `%s'.\n",
1088b725ae77Skettenis                        host_charset ());
1089b725ae77Skettenis       printf_filtered ("The current target character set is `%s'.\n",
1090b725ae77Skettenis                        target_charset ());
1091b725ae77Skettenis     }
1092b725ae77Skettenis }
1093b725ae77Skettenis 
1094b725ae77Skettenis 
1095b725ae77Skettenis /* Accessor functions.  */
1096b725ae77Skettenis 
1097b725ae77Skettenis const char *
host_charset(void)1098b725ae77Skettenis host_charset (void)
1099b725ae77Skettenis {
1100b725ae77Skettenis   return current_host_charset->name;
1101b725ae77Skettenis }
1102b725ae77Skettenis 
1103b725ae77Skettenis const char *
target_charset(void)1104b725ae77Skettenis target_charset (void)
1105b725ae77Skettenis {
1106b725ae77Skettenis   return current_target_charset->name;
1107b725ae77Skettenis }
1108b725ae77Skettenis 
1109b725ae77Skettenis 
1110b725ae77Skettenis 
1111b725ae77Skettenis /* Public character management functions.  */
1112b725ae77Skettenis 
1113b725ae77Skettenis 
1114b725ae77Skettenis const char *
c_target_char_has_backslash_escape(int target_char)1115b725ae77Skettenis c_target_char_has_backslash_escape (int target_char)
1116b725ae77Skettenis {
1117b725ae77Skettenis   return ((*c_target_char_has_backslash_escape_func)
1118b725ae77Skettenis           (c_target_char_has_backslash_escape_baton, target_char));
1119b725ae77Skettenis }
1120b725ae77Skettenis 
1121b725ae77Skettenis 
1122b725ae77Skettenis int
c_parse_backslash(int host_char,int * target_char)1123b725ae77Skettenis c_parse_backslash (int host_char, int *target_char)
1124b725ae77Skettenis {
1125b725ae77Skettenis   return (*c_parse_backslash_func) (c_parse_backslash_baton,
1126b725ae77Skettenis                                     host_char, target_char);
1127b725ae77Skettenis }
1128b725ae77Skettenis 
1129b725ae77Skettenis 
1130b725ae77Skettenis int
host_char_print_literally(int host_char)1131b725ae77Skettenis host_char_print_literally (int host_char)
1132b725ae77Skettenis {
1133b725ae77Skettenis   return ((*current_host_charset->host_char_print_literally)
1134b725ae77Skettenis           (current_host_charset->host_char_print_literally_baton,
1135b725ae77Skettenis            host_char));
1136b725ae77Skettenis }
1137b725ae77Skettenis 
1138b725ae77Skettenis 
1139b725ae77Skettenis int
target_char_to_control_char(int target_char,int * target_ctrl_char)1140b725ae77Skettenis target_char_to_control_char (int target_char, int *target_ctrl_char)
1141b725ae77Skettenis {
1142b725ae77Skettenis   return ((*current_target_charset->target_char_to_control_char)
1143b725ae77Skettenis           (current_target_charset->target_char_to_control_char_baton,
1144b725ae77Skettenis            target_char, target_ctrl_char));
1145b725ae77Skettenis }
1146b725ae77Skettenis 
1147b725ae77Skettenis 
1148b725ae77Skettenis int
host_char_to_target(int host_char,int * target_char)1149b725ae77Skettenis host_char_to_target (int host_char, int *target_char)
1150b725ae77Skettenis {
1151b725ae77Skettenis   return ((*host_char_to_target_func)
1152b725ae77Skettenis           (host_char_to_target_baton, host_char, target_char));
1153b725ae77Skettenis }
1154b725ae77Skettenis 
1155b725ae77Skettenis 
1156b725ae77Skettenis int
target_char_to_host(int target_char,int * host_char)1157b725ae77Skettenis target_char_to_host (int target_char, int *host_char)
1158b725ae77Skettenis {
1159b725ae77Skettenis   return ((*target_char_to_host_func)
1160b725ae77Skettenis           (target_char_to_host_baton, target_char, host_char));
1161b725ae77Skettenis }
1162b725ae77Skettenis 
1163b725ae77Skettenis 
1164b725ae77Skettenis 
1165b725ae77Skettenis /* The charset.c module initialization function.  */
1166b725ae77Skettenis 
1167b725ae77Skettenis extern initialize_file_ftype _initialize_charset; /* -Wmissing-prototype */
1168b725ae77Skettenis 
1169b725ae77Skettenis void
_initialize_charset(void)1170b725ae77Skettenis _initialize_charset (void)
1171b725ae77Skettenis {
1172b725ae77Skettenis   struct cmd_list_element *new_cmd;
1173b725ae77Skettenis 
1174b725ae77Skettenis   /* Register all the character set GDB knows about.
1175b725ae77Skettenis 
1176b725ae77Skettenis      You should use the same names that iconv does, where possible, to
1177b725ae77Skettenis      take advantage of the iconv-based default behaviors.
1178b725ae77Skettenis 
1179b725ae77Skettenis      CAUTION: if you register a character set, you must also register
1180b725ae77Skettenis      as many translations as are necessary to make that character set
1181b725ae77Skettenis      interoperate correctly with all the other character sets.  We do
1182b725ae77Skettenis      provide default behaviors when no translation is available, or
1183b725ae77Skettenis      when a translation's function pointer for a particular operation
1184b725ae77Skettenis      is zero.  Hopefully, these defaults will be correct often enough
1185b725ae77Skettenis      that we won't need to provide too many translations.  */
1186b725ae77Skettenis   register_charset (simple_charset ("ASCII", 1,
1187b725ae77Skettenis                                     ascii_print_literally, 0,
1188b725ae77Skettenis                                     ascii_to_control, 0));
1189b725ae77Skettenis   register_charset (iso_8859_family_charset ("ISO-8859-1"));
1190b725ae77Skettenis   register_charset (ebcdic_family_charset ("EBCDIC-US"));
1191b725ae77Skettenis   register_charset (ebcdic_family_charset ("IBM1047"));
1192b725ae77Skettenis   register_iconv_charsets ();
1193b725ae77Skettenis 
1194b725ae77Skettenis   {
1195b725ae77Skettenis     struct { char *from; char *to; int *table; } tlist[] = {
1196b725ae77Skettenis       { "ASCII",      "ISO-8859-1", ascii_to_iso_8859_1_table },
1197b725ae77Skettenis       { "ASCII",      "EBCDIC-US",  ascii_to_ebcdic_us_table },
1198b725ae77Skettenis       { "ASCII",      "IBM1047",    ascii_to_ibm1047_table },
1199b725ae77Skettenis       { "ISO-8859-1", "ASCII",      iso_8859_1_to_ascii_table },
1200b725ae77Skettenis       { "ISO-8859-1", "EBCDIC-US",  iso_8859_1_to_ebcdic_us_table },
1201b725ae77Skettenis       { "ISO-8859-1", "IBM1047",    iso_8859_1_to_ibm1047_table },
1202b725ae77Skettenis       { "EBCDIC-US",  "ASCII",      ebcdic_us_to_ascii_table },
1203b725ae77Skettenis       { "EBCDIC-US",  "ISO-8859-1", ebcdic_us_to_iso_8859_1_table },
1204b725ae77Skettenis       { "EBCDIC-US",  "IBM1047",    ebcdic_us_to_ibm1047_table },
1205b725ae77Skettenis       { "IBM1047",    "ASCII",      ibm1047_to_ascii_table },
1206b725ae77Skettenis       { "IBM1047",    "ISO-8859-1", ibm1047_to_iso_8859_1_table },
1207b725ae77Skettenis       { "IBM1047",    "EBCDIC-US",  ibm1047_to_ebcdic_us_table }
1208b725ae77Skettenis     };
1209b725ae77Skettenis 
1210b725ae77Skettenis     int i;
1211b725ae77Skettenis 
1212b725ae77Skettenis     for (i = 0; i < (sizeof (tlist) / sizeof (tlist[0])); i++)
1213b725ae77Skettenis       register_translation (simple_table_translation (tlist[i].from,
1214b725ae77Skettenis                                                       tlist[i].to,
1215b725ae77Skettenis                                                       tlist[i].table));
1216b725ae77Skettenis   }
1217b725ae77Skettenis 
1218b725ae77Skettenis   set_host_charset (host_charset_name);
1219b725ae77Skettenis   set_target_charset (target_charset_name);
1220b725ae77Skettenis 
1221b725ae77Skettenis   new_cmd = add_set_enum_cmd ("charset",
1222b725ae77Skettenis 			      class_support,
1223b725ae77Skettenis 			      host_charset_enum,
1224b725ae77Skettenis 			      &host_charset_name,
1225b725ae77Skettenis                               "Set the host and target character sets.\n"
1226b725ae77Skettenis                               "The `host character set' is the one used by the system GDB is running on.\n"
1227b725ae77Skettenis                               "The `target character set' is the one used by the program being debugged.\n"
1228b725ae77Skettenis                               "You may only use supersets of ASCII for your host character set; GDB does\n"
1229b725ae77Skettenis                               "not support any others.\n"
1230b725ae77Skettenis                               "To see a list of the character sets GDB supports, type `set charset <TAB>'.",
1231b725ae77Skettenis 			      &setlist);
1232b725ae77Skettenis 
1233b725ae77Skettenis   /* Note that the sfunc below needs to set target_charset_name, because
1234b725ae77Skettenis      the 'set charset' command sets two variables.  */
1235b725ae77Skettenis   set_cmd_sfunc (new_cmd, set_charset_sfunc);
1236b725ae77Skettenis   /* Don't use set_from_show - need to print some extra info. */
1237b725ae77Skettenis   add_cmd ("charset", class_support, show_charset,
1238b725ae77Skettenis 	   "Show the host and target character sets.\n"
1239b725ae77Skettenis 	   "The `host character set' is the one used by the system GDB is running on.\n"
1240b725ae77Skettenis 	   "The `target character set' is the one used by the program being debugged.\n"
1241b725ae77Skettenis 	   "You may only use supersets of ASCII for your host character set; GDB does\n"
1242b725ae77Skettenis 	   "not support any others.\n"
1243b725ae77Skettenis 	   "To see a list of the character sets GDB supports, type `set charset <TAB>'.",
1244b725ae77Skettenis 	   &showlist);
1245b725ae77Skettenis 
1246b725ae77Skettenis 
1247b725ae77Skettenis   new_cmd = add_set_enum_cmd ("host-charset",
1248b725ae77Skettenis 			      class_support,
1249b725ae77Skettenis 			      host_charset_enum,
1250b725ae77Skettenis 			      &host_charset_name,
1251b725ae77Skettenis 			      "Set the host character set.\n"
1252b725ae77Skettenis 			      "The `host character set' is the one used by the system GDB is running on.\n"
1253b725ae77Skettenis 			      "You may only use supersets of ASCII for your host character set; GDB does\n"
1254b725ae77Skettenis 			      "not support any others.\n"
1255b725ae77Skettenis 			      "To see a list of the character sets GDB supports, type `set host-charset <TAB>'.",
1256b725ae77Skettenis 			      &setlist);
1257b725ae77Skettenis 
1258b725ae77Skettenis   set_cmd_sfunc (new_cmd, set_host_charset_sfunc);
1259b725ae77Skettenis 
1260*11efff7fSkettenis   deprecated_add_show_from_set (new_cmd, &showlist);
1261b725ae77Skettenis 
1262b725ae77Skettenis 
1263b725ae77Skettenis 
1264b725ae77Skettenis   new_cmd = add_set_enum_cmd ("target-charset",
1265b725ae77Skettenis 			      class_support,
1266b725ae77Skettenis 			      target_charset_enum,
1267b725ae77Skettenis 			      &target_charset_name,
1268b725ae77Skettenis 			      "Set the target character set.\n"
1269b725ae77Skettenis 			      "The `target character set' is the one used by the program being debugged.\n"
1270b725ae77Skettenis 			      "GDB translates characters and strings between the host and target\n"
1271b725ae77Skettenis 			      "character sets as needed.\n"
1272b725ae77Skettenis 			      "To see a list of the character sets GDB supports, type `set target-charset'<TAB>",
1273b725ae77Skettenis 			      &setlist);
1274b725ae77Skettenis 
1275b725ae77Skettenis   set_cmd_sfunc (new_cmd, set_target_charset_sfunc);
1276*11efff7fSkettenis   deprecated_add_show_from_set (new_cmd, &showlist);
1277b725ae77Skettenis }
1278