Make fdwalk work when /proc isn't mounted
[kopensolaris-gnu/glibc.git] / stdio-common / printf-prs.c
1 /* Copyright (C) 1991, 1992, 1995, 1996, 1999, 2000, 2002, 2003, 2004, 2005,
2    2007 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library 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 GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <stdio.h>
21 #include <printf.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <wchar.h>
25 #include <sys/param.h>
26
27 #include "../locale/localeinfo.h"
28
29 #ifndef COMPILE_WPRINTF
30 # define CHAR_T         char
31 # define UCHAR_T        unsigned char
32 # define INT_T          int
33 # define L_(Str)        Str
34 # define ISDIGIT(Ch)    isdigit (Ch)
35 # define ISASCII(Ch)    isascii (Ch)
36 # define MBRLEN(Cp, L, St) __mbrlen (Cp, L, St)
37
38 # define PUT(F, S, N)   _IO_sputn (F, S, N)
39 # define PAD(Padchar)                                                         \
40   if (width > 0)                                                              \
41     done += INTUSE(_IO_padn) (s, Padchar, width)
42 #else
43 # define vfprintf       vfwprintf
44 # define CHAR_T         wchar_t
45 # define UCHAR_T        uwchar_t
46 # define INT_T          wint_t
47 # define L_(Str)        L##Str
48 # define ISDIGIT(Ch)    iswdigit (Ch)
49
50 # define PUT(F, S, N)   _IO_sputn (F, S, N)
51 # define PAD(Padchar)                                                         \
52   if (width > 0)                                                              \
53     done += _IO_wpadn (s, Padchar, width)
54 #endif
55
56 #define DONT_NEED_READ_INT
57 #include "printf-parse.h"
58
59
60 size_t
61 parse_printf_format (fmt, n, argtypes)
62       const char *fmt;
63       size_t n;
64       int *argtypes;
65 {
66   size_t nargs;                 /* Number of arguments.  */
67   size_t max_ref_arg;           /* Highest index used in a positional arg.  */
68   struct printf_spec spec;
69   const unsigned char *f = (const unsigned char *) fmt;
70
71   nargs = 0;
72   max_ref_arg = 0;
73
74   /* Search for format specifications.  */
75   for (f = __find_specmb (f); *f != '\0'; f = spec.next_fmt)
76     {
77       /* Parse this spec.  */
78       nargs += __parse_one_specmb (f, nargs, &spec, &max_ref_arg);
79
80       /* If the width is determined by an argument this is an int.  */
81       if (spec.width_arg != -1 && (size_t) spec.width_arg < n)
82         argtypes[spec.width_arg] = PA_INT;
83
84       /* If the precision is determined by an argument this is an int.  */
85       if (spec.prec_arg != -1 && (size_t) spec.prec_arg < n)
86         argtypes[spec.prec_arg] = PA_INT;
87
88       if ((size_t) spec.data_arg < n)
89         switch (spec.ndata_args)
90           {
91           case 0:               /* No arguments.  */
92             break;
93           case 1:               /* One argument; we already have the type.  */
94             argtypes[spec.data_arg] = spec.data_arg_type;
95             break;
96           default:
97             /* We have more than one argument for this format spec.  We must
98                call the arginfo function again to determine all the types.  */
99             (void) (*__printf_arginfo_table[spec.info.spec])
100               (&spec.info, n - spec.data_arg, &argtypes[spec.data_arg]);
101             break;
102           }
103     }
104
105   return MAX (nargs, max_ref_arg);
106 }