2 Copyright (C) 2001-2004 Free Software Foundation, Inc.
3 Written by Bruno Haible <haible@clisp.cons.org>, 2001.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
30 #include "format-invalid.h"
33 #define _(str) gettext (str)
35 /* C format strings are described in POSIX (IEEE P1003.1 2001), section
36 XSH 3 fprintf(). See also Linux fprintf(3) manual page.
38 - starts with '%' or '%m$' where m is a positive integer,
39 - is optionally followed by any of the characters '#', '0', '-', ' ', '+',
40 "'", or - only in msgstr strings - the string "I", each of which acts as
42 - is optionally followed by a width specification: '*' (reads an argument)
43 or '*m$' or a nonempty digit sequence,
44 - is optionally followed by '.' and a precision specification: '*' (reads
45 an argument) or '*m$' or a nonempty digit sequence,
46 - is either continued like this:
47 - is optionally followed by a size specifier, one of 'hh' 'h' 'l' 'll'
49 - is finished by a specifier
50 - '%', that needs no argument,
51 - 'c', 'C', that need a character argument,
52 - 's', 'S', that need a string argument,
53 - 'i', 'd', that need a signed integer argument,
54 - 'o', 'u', 'x', 'X', that need an unsigned integer argument,
55 - 'e', 'E', 'f', 'F', 'g', 'G', 'a', 'A', that need a floating-point
57 - 'p', that needs a 'void *' argument,
58 - 'n', that needs a pointer to integer.
59 or is finished by a specifier '<' inttypes-macro '>' where inttypes-macro
60 is an ISO C 99 section 7.8.1 format directive.
61 Numbered ('%m$' or '*m$') and unnumbered argument specifications cannot
62 be used in the same string. When numbered argument specifications are
63 used, specifying the Nth argument requires that all the leading arguments,
64 from the first to the (N-1)th, are specified in the format string.
77 FAT_COUNT_POINTER
= 7,
79 FAT_UNSIGNED
= 1 << 3,
80 FAT_SIZE_SHORT
= 1 << 4,
81 FAT_SIZE_CHAR
= 2 << 4,
82 FAT_SIZE_LONG
= 1 << 6,
83 FAT_SIZE_LONGLONG
= 2 << 6,
84 FAT_SIZE_8_T
= 1 << 8,
85 FAT_SIZE_16_T
= 1 << 9,
86 FAT_SIZE_32_T
= 1 << 10,
87 FAT_SIZE_64_T
= 1 << 11,
88 FAT_SIZE_LEAST8_T
= 1 << 12,
89 FAT_SIZE_LEAST16_T
= 1 << 13,
90 FAT_SIZE_LEAST32_T
= 1 << 14,
91 FAT_SIZE_LEAST64_T
= 1 << 15,
92 FAT_SIZE_FAST8_T
= 1 << 16,
93 FAT_SIZE_FAST16_T
= 1 << 17,
94 FAT_SIZE_FAST32_T
= 1 << 18,
95 FAT_SIZE_FAST64_T
= 1 << 19,
96 FAT_SIZE_INTMAX_T
= 1 << 20,
97 FAT_SIZE_INTPTR_T
= 1 << 21,
98 FAT_SIZE_SIZE_T
= 1 << 22,
99 FAT_SIZE_PTRDIFF_T
= 1 << 23,
100 FAT_WIDE
= FAT_SIZE_LONG
,
101 /* Meaningful combinations of basic types and flags:
102 'signed char' = FAT_INTEGER | FAT_SIZE_CHAR,
103 'unsigned char' = FAT_INTEGER | FAT_SIZE_CHAR | FAT_UNSIGNED,
104 'short' = FAT_INTEGER | FAT_SIZE_SHORT,
105 'unsigned short' = FAT_INTEGER | FAT_SIZE_SHORT | FAT_UNSIGNED,
107 'unsigned int' = FAT_INTEGER | FAT_UNSIGNED,
108 'long int' = FAT_INTEGER | FAT_SIZE_LONG,
109 'unsigned long int' = FAT_INTEGER | FAT_SIZE_LONG | FAT_UNSIGNED,
110 'long long int' = FAT_INTEGER | FAT_SIZE_LONGLONG,
111 'unsigned long long int' = FAT_INTEGER | FAT_SIZE_LONGLONG | FAT_UNSIGNED,
112 'double' = FAT_DOUBLE,
113 'long double' = FAT_DOUBLE | FAT_SIZE_LONGLONG,
114 'char'/'int' = FAT_CHAR,
115 'wchar_t'/'wint_t' = FAT_CHAR | FAT_SIZE_LONG,
116 'const char *' = FAT_STRING,
117 'const wchar_t *' = FAT_STRING | FAT_SIZE_LONG,
118 'void *' = FAT_POINTER,
119 FAT_COUNT_SCHAR_POINTER = FAT_COUNT_POINTER | FAT_SIZE_CHAR,
120 FAT_COUNT_SHORT_POINTER = FAT_COUNT_POINTER | FAT_SIZE_SHORT,
121 FAT_COUNT_INT_POINTER = FAT_COUNT_POINTER,
122 FAT_COUNT_LONGINT_POINTER = FAT_COUNT_POINTER | FAT_SIZE_LONG,
123 FAT_COUNT_LONGLONGINT_POINTER = FAT_COUNT_POINTER | FAT_SIZE_LONGLONG,
126 FAT_SIZE_MASK
= (FAT_SIZE_SHORT
| FAT_SIZE_CHAR
127 | FAT_SIZE_LONG
| FAT_SIZE_LONGLONG
128 | FAT_SIZE_8_T
| FAT_SIZE_16_T
129 | FAT_SIZE_32_T
| FAT_SIZE_64_T
130 | FAT_SIZE_LEAST8_T
| FAT_SIZE_LEAST16_T
131 | FAT_SIZE_LEAST32_T
| FAT_SIZE_LEAST64_T
132 | FAT_SIZE_FAST8_T
| FAT_SIZE_FAST16_T
133 | FAT_SIZE_FAST32_T
| FAT_SIZE_FAST64_T
134 | FAT_SIZE_INTMAX_T
| FAT_SIZE_INTPTR_T
135 | FAT_SIZE_SIZE_T
| FAT_SIZE_PTRDIFF_T
)
141 enum format_arg_type type
;
144 struct unnumbered_arg
146 enum format_arg_type type
;
151 unsigned int directives
;
152 unsigned int unnumbered_arg_count
;
153 unsigned int allocated
;
154 struct unnumbered_arg
*unnumbered
;
155 unsigned int sysdep_directives_count
;
156 const char **sysdep_directives
;
159 /* Locale independent test for a decimal digit.
160 Argument can be 'char' or 'unsigned char'. (Whereas the argument of
161 <ctype.h> isdigit must be an 'unsigned char'.) */
163 #define isdigit(c) ((unsigned int) ((c) - '0') < 10)
167 numbered_arg_compare (const void *p1
, const void *p2
)
169 unsigned int n1
= ((const struct numbered_arg
*) p1
)->number
;
170 unsigned int n2
= ((const struct numbered_arg
*) p2
)->number
;
172 return (n1
> n2
? 1 : n1
< n2
? -1 : 0);
175 #define INVALID_C99_MACRO(directive_number) \
176 xasprintf (_("In the directive number %u, the token after '<' is not the name of a format specifier macro. The valid macro names are listed in ISO C 99 section 7.8.1."), directive_number)
179 format_parse (const char *format
, bool translated
, bool objc_extensions
,
180 char **invalid_reason
)
183 unsigned int numbered_arg_count
;
184 struct numbered_arg
*numbered
;
188 numbered_arg_count
= 0;
189 spec
.unnumbered_arg_count
= 0;
192 spec
.unnumbered
= NULL
;
193 spec
.sysdep_directives_count
= 0;
194 spec
.sysdep_directives
= NULL
;
196 for (; *format
!= '\0';)
197 if (*format
++ == '%')
200 unsigned int number
= 0;
201 enum format_arg_type type
;
202 enum format_arg_type size
;
206 if (isdigit (*format
))
208 const char *f
= format
;
213 m
= 10 * m
+ (*f
- '0');
216 while (isdigit (*f
));
222 *invalid_reason
= INVALID_ARGNO_0 (spec
.directives
);
233 if (*format
== ' ' || *format
== '+' || *format
== '-'
234 || *format
== '#' || *format
== '0' || *format
== '\'')
236 else if (translated
&& *format
== 'I')
238 spec
.sysdep_directives
=
240 xrealloc (spec
.sysdep_directives
,
241 2 * (spec
.sysdep_directives_count
+ 1)
242 * sizeof (const char *));
243 spec
.sysdep_directives
[2 * spec
.sysdep_directives_count
] = format
;
244 spec
.sysdep_directives
[2 * spec
.sysdep_directives_count
+ 1] = format
+ 1;
245 spec
.sysdep_directives_count
++;
255 unsigned int width_number
= 0;
259 if (isdigit (*format
))
261 const char *f
= format
;
266 m
= 10 * m
+ (*f
- '0');
269 while (isdigit (*f
));
276 INVALID_WIDTH_ARGNO_0 (spec
.directives
);
286 /* Numbered argument. */
288 /* Numbered and unnumbered specifications are exclusive. */
289 if (spec
.unnumbered_arg_count
> 0)
291 *invalid_reason
= INVALID_MIXES_NUMBERED_UNNUMBERED ();
295 if (spec
.allocated
== numbered_arg_count
)
297 spec
.allocated
= 2 * spec
.allocated
+ 1;
298 numbered
= (struct numbered_arg
*) xrealloc (numbered
, spec
.allocated
* sizeof (struct numbered_arg
));
300 numbered
[numbered_arg_count
].number
= width_number
;
301 numbered
[numbered_arg_count
].type
= FAT_INTEGER
;
302 numbered_arg_count
++;
306 /* Unnumbered argument. */
308 /* Numbered and unnumbered specifications are exclusive. */
309 if (numbered_arg_count
> 0)
311 *invalid_reason
= INVALID_MIXES_NUMBERED_UNNUMBERED ();
315 if (spec
.allocated
== spec
.unnumbered_arg_count
)
317 spec
.allocated
= 2 * spec
.allocated
+ 1;
318 spec
.unnumbered
= (struct unnumbered_arg
*) xrealloc (spec
.unnumbered
, spec
.allocated
* sizeof (struct unnumbered_arg
));
320 spec
.unnumbered
[spec
.unnumbered_arg_count
].type
= FAT_INTEGER
;
321 spec
.unnumbered_arg_count
++;
324 else if (isdigit (*format
))
326 do format
++; while (isdigit (*format
));
329 /* Parse precision. */
336 unsigned int precision_number
= 0;
340 if (isdigit (*format
))
342 const char *f
= format
;
347 m
= 10 * m
+ (*f
- '0');
350 while (isdigit (*f
));
357 INVALID_PRECISION_ARGNO_0 (spec
.directives
);
360 precision_number
= m
;
365 if (precision_number
)
367 /* Numbered argument. */
369 /* Numbered and unnumbered specifications are exclusive. */
370 if (spec
.unnumbered_arg_count
> 0)
372 *invalid_reason
= INVALID_MIXES_NUMBERED_UNNUMBERED ();
376 if (spec
.allocated
== numbered_arg_count
)
378 spec
.allocated
= 2 * spec
.allocated
+ 1;
379 numbered
= (struct numbered_arg
*) xrealloc (numbered
, spec
.allocated
* sizeof (struct numbered_arg
));
381 numbered
[numbered_arg_count
].number
= precision_number
;
382 numbered
[numbered_arg_count
].type
= FAT_INTEGER
;
383 numbered_arg_count
++;
387 /* Unnumbered argument. */
389 /* Numbered and unnumbered specifications are exclusive. */
390 if (numbered_arg_count
> 0)
392 *invalid_reason
= INVALID_MIXES_NUMBERED_UNNUMBERED ();
396 if (spec
.allocated
== spec
.unnumbered_arg_count
)
398 spec
.allocated
= 2 * spec
.allocated
+ 1;
399 spec
.unnumbered
= (struct unnumbered_arg
*) xrealloc (spec
.unnumbered
, spec
.allocated
* sizeof (struct unnumbered_arg
));
401 spec
.unnumbered
[spec
.unnumbered_arg_count
].type
= FAT_INTEGER
;
402 spec
.unnumbered_arg_count
++;
405 else if (isdigit (*format
))
407 do format
++; while (isdigit (*format
));
413 spec
.sysdep_directives
=
415 xrealloc (spec
.sysdep_directives
,
416 2 * (spec
.sysdep_directives_count
+ 1)
417 * sizeof (const char *));
418 spec
.sysdep_directives
[2 * spec
.sysdep_directives_count
] = format
;
421 /* Parse ISO C 99 section 7.8.1 format string directive.
423 P R I { d | i | o | u | x | X }
424 { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR } */
427 *invalid_reason
= INVALID_C99_MACRO (spec
.directives
);
433 *invalid_reason
= INVALID_C99_MACRO (spec
.directives
);
439 *invalid_reason
= INVALID_C99_MACRO (spec
.directives
);
449 case 'u': case 'o': case 'x': case 'X':
450 type
= FAT_INTEGER
| FAT_UNSIGNED
;
453 *invalid_reason
= INVALID_C99_MACRO (spec
.directives
);
458 if (format
[0] == 'M' && format
[1] == 'A' && format
[2] == 'X')
460 type
|= FAT_SIZE_INTMAX_T
;
463 else if (format
[0] == 'P' && format
[1] == 'T' && format
[2] == 'R')
465 type
|= FAT_SIZE_INTPTR_T
;
470 if (format
[0] == 'L' && format
[1] == 'E' && format
[2] == 'A'
471 && format
[3] == 'S' && format
[4] == 'T')
474 if (format
[0] == '8')
476 type
|= FAT_SIZE_LEAST8_T
;
479 else if (format
[0] == '1' && format
[1] == '6')
481 type
|= FAT_SIZE_LEAST16_T
;
484 else if (format
[0] == '3' && format
[1] == '2')
486 type
|= FAT_SIZE_LEAST32_T
;
489 else if (format
[0] == '6' && format
[1] == '4')
491 type
|= FAT_SIZE_LEAST64_T
;
496 *invalid_reason
= INVALID_C99_MACRO (spec
.directives
);
500 else if (format
[0] == 'F' && format
[1] == 'A'
501 && format
[2] == 'S' && format
[3] == 'T')
504 if (format
[0] == '8')
506 type
|= FAT_SIZE_FAST8_T
;
509 else if (format
[0] == '1' && format
[1] == '6')
511 type
|= FAT_SIZE_FAST16_T
;
514 else if (format
[0] == '3' && format
[1] == '2')
516 type
|= FAT_SIZE_FAST32_T
;
519 else if (format
[0] == '6' && format
[1] == '4')
521 type
|= FAT_SIZE_FAST64_T
;
526 *invalid_reason
= INVALID_C99_MACRO (spec
.directives
);
532 if (format
[0] == '8')
534 type
|= FAT_SIZE_8_T
;
537 else if (format
[0] == '1' && format
[1] == '6')
539 type
|= FAT_SIZE_16_T
;
542 else if (format
[0] == '3' && format
[1] == '2')
544 type
|= FAT_SIZE_32_T
;
547 else if (format
[0] == '6' && format
[1] == '4')
549 type
|= FAT_SIZE_64_T
;
554 *invalid_reason
= INVALID_C99_MACRO (spec
.directives
);
563 xasprintf (_("In the directive number %u, the token after '<' is not followed by '>'."), spec
.directives
);
567 spec
.sysdep_directives
[2 * spec
.sysdep_directives_count
+ 1] = format
+ 1;
568 spec
.sysdep_directives_count
++;
578 if (size
& (FAT_SIZE_SHORT
| FAT_SIZE_CHAR
))
579 size
= FAT_SIZE_CHAR
;
581 size
= FAT_SIZE_SHORT
;
583 else if (*format
== 'l')
585 if (size
& (FAT_SIZE_LONG
| FAT_SIZE_LONGLONG
))
586 size
= FAT_SIZE_LONGLONG
;
588 size
= FAT_SIZE_LONG
;
590 else if (*format
== 'L')
591 size
= FAT_SIZE_LONGLONG
;
592 else if (*format
== 'q')
593 /* Old BSD 4.4 convention. */
594 size
= FAT_SIZE_LONGLONG
;
595 else if (*format
== 'j')
596 size
= FAT_SIZE_INTMAX_T
;
597 else if (*format
== 'z' || *format
== 'Z')
598 /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
599 because the warning facility in gcc-2.95.2 understands
600 only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */
601 size
= FAT_SIZE_SIZE_T
;
602 else if (*format
== 't')
603 size
= FAT_SIZE_PTRDIFF_T
;
611 case 'm': /* glibc extension */
616 type
|= (size
& (FAT_SIZE_LONG
| FAT_SIZE_LONGLONG
)
619 case 'C': /* obsolete */
620 type
= FAT_CHAR
| FAT_WIDE
;
624 type
|= (size
& (FAT_SIZE_LONG
| FAT_SIZE_LONGLONG
)
627 case 'S': /* obsolete */
628 type
= FAT_STRING
| FAT_WIDE
;
632 type
|= (size
& FAT_SIZE_MASK
);
634 case 'u': case 'o': case 'x': case 'X':
635 type
= FAT_INTEGER
| FAT_UNSIGNED
;
636 type
|= (size
& FAT_SIZE_MASK
);
638 case 'e': case 'E': case 'f': case 'F': case 'g': case 'G':
641 type
|= (size
& FAT_SIZE_LONGLONG
);
646 type
= FAT_OBJC_OBJECT
;
654 type
= FAT_COUNT_POINTER
;
655 type
|= (size
& FAT_SIZE_MASK
);
661 ? INVALID_UNTERMINATED_DIRECTIVE ()
662 : INVALID_CONVERSION_SPECIFIER (spec
.directives
, *format
));
667 if (type
!= FAT_NONE
)
671 /* Numbered argument. */
673 /* Numbered and unnumbered specifications are exclusive. */
674 if (spec
.unnumbered_arg_count
> 0)
676 *invalid_reason
= INVALID_MIXES_NUMBERED_UNNUMBERED ();
680 if (spec
.allocated
== numbered_arg_count
)
682 spec
.allocated
= 2 * spec
.allocated
+ 1;
683 numbered
= (struct numbered_arg
*) xrealloc (numbered
, spec
.allocated
* sizeof (struct numbered_arg
));
685 numbered
[numbered_arg_count
].number
= number
;
686 numbered
[numbered_arg_count
].type
= type
;
687 numbered_arg_count
++;
691 /* Unnumbered argument. */
693 /* Numbered and unnumbered specifications are exclusive. */
694 if (numbered_arg_count
> 0)
696 *invalid_reason
= INVALID_MIXES_NUMBERED_UNNUMBERED ();
700 if (spec
.allocated
== spec
.unnumbered_arg_count
)
702 spec
.allocated
= 2 * spec
.allocated
+ 1;
703 spec
.unnumbered
= (struct unnumbered_arg
*) xrealloc (spec
.unnumbered
, spec
.allocated
* sizeof (struct unnumbered_arg
));
705 spec
.unnumbered
[spec
.unnumbered_arg_count
].type
= type
;
706 spec
.unnumbered_arg_count
++;
713 /* Sort the numbered argument array, and eliminate duplicates. */
714 if (numbered_arg_count
> 1)
719 qsort (numbered
, numbered_arg_count
,
720 sizeof (struct numbered_arg
), numbered_arg_compare
);
722 /* Remove duplicates: Copy from i to j, keeping 0 <= j <= i. */
724 for (i
= j
= 0; i
< numbered_arg_count
; i
++)
725 if (j
> 0 && numbered
[i
].number
== numbered
[j
-1].number
)
727 enum format_arg_type type1
= numbered
[i
].type
;
728 enum format_arg_type type2
= numbered
[j
-1].type
;
729 enum format_arg_type type_both
;
735 /* Incompatible types. */
736 type_both
= FAT_NONE
;
739 INVALID_INCOMPATIBLE_ARG_TYPES (numbered
[i
].number
);
743 numbered
[j
-1].type
= type_both
;
749 numbered
[j
].number
= numbered
[i
].number
;
750 numbered
[j
].type
= numbered
[i
].type
;
754 numbered_arg_count
= j
;
756 /* *invalid_reason has already been set above. */
760 /* Verify that the format strings uses all arguments up to the highest
762 if (numbered_arg_count
> 0)
766 for (i
= 0; i
< numbered_arg_count
; i
++)
767 if (numbered
[i
].number
!= i
+ 1)
770 xasprintf (_("The string refers to argument number %u but ignores argument number %u."), numbered
[i
].number
, i
+ 1);
774 /* So now the numbered arguments array is equivalent to a sequence
775 of unnumbered arguments. */
776 spec
.unnumbered_arg_count
= numbered_arg_count
;
777 spec
.allocated
= spec
.unnumbered_arg_count
;
778 spec
.unnumbered
= (struct unnumbered_arg
*) xmalloc (spec
.allocated
* sizeof (struct unnumbered_arg
));
779 for (i
= 0; i
< spec
.unnumbered_arg_count
; i
++)
780 spec
.unnumbered
[i
].type
= numbered
[i
].type
;
782 numbered_arg_count
= 0;
785 result
= (struct spec
*) xmalloc (sizeof (struct spec
));
790 if (numbered
!= NULL
)
792 if (spec
.unnumbered
!= NULL
)
793 free (spec
.unnumbered
);
794 if (spec
.sysdep_directives
!= NULL
)
795 free (spec
.sysdep_directives
);
800 format_c_parse (const char *format
, bool translated
, char **invalid_reason
)
802 return format_parse (format
, translated
, false, invalid_reason
);
806 format_objc_parse (const char *format
, bool translated
, char **invalid_reason
)
808 return format_parse (format
, translated
, true, invalid_reason
);
812 format_free (void *descr
)
814 struct spec
*spec
= (struct spec
*) descr
;
816 if (spec
->unnumbered
!= NULL
)
817 free (spec
->unnumbered
);
818 if (spec
->sysdep_directives
!= NULL
)
819 free (spec
->sysdep_directives
);
824 format_get_number_of_directives (void *descr
)
826 struct spec
*spec
= (struct spec
*) descr
;
828 return spec
->directives
;
832 format_check (void *msgid_descr
, void *msgstr_descr
, bool equality
,
833 formatstring_error_logger_t error_logger
,
834 const char *pretty_msgstr
)
836 struct spec
*spec1
= (struct spec
*) msgid_descr
;
837 struct spec
*spec2
= (struct spec
*) msgstr_descr
;
841 /* Check the argument types are the same. */
843 ? spec1
->unnumbered_arg_count
!= spec2
->unnumbered_arg_count
844 : spec1
->unnumbered_arg_count
< spec2
->unnumbered_arg_count
)
847 error_logger (_("number of format specifications in 'msgid' and '%s' does not match"),
852 for (i
= 0; i
< spec2
->unnumbered_arg_count
; i
++)
853 if (spec1
->unnumbered
[i
].type
!= spec2
->unnumbered
[i
].type
)
856 error_logger (_("format specifications in 'msgid' and '%s' for argument %u are not the same"),
857 pretty_msgstr
, i
+ 1);
865 struct formatstring_parser formatstring_c
=
869 format_get_number_of_directives
,
874 struct formatstring_parser formatstring_objc
=
878 format_get_number_of_directives
,
884 get_sysdep_c_format_directives (const char *string
, bool translated
,
885 struct interval
**intervalsp
, size_t *lengthp
)
887 /* Parse the format string with all possible extensions turned on. (The
888 caller has already verified that the format string is valid for the
889 particular language.) */
890 char *invalid_reason
= NULL
;
892 (struct spec
*) format_parse (string
, translated
, true, &invalid_reason
);
894 if (descr
!= NULL
&& descr
->sysdep_directives_count
> 0)
896 unsigned int n
= descr
->sysdep_directives_count
;
897 struct interval
*intervals
=
898 (struct interval
*) xmalloc (n
* sizeof (struct interval
));
901 for (i
= 0; i
< n
; i
++)
903 intervals
[i
].startpos
= descr
->sysdep_directives
[2 * i
] - string
;
904 intervals
[i
].endpos
= descr
->sysdep_directives
[2 * i
+ 1] - string
;
906 *intervalsp
= intervals
;
918 free (invalid_reason
);
924 /* Test program: Print the argument list specification returned by
925 format_parse for strings read from standard input. */
931 format_print (void *descr
)
933 struct spec
*spec
= (struct spec
*) descr
;
943 for (i
= 0; i
< spec
->unnumbered_arg_count
; i
++)
947 if (spec
->unnumbered
[i
].type
& FAT_UNSIGNED
)
948 printf ("[unsigned]");
949 switch (spec
->unnumbered
[i
].type
& FAT_SIZE_MASK
)
962 case FAT_SIZE_LONGLONG
:
963 printf ("[long long]");
969 printf ("[int16_t]");
972 printf ("[int32_t]");
975 printf ("[int64_t]");
977 case FAT_SIZE_LEAST8_T
:
978 printf ("[int_least8_t]");
980 case FAT_SIZE_LEAST16_T
:
981 printf ("[int_least16_t]");
983 case FAT_SIZE_LEAST32_T
:
984 printf ("[int_least32_t]");
986 case FAT_SIZE_LEAST64_T
:
987 printf ("[int_least64_t]");
989 case FAT_SIZE_FAST8_T
:
990 printf ("[int_fast8_t]");
992 case FAT_SIZE_FAST16_T
:
993 printf ("[int_fast16_t]");
995 case FAT_SIZE_FAST32_T
:
996 printf ("[int_fast32_t]");
998 case FAT_SIZE_FAST64_T
:
999 printf ("[int_fast64_t]");
1001 case FAT_SIZE_INTMAX_T
:
1002 printf ("[intmax_t]");
1004 case FAT_SIZE_INTPTR_T
:
1005 printf ("[intptr_t]");
1007 case FAT_SIZE_SIZE_T
:
1008 printf ("[size_t]");
1010 case FAT_SIZE_PTRDIFF_T
:
1011 printf ("[ptrdiff_t]");
1016 switch (spec
->unnumbered
[i
].type
& ~(FAT_UNSIGNED
| FAT_SIZE_MASK
))
1030 case FAT_OBJC_OBJECT
:
1036 case FAT_COUNT_POINTER
:
1052 size_t line_size
= 0;
1054 char *invalid_reason
;
1057 line_len
= getline (&line
, &line_size
, stdin
);
1060 if (line_len
> 0 && line
[line_len
- 1] == '\n')
1061 line
[--line_len
] = '\0';
1063 invalid_reason
= NULL
;
1064 descr
= format_c_parse (line
, false, &invalid_reason
);
1066 format_print (descr
);
1069 printf ("%s\n", invalid_reason
);
1071 free (invalid_reason
);
1079 * For Emacs M-x compile
1081 * compile-command: "/bin/sh ../libtool --mode=link gcc -o a.out -static -O -g -Wall -I.. -I../lib -I../intl -DHAVE_CONFIG_H -DTEST format-c.c ../lib/libgettextlib.la"