Many files moved from stdio to stdio-common.
[kopensolaris-gnu/glibc.git] / stdio-common / printf-prs.c
1 /* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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.
8
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.
13
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.  */
18
19 #include <stdio.h>
20 #include <printf.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "printf-parse.h"
25
26
27 size_t
28 parse_printf_format (fmt, n, argtypes)
29       const char *fmt;
30       size_t n;
31       int *argtypes;
32 {
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;
36
37   nargs = 0;
38   max_ref_arg = 0;
39
40   /* Search for format specifications.  */
41   for (fmt = find_spec (fmt); *fmt != '\0'; fmt = spec.next_fmt)
42     {
43       /* Parse this spec.  */
44       nargs += parse_one_spec (fmt, nargs, &spec, &max_ref_arg);
45
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;
49
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;
53
54       if (spec.data_arg < n)
55         switch (spec.ndata_args)
56           {
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;
68           }
69     }
70
71   return MAX (nargs, max_ref_arg);
72 }