1 /* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
30 extern printf_arginfo_function
*__printf_arginfo_table
[];
33 DEFUN(parse_printf_format
, (fmt
, n
, argtypes
),
34 CONST
char *fmt AND
size_t n AND
int *argtypes
)
36 register CONST
char *f
;
39 for (f
= strchr (fmt
, '%'); f
!= NULL
; f
= strchr (f
, '%'))
41 struct printf_info info
;
42 printf_arginfo_function
*arginfo
;
46 info
.space
= info
.showsign
= info
.left
= info
.alt
= info
.group
= 0;
48 while (*f
== ' ' || *f
== '+' || *f
== '-' || *f
== '#' || *f
== '0' ||
74 /* Get the field width. */
88 info
.width
+= *f
++ - '0';
92 /* Get the precision. */
93 /* -1 means none given; 0 means explicit 0. */
100 /* The precision is given in an argument. */
102 *argtypes
++ = PA_INT
;
106 else if (isdigit(*f
))
109 while (*f
!= '\0' && isdigit(*f
))
112 info
.prec
+= *f
++ - '0';
117 /* Check for type modifiers. */
118 info
.is_short
= info
.is_long
= info
.is_long_double
= 0;
119 while (*f
== 'h' || *f
== 'l' || *f
== 'L')
123 /* int's are short int's. */
129 /* A double `l' is equivalent to an `L'. */
130 info
.is_long_double
= 1;
133 /* int's are long int's. */
137 /* double's are long double's, and int's are long long int's. */
138 info
.is_long_double
= 1;
147 arginfo
= __printf_arginfo_table
[info
.spec
];
151 = (*arginfo
) (&info
, need
> n
? 0 : n
- need
, argtypes
);
190 type
= PA_INT
| PA_FLAG_PTR
;
194 /* No arg for an unknown spec. */
198 if (info
.is_long_double
)
199 type
|= PA_FLAG_LONG_DOUBLE
;
201 type
|= PA_FLAG_LONG
;
203 type
|= PA_FLAG_SHORT
;