Mercurial > hg > octave-kai > gnulib-hg
annotate lib/printf-parse.c @ 17476:6057744acd2c default tip master
autoupdate
author | Karl Berry <karl@freefriends.org> |
---|---|
date | Fri, 16 Aug 2013 06:32:22 -0700 (2013-08-16) |
parents | e542fd46ad6f |
children |
rev | line source |
---|---|
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
1 /* Formatted output to strings. |
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
16935
diff
changeset
|
2 Copyright (C) 1999-2000, 2002-2003, 2006-2013 Free Software Foundation, Inc. |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
3 |
4440
e58a1c05a6ba
Update gettext source files from gettext automatically, using srclist-update.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4224
diff
changeset
|
4 This program is free software; you can redistribute it and/or modify |
e58a1c05a6ba
Update gettext source files from gettext automatically, using srclist-update.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4224
diff
changeset
|
5 it under the terms of the GNU General Public License as published by |
e58a1c05a6ba
Update gettext source files from gettext automatically, using srclist-update.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4224
diff
changeset
|
6 the Free Software Foundation; either version 2, or (at your option) |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
7 any later version. |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
8 |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
9 This program is distributed in the hope that it will be useful, |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
10 but WITHOUT ANY WARRANTY; without even the implied warranty of |
4440
e58a1c05a6ba
Update gettext source files from gettext automatically, using srclist-update.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4224
diff
changeset
|
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
e58a1c05a6ba
Update gettext source files from gettext automatically, using srclist-update.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4224
diff
changeset
|
12 GNU General Public License for more details. |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
13 |
4440
e58a1c05a6ba
Update gettext source files from gettext automatically, using srclist-update.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4224
diff
changeset
|
14 You should have received a copy of the GNU General Public License along |
16366
bb182ee4a09d
maint: replace FSF snail-mail addresses with URLs
Paul Eggert <eggert@cs.ucla.edu>
parents:
16214
diff
changeset
|
15 with this program; if not, see <http://www.gnu.org/licenses/>. */ |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
16 |
8973
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
17 /* This file can be parametrized with the following macros: |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
18 CHAR_T The element type of the format string. |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
19 CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
20 in the format string are ASCII. |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
21 DIRECTIVE Structure denoting a format directive. |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
22 Depends on CHAR_T. |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
23 DIRECTIVES Structure denoting the set of format directives of a |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
24 format string. Depends on CHAR_T. |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
25 PRINTF_PARSE Function that parses a format string. |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
26 Depends on CHAR_T. |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
27 STATIC Set to 'static' to declare the function static. |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
28 ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. */ |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
29 |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
30 #ifndef PRINTF_PARSE |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
31 # include <config.h> |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
32 #endif |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
33 |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
34 /* Specification. */ |
8973
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
35 #ifndef PRINTF_PARSE |
4871
87df35000dab
Merge support for wide characters, from GNU gettext.
Bruno Haible <bruno@clisp.org>
parents:
4440
diff
changeset
|
36 # include "printf-parse.h" |
87df35000dab
Merge support for wide characters, from GNU gettext.
Bruno Haible <bruno@clisp.org>
parents:
4440
diff
changeset
|
37 #endif |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
38 |
8973
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
39 /* Default parameters. */ |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
40 #ifndef PRINTF_PARSE |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
41 # define PRINTF_PARSE printf_parse |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
42 # define CHAR_T char |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
43 # define DIRECTIVE char_directive |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
44 # define DIRECTIVES char_directives |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
45 #endif |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
46 |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
47 /* Get size_t, NULL. */ |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
48 #include <stddef.h> |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
49 |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
50 /* Get intmax_t. */ |
9384
e5e1a09aa484
Tweak to make it usable in gettext's libasprintf.
Bruno Haible <bruno@clisp.org>
parents:
8973
diff
changeset
|
51 #if defined IN_LIBINTL || defined IN_LIBASPRINTF |
8551
a2ed636e1b10
Support 'j' size specifier on all platforms.
Bruno Haible <bruno@clisp.org>
parents:
8051
diff
changeset
|
52 # if HAVE_STDINT_H_WITH_UINTMAX |
a2ed636e1b10
Support 'j' size specifier on all platforms.
Bruno Haible <bruno@clisp.org>
parents:
8051
diff
changeset
|
53 # include <stdint.h> |
a2ed636e1b10
Support 'j' size specifier on all platforms.
Bruno Haible <bruno@clisp.org>
parents:
8051
diff
changeset
|
54 # endif |
a2ed636e1b10
Support 'j' size specifier on all platforms.
Bruno Haible <bruno@clisp.org>
parents:
8051
diff
changeset
|
55 # if HAVE_INTTYPES_H_WITH_UINTMAX |
a2ed636e1b10
Support 'j' size specifier on all platforms.
Bruno Haible <bruno@clisp.org>
parents:
8051
diff
changeset
|
56 # include <inttypes.h> |
a2ed636e1b10
Support 'j' size specifier on all platforms.
Bruno Haible <bruno@clisp.org>
parents:
8051
diff
changeset
|
57 # endif |
a2ed636e1b10
Support 'j' size specifier on all platforms.
Bruno Haible <bruno@clisp.org>
parents:
8051
diff
changeset
|
58 #else |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
59 # include <stdint.h> |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
60 #endif |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
61 |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
62 /* malloc(), realloc(), free(). */ |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
63 #include <stdlib.h> |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
64 |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
65 /* memcpy(). */ |
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
66 #include <string.h> |
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
67 |
9438
290aa46b4526
Fix out-of-memory handling of vasnprintf.
Bruno Haible <bruno@clisp.org>
parents:
9384
diff
changeset
|
68 /* errno. */ |
290aa46b4526
Fix out-of-memory handling of vasnprintf.
Bruno Haible <bruno@clisp.org>
parents:
9384
diff
changeset
|
69 #include <errno.h> |
290aa46b4526
Fix out-of-memory handling of vasnprintf.
Bruno Haible <bruno@clisp.org>
parents:
9384
diff
changeset
|
70 |
4872
c5afc99b8ce5
Use xsize.h to protect against memory size overflows.
Bruno Haible <bruno@clisp.org>
parents:
4871
diff
changeset
|
71 /* Checked size_t computations. */ |
c5afc99b8ce5
Use xsize.h to protect against memory size overflows.
Bruno Haible <bruno@clisp.org>
parents:
4871
diff
changeset
|
72 #include "xsize.h" |
c5afc99b8ce5
Use xsize.h to protect against memory size overflows.
Bruno Haible <bruno@clisp.org>
parents:
4871
diff
changeset
|
73 |
8973
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
74 #if CHAR_T_ONLY_ASCII |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
75 /* c_isascii(). */ |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
76 # include "c-ctype.h" |
4871
87df35000dab
Merge support for wide characters, from GNU gettext.
Bruno Haible <bruno@clisp.org>
parents:
4440
diff
changeset
|
77 #endif |
87df35000dab
Merge support for wide characters, from GNU gettext.
Bruno Haible <bruno@clisp.org>
parents:
4440
diff
changeset
|
78 |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
79 #ifdef STATIC |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
80 STATIC |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
81 #endif |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
82 int |
4871
87df35000dab
Merge support for wide characters, from GNU gettext.
Bruno Haible <bruno@clisp.org>
parents:
4440
diff
changeset
|
83 PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
84 { |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
85 const CHAR_T *cp = format; /* pointer into format */ |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
86 size_t arg_posn = 0; /* number of regular arguments consumed */ |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
87 size_t d_allocated; /* allocated elements of d->dir */ |
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
88 size_t a_allocated; /* allocated elements of a->arg */ |
4872
c5afc99b8ce5
Use xsize.h to protect against memory size overflows.
Bruno Haible <bruno@clisp.org>
parents:
4871
diff
changeset
|
89 size_t max_width_length = 0; |
c5afc99b8ce5
Use xsize.h to protect against memory size overflows.
Bruno Haible <bruno@clisp.org>
parents:
4871
diff
changeset
|
90 size_t max_precision_length = 0; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
91 |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
92 d->count = 0; |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
93 d_allocated = N_DIRECT_ALLOC_DIRECTIVES; |
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
94 d->dir = d->direct_alloc_dir; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
95 |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
96 a->count = 0; |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
97 a_allocated = N_DIRECT_ALLOC_ARGUMENTS; |
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
98 a->arg = a->direct_alloc_arg; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
99 |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
100 #define REGISTER_ARG(_index_,_type_) \ |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
101 { \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
102 size_t n = (_index_); \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
103 if (n >= a_allocated) \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
104 { \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
105 size_t memory_size; \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
106 argument *memory; \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
107 \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
108 a_allocated = xtimes (a_allocated, 2); \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
109 if (a_allocated <= n) \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
110 a_allocated = xsum (n, 1); \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
111 memory_size = xtimes (a_allocated, sizeof (argument)); \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
112 if (size_overflow_p (memory_size)) \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
113 /* Overflow, would lead to out of memory. */ \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
114 goto out_of_memory; \ |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
115 memory = (argument *) (a->arg != a->direct_alloc_arg \ |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
116 ? realloc (a->arg, memory_size) \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
117 : malloc (memory_size)); \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
118 if (memory == NULL) \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
119 /* Out of memory. */ \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
120 goto out_of_memory; \ |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
121 if (a->arg == a->direct_alloc_arg) \ |
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
122 memcpy (memory, a->arg, a->count * sizeof (argument)); \ |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
123 a->arg = memory; \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
124 } \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
125 while (a->count <= n) \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
126 a->arg[a->count++].type = TYPE_NONE; \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
127 if (a->arg[n].type == TYPE_NONE) \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
128 a->arg[n].type = (_type_); \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
129 else if (a->arg[n].type != (_type_)) \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
130 /* Ambiguous type for positional argument. */ \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
131 goto error; \ |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
132 } |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
133 |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
134 while (*cp != '\0') |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
135 { |
4871
87df35000dab
Merge support for wide characters, from GNU gettext.
Bruno Haible <bruno@clisp.org>
parents:
4440
diff
changeset
|
136 CHAR_T c = *cp++; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
137 if (c == '%') |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
138 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
139 size_t arg_index = ARG_NONE; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
140 DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */ |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
141 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
142 /* Initialize the next directive. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
143 dp->dir_start = cp - 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
144 dp->flags = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
145 dp->width_start = NULL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
146 dp->width_end = NULL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
147 dp->width_arg_index = ARG_NONE; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
148 dp->precision_start = NULL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
149 dp->precision_end = NULL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
150 dp->precision_arg_index = ARG_NONE; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
151 dp->arg_index = ARG_NONE; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
152 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
153 /* Test for positional argument. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
154 if (*cp >= '0' && *cp <= '9') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
155 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
156 const CHAR_T *np; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
157 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
158 for (np = cp; *np >= '0' && *np <= '9'; np++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
159 ; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
160 if (*np == '$') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
161 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
162 size_t n = 0; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
163 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
164 for (np = cp; *np >= '0' && *np <= '9'; np++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
165 n = xsum (xtimes (n, 10), *np - '0'); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
166 if (n == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
167 /* Positional argument 0. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
168 goto error; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
169 if (size_overflow_p (n)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
170 /* n too large, would lead to out of memory later. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
171 goto error; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
172 arg_index = n - 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
173 cp = np + 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
174 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
175 } |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
176 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
177 /* Read the flags. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
178 for (;;) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
179 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
180 if (*cp == '\'') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
181 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
182 dp->flags |= FLAG_GROUP; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
183 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
184 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
185 else if (*cp == '-') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
186 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
187 dp->flags |= FLAG_LEFT; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
188 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
189 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
190 else if (*cp == '+') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
191 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
192 dp->flags |= FLAG_SHOWSIGN; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
193 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
194 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
195 else if (*cp == ' ') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
196 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
197 dp->flags |= FLAG_SPACE; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
198 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
199 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
200 else if (*cp == '#') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
201 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
202 dp->flags |= FLAG_ALT; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
203 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
204 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
205 else if (*cp == '0') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
206 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
207 dp->flags |= FLAG_ZERO; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
208 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
209 } |
13885 | 210 #if __GLIBC__ >= 2 && !defined __UCLIBC__ |
13841
05717fb89fa4
vasnprintf: Support I flag on glibc systems.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
211 else if (*cp == 'I') |
05717fb89fa4
vasnprintf: Support I flag on glibc systems.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
212 { |
05717fb89fa4
vasnprintf: Support I flag on glibc systems.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
213 dp->flags |= FLAG_LOCALIZED; |
05717fb89fa4
vasnprintf: Support I flag on glibc systems.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
214 cp++; |
05717fb89fa4
vasnprintf: Support I flag on glibc systems.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
215 } |
05717fb89fa4
vasnprintf: Support I flag on glibc systems.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
216 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
217 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
218 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
219 } |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
220 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
221 /* Parse the field width. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
222 if (*cp == '*') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
223 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
224 dp->width_start = cp; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
225 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
226 dp->width_end = cp; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
227 if (max_width_length < 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
228 max_width_length = 1; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
229 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
230 /* Test for positional argument. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
231 if (*cp >= '0' && *cp <= '9') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
232 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
233 const CHAR_T *np; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
234 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
235 for (np = cp; *np >= '0' && *np <= '9'; np++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
236 ; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
237 if (*np == '$') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
238 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
239 size_t n = 0; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
240 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
241 for (np = cp; *np >= '0' && *np <= '9'; np++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
242 n = xsum (xtimes (n, 10), *np - '0'); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
243 if (n == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
244 /* Positional argument 0. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
245 goto error; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
246 if (size_overflow_p (n)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
247 /* n too large, would lead to out of memory later. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
248 goto error; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
249 dp->width_arg_index = n - 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
250 cp = np + 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
251 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
252 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
253 if (dp->width_arg_index == ARG_NONE) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
254 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
255 dp->width_arg_index = arg_posn++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
256 if (dp->width_arg_index == ARG_NONE) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
257 /* arg_posn wrapped around. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
258 goto error; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
259 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
260 REGISTER_ARG (dp->width_arg_index, TYPE_INT); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
261 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
262 else if (*cp >= '0' && *cp <= '9') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
263 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
264 size_t width_length; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
265 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
266 dp->width_start = cp; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
267 for (; *cp >= '0' && *cp <= '9'; cp++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
268 ; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
269 dp->width_end = cp; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
270 width_length = dp->width_end - dp->width_start; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
271 if (max_width_length < width_length) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
272 max_width_length = width_length; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
273 } |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
274 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
275 /* Parse the precision. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
276 if (*cp == '.') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
277 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
278 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
279 if (*cp == '*') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
280 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
281 dp->precision_start = cp - 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
282 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
283 dp->precision_end = cp; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
284 if (max_precision_length < 2) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
285 max_precision_length = 2; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
286 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
287 /* Test for positional argument. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
288 if (*cp >= '0' && *cp <= '9') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
289 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
290 const CHAR_T *np; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
291 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
292 for (np = cp; *np >= '0' && *np <= '9'; np++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
293 ; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
294 if (*np == '$') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
295 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
296 size_t n = 0; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
297 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
298 for (np = cp; *np >= '0' && *np <= '9'; np++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
299 n = xsum (xtimes (n, 10), *np - '0'); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
300 if (n == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
301 /* Positional argument 0. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
302 goto error; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
303 if (size_overflow_p (n)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
304 /* n too large, would lead to out of memory |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
305 later. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
306 goto error; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
307 dp->precision_arg_index = n - 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
308 cp = np + 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
309 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
310 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
311 if (dp->precision_arg_index == ARG_NONE) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
312 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
313 dp->precision_arg_index = arg_posn++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
314 if (dp->precision_arg_index == ARG_NONE) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
315 /* arg_posn wrapped around. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
316 goto error; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
317 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
318 REGISTER_ARG (dp->precision_arg_index, TYPE_INT); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
319 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
320 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
321 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
322 size_t precision_length; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
323 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
324 dp->precision_start = cp - 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
325 for (; *cp >= '0' && *cp <= '9'; cp++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
326 ; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
327 dp->precision_end = cp; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
328 precision_length = dp->precision_end - dp->precision_start; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
329 if (max_precision_length < precision_length) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
330 max_precision_length = precision_length; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
331 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
332 } |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
333 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
334 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
335 arg_type type; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
336 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
337 /* Parse argument type/size specifiers. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
338 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
339 int flags = 0; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
340 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
341 for (;;) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
342 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
343 if (*cp == 'h') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
344 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
345 flags |= (1 << (flags & 1)); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
346 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
347 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
348 else if (*cp == 'L') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
349 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
350 flags |= 4; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
351 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
352 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
353 else if (*cp == 'l') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
354 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
355 flags += 8; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
356 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
357 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
358 else if (*cp == 'j') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
359 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
360 if (sizeof (intmax_t) > sizeof (long)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
361 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
362 /* intmax_t = long long */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
363 flags += 16; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
364 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
365 else if (sizeof (intmax_t) > sizeof (int)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
366 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
367 /* intmax_t = long */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
368 flags += 8; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
369 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
370 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
371 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
372 else if (*cp == 'z' || *cp == 'Z') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
373 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
374 /* 'z' is standardized in ISO C 99, but glibc uses 'Z' |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
375 because the warning facility in gcc-2.95.2 understands |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
376 only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
377 if (sizeof (size_t) > sizeof (long)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
378 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
379 /* size_t = long long */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
380 flags += 16; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
381 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
382 else if (sizeof (size_t) > sizeof (int)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
383 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
384 /* size_t = long */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
385 flags += 8; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
386 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
387 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
388 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
389 else if (*cp == 't') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
390 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
391 if (sizeof (ptrdiff_t) > sizeof (long)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
392 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
393 /* ptrdiff_t = long long */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
394 flags += 16; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
395 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
396 else if (sizeof (ptrdiff_t) > sizeof (int)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
397 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
398 /* ptrdiff_t = long */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
399 flags += 8; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
400 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
401 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
402 } |
9588
82384b8e3c31
Handle the particular PRIdMAX values on MacOS X and mingw.
Bruno Haible <bruno@clisp.org>
parents:
9438
diff
changeset
|
403 #if defined __APPLE__ && defined __MACH__ |
16935
498a2211d839
Write "Mac OS X" instead of "MacOS X".
Bruno Haible <bruno@clisp.org>
parents:
16366
diff
changeset
|
404 /* On Mac OS X 10.3, PRIdMAX is defined as "qd". |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
405 We cannot change it to "lld" because PRIdMAX must also |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
406 be understood by the system's printf routines. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
407 else if (*cp == 'q') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
408 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
409 if (64 / 8 > sizeof (long)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
410 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
411 /* int64_t = long long */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
412 flags += 16; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
413 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
414 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
415 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
416 /* int64_t = long */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
417 flags += 8; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
418 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
419 cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
420 } |
9588
82384b8e3c31
Handle the particular PRIdMAX values on MacOS X and mingw.
Bruno Haible <bruno@clisp.org>
parents:
9438
diff
changeset
|
421 #endif |
82384b8e3c31
Handle the particular PRIdMAX values on MacOS X and mingw.
Bruno Haible <bruno@clisp.org>
parents:
9438
diff
changeset
|
422 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
423 /* On native Windows, PRIdMAX is defined as "I64d". |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
424 We cannot change it to "lld" because PRIdMAX must also |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
425 be understood by the system's printf routines. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
426 else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
427 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
428 if (64 / 8 > sizeof (long)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
429 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
430 /* __int64 = long long */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
431 flags += 16; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
432 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
433 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
434 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
435 /* __int64 = long */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
436 flags += 8; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
437 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
438 cp += 3; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
439 } |
9588
82384b8e3c31
Handle the particular PRIdMAX values on MacOS X and mingw.
Bruno Haible <bruno@clisp.org>
parents:
9438
diff
changeset
|
440 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
441 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
442 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
443 } |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
444 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
445 /* Read the conversion character. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
446 c = *cp++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
447 switch (c) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
448 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
449 case 'd': case 'i': |
8051
9c2b0396b27c
Stylistic change: Use '#if HAVE_*' instead of '#ifdef HAVE_*'.
Bruno Haible <bruno@clisp.org>
parents:
7596
diff
changeset
|
450 #if HAVE_LONG_LONG_INT |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
451 /* If 'long long' exists and is larger than 'long': */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
452 if (flags >= 16 || (flags & 4)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
453 type = TYPE_LONGLONGINT; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
454 else |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
455 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
456 /* If 'long long' exists and is the same as 'long', we parse |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
457 "lld" into TYPE_LONGINT. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
458 if (flags >= 8) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
459 type = TYPE_LONGINT; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
460 else if (flags & 2) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
461 type = TYPE_SCHAR; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
462 else if (flags & 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
463 type = TYPE_SHORT; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
464 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
465 type = TYPE_INT; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
466 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
467 case 'o': case 'u': case 'x': case 'X': |
8051
9c2b0396b27c
Stylistic change: Use '#if HAVE_*' instead of '#ifdef HAVE_*'.
Bruno Haible <bruno@clisp.org>
parents:
7596
diff
changeset
|
468 #if HAVE_LONG_LONG_INT |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
469 /* If 'long long' exists and is larger than 'long': */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
470 if (flags >= 16 || (flags & 4)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
471 type = TYPE_ULONGLONGINT; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
472 else |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
473 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
474 /* If 'unsigned long long' exists and is the same as |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
475 'unsigned long', we parse "llu" into TYPE_ULONGINT. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
476 if (flags >= 8) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
477 type = TYPE_ULONGINT; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
478 else if (flags & 2) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
479 type = TYPE_UCHAR; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
480 else if (flags & 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
481 type = TYPE_USHORT; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
482 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
483 type = TYPE_UINT; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
484 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
485 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
486 case 'a': case 'A': |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
487 if (flags >= 16 || (flags & 4)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
488 type = TYPE_LONGDOUBLE; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
489 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
490 type = TYPE_DOUBLE; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
491 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
492 case 'c': |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
493 if (flags >= 8) |
8051
9c2b0396b27c
Stylistic change: Use '#if HAVE_*' instead of '#ifdef HAVE_*'.
Bruno Haible <bruno@clisp.org>
parents:
7596
diff
changeset
|
494 #if HAVE_WINT_T |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
495 type = TYPE_WIDE_CHAR; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
496 #else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
497 goto error; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
498 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
499 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
500 type = TYPE_CHAR; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
501 break; |
8051
9c2b0396b27c
Stylistic change: Use '#if HAVE_*' instead of '#ifdef HAVE_*'.
Bruno Haible <bruno@clisp.org>
parents:
7596
diff
changeset
|
502 #if HAVE_WINT_T |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
503 case 'C': |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
504 type = TYPE_WIDE_CHAR; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
505 c = 'c'; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
506 break; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
507 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
508 case 's': |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
509 if (flags >= 8) |
8051
9c2b0396b27c
Stylistic change: Use '#if HAVE_*' instead of '#ifdef HAVE_*'.
Bruno Haible <bruno@clisp.org>
parents:
7596
diff
changeset
|
510 #if HAVE_WCHAR_T |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
511 type = TYPE_WIDE_STRING; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
512 #else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
513 goto error; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
514 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
515 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
516 type = TYPE_STRING; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
517 break; |
8051
9c2b0396b27c
Stylistic change: Use '#if HAVE_*' instead of '#ifdef HAVE_*'.
Bruno Haible <bruno@clisp.org>
parents:
7596
diff
changeset
|
518 #if HAVE_WCHAR_T |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
519 case 'S': |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
520 type = TYPE_WIDE_STRING; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
521 c = 's'; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
522 break; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
523 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
524 case 'p': |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
525 type = TYPE_POINTER; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
526 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
527 case 'n': |
8051
9c2b0396b27c
Stylistic change: Use '#if HAVE_*' instead of '#ifdef HAVE_*'.
Bruno Haible <bruno@clisp.org>
parents:
7596
diff
changeset
|
528 #if HAVE_LONG_LONG_INT |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
529 /* If 'long long' exists and is larger than 'long': */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
530 if (flags >= 16 || (flags & 4)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
531 type = TYPE_COUNT_LONGLONGINT_POINTER; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
532 else |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
533 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
534 /* If 'long long' exists and is the same as 'long', we parse |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
535 "lln" into TYPE_COUNT_LONGINT_POINTER. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
536 if (flags >= 8) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
537 type = TYPE_COUNT_LONGINT_POINTER; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
538 else if (flags & 2) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
539 type = TYPE_COUNT_SCHAR_POINTER; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
540 else if (flags & 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
541 type = TYPE_COUNT_SHORT_POINTER; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
542 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
543 type = TYPE_COUNT_INT_POINTER; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
544 break; |
8973
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
545 #if ENABLE_UNISTDIO |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
546 /* The unistdio extensions. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
547 case 'U': |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
548 if (flags >= 16) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
549 type = TYPE_U32_STRING; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
550 else if (flags >= 8) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
551 type = TYPE_U16_STRING; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
552 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
553 type = TYPE_U8_STRING; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
554 break; |
8973
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
555 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
556 case '%': |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
557 type = TYPE_NONE; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
558 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
559 default: |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
560 /* Unknown conversion character. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
561 goto error; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
562 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
563 } |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
564 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
565 if (type != TYPE_NONE) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
566 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
567 dp->arg_index = arg_index; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
568 if (dp->arg_index == ARG_NONE) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
569 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
570 dp->arg_index = arg_posn++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
571 if (dp->arg_index == ARG_NONE) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
572 /* arg_posn wrapped around. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
573 goto error; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
574 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
575 REGISTER_ARG (dp->arg_index, type); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
576 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
577 dp->conversion = c; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
578 dp->dir_end = cp; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
579 } |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
580 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
581 d->count++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
582 if (d->count >= d_allocated) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
583 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
584 size_t memory_size; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
585 DIRECTIVE *memory; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
586 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
587 d_allocated = xtimes (d_allocated, 2); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
588 memory_size = xtimes (d_allocated, sizeof (DIRECTIVE)); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
589 if (size_overflow_p (memory_size)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
590 /* Overflow, would lead to out of memory. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
591 goto out_of_memory; |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
592 memory = (DIRECTIVE *) (d->dir != d->direct_alloc_dir |
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
593 ? realloc (d->dir, memory_size) |
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
594 : malloc (memory_size)); |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
595 if (memory == NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
596 /* Out of memory. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
597 goto out_of_memory; |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
598 if (d->dir == d->direct_alloc_dir) |
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
599 memcpy (memory, d->dir, d->count * sizeof (DIRECTIVE)); |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
600 d->dir = memory; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
601 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
602 } |
8973
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
603 #if CHAR_T_ONLY_ASCII |
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
604 else if (!c_isascii (c)) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
605 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
606 /* Non-ASCII character. Not supported. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
607 goto error; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9588
diff
changeset
|
608 } |
8973
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
609 #endif |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
610 } |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
611 d->dir[d->count].dir_start = cp; |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
612 |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
613 d->max_width_length = max_width_length; |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
614 d->max_precision_length = max_precision_length; |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
615 return 0; |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
616 |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
617 error: |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
618 if (a->arg != a->direct_alloc_arg) |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
619 free (a->arg); |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
620 if (d->dir != d->direct_alloc_dir) |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
621 free (d->dir); |
9438
290aa46b4526
Fix out-of-memory handling of vasnprintf.
Bruno Haible <bruno@clisp.org>
parents:
9384
diff
changeset
|
622 errno = EINVAL; |
290aa46b4526
Fix out-of-memory handling of vasnprintf.
Bruno Haible <bruno@clisp.org>
parents:
9384
diff
changeset
|
623 return -1; |
290aa46b4526
Fix out-of-memory handling of vasnprintf.
Bruno Haible <bruno@clisp.org>
parents:
9384
diff
changeset
|
624 |
290aa46b4526
Fix out-of-memory handling of vasnprintf.
Bruno Haible <bruno@clisp.org>
parents:
9384
diff
changeset
|
625 out_of_memory: |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
626 if (a->arg != a->direct_alloc_arg) |
9438
290aa46b4526
Fix out-of-memory handling of vasnprintf.
Bruno Haible <bruno@clisp.org>
parents:
9384
diff
changeset
|
627 free (a->arg); |
14260
2113f76f7b44
vasnprintf: Reduce use of malloc for small format strings.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
628 if (d->dir != d->direct_alloc_dir) |
9438
290aa46b4526
Fix out-of-memory handling of vasnprintf.
Bruno Haible <bruno@clisp.org>
parents:
9384
diff
changeset
|
629 free (d->dir); |
290aa46b4526
Fix out-of-memory handling of vasnprintf.
Bruno Haible <bruno@clisp.org>
parents:
9384
diff
changeset
|
630 errno = ENOMEM; |
4224
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
631 return -1; |
83eabea25586
New modules vasnprintf and vasprintf.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
632 } |
4871
87df35000dab
Merge support for wide characters, from GNU gettext.
Bruno Haible <bruno@clisp.org>
parents:
4440
diff
changeset
|
633 |
8973
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
634 #undef PRINTF_PARSE |
4871
87df35000dab
Merge support for wide characters, from GNU gettext.
Bruno Haible <bruno@clisp.org>
parents:
4440
diff
changeset
|
635 #undef DIRECTIVES |
87df35000dab
Merge support for wide characters, from GNU gettext.
Bruno Haible <bruno@clisp.org>
parents:
4440
diff
changeset
|
636 #undef DIRECTIVE |
8973
7df86a1985e4
Add support for Unicode strings (both as output format and as arguments to
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
637 #undef CHAR_T_ONLY_ASCII |
4871
87df35000dab
Merge support for wide characters, from GNU gettext.
Bruno Haible <bruno@clisp.org>
parents:
4440
diff
changeset
|
638 #undef CHAR_T |