Sun Nov 26 12:44:38 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
[glibc.git] / stdio-common / printf-prs.c
blob811a9cb7eb31f0eac69dca8b15d009d5f5ef58db
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. */
19 #include <stdio.h>
20 #include <printf.h>
21 #include <stdlib.h>
22 #include <string.h>
24 #include "printf-parse.h"
27 size_t
28 parse_printf_format (fmt, n, argtypes)
29 const char *fmt;
30 size_t n;
31 int *argtypes;
33 size_t nargs; /* Number of arguments. */
34 size_t max_ref_arg; /* Highest index used in a positional arg. */
35 struct printf_spec spec;
37 nargs = 0;
38 max_ref_arg = 0;
40 /* Search for format specifications. */
41 for (fmt = find_spec (fmt); *fmt != '\0'; fmt = spec.next_fmt)
43 /* Parse this spec. */
44 nargs += parse_one_spec (fmt, nargs, &spec, &max_ref_arg);
46 /* If the width is determined by an argument this is an int. */
47 if (spec.width_arg != -1 && spec.width_arg < n)
48 argtypes[spec.width_arg] = PA_INT;
50 /* If the precision is determined by an argument this is an int. */
51 if (spec.prec_arg != -1 && spec.prec_arg < n)
52 argtypes[spec.prec_arg] = PA_INT;
54 if (spec.data_arg < n)
55 switch (spec.ndata_args)
57 case 0: /* No arguments. */
58 break;
59 case 1: /* One argument; we already have the type. */
60 argtypes[spec.data_arg] = spec.data_arg_type;
61 break;
62 default:
63 /* We have more than one argument for this format spec. We must
64 call the arginfo function again to determine all the types. */
65 (void) (*__printf_arginfo_table[spec.info.spec])
66 (&spec.info, n - spec.data_arg, &argtypes[spec.data_arg]);
67 break;
71 return MAX (nargs, max_ref_arg);