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 /* The string starting at P has LEN (at least 1) bytes left; if they
907 start with a valid UTF-8 sequence, return the length of that
908 sequence and set *VALUE to the value of that sequence, and
909 otherwise return 0 and set *VALUE to (unsigned int) -1. */
912 decode_utf8_char (const unsigned char *p
, size_t len
, unsigned int *value
)
923 for (t
= *p
; t
& 0x80; t
<<= 1)
926 if (utf8_len
> len
|| utf8_len
< 2 || utf8_len
> 6)
928 *value
= (unsigned int) -1;
931 ch
= *p
& ((1 << (7 - utf8_len
)) - 1);
932 for (i
= 1; i
< utf8_len
; i
++)
934 unsigned int u
= p
[i
];
935 if ((u
& 0xC0) != 0x80)
937 *value
= (unsigned int) -1;
940 ch
= (ch
<< 6) | (u
& 0x3F);
942 if ( (ch
<= 0x7F && utf8_len
> 1)
943 || (ch
<= 0x7FF && utf8_len
> 2)
944 || (ch
<= 0xFFFF && utf8_len
> 3)
945 || (ch
<= 0x1FFFFF && utf8_len
> 4)
946 || (ch
<= 0x3FFFFFF && utf8_len
> 5)
947 || (ch
>= 0xD800 && ch
<= 0xDFFF))
949 *value
= (unsigned int) -1;
962 /* Allocator for identifier_to_locale and corresponding function to
965 void *(*identifier_to_locale_alloc
) (size_t) = xmalloc
;
966 void (*identifier_to_locale_free
) (void *) = free
;
968 /* Given IDENT, an identifier in the internal encoding, return a
969 version of IDENT suitable for diagnostics in the locale character
970 set: either IDENT itself, or a string, allocated using
971 identifier_to_locale_alloc, converted to the locale character set
972 and using escape sequences if not representable in the locale
973 character set or containing control characters or invalid byte
974 sequences. Existing backslashes in IDENT are not doubled, so the
975 result may not uniquely specify the contents of an arbitrary byte
976 sequence identifier. */
979 identifier_to_locale (const char *ident
)
981 const unsigned char *uid
= (const unsigned char *) ident
;
982 size_t idlen
= strlen (ident
);
983 bool valid_printable_utf8
= true;
984 bool all_ascii
= true;
987 for (i
= 0; i
< idlen
;)
990 size_t utf8_len
= decode_utf8_char (&uid
[i
], idlen
- i
, &c
);
991 if (utf8_len
== 0 || c
<= 0x1F || (c
>= 0x7F && c
<= 0x9F))
993 valid_printable_utf8
= false;
1001 /* If IDENT contains invalid UTF-8 sequences (which may occur with
1002 attributes putting arbitrary byte sequences in identifiers), or
1003 control characters, we use octal escape sequences for all bytes
1004 outside printable ASCII. */
1005 if (!valid_printable_utf8
)
1007 char *ret
= (char *) identifier_to_locale_alloc (4 * idlen
+ 1);
1009 for (i
= 0; i
< idlen
; i
++)
1011 if (uid
[i
] > 0x1F && uid
[i
] < 0x7F)
1015 sprintf (p
, "\\%03o", uid
[i
]);
1023 /* Otherwise, if it is valid printable ASCII, or printable UTF-8
1024 with the locale character set being UTF-8, IDENT is used. */
1025 if (all_ascii
|| locale_utf8
)
1028 /* Otherwise IDENT is converted to the locale character set if
1030 #if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV
1031 if (locale_encoding
!= NULL
)
1033 iconv_t cd
= iconv_open (locale_encoding
, "UTF-8");
1034 bool conversion_ok
= true;
1036 if (cd
!= (iconv_t
) -1)
1038 size_t ret_alloc
= 4 * idlen
+ 1;
1041 /* Repeat the whole conversion process as needed with
1042 larger buffers so non-reversible transformations can
1043 always be detected. */
1044 ICONV_CONST
char *inbuf
= CONST_CAST (char *, ident
);
1046 size_t inbytesleft
= idlen
;
1047 size_t outbytesleft
= ret_alloc
- 1;
1050 ret
= (char *) identifier_to_locale_alloc (ret_alloc
);
1053 if (iconv (cd
, 0, 0, 0, 0) == (size_t) -1)
1055 conversion_ok
= false;
1059 iconv_ret
= iconv (cd
, &inbuf
, &inbytesleft
,
1060 &outbuf
, &outbytesleft
);
1061 if (iconv_ret
== (size_t) -1 || inbytesleft
!= 0)
1066 identifier_to_locale_free (ret
);
1072 conversion_ok
= false;
1076 else if (iconv_ret
!= 0)
1078 conversion_ok
= false;
1081 /* Return to initial shift state. */
1082 if (iconv (cd
, 0, 0, &outbuf
, &outbytesleft
) == (size_t) -1)
1087 identifier_to_locale_free (ret
);
1093 conversion_ok
= false;
1107 /* Otherwise, convert non-ASCII characters in IDENT to UCNs. */
1109 char *ret
= (char *) identifier_to_locale_alloc (10 * idlen
+ 1);
1111 for (i
= 0; i
< idlen
;)
1114 size_t utf8_len
= decode_utf8_char (&uid
[i
], idlen
- i
, &c
);
1119 sprintf (p
, "\\U%08x", c
);