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