1 /* Various declarations for language-independent pretty-print subroutines.
2 Copyright (C) 2003-2013 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
25 #include "pretty-print.h"
26 #include "diagnostic-color.h"
28 #include <new> // For placement-new.
34 // Default construct an output buffer.
36 output_buffer::output_buffer ()
37 : formatted_obstack (),
39 obstack (&formatted_obstack),
45 obstack_init (&formatted_obstack);
46 obstack_init (&chunk_obstack);
49 /* A pointer to the formatted diagnostic message. */
50 #define pp_formatted_text_data(PP) \
51 ((const char *) obstack_base ((PP)->buffer->obstack))
53 /* Format an integer given by va_arg (ARG, type-specifier T) where
54 type-specifier is a precision modifier as indicated by PREC. F is
55 a string used to construct the appropriate format-specifier. */
56 #define pp_integer_with_precision(PP, ARG, PREC, T, F) \
61 pp_scalar (PP, "%" F, va_arg (ARG, T)); \
65 pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \
69 pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T)); \
78 /* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's
79 internal maximum characters per line. */
81 pp_set_real_maximum_length (pretty_printer *pp)
83 /* If we're told not to wrap lines then do the obvious thing. In case
84 we'll emit prefix only once per message, it is appropriate
85 not to increase unnecessarily the line-length cut-off. */
86 if (!pp_is_wrapping_line (pp)
87 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE
88 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
89 pp->maximum_length = pp_line_cutoff (pp);
92 int prefix_length = pp->prefix ? strlen (pp->prefix) : 0;
93 /* If the prefix is ridiculously too long, output at least
95 if (pp_line_cutoff (pp) - prefix_length < 32)
96 pp->maximum_length = pp_line_cutoff (pp) + 32;
98 pp->maximum_length = pp_line_cutoff (pp);
102 /* Clear PRETTY-PRINTER's output state. */
104 pp_clear_state (pretty_printer *pp)
106 pp->emitted_prefix = false;
107 pp_indentation (pp) = 0;
110 /* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */
112 pp_write_text_to_stream (pretty_printer *pp)
114 const char *text = pp_formatted_text (pp);
115 fputs (text, pp->buffer->stream);
116 pp_clear_output_area (pp);
119 /* As pp_write_text_to_stream, but for GraphViz label output.
121 Flush the formatted text of pretty-printer PP onto the attached stream.
122 Replace characters in PPF that have special meaning in a GraphViz .dot
125 This routine is not very fast, but it doesn't have to be as this is only
126 be used by routines dumping intermediate representations in graph form. */
129 pp_write_text_as_dot_label_to_stream (pretty_printer *pp, bool for_record)
131 const char *text = pp_formatted_text (pp);
132 const char *p = text;
133 FILE *fp = pp->buffer->stream;
139 /* Print newlines as a left-aligned newline. */
141 fputs ("\\l\\\n", fp);
144 /* A pipe is only special for record-shape nodes. */
151 /* The following characters always have to be escaped
152 for use in labels. */
168 pp_clear_output_area (pp);
171 /* Wrap a text delimited by START and END into PRETTY-PRINTER. */
173 pp_wrap_text (pretty_printer *pp, const char *start, const char *end)
175 bool wrapping_line = pp_is_wrapping_line (pp);
179 /* Dump anything bordered by whitespaces. */
181 const char *p = start;
182 while (p != end && !ISBLANK (*p) && *p != '\n')
185 && p - start >= pp_remaining_character_count_for_line (pp))
187 pp_append_text (pp, start, p);
191 if (start != end && ISBLANK (*start))
196 if (start != end && *start == '\n')
204 /* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */
206 pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end)
208 if (pp_is_wrapping_line (pp))
209 pp_wrap_text (pp, start, end);
211 pp_append_text (pp, start, end);
214 /* Append to the output area of PRETTY-PRINTER a string specified by its
215 STARTing character and LENGTH. */
217 pp_append_r (pretty_printer *pp, const char *start, int length)
219 obstack_grow (pp->buffer->obstack, start, length);
220 pp->buffer->line_length += length;
223 /* Insert enough spaces into the output area of PRETTY-PRINTER to bring
224 the column position to the current indentation level, assuming that a
225 newline has just been written to the buffer. */
227 pp_indent (pretty_printer *pp)
229 int n = pp_indentation (pp);
232 for (i = 0; i < n; ++i)
236 /* The following format specifiers are recognized as being client independent:
237 %d, %i: (signed) integer in base ten.
238 %u: unsigned integer in base ten.
239 %o: unsigned integer in base eight.
240 %x: unsigned integer in base sixteen.
241 %ld, %li, %lo, %lu, %lx: long versions of the above.
242 %lld, %lli, %llo, %llu, %llx: long long versions.
243 %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
247 %r: if pp_show_color(pp), switch to color identified by const char *.
248 %R: if pp_show_color(pp), reset color.
249 %m: strerror(text->err_no) - does not consume a value from args_ptr.
253 %': apostrophe (should only be used in untranslated messages;
254 translations should use appropriate punctuation directly).
255 %.*s: a substring the length of which is specified by an argument
257 %Ns: likewise, but length specified as constant in the format string.
258 Flag 'q': quote formatted text (must come immediately after '%').
260 Arguments can be used sequentially, or through %N$ resp. *N$
261 notation Nth argument after the format string. If %N$ / *N$
262 notation is used, it must be used for all arguments, except %m, %%,
263 %<, %> and %', which may not have a number, as they do not consume
264 an argument. When %M$.*N$s is used, M must be N + 1. (This may
265 also be written %M$.*s, provided N is not otherwise used.) The
266 format string must have conversion specifiers with argument numbers
267 1 up to highest argument; each argument may only be used once.
268 A format string can have at most 30 arguments. */
270 /* Formatting phases 1 and 2: render TEXT->format_spec plus
271 TEXT->args_ptr into a series of chunks in PP->buffer->args[].
272 Phase 3 is in pp_format_text. */
275 pp_format (pretty_printer *pp, text_info *text)
277 output_buffer *buffer = pp->buffer;
280 struct chunk_info *new_chunk_array;
282 unsigned int curarg = 0, chunk = 0, argno;
283 pp_wrapping_mode_t old_wrapping_mode;
284 bool any_unnumbered = false, any_numbered = false;
285 const char **formatters[PP_NL_ARGMAX];
287 /* Allocate a new chunk structure. */
288 new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info);
289 new_chunk_array->prev = buffer->cur_chunk_array;
290 buffer->cur_chunk_array = new_chunk_array;
291 args = new_chunk_array->args;
293 /* Formatting phase 1: split up TEXT->format_spec into chunks in
294 PP->buffer->args[]. Even-numbered chunks are to be output
295 verbatim, odd-numbered chunks are format specifiers.
296 %m, %%, %<, %>, and %' are replaced with the appropriate text at
299 memset (formatters, 0, sizeof formatters);
301 for (p = text->format_spec; *p; )
303 while (*p != '\0' && *p != '%')
305 obstack_1grow (&buffer->chunk_obstack, *p);
318 obstack_1grow (&buffer->chunk_obstack, '%');
324 obstack_grow (&buffer->chunk_obstack,
325 open_quote, strlen (open_quote));
327 = colorize_start (pp_show_color (pp), "quote");
328 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
335 const char *colorstr = colorize_stop (pp_show_color (pp));
336 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
340 obstack_grow (&buffer->chunk_obstack,
341 close_quote, strlen (close_quote));
347 const char *colorstr = colorize_stop (pp_show_color (pp));
348 obstack_grow (&buffer->chunk_obstack, colorstr,
356 const char *errstr = xstrerror (text->err_no);
357 obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr));
363 /* Handled in phase 2. Terminate the plain chunk here. */
364 obstack_1grow (&buffer->chunk_obstack, '\0');
365 gcc_assert (chunk < PP_NL_ARGMAX * 2);
366 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
373 argno = strtoul (p, &end, 10) - 1;
375 gcc_assert (*p == '$');
379 gcc_assert (!any_unnumbered);
384 any_unnumbered = true;
385 gcc_assert (!any_numbered);
387 gcc_assert (argno < PP_NL_ARGMAX);
388 gcc_assert (!formatters[argno]);
389 formatters[argno] = &args[chunk];
392 obstack_1grow (&buffer->chunk_obstack, *p);
395 while (strchr ("qwl+#", p[-1]));
399 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
400 (where M == N + 1). */
405 obstack_1grow (&buffer->chunk_obstack, *p);
408 while (ISDIGIT (p[-1]));
409 gcc_assert (p[-1] == 's');
413 gcc_assert (*p == '*');
414 obstack_1grow (&buffer->chunk_obstack, '*');
420 unsigned int argno2 = strtoul (p, &end, 10) - 1;
422 gcc_assert (argno2 == argno - 1);
423 gcc_assert (!any_unnumbered);
424 gcc_assert (*p == '$');
427 formatters[argno2] = formatters[argno];
431 gcc_assert (!any_numbered);
432 formatters[argno+1] = formatters[argno];
435 gcc_assert (*p == 's');
436 obstack_1grow (&buffer->chunk_obstack, 's');
443 obstack_1grow (&buffer->chunk_obstack, '\0');
444 gcc_assert (chunk < PP_NL_ARGMAX * 2);
445 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
448 obstack_1grow (&buffer->chunk_obstack, '\0');
449 gcc_assert (chunk < PP_NL_ARGMAX * 2);
450 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
453 /* Set output to the argument obstack, and switch line-wrapping and
455 buffer->obstack = &buffer->chunk_obstack;
456 old_wrapping_mode = pp_set_verbatim_wrapping (pp);
458 /* Second phase. Replace each formatter with the formatted text it
461 for (argno = 0; formatters[argno]; argno++)
469 /* We do not attempt to enforce any ordering on the modifier
472 for (p = *formatters[argno];; p++)
497 /* We don't support precision beyond that of "long long". */
498 gcc_assert (precision < 2);
505 gcc_assert (!wide || precision == 0);
509 pp_string (pp, open_quote);
510 pp_string (pp, colorize_start (pp_show_color (pp), "quote"));
516 pp_string (pp, colorize_start (pp_show_color (pp),
517 va_arg (*text->args_ptr,
522 pp_character (pp, va_arg (*text->args_ptr, int));
528 pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
530 pp_integer_with_precision
531 (pp, *text->args_ptr, precision, int, "d");
536 pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
537 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
539 pp_integer_with_precision
540 (pp, *text->args_ptr, precision, unsigned, "o");
544 pp_string (pp, va_arg (*text->args_ptr, const char *));
548 pp_pointer (pp, va_arg (*text->args_ptr, void *));
553 pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
554 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
556 pp_integer_with_precision
557 (pp, *text->args_ptr, precision, unsigned, "u");
562 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
563 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
565 pp_integer_with_precision
566 (pp, *text->args_ptr, precision, unsigned, "x");
574 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
575 (where M == N + 1). The format string should be verified
576 already from the first phase. */
581 n = strtoul (p, &end, 10);
583 gcc_assert (*p == 's');
587 gcc_assert (*p == '*');
589 gcc_assert (*p == 's');
590 n = va_arg (*text->args_ptr, int);
592 /* This consumes a second entry in the formatters array. */
593 gcc_assert (formatters[argno] == formatters[argno+1]);
597 s = va_arg (*text->args_ptr, const char *);
598 pp_append_text (pp, s, s + n);
606 gcc_assert (pp_format_decoder (pp));
607 ok = pp_format_decoder (pp) (pp, text, p,
608 precision, wide, plus, hash);
615 pp_string (pp, colorize_stop (pp_show_color (pp)));
616 pp_string (pp, close_quote);
619 obstack_1grow (&buffer->chunk_obstack, '\0');
620 *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
623 #ifdef ENABLE_CHECKING
624 for (; argno < PP_NL_ARGMAX; argno++)
625 gcc_assert (!formatters[argno]);
628 /* Revert to normal obstack and wrapping mode. */
629 buffer->obstack = &buffer->formatted_obstack;
630 buffer->line_length = 0;
631 pp_wrapping_mode (pp) = old_wrapping_mode;
635 /* Format of a message pointed to by TEXT. */
637 pp_output_formatted_text (pretty_printer *pp)
640 output_buffer *buffer = pp_buffer (pp);
641 struct chunk_info *chunk_array = buffer->cur_chunk_array;
642 const char **args = chunk_array->args;
644 gcc_assert (buffer->obstack == &buffer->formatted_obstack);
645 gcc_assert (buffer->line_length == 0);
647 /* This is a third phase, first 2 phases done in pp_format_args.
648 Now we actually print it. */
649 for (chunk = 0; args[chunk]; chunk++)
650 pp_string (pp, args[chunk]);
652 /* Deallocate the chunk structure and everything after it (i.e. the
653 associated series of formatted strings). */
654 buffer->cur_chunk_array = chunk_array->prev;
655 obstack_free (&buffer->chunk_obstack, chunk_array);
658 /* Helper subroutine of output_verbatim and verbatim. Do the appropriate
659 settings needed by BUFFER for a verbatim formatting. */
661 pp_format_verbatim (pretty_printer *pp, text_info *text)
663 /* Set verbatim mode. */
664 pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp);
666 /* Do the actual formatting. */
667 pp_format (pp, text);
668 pp_output_formatted_text (pp);
670 /* Restore previous settings. */
671 pp_wrapping_mode (pp) = oldmode;
674 /* Flush the content of BUFFER onto the attached stream. */
676 pp_flush (pretty_printer *pp)
678 pp_write_text_to_stream (pp);
680 fflush (pp->buffer->stream);
683 /* Sets the number of maximum characters per line PRETTY-PRINTER can
684 output in line-wrapping mode. A LENGTH value 0 suppresses
687 pp_set_line_maximum_length (pretty_printer *pp, int length)
689 pp_line_cutoff (pp) = length;
690 pp_set_real_maximum_length (pp);
693 /* Clear PRETTY-PRINTER output area text info. */
695 pp_clear_output_area (pretty_printer *pp)
697 obstack_free (pp->buffer->obstack, obstack_base (pp->buffer->obstack));
698 pp->buffer->line_length = 0;
701 /* Set PREFIX for PRETTY-PRINTER. */
703 pp_set_prefix (pretty_printer *pp, const char *prefix)
706 pp_set_real_maximum_length (pp);
707 pp->emitted_prefix = false;
708 pp_indentation (pp) = 0;
711 /* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */
713 pp_destroy_prefix (pretty_printer *pp)
715 if (pp->prefix != NULL)
717 free (CONST_CAST (char *, pp->prefix));
722 /* Write out PRETTY-PRINTER's prefix. */
724 pp_emit_prefix (pretty_printer *pp)
726 if (pp->prefix != NULL)
728 switch (pp_prefixing_rule (pp))
731 case DIAGNOSTICS_SHOW_PREFIX_NEVER:
734 case DIAGNOSTICS_SHOW_PREFIX_ONCE:
735 if (pp->emitted_prefix)
740 pp_indentation (pp) += 3;
743 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
745 int prefix_length = strlen (pp->prefix);
746 pp_append_r (pp, pp->prefix, prefix_length);
747 pp->emitted_prefix = true;
754 /* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH
755 characters per line. */
757 pretty_printer::pretty_printer (const char *p, int l)
758 : buffer (new (XCNEW (output_buffer)) output_buffer ()),
767 translate_identifiers(true),
770 pp_line_cutoff (this) = l;
771 /* By default, we emit prefixes once per message. */
772 pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
773 pp_set_prefix (this, p);
776 /* Append a string delimited by START and END to the output area of
777 PRETTY-PRINTER. No line wrapping is done. However, if beginning a
778 new line then emit PRETTY-PRINTER's prefix and skip any leading
779 whitespace if appropriate. The caller must ensure that it is
782 pp_append_text (pretty_printer *pp, const char *start, const char *end)
784 /* Emit prefix and skip whitespace if we're starting a new line. */
785 if (pp->buffer->line_length == 0)
788 if (pp_is_wrapping_line (pp))
789 while (start != end && *start == ' ')
792 pp_append_r (pp, start, end - start);
795 /* Finishes constructing a NULL-terminated character string representing
796 the PRETTY-PRINTED text. */
798 pp_formatted_text (pretty_printer *pp)
800 obstack_1grow (pp->buffer->obstack, '\0');
801 return pp_formatted_text_data (pp);
804 /* Return a pointer to the last character emitted in PRETTY-PRINTER's
805 output area. A NULL pointer means no character available. */
807 pp_last_position_in_text (const pretty_printer *pp)
809 const char *p = NULL;
810 struct obstack *text = pp->buffer->obstack;
812 if (obstack_base (text) != obstack_next_free (text))
813 p = ((const char *) obstack_next_free (text)) - 1;
817 /* Return the amount of characters PRETTY-PRINTER can accept to
818 make a full line. Meaningful only in line-wrapping mode. */
820 pp_remaining_character_count_for_line (pretty_printer *pp)
822 return pp->maximum_length - pp->buffer->line_length;
826 /* Format a message into BUFFER a la printf. */
828 pp_printf (pretty_printer *pp, const char *msg, ...)
836 text.format_spec = msg;
838 pp_format (pp, &text);
839 pp_output_formatted_text (pp);
844 /* Output MESSAGE verbatim into BUFFER. */
846 pp_verbatim (pretty_printer *pp, const char *msg, ...)
854 text.format_spec = msg;
856 pp_format_verbatim (pp, &text);
862 /* Have PRETTY-PRINTER start a new line. */
864 pp_newline (pretty_printer *pp)
866 obstack_1grow (pp->buffer->obstack, '\n');
867 pp_needs_newline (pp) = false;
868 pp->buffer->line_length = 0;
871 /* Have PRETTY-PRINTER add a CHARACTER. */
873 pp_character (pretty_printer *pp, int c)
875 if (pp_is_wrapping_line (pp)
876 && pp_remaining_character_count_for_line (pp) <= 0)
882 obstack_1grow (pp->buffer->obstack, c);
883 ++pp->buffer->line_length;
886 /* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
887 be line-wrapped if in appropriate mode. */
889 pp_string (pretty_printer *pp, const char *str)
891 pp_maybe_wrap_text (pp, str, str + (str ? strlen (str) : 0));
894 /* Maybe print out a whitespace if needed. */
897 pp_maybe_space (pretty_printer *pp)
899 if (pp->padding != pp_none)
902 pp->padding = pp_none;
906 // Add a newline to the pretty printer PP and flush formatted text.
909 pp_newline_and_flush (pretty_printer *pp)
913 pp_needs_newline (pp) = false;
916 // Add a newline to the pretty printer PP, followed by indentation.
919 pp_newline_and_indent (pretty_printer *pp, int n)
921 pp_indentation (pp) += n;
924 pp_needs_newline (pp) = false;
927 // Add separator C, followed by a single whitespace.
930 pp_separate_with (pretty_printer *pp, char c)
932 pp_character (pp, c);
937 /* The string starting at P has LEN (at least 1) bytes left; if they
938 start with a valid UTF-8 sequence, return the length of that
939 sequence and set *VALUE to the value of that sequence, and
940 otherwise return 0 and set *VALUE to (unsigned int) -1. */
943 decode_utf8_char (const unsigned char *p, size_t len, unsigned int *value)
954 for (t = *p; t & 0x80; t <<= 1)
957 if (utf8_len > len || utf8_len < 2 || utf8_len > 6)
959 *value = (unsigned int) -1;
962 ch = *p & ((1 << (7 - utf8_len)) - 1);
963 for (i = 1; i < utf8_len; i++)
965 unsigned int u = p[i];
966 if ((u & 0xC0) != 0x80)
968 *value = (unsigned int) -1;
971 ch = (ch << 6) | (u & 0x3F);
973 if ( (ch <= 0x7F && utf8_len > 1)
974 || (ch <= 0x7FF && utf8_len > 2)
975 || (ch <= 0xFFFF && utf8_len > 3)
976 || (ch <= 0x1FFFFF && utf8_len > 4)
977 || (ch <= 0x3FFFFFF && utf8_len > 5)
978 || (ch >= 0xD800 && ch <= 0xDFFF))
980 *value = (unsigned int) -1;
993 /* Allocator for identifier_to_locale and corresponding function to
996 void *(*identifier_to_locale_alloc) (size_t) = xmalloc;
997 void (*identifier_to_locale_free) (void *) = free;
999 /* Given IDENT, an identifier in the internal encoding, return a
1000 version of IDENT suitable for diagnostics in the locale character
1001 set: either IDENT itself, or a string, allocated using
1002 identifier_to_locale_alloc, converted to the locale character set
1003 and using escape sequences if not representable in the locale
1004 character set or containing control characters or invalid byte
1005 sequences. Existing backslashes in IDENT are not doubled, so the
1006 result may not uniquely specify the contents of an arbitrary byte
1007 sequence identifier. */
1010 identifier_to_locale (const char *ident)
1012 const unsigned char *uid = (const unsigned char *) ident;
1013 size_t idlen = strlen (ident);
1014 bool valid_printable_utf8 = true;
1015 bool all_ascii = true;
1018 for (i = 0; i < idlen;)
1021 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
1022 if (utf8_len == 0 || c <= 0x1F || (c >= 0x7F && c <= 0x9F))
1024 valid_printable_utf8 = false;
1032 /* If IDENT contains invalid UTF-8 sequences (which may occur with
1033 attributes putting arbitrary byte sequences in identifiers), or
1034 control characters, we use octal escape sequences for all bytes
1035 outside printable ASCII. */
1036 if (!valid_printable_utf8)
1038 char *ret = (char *) identifier_to_locale_alloc (4 * idlen + 1);
1040 for (i = 0; i < idlen; i++)
1042 if (uid[i] > 0x1F && uid[i] < 0x7F)
1046 sprintf (p, "\\%03o", uid[i]);
1054 /* Otherwise, if it is valid printable ASCII, or printable UTF-8
1055 with the locale character set being UTF-8, IDENT is used. */
1056 if (all_ascii || locale_utf8)
1059 /* Otherwise IDENT is converted to the locale character set if
1061 #if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV
1062 if (locale_encoding != NULL)
1064 iconv_t cd = iconv_open (locale_encoding, "UTF-8");
1065 bool conversion_ok = true;
1067 if (cd != (iconv_t) -1)
1069 size_t ret_alloc = 4 * idlen + 1;
1072 /* Repeat the whole conversion process as needed with
1073 larger buffers so non-reversible transformations can
1074 always be detected. */
1075 ICONV_CONST char *inbuf = CONST_CAST (char *, ident);
1077 size_t inbytesleft = idlen;
1078 size_t outbytesleft = ret_alloc - 1;
1081 ret = (char *) identifier_to_locale_alloc (ret_alloc);
1084 if (iconv (cd, 0, 0, 0, 0) == (size_t) -1)
1086 conversion_ok = false;
1090 iconv_ret = iconv (cd, &inbuf, &inbytesleft,
1091 &outbuf, &outbytesleft);
1092 if (iconv_ret == (size_t) -1 || inbytesleft != 0)
1097 identifier_to_locale_free (ret);
1103 conversion_ok = false;
1107 else if (iconv_ret != 0)
1109 conversion_ok = false;
1112 /* Return to initial shift state. */
1113 if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t) -1)
1118 identifier_to_locale_free (ret);
1124 conversion_ok = false;
1138 /* Otherwise, convert non-ASCII characters in IDENT to UCNs. */
1140 char *ret = (char *) identifier_to_locale_alloc (10 * idlen + 1);
1142 for (i = 0; i < idlen;)
1145 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
1150 sprintf (p, "\\U%08x", c);