gdb
[deliverable/binutils-gdb.git] / gdb / charset.c
CommitLineData
234b45d4 1/* Character set conversion support for GDB.
1bac305b 2
0fb0cc75 3 Copyright (C) 2001, 2003, 2007, 2008, 2009 Free Software Foundation, Inc.
234b45d4
KB
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
234b45d4
KB
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
234b45d4
KB
19
20#include "defs.h"
21#include "charset.h"
22#include "gdbcmd.h"
23#include "gdb_assert.h"
6c7a06a3
TT
24#include "gdb_obstack.h"
25#include "charset-list.h"
26#include "vec.h"
234b45d4
KB
27
28#include <stddef.h>
4ef3f3be 29#include "gdb_string.h"
234b45d4
KB
30#include <ctype.h>
31
234b45d4
KB
32\f
33/* How GDB's character set support works
34
6c7a06a3 35 GDB has three global settings:
234b45d4
KB
36
37 - The `current host character set' is the character set GDB should
38 use in talking to the user, and which (hopefully) the user's
6c7a06a3
TT
39 terminal knows how to display properly. Most users should not
40 change this.
234b45d4
KB
41
42 - The `current target character set' is the character set the
43 program being debugged uses.
44
6c7a06a3
TT
45 - The `current target wide character set' is the wide character set
46 the program being debugged uses, that is, the encoding used for
47 wchar_t.
48
234b45d4
KB
49 There are commands to set each of these, and mechanisms for
50 choosing reasonable default values. GDB has a global list of
51 character sets that it can use as its host or target character
52 sets.
53
54 The header file `charset.h' declares various functions that
55 different pieces of GDB need to perform tasks like:
56
57 - printing target strings and characters to the user's terminal
58 (mostly target->host conversions),
59
60 - building target-appropriate representations of strings and
61 characters the user enters in expressions (mostly host->target
62 conversions),
63
6c7a06a3
TT
64 and so on.
65
66 To avoid excessive code duplication and maintenance efforts,
67 GDB simply requires a capable iconv function. Users on platforms
68 without a suitable iconv can use the GNU iconv library. */
234b45d4
KB
69
70\f
6c7a06a3 71#ifdef PHONY_ICONV
234b45d4 72
6c7a06a3
TT
73/* Provide a phony iconv that does as little as possible. Also,
74 arrange for there to be a single available character set. */
234b45d4 75
6c7a06a3
TT
76#undef GDB_DEFAULT_HOST_CHARSET
77#define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1"
78#define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1"
79#define GDB_DEFAULT_TARGET_WIDE_CHARSET "ISO-8859-1"
80#undef DEFAULT_CHARSET_NAMES
81#define DEFAULT_CHARSET_NAMES GDB_DEFAULT_HOST_CHARSET ,
82
83#undef iconv_t
84#define iconv_t int
85#undef iconv_open
86#undef iconv
87#undef iconv_close
88
0dd7fb99
TT
89#undef ICONV_CONST
90#define ICONV_CONST const
91
76208fec 92/* Some systems don't have EILSEQ, so we define it here, but not as
e726d784
EZ
93 EINVAL, because callers of `iconv' want to distinguish EINVAL and
94 EILSEQ. This is what iconv.h from libiconv does as well. Note
95 that wchar.h may also define EILSEQ, so this needs to be after we
96 include wchar.h, which happens in defs.h through gdb_wchar.h. */
97#ifndef EILSEQ
98#define EILSEQ ENOENT
99#endif
100
6c7a06a3
TT
101iconv_t
102iconv_open (const char *to, const char *from)
103{
104 /* We allow conversions from UCS-4BE, wchar_t, and the host charset.
105 We allow conversions to wchar_t and the host charset. */
106 if (strcmp (from, "UCS-4BE") && strcmp (from, "wchar_t")
107 && strcmp (from, GDB_DEFAULT_HOST_CHARSET))
108 return -1;
109 if (strcmp (to, "wchar_t") && strcmp (to, GDB_DEFAULT_HOST_CHARSET))
110 return -1;
234b45d4 111
6c7a06a3
TT
112 /* Return 1 if we are converting from UCS-4BE, 0 otherwise. This is
113 used as a flag in calls to iconv. */
114 return !strcmp (from, "UCS-4BE");
115}
234b45d4 116
6c7a06a3
TT
117int
118iconv_close (iconv_t arg)
119{
120 return 0;
121}
234b45d4 122
6c7a06a3 123size_t
0dd7fb99 124iconv (iconv_t ucs_flag, const char **inbuf, size_t *inbytesleft,
6c7a06a3
TT
125 char **outbuf, size_t *outbytesleft)
126{
127 if (ucs_flag)
128 {
129 while (*inbytesleft >= 4)
130 {
131 size_t j;
132 unsigned long c = 0;
133
134 for (j = 0; j < 4; ++j)
135 {
136 c <<= 8;
137 c += (*inbuf)[j] & 0xff;
138 }
139
140 if (c >= 256)
141 {
142 errno = EILSEQ;
143 return -1;
144 }
145 **outbuf = c & 0xff;
146 ++*outbuf;
147 --*outbytesleft;
148
149 ++*inbuf;
150 *inbytesleft -= 4;
151 }
152 if (*inbytesleft < 4)
153 {
154 errno = EINVAL;
155 return -1;
156 }
157 }
158 else
159 {
160 /* In all other cases we simply copy input bytes to the
161 output. */
162 size_t amt = *inbytesleft;
163 if (amt > *outbytesleft)
164 amt = *outbytesleft;
165 memcpy (*outbuf, *inbuf, amt);
166 *inbuf += amt;
167 *outbuf += amt;
168 *inbytesleft -= amt;
169 *outbytesleft -= amt;
170 }
234b45d4 171
6c7a06a3
TT
172 if (*inbytesleft)
173 {
174 errno = E2BIG;
175 return -1;
176 }
234b45d4 177
6c7a06a3
TT
178 /* The number of non-reversible conversions -- but they were all
179 reversible. */
180 return 0;
181}
234b45d4 182
6c7a06a3 183#endif
234b45d4
KB
184
185
186\f
187/* The global lists of character sets and translations. */
188
189
e33d66ec
EZ
190#ifndef GDB_DEFAULT_TARGET_CHARSET
191#define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1"
192#endif
193
6c7a06a3
TT
194#ifndef GDB_DEFAULT_TARGET_WIDE_CHARSET
195#define GDB_DEFAULT_TARGET_WIDE_CHARSET "UCS-4"
196#endif
197
198static const char *auto_host_charset_name = GDB_DEFAULT_HOST_CHARSET;
199static const char *host_charset_name = "auto";
920d2a44
AC
200static void
201show_host_charset_name (struct ui_file *file, int from_tty,
202 struct cmd_list_element *c,
203 const char *value)
204{
6c7a06a3
TT
205 if (!strcmp (value, "auto"))
206 fprintf_filtered (file,
207 _("The host character set is \"auto; currently %s\".\n"),
208 auto_host_charset_name);
209 else
210 fprintf_filtered (file, _("The host character set is \"%s\".\n"), value);
920d2a44
AC
211}
212
e33d66ec 213static const char *target_charset_name = GDB_DEFAULT_TARGET_CHARSET;
920d2a44
AC
214static void
215show_target_charset_name (struct ui_file *file, int from_tty,
216 struct cmd_list_element *c, const char *value)
217{
218 fprintf_filtered (file, _("The target character set is \"%s\".\n"),
219 value);
220}
221
6c7a06a3
TT
222static const char *target_wide_charset_name = GDB_DEFAULT_TARGET_WIDE_CHARSET;
223static void
224show_target_wide_charset_name (struct ui_file *file, int from_tty,
225 struct cmd_list_element *c, const char *value)
e33d66ec 226{
6c7a06a3
TT
227 fprintf_filtered (file, _("The target wide character set is \"%s\".\n"),
228 value);
229}
e33d66ec 230
6c7a06a3 231static const char *default_charset_names[] =
e33d66ec 232{
6c7a06a3 233 DEFAULT_CHARSET_NAMES
e33d66ec
EZ
234 0
235};
234b45d4 236
6c7a06a3 237static const char **charset_enum;
234b45d4 238
6c7a06a3
TT
239\f
240/* If the target wide character set has big- or little-endian
241 variants, these are the corresponding names. */
242static const char *target_wide_charset_be_name;
243static const char *target_wide_charset_le_name;
234b45d4 244
6c7a06a3
TT
245/* A helper function for validate which sets the target wide big- and
246 little-endian character set names, if possible. */
234b45d4 247
6c7a06a3
TT
248static void
249set_be_le_names (void)
234b45d4 250{
6c7a06a3 251 int i, len;
234b45d4 252
6c7a06a3
TT
253 target_wide_charset_le_name = NULL;
254 target_wide_charset_be_name = NULL;
234b45d4 255
6c7a06a3
TT
256 len = strlen (target_wide_charset_name);
257 for (i = 0; charset_enum[i]; ++i)
258 {
259 if (strncmp (target_wide_charset_name, charset_enum[i], len))
260 continue;
261 if ((charset_enum[i][len] == 'B'
262 || charset_enum[i][len] == 'L')
263 && charset_enum[i][len + 1] == 'E'
264 && charset_enum[i][len + 2] == '\0')
265 {
266 if (charset_enum[i][len] == 'B')
267 target_wide_charset_be_name = charset_enum[i];
268 else
269 target_wide_charset_le_name = charset_enum[i];
270 }
271 }
234b45d4
KB
272}
273
6c7a06a3
TT
274/* 'Set charset', 'set host-charset', 'set target-charset', 'set
275 target-wide-charset', 'set charset' sfunc's. */
234b45d4
KB
276
277static void
6c7a06a3 278validate (void)
234b45d4 279{
6c7a06a3
TT
280 iconv_t desc;
281 const char *host_cset = host_charset ();
234b45d4 282
6c7a06a3
TT
283 desc = iconv_open (target_wide_charset_name, host_cset);
284 if (desc == (iconv_t) -1)
285 error ("Cannot convert between character sets `%s' and `%s'",
286 target_wide_charset_name, host_cset);
287 iconv_close (desc);
234b45d4 288
6c7a06a3
TT
289 desc = iconv_open (target_charset_name, host_cset);
290 if (desc == (iconv_t) -1)
291 error ("Cannot convert between character sets `%s' and `%s'",
292 target_charset_name, host_cset);
293 iconv_close (desc);
234b45d4 294
6c7a06a3 295 set_be_le_names ();
234b45d4
KB
296}
297
6c7a06a3
TT
298/* This is the sfunc for the 'set charset' command. */
299static void
300set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c)
234b45d4 301{
6c7a06a3
TT
302 /* CAREFUL: set the target charset here as well. */
303 target_charset_name = host_charset_name;
304 validate ();
234b45d4
KB
305}
306
6c7a06a3
TT
307/* 'set host-charset' command sfunc. We need a wrapper here because
308 the function needs to have a specific signature. */
309static void
310set_host_charset_sfunc (char *charset, int from_tty,
311 struct cmd_list_element *c)
234b45d4 312{
6c7a06a3 313 validate ();
234b45d4
KB
314}
315
6c7a06a3
TT
316/* Wrapper for the 'set target-charset' command. */
317static void
318set_target_charset_sfunc (char *charset, int from_tty,
319 struct cmd_list_element *c)
234b45d4 320{
6c7a06a3 321 validate ();
234b45d4
KB
322}
323
6c7a06a3
TT
324/* Wrapper for the 'set target-wide-charset' command. */
325static void
326set_target_wide_charset_sfunc (char *charset, int from_tty,
327 struct cmd_list_element *c)
234b45d4 328{
6c7a06a3 329 validate ();
234b45d4
KB
330}
331
6c7a06a3
TT
332/* sfunc for the 'show charset' command. */
333static void
334show_charset (struct ui_file *file, int from_tty, struct cmd_list_element *c,
335 const char *name)
234b45d4 336{
6c7a06a3
TT
337 show_host_charset_name (file, from_tty, c, host_charset_name);
338 show_target_charset_name (file, from_tty, c, target_charset_name);
339 show_target_wide_charset_name (file, from_tty, c, target_wide_charset_name);
234b45d4
KB
340}
341
234b45d4 342\f
6c7a06a3 343/* Accessor functions. */
234b45d4 344
6c7a06a3
TT
345const char *
346host_charset (void)
234b45d4 347{
6c7a06a3
TT
348 if (!strcmp (host_charset_name, "auto"))
349 return auto_host_charset_name;
350 return host_charset_name;
234b45d4
KB
351}
352
6c7a06a3
TT
353const char *
354target_charset (void)
234b45d4 355{
6c7a06a3 356 return target_charset_name;
234b45d4 357}
234b45d4 358
6c7a06a3
TT
359const char *
360target_wide_charset (void)
234b45d4 361{
6c7a06a3 362 if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
234b45d4 363 {
6c7a06a3
TT
364 if (target_wide_charset_be_name)
365 return target_wide_charset_be_name;
234b45d4 366 }
6c7a06a3 367 else
234b45d4 368 {
6c7a06a3
TT
369 if (target_wide_charset_le_name)
370 return target_wide_charset_le_name;
234b45d4
KB
371 }
372
6c7a06a3 373 return target_wide_charset_name;
234b45d4
KB
374}
375
234b45d4 376\f
6c7a06a3
TT
377/* Host character set management. For the time being, we assume that
378 the host character set is some superset of ASCII. */
234b45d4 379
6c7a06a3
TT
380char
381host_letter_to_control_character (char c)
234b45d4 382{
6c7a06a3
TT
383 if (c == '?')
384 return 0177;
385 return c & 0237;
234b45d4
KB
386}
387
6c7a06a3
TT
388/* Convert a host character, C, to its hex value. C must already have
389 been validated using isxdigit. */
234b45d4 390
6c7a06a3
TT
391int
392host_hex_value (char c)
234b45d4 393{
6c7a06a3
TT
394 if (isdigit (c))
395 return c - '0';
396 if (c >= 'a' && c <= 'f')
397 return 10 + c - 'a';
398 gdb_assert (c >= 'A' && c <= 'F');
399 return 10 + c - 'A';
234b45d4
KB
400}
401
234b45d4 402\f
6c7a06a3 403/* Public character management functions. */
234b45d4 404
6c7a06a3 405/* A cleanup function which is run to close an iconv descriptor. */
234b45d4 406
6c7a06a3
TT
407static void
408cleanup_iconv (void *p)
234b45d4 409{
6c7a06a3
TT
410 iconv_t *descp = p;
411 iconv_close (*descp);
234b45d4
KB
412}
413
6c7a06a3
TT
414void
415convert_between_encodings (const char *from, const char *to,
416 const gdb_byte *bytes, unsigned int num_bytes,
417 int width, struct obstack *output,
418 enum transliterations translit)
419{
420 iconv_t desc;
421 struct cleanup *cleanups;
422 size_t inleft;
423 char *inp;
424 unsigned int space_request;
425
426 /* Often, the host and target charsets will be the same. */
427 if (!strcmp (from, to))
428 {
429 obstack_grow (output, bytes, num_bytes);
430 return;
431 }
234b45d4 432
6c7a06a3
TT
433 desc = iconv_open (to, from);
434 if (desc == (iconv_t) -1)
435 perror_with_name ("Converting character sets");
436 cleanups = make_cleanup (cleanup_iconv, &desc);
234b45d4 437
6c7a06a3
TT
438 inleft = num_bytes;
439 inp = (char *) bytes;
234b45d4 440
6c7a06a3 441 space_request = num_bytes;
234b45d4 442
6c7a06a3 443 while (inleft > 0)
234b45d4 444 {
6c7a06a3
TT
445 char *outp;
446 size_t outleft, r;
447 int old_size;
448
449 old_size = obstack_object_size (output);
450 obstack_blank (output, space_request);
451
452 outp = obstack_base (output) + old_size;
453 outleft = space_request;
454
0dd7fb99 455 r = iconv (desc, (ICONV_CONST char **) &inp, &inleft, &outp, &outleft);
6c7a06a3
TT
456
457 /* Now make sure that the object on the obstack only includes
458 bytes we have converted. */
459 obstack_blank (output, - (int) outleft);
460
461 if (r == (size_t) -1)
462 {
463 switch (errno)
464 {
465 case EILSEQ:
466 {
467 int i;
468
469 /* Invalid input sequence. */
470 if (translit == translit_none)
471 error (_("Could not convert character to `%s' character set"),
472 to);
473
474 /* We emit escape sequence for the bytes, skip them,
475 and try again. */
476 for (i = 0; i < width; ++i)
477 {
478 char octal[5];
479
480 sprintf (octal, "\\%.3o", *inp & 0xff);
481 obstack_grow_str (output, octal);
482
483 ++inp;
484 --inleft;
485 }
486 }
487 break;
488
489 case E2BIG:
490 /* We ran out of space in the output buffer. Make it
491 bigger next time around. */
492 space_request *= 2;
493 break;
494
495 case EINVAL:
496 /* Incomplete input sequence. FIXME: ought to report this
497 to the caller somehow. */
498 inleft = 0;
499 break;
500
501 default:
502 perror_with_name ("Internal error while converting character sets");
503 }
504 }
234b45d4 505 }
234b45d4 506
6c7a06a3 507 do_cleanups (cleanups);
234b45d4
KB
508}
509
e33d66ec 510\f
e33d66ec 511
6c7a06a3
TT
512/* An iterator that returns host wchar_t's from a target string. */
513struct wchar_iterator
e33d66ec 514{
6c7a06a3
TT
515 /* The underlying iconv descriptor. */
516 iconv_t desc;
e33d66ec 517
6c7a06a3
TT
518 /* The input string. This is updated as convert characters. */
519 char *input;
520 /* The number of bytes remaining in the input. */
521 size_t bytes;
e33d66ec 522
6c7a06a3
TT
523 /* The width of an input character. */
524 size_t width;
e33d66ec 525
6c7a06a3
TT
526 /* The output buffer and its size. */
527 gdb_wchar_t *out;
528 size_t out_size;
529};
234b45d4 530
6c7a06a3
TT
531/* Create a new iterator. */
532struct wchar_iterator *
533make_wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset,
534 size_t width)
234b45d4 535{
6c7a06a3
TT
536 struct wchar_iterator *result;
537 iconv_t desc;
234b45d4 538
6c7a06a3
TT
539 desc = iconv_open ("wchar_t", charset);
540 if (desc == (iconv_t) -1)
541 perror_with_name ("Converting character sets");
234b45d4 542
6c7a06a3
TT
543 result = XNEW (struct wchar_iterator);
544 result->desc = desc;
545 result->input = (char *) input;
546 result->bytes = bytes;
547 result->width = width;
234b45d4 548
6c7a06a3
TT
549 result->out = XNEW (gdb_wchar_t);
550 result->out_size = 1;
234b45d4 551
6c7a06a3 552 return result;
e33d66ec 553}
234b45d4 554
e33d66ec 555static void
6c7a06a3 556do_cleanup_iterator (void *p)
e33d66ec 557{
6c7a06a3 558 struct wchar_iterator *iter = p;
234b45d4 559
6c7a06a3
TT
560 iconv_close (iter->desc);
561 xfree (iter->out);
562 xfree (iter);
234b45d4
KB
563}
564
6c7a06a3
TT
565struct cleanup *
566make_cleanup_wchar_iterator (struct wchar_iterator *iter)
e33d66ec 567{
6c7a06a3 568 return make_cleanup (do_cleanup_iterator, iter);
e33d66ec 569}
234b45d4 570
6c7a06a3
TT
571int
572wchar_iterate (struct wchar_iterator *iter,
573 enum wchar_iterate_result *out_result,
574 gdb_wchar_t **out_chars,
575 const gdb_byte **ptr,
576 size_t *len)
577{
578 size_t out_request;
579
580 /* Try to convert some characters. At first we try to convert just
581 a single character. The reason for this is that iconv does not
582 necessarily update its outgoing arguments when it encounters an
583 invalid input sequence -- but we want to reliably report this to
584 our caller so it can emit an escape sequence. */
585 out_request = 1;
586 while (iter->bytes > 0)
e33d66ec 587 {
6c7a06a3
TT
588 char *outptr = (char *) &iter->out[0];
589 char *orig_inptr = iter->input;
590 size_t orig_in = iter->bytes;
591 size_t out_avail = out_request * sizeof (gdb_wchar_t);
592 size_t num;
593 gdb_wchar_t result;
594
0dd7fb99
TT
595 size_t r = iconv (iter->desc,
596 (ICONV_CONST char **) &iter->input, &iter->bytes,
6c7a06a3
TT
597 &outptr, &out_avail);
598 if (r == (size_t) -1)
599 {
600 switch (errno)
601 {
602 case EILSEQ:
603 /* Invalid input sequence. Skip it, and let the caller
604 know about it. */
605 *out_result = wchar_iterate_invalid;
606 *ptr = iter->input;
607 *len = iter->width;
608 iter->input += iter->width;
609 iter->bytes -= iter->width;
610 return 0;
611
612 case E2BIG:
613 /* We ran out of space. We still might have converted a
614 character; if so, return it. Otherwise, grow the
615 buffer and try again. */
616 if (out_avail < out_request * sizeof (gdb_wchar_t))
617 break;
618
619 ++out_request;
620 if (out_request > iter->out_size)
621 {
622 iter->out_size = out_request;
623 iter->out = xrealloc (iter->out,
624 out_request * sizeof (gdb_wchar_t));
625 }
626 continue;
627
628 case EINVAL:
629 /* Incomplete input sequence. Let the caller know, and
630 arrange for future calls to see EOF. */
631 *out_result = wchar_iterate_incomplete;
632 *ptr = iter->input;
633 *len = iter->bytes;
634 iter->bytes = 0;
635 return 0;
636
637 default:
638 perror_with_name ("Internal error while converting character sets");
639 }
640 }
641
642 /* We converted something. */
643 num = out_request - out_avail / sizeof (gdb_wchar_t);
644 *out_result = wchar_iterate_ok;
645 *out_chars = iter->out;
646 *ptr = orig_inptr;
647 *len = orig_in - iter->bytes;
648 return num;
e33d66ec 649 }
6c7a06a3
TT
650
651 /* Really done. */
652 *out_result = wchar_iterate_eof;
653 return -1;
234b45d4
KB
654}
655
e33d66ec 656\f
6c7a06a3 657/* The charset.c module initialization function. */
234b45d4 658
6c7a06a3 659extern initialize_file_ftype _initialize_charset; /* -Wmissing-prototype */
234b45d4 660
6c7a06a3
TT
661typedef char *char_ptr;
662DEF_VEC_P (char_ptr);
234b45d4 663
6c7a06a3 664static VEC (char_ptr) *charsets;
234b45d4 665
6c7a06a3 666#ifdef PHONY_ICONV
234b45d4 667
6c7a06a3
TT
668static void
669find_charset_names (void)
234b45d4 670{
6c7a06a3
TT
671 VEC_safe_push (char_ptr, charsets, GDB_DEFAULT_HOST_CHARSET);
672 VEC_safe_push (char_ptr, charsets, NULL);
234b45d4
KB
673}
674
6c7a06a3 675#else /* PHONY_ICONV */
fc3b640d
TT
676
677/* Sometimes, libiconv redefines iconvlist as libiconvlist -- but
678 provides different symbols in the static and dynamic libraries.
679 So, configure may see libiconvlist but not iconvlist. But, calling
680 iconvlist is the right thing to do and will work. Hence we do a
681 check here but unconditionally call iconvlist below. */
682#if defined (HAVE_ICONVLIST) || defined (HAVE_LIBICONVLIST)
234b45d4 683
6c7a06a3
TT
684/* A helper function that adds some character sets to the vector of
685 all character sets. This is a callback function for iconvlist. */
686
687static int
688add_one (unsigned int count, const char *const *names, void *data)
234b45d4 689{
6c7a06a3 690 unsigned int i;
234b45d4 691
6c7a06a3
TT
692 for (i = 0; i < count; ++i)
693 VEC_safe_push (char_ptr, charsets, xstrdup (names[i]));
234b45d4 694
6c7a06a3 695 return 0;
234b45d4
KB
696}
697
6c7a06a3
TT
698static void
699find_charset_names (void)
234b45d4 700{
6c7a06a3
TT
701 iconvlist (add_one, NULL);
702 VEC_safe_push (char_ptr, charsets, NULL);
234b45d4
KB
703}
704
6c7a06a3 705#else
234b45d4 706
6c7a06a3
TT
707static void
708find_charset_names (void)
234b45d4 709{
6c7a06a3 710 FILE *in;
234b45d4 711
6c7a06a3
TT
712 in = popen ("iconv -l", "r");
713 /* It is ok to ignore errors; we'll fall back on a default. */
714 if (!in)
715 return;
234b45d4 716
6c7a06a3
TT
717 /* POSIX says that iconv -l uses an unspecified format. We parse
718 the glibc format; feel free to add others as needed. */
719 while (!feof (in))
720 {
721 /* The size of buf is chosen arbitrarily. A character set name
722 longer than this would not be very nice. */
723 char buf[80];
724 int len;
725 char *r = fgets (buf, sizeof (buf), in);
726 if (!r)
727 break;
728 len = strlen (r);
729 if (len <= 3)
730 continue;
731 if (buf[len - 2] == '/' && buf[len - 3] == '/')
732 buf[len - 3] = '\0';
733 VEC_safe_push (char_ptr, charsets, xstrdup (buf));
734 }
234b45d4 735
6c7a06a3 736 pclose (in);
234b45d4 737
6c7a06a3
TT
738 VEC_safe_push (char_ptr, charsets, NULL);
739}
234b45d4 740
fc3b640d 741#endif /* HAVE_ICONVLIST || HAVE_LIBICONVLIST */
6c7a06a3 742#endif /* PHONY_ICONV */
234b45d4
KB
743
744void
745_initialize_charset (void)
746{
e33d66ec
EZ
747 struct cmd_list_element *new_cmd;
748
6c7a06a3
TT
749 /* The first element is always "auto"; then we skip it for the
750 commands where it is not allowed. */
751 VEC_safe_push (char_ptr, charsets, "auto");
752 find_charset_names ();
753
754 if (VEC_length (char_ptr, charsets) > 1)
755 charset_enum = (const char **) VEC_address (char_ptr, charsets);
756 else
757 charset_enum = default_charset_names;
758
759#ifndef PHONY_ICONV
760#ifdef HAVE_LANGINFO_CODESET
761 auto_host_charset_name = nl_langinfo (CODESET);
762 target_charset_name = auto_host_charset_name;
763
764 set_be_le_names ();
765#endif
766#endif
e33d66ec 767
7ab04401 768 add_setshow_enum_cmd ("charset", class_support,
6c7a06a3 769 &charset_enum[1], &host_charset_name, _("\
7ab04401
AC
770Set the host and target character sets."), _("\
771Show the host and target character sets."), _("\
3d263c1d
BI
772The `host character set' is the one used by the system GDB is running on.\n\
773The `target character set' is the one used by the program being debugged.\n\
774You may only use supersets of ASCII for your host character set; GDB does\n\
775not support any others.\n\
776To see a list of the character sets GDB supports, type `set charset <TAB>'."),
7ab04401
AC
777 /* Note that the sfunc below needs to set
778 target_charset_name, because the 'set
779 charset' command sets two variables. */
780 set_charset_sfunc,
781 show_charset,
782 &setlist, &showlist);
783
784 add_setshow_enum_cmd ("host-charset", class_support,
6c7a06a3 785 charset_enum, &host_charset_name, _("\
7ab04401
AC
786Set the host character set."), _("\
787Show the host character set."), _("\
3d263c1d
BI
788The `host character set' is the one used by the system GDB is running on.\n\
789You may only use supersets of ASCII for your host character set; GDB does\n\
790not support any others.\n\
791To see a list of the character sets GDB supports, type `set host-charset <TAB>'."),
7ab04401 792 set_host_charset_sfunc,
920d2a44 793 show_host_charset_name,
7ab04401
AC
794 &setlist, &showlist);
795
796 add_setshow_enum_cmd ("target-charset", class_support,
6c7a06a3 797 &charset_enum[1], &target_charset_name, _("\
7ab04401
AC
798Set the target character set."), _("\
799Show the target character set."), _("\
3d263c1d
BI
800The `target character set' is the one used by the program being debugged.\n\
801GDB translates characters and strings between the host and target\n\
802character sets as needed.\n\
803To see a list of the character sets GDB supports, type `set target-charset'<TAB>"),
7ab04401 804 set_target_charset_sfunc,
920d2a44 805 show_target_charset_name,
7ab04401 806 &setlist, &showlist);
6c7a06a3
TT
807
808 add_setshow_enum_cmd ("target-wide-charset", class_support,
809 &charset_enum[1], &target_wide_charset_name,
810 _("\
811Set the target wide character set."), _("\
812Show the target wide character set."), _("\
813The `target wide character set' is the one used by the program being debugged.\n\
814In particular it is the encoding used by `wchar_t'.\n\
815GDB translates characters and strings between the host and target\n\
816character sets as needed.\n\
817To see a list of the character sets GDB supports, type\n\
818`set target-wide-charset'<TAB>"),
819 set_target_wide_charset_sfunc,
820 show_target_wide_charset_name,
821 &setlist, &showlist);
234b45d4 822}
This page took 0.691462 seconds and 4 git commands to generate.