git-svn-id: file:///home/git/hedgehog.fhcrc.org/bioconductor/trunk/madman/Rpacks/seqbias@52495 bc3139a8-67e5-0310-9ffc-ced21a209358
... | ... |
@@ -118,8 +118,7 @@ configure:2948: result: yes |
118 | 118 |
configure:2948: checking for pow |
119 | 119 |
configure:2948: gcc -o conftest -g -O2 conftest.c -lz >&5 |
120 | 120 |
conftest.c:35: warning: conflicting types for built-in function 'pow' |
121 |
-/tmp/cc2oJinr.o: In function `main': |
|
122 |
-/tmp/ccFHWg6Y.o: In function `main': |
|
121 |
+/tmp/ccoIQCRB.o: In function `main': |
|
123 | 122 |
/home/dcjones/bio/seqbias/conftest.c:46: undefined reference to `pow' |
124 | 123 |
collect2: ld returned 1 exit status |
125 | 124 |
configure:2948: $? = 1 |
... | ... |
@@ -177,11 +176,7 @@ configure:2948: result: no |
177 | 176 |
configure:2948: checking for sqrt |
178 | 177 |
configure:2948: gcc -o conftest -g -O2 conftest.c -lz >&5 |
179 | 178 |
conftest.c:35: warning: conflicting types for built-in function 'sqrt' |
180 |
-<<<<<<< HEAD |
|
181 |
-/tmp/ccFdFAsw.o: In function `main': |
|
182 |
-======= |
|
183 |
-/tmp/ccgUY6M3.o: In function `main': |
|
184 |
->>>>>>> working |
|
179 |
+/tmp/ccAAPyGF.o: In function `main': |
|
185 | 180 |
/home/dcjones/bio/seqbias/conftest.c:46: undefined reference to `sqrt' |
186 | 181 |
collect2: ld returned 1 exit status |
187 | 182 |
configure:2948: $? = 1 |
... | ... |
@@ -10,7 +10,8 @@ YAML_CPP_OBJ = aliascontent.o conversion.o emitter.o emitterstate.o \ |
10 | 10 |
|
11 | 11 |
SEQBIAS_OBJ = sequencing_bias.o kmers.o miscmath.o common.o \ |
12 | 12 |
table.o superfasthash.o logger.o seqbias.o \ |
13 |
- snprintf.o |
|
13 |
+ |
|
14 |
+GNULIB_OBJ = asprintf.o printf-args.o printf-parse.o vasnprintf.o vasprintf.o |
|
14 | 15 |
|
15 | 16 |
DFLAGS = -D_USE_KNETFILE -D_FILE_OFFSET_BITS=64 |
16 | 17 |
PKG_CFLAGS += $(DFLAGS) -Wall |
... | ... |
@@ -1,10 +1,13 @@ |
1 | 1 |
|
2 |
-PKG_LIBS+=-$(ZLIB_LIBS) -lws2_32 |
|
3 |
-PKG_CFLAGS+=-D_LARGEFILE64_SOURCE |
|
2 |
+PKG_LIBS+=$(ZLIB_LIBS) -lws2_32 |
|
3 |
+PKG_CFLAGS+=-D_LARGEFILE64_SOURCE -DNEED_ASPRINTF |
|
4 | 4 |
|
5 | 5 |
include Makevars.common |
6 | 6 |
|
7 |
-OBJECTS = $(SEQBIAS_OBJ) $(SAMTOOLS_OBJ:%=samtools/%) $(YAML_CPP_OBJ:%=yaml-cpp/%) |
|
7 |
+OBJECTS = $(SEQBIAS_OBJ) \ |
|
8 |
+ $(SAMTOOLS_OBJ:%=samtools/%) \ |
|
9 |
+ $(YAML_CPP_OBJ:%=yaml-cpp/%) \ |
|
10 |
+ $(GNULIB_OBJ:%=gnulib/%) |
|
8 | 11 |
|
9 | 12 |
all : $(SHLIB) |
10 | 13 |
|
11 | 14 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,26 @@ |
1 |
+ |
|
2 |
+ |
|
3 |
+ |
|
4 |
+#ifndef ASPRINTF_INC |
|
5 |
+#define ASPRINTF_INC |
|
6 |
+ |
|
7 |
+#ifdef __cplusplus |
|
8 |
+extern "C" { |
|
9 |
+#endif |
|
10 |
+ |
|
11 |
+#ifndef NEED_ASPRINTF |
|
12 |
+#include <stdio.h> |
|
13 |
+#else |
|
14 |
+int asprintf (char **resultp, const char *format, ...); |
|
15 |
+/* defined in gnulib/asprintf.c */ |
|
16 |
+#endif |
|
17 |
+ |
|
18 |
+ |
|
19 |
+#ifdef __cplusplus |
|
20 |
+} |
|
21 |
+#endif |
|
22 |
+ |
|
23 |
+#endif |
|
24 |
+ |
|
25 |
+ |
|
26 |
+ |
0 | 27 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,40 @@ |
1 |
+/* Formatted output to strings. |
|
2 |
+ Copyright (C) 1999, 2002, 2006-2007, 2009-2011 Free Software Foundation, |
|
3 |
+ Inc. |
|
4 |
+ |
|
5 |
+ This program is free software; you can redistribute it and/or modify |
|
6 |
+ it under the terms of the GNU General Public License as published by |
|
7 |
+ the Free Software Foundation; either version 2, or (at your option) |
|
8 |
+ any later version. |
|
9 |
+ |
|
10 |
+ This program 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 |
|
13 |
+ GNU General Public License for more details. |
|
14 |
+ |
|
15 |
+ You should have received a copy of the GNU General Public License along |
|
16 |
+ with this program; if not, write to the Free Software Foundation, |
|
17 |
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
|
18 |
+ |
|
19 |
+/*#include <config.h>*/ |
|
20 |
+ |
|
21 |
+/* Specification. */ |
|
22 |
+#ifdef IN_LIBASPRINTF |
|
23 |
+# include "vasprintf.h" |
|
24 |
+#else |
|
25 |
+# include <stdio.h> |
|
26 |
+#endif |
|
27 |
+ |
|
28 |
+#include <stdarg.h> |
|
29 |
+ |
|
30 |
+int |
|
31 |
+asprintf (char **resultp, const char *format, ...) |
|
32 |
+{ |
|
33 |
+ va_list args; |
|
34 |
+ int result; |
|
35 |
+ |
|
36 |
+ va_start (args, format); |
|
37 |
+ result = vasprintf (resultp, format, args); |
|
38 |
+ va_end (args); |
|
39 |
+ return result; |
|
40 |
+} |
0 | 41 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,188 @@ |
1 |
+/* Decomposed printf argument list. |
|
2 |
+ Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2011 Free Software |
|
3 |
+ Foundation, Inc. |
|
4 |
+ |
|
5 |
+ This program is free software; you can redistribute it and/or modify |
|
6 |
+ it under the terms of the GNU General Public License as published by |
|
7 |
+ the Free Software Foundation; either version 2, or (at your option) |
|
8 |
+ any later version. |
|
9 |
+ |
|
10 |
+ This program 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 |
|
13 |
+ GNU General Public License for more details. |
|
14 |
+ |
|
15 |
+ You should have received a copy of the GNU General Public License along |
|
16 |
+ with this program; if not, write to the Free Software Foundation, |
|
17 |
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
|
18 |
+ |
|
19 |
+/* This file can be parametrized with the following macros: |
|
20 |
+ ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. |
|
21 |
+ PRINTF_FETCHARGS Name of the function to be defined. |
|
22 |
+ STATIC Set to 'static' to declare the function static. */ |
|
23 |
+ |
|
24 |
+#ifndef PRINTF_FETCHARGS |
|
25 |
+/*# include <config.h>*/ |
|
26 |
+#endif |
|
27 |
+ |
|
28 |
+/* Specification. */ |
|
29 |
+#ifndef PRINTF_FETCHARGS |
|
30 |
+# include "printf-args.h" |
|
31 |
+#endif |
|
32 |
+ |
|
33 |
+#ifdef STATIC |
|
34 |
+STATIC |
|
35 |
+#endif |
|
36 |
+int |
|
37 |
+PRINTF_FETCHARGS (va_list args, arguments *a) |
|
38 |
+{ |
|
39 |
+ size_t i; |
|
40 |
+ argument *ap; |
|
41 |
+ |
|
42 |
+ for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++) |
|
43 |
+ switch (ap->type) |
|
44 |
+ { |
|
45 |
+ case TYPE_SCHAR: |
|
46 |
+ ap->a.a_schar = va_arg (args, /*signed char*/ int); |
|
47 |
+ break; |
|
48 |
+ case TYPE_UCHAR: |
|
49 |
+ ap->a.a_uchar = va_arg (args, /*unsigned char*/ int); |
|
50 |
+ break; |
|
51 |
+ case TYPE_SHORT: |
|
52 |
+ ap->a.a_short = va_arg (args, /*short*/ int); |
|
53 |
+ break; |
|
54 |
+ case TYPE_USHORT: |
|
55 |
+ ap->a.a_ushort = va_arg (args, /*unsigned short*/ int); |
|
56 |
+ break; |
|
57 |
+ case TYPE_INT: |
|
58 |
+ ap->a.a_int = va_arg (args, int); |
|
59 |
+ break; |
|
60 |
+ case TYPE_UINT: |
|
61 |
+ ap->a.a_uint = va_arg (args, unsigned int); |
|
62 |
+ break; |
|
63 |
+ case TYPE_LONGINT: |
|
64 |
+ ap->a.a_longint = va_arg (args, long int); |
|
65 |
+ break; |
|
66 |
+ case TYPE_ULONGINT: |
|
67 |
+ ap->a.a_ulongint = va_arg (args, unsigned long int); |
|
68 |
+ break; |
|
69 |
+#if HAVE_LONG_LONG_INT |
|
70 |
+ case TYPE_LONGLONGINT: |
|
71 |
+ ap->a.a_longlongint = va_arg (args, long long int); |
|
72 |
+ break; |
|
73 |
+ case TYPE_ULONGLONGINT: |
|
74 |
+ ap->a.a_ulonglongint = va_arg (args, unsigned long long int); |
|
75 |
+ break; |
|
76 |
+#endif |
|
77 |
+ case TYPE_DOUBLE: |
|
78 |
+ ap->a.a_double = va_arg (args, double); |
|
79 |
+ break; |
|
80 |
+ case TYPE_LONGDOUBLE: |
|
81 |
+ ap->a.a_longdouble = va_arg (args, long double); |
|
82 |
+ break; |
|
83 |
+ case TYPE_CHAR: |
|
84 |
+ ap->a.a_char = va_arg (args, int); |
|
85 |
+ break; |
|
86 |
+#if HAVE_WINT_T |
|
87 |
+ case TYPE_WIDE_CHAR: |
|
88 |
+ /* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by |
|
89 |
+ default argument promotions", this is not the case in mingw32, |
|
90 |
+ where wint_t is 'unsigned short'. */ |
|
91 |
+ ap->a.a_wide_char = |
|
92 |
+ (sizeof (wint_t) < sizeof (int) |
|
93 |
+ ? (wint_t) va_arg (args, int) |
|
94 |
+ : va_arg (args, wint_t)); |
|
95 |
+ break; |
|
96 |
+#endif |
|
97 |
+ case TYPE_STRING: |
|
98 |
+ ap->a.a_string = va_arg (args, const char *); |
|
99 |
+ /* A null pointer is an invalid argument for "%s", but in practice |
|
100 |
+ it occurs quite frequently in printf statements that produce |
|
101 |
+ debug output. Use a fallback in this case. */ |
|
102 |
+ if (ap->a.a_string == NULL) |
|
103 |
+ ap->a.a_string = "(NULL)"; |
|
104 |
+ break; |
|
105 |
+#if HAVE_WCHAR_T |
|
106 |
+ case TYPE_WIDE_STRING: |
|
107 |
+ ap->a.a_wide_string = va_arg (args, const wchar_t *); |
|
108 |
+ /* A null pointer is an invalid argument for "%ls", but in practice |
|
109 |
+ it occurs quite frequently in printf statements that produce |
|
110 |
+ debug output. Use a fallback in this case. */ |
|
111 |
+ if (ap->a.a_wide_string == NULL) |
|
112 |
+ { |
|
113 |
+ static const wchar_t wide_null_string[] = |
|
114 |
+ { |
|
115 |
+ (wchar_t)'(', |
|
116 |
+ (wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L', |
|
117 |
+ (wchar_t)')', |
|
118 |
+ (wchar_t)0 |
|
119 |
+ }; |
|
120 |
+ ap->a.a_wide_string = wide_null_string; |
|
121 |
+ } |
|
122 |
+ break; |
|
123 |
+#endif |
|
124 |
+ case TYPE_POINTER: |
|
125 |
+ ap->a.a_pointer = va_arg (args, void *); |
|
126 |
+ break; |
|
127 |
+ case TYPE_COUNT_SCHAR_POINTER: |
|
128 |
+ ap->a.a_count_schar_pointer = va_arg (args, signed char *); |
|
129 |
+ break; |
|
130 |
+ case TYPE_COUNT_SHORT_POINTER: |
|
131 |
+ ap->a.a_count_short_pointer = va_arg (args, short *); |
|
132 |
+ break; |
|
133 |
+ case TYPE_COUNT_INT_POINTER: |
|
134 |
+ ap->a.a_count_int_pointer = va_arg (args, int *); |
|
135 |
+ break; |
|
136 |
+ case TYPE_COUNT_LONGINT_POINTER: |
|
137 |
+ ap->a.a_count_longint_pointer = va_arg (args, long int *); |
|
138 |
+ break; |
|
139 |
+#if HAVE_LONG_LONG_INT |
|
140 |
+ case TYPE_COUNT_LONGLONGINT_POINTER: |
|
141 |
+ ap->a.a_count_longlongint_pointer = va_arg (args, long long int *); |
|
142 |
+ break; |
|
143 |
+#endif |
|
144 |
+#if ENABLE_UNISTDIO |
|
145 |
+ /* The unistdio extensions. */ |
|
146 |
+ case TYPE_U8_STRING: |
|
147 |
+ ap->a.a_u8_string = va_arg (args, const uint8_t *); |
|
148 |
+ /* A null pointer is an invalid argument for "%U", but in practice |
|
149 |
+ it occurs quite frequently in printf statements that produce |
|
150 |
+ debug output. Use a fallback in this case. */ |
|
151 |
+ if (ap->a.a_u8_string == NULL) |
|
152 |
+ { |
|
153 |
+ static const uint8_t u8_null_string[] = |
|
154 |
+ { '(', 'N', 'U', 'L', 'L', ')', 0 }; |
|
155 |
+ ap->a.a_u8_string = u8_null_string; |
|
156 |
+ } |
|
157 |
+ break; |
|
158 |
+ case TYPE_U16_STRING: |
|
159 |
+ ap->a.a_u16_string = va_arg (args, const uint16_t *); |
|
160 |
+ /* A null pointer is an invalid argument for "%lU", but in practice |
|
161 |
+ it occurs quite frequently in printf statements that produce |
|
162 |
+ debug output. Use a fallback in this case. */ |
|
163 |
+ if (ap->a.a_u16_string == NULL) |
|
164 |
+ { |
|
165 |
+ static const uint16_t u16_null_string[] = |
|
166 |
+ { '(', 'N', 'U', 'L', 'L', ')', 0 }; |
|
167 |
+ ap->a.a_u16_string = u16_null_string; |
|
168 |
+ } |
|
169 |
+ break; |
|
170 |
+ case TYPE_U32_STRING: |
|
171 |
+ ap->a.a_u32_string = va_arg (args, const uint32_t *); |
|
172 |
+ /* A null pointer is an invalid argument for "%llU", but in practice |
|
173 |
+ it occurs quite frequently in printf statements that produce |
|
174 |
+ debug output. Use a fallback in this case. */ |
|
175 |
+ if (ap->a.a_u32_string == NULL) |
|
176 |
+ { |
|
177 |
+ static const uint32_t u32_null_string[] = |
|
178 |
+ { '(', 'N', 'U', 'L', 'L', ')', 0 }; |
|
179 |
+ ap->a.a_u32_string = u32_null_string; |
|
180 |
+ } |
|
181 |
+ break; |
|
182 |
+#endif |
|
183 |
+ default: |
|
184 |
+ /* Unknown type. */ |
|
185 |
+ return -1; |
|
186 |
+ } |
|
187 |
+ return 0; |
|
188 |
+} |
0 | 189 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,159 @@ |
1 |
+/* Decomposed printf argument list. |
|
2 |
+ Copyright (C) 1999, 2002-2003, 2006-2007, 2011 Free Software |
|
3 |
+ Foundation, Inc. |
|
4 |
+ |
|
5 |
+ This program is free software; you can redistribute it and/or modify |
|
6 |
+ it under the terms of the GNU General Public License as published by |
|
7 |
+ the Free Software Foundation; either version 2, or (at your option) |
|
8 |
+ any later version. |
|
9 |
+ |
|
10 |
+ This program 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 |
|
13 |
+ GNU General Public License for more details. |
|
14 |
+ |
|
15 |
+ You should have received a copy of the GNU General Public License along |
|
16 |
+ with this program; if not, write to the Free Software Foundation, |
|
17 |
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
|
18 |
+ |
|
19 |
+#ifndef _PRINTF_ARGS_H |
|
20 |
+#define _PRINTF_ARGS_H |
|
21 |
+ |
|
22 |
+/* This file can be parametrized with the following macros: |
|
23 |
+ ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. |
|
24 |
+ PRINTF_FETCHARGS Name of the function to be declared. |
|
25 |
+ STATIC Set to 'static' to declare the function static. */ |
|
26 |
+ |
|
27 |
+/* Default parameters. */ |
|
28 |
+#ifndef PRINTF_FETCHARGS |
|
29 |
+# define PRINTF_FETCHARGS printf_fetchargs |
|
30 |
+#endif |
|
31 |
+ |
|
32 |
+/* Get size_t. */ |
|
33 |
+#include <stddef.h> |
|
34 |
+ |
|
35 |
+/* Get wchar_t. */ |
|
36 |
+#if HAVE_WCHAR_T |
|
37 |
+# include <stddef.h> |
|
38 |
+#endif |
|
39 |
+ |
|
40 |
+/* Get wint_t. */ |
|
41 |
+#if HAVE_WINT_T |
|
42 |
+# include <wchar.h> |
|
43 |
+#endif |
|
44 |
+ |
|
45 |
+/* Get va_list. */ |
|
46 |
+#include <stdarg.h> |
|
47 |
+ |
|
48 |
+ |
|
49 |
+/* Argument types */ |
|
50 |
+typedef enum |
|
51 |
+{ |
|
52 |
+ TYPE_NONE, |
|
53 |
+ TYPE_SCHAR, |
|
54 |
+ TYPE_UCHAR, |
|
55 |
+ TYPE_SHORT, |
|
56 |
+ TYPE_USHORT, |
|
57 |
+ TYPE_INT, |
|
58 |
+ TYPE_UINT, |
|
59 |
+ TYPE_LONGINT, |
|
60 |
+ TYPE_ULONGINT, |
|
61 |
+#if HAVE_LONG_LONG_INT |
|
62 |
+ TYPE_LONGLONGINT, |
|
63 |
+ TYPE_ULONGLONGINT, |
|
64 |
+#endif |
|
65 |
+ TYPE_DOUBLE, |
|
66 |
+ TYPE_LONGDOUBLE, |
|
67 |
+ TYPE_CHAR, |
|
68 |
+#if HAVE_WINT_T |
|
69 |
+ TYPE_WIDE_CHAR, |
|
70 |
+#endif |
|
71 |
+ TYPE_STRING, |
|
72 |
+#if HAVE_WCHAR_T |
|
73 |
+ TYPE_WIDE_STRING, |
|
74 |
+#endif |
|
75 |
+ TYPE_POINTER, |
|
76 |
+ TYPE_COUNT_SCHAR_POINTER, |
|
77 |
+ TYPE_COUNT_SHORT_POINTER, |
|
78 |
+ TYPE_COUNT_INT_POINTER, |
|
79 |
+ TYPE_COUNT_LONGINT_POINTER |
|
80 |
+#if HAVE_LONG_LONG_INT |
|
81 |
+, TYPE_COUNT_LONGLONGINT_POINTER |
|
82 |
+#endif |
|
83 |
+#if ENABLE_UNISTDIO |
|
84 |
+ /* The unistdio extensions. */ |
|
85 |
+, TYPE_U8_STRING |
|
86 |
+, TYPE_U16_STRING |
|
87 |
+, TYPE_U32_STRING |
|
88 |
+#endif |
|
89 |
+} arg_type; |
|
90 |
+ |
|
91 |
+/* Polymorphic argument */ |
|
92 |
+typedef struct |
|
93 |
+{ |
|
94 |
+ arg_type type; |
|
95 |
+ union |
|
96 |
+ { |
|
97 |
+ signed char a_schar; |
|
98 |
+ unsigned char a_uchar; |
|
99 |
+ short a_short; |
|
100 |
+ unsigned short a_ushort; |
|
101 |
+ int a_int; |
|
102 |
+ unsigned int a_uint; |
|
103 |
+ long int a_longint; |
|
104 |
+ unsigned long int a_ulongint; |
|
105 |
+#if HAVE_LONG_LONG_INT |
|
106 |
+ long long int a_longlongint; |
|
107 |
+ unsigned long long int a_ulonglongint; |
|
108 |
+#endif |
|
109 |
+ float a_float; |
|
110 |
+ double a_double; |
|
111 |
+ long double a_longdouble; |
|
112 |
+ int a_char; |
|
113 |
+#if HAVE_WINT_T |
|
114 |
+ wint_t a_wide_char; |
|
115 |
+#endif |
|
116 |
+ const char* a_string; |
|
117 |
+#if HAVE_WCHAR_T |
|
118 |
+ const wchar_t* a_wide_string; |
|
119 |
+#endif |
|
120 |
+ void* a_pointer; |
|
121 |
+ signed char * a_count_schar_pointer; |
|
122 |
+ short * a_count_short_pointer; |
|
123 |
+ int * a_count_int_pointer; |
|
124 |
+ long int * a_count_longint_pointer; |
|
125 |
+#if HAVE_LONG_LONG_INT |
|
126 |
+ long long int * a_count_longlongint_pointer; |
|
127 |
+#endif |
|
128 |
+#if ENABLE_UNISTDIO |
|
129 |
+ /* The unistdio extensions. */ |
|
130 |
+ const uint8_t * a_u8_string; |
|
131 |
+ const uint16_t * a_u16_string; |
|
132 |
+ const uint32_t * a_u32_string; |
|
133 |
+#endif |
|
134 |
+ } |
|
135 |
+ a; |
|
136 |
+} |
|
137 |
+argument; |
|
138 |
+ |
|
139 |
+/* Number of directly allocated arguments (no malloc() needed). */ |
|
140 |
+#define N_DIRECT_ALLOC_ARGUMENTS 7 |
|
141 |
+ |
|
142 |
+typedef struct |
|
143 |
+{ |
|
144 |
+ size_t count; |
|
145 |
+ argument *arg; |
|
146 |
+ argument direct_alloc_arg[N_DIRECT_ALLOC_ARGUMENTS]; |
|
147 |
+} |
|
148 |
+arguments; |
|
149 |
+ |
|
150 |
+ |
|
151 |
+/* Fetch the arguments, putting them into a. */ |
|
152 |
+#ifdef STATIC |
|
153 |
+STATIC |
|
154 |
+#else |
|
155 |
+extern |
|
156 |
+#endif |
|
157 |
+int PRINTF_FETCHARGS (va_list args, arguments *a); |
|
158 |
+ |
|
159 |
+#endif /* _PRINTF_ARGS_H */ |
0 | 160 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,639 @@ |
1 |
+/* Formatted output to strings. |
|
2 |
+ Copyright (C) 1999-2000, 2002-2003, 2006-2011 Free Software Foundation, Inc. |
|
3 |
+ |
|
4 |
+ This program is free software; you can redistribute it and/or modify |
|
5 |
+ it under the terms of the GNU General Public License as published by |
|
6 |
+ the Free Software Foundation; either version 2, or (at your option) |
|
7 |
+ any later version. |
|
8 |
+ |
|
9 |
+ This program is distributed in the hope that it will be useful, |
|
10 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
+ GNU General Public License for more details. |
|
13 |
+ |
|
14 |
+ You should have received a copy of the GNU General Public License along |
|
15 |
+ with this program; if not, write to the Free Software Foundation, |
|
16 |
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
|
17 |
+ |
|
18 |
+/* This file can be parametrized with the following macros: |
|
19 |
+ CHAR_T The element type of the format string. |
|
20 |
+ CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters |
|
21 |
+ in the format string are ASCII. |
|
22 |
+ DIRECTIVE Structure denoting a format directive. |
|
23 |
+ Depends on CHAR_T. |
|
24 |
+ DIRECTIVES Structure denoting the set of format directives of a |
|
25 |
+ format string. Depends on CHAR_T. |
|
26 |
+ PRINTF_PARSE Function that parses a format string. |
|
27 |
+ Depends on CHAR_T. |
|
28 |
+ STATIC Set to 'static' to declare the function static. |
|
29 |
+ ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. */ |
|
30 |
+ |
|
31 |
+#ifndef PRINTF_PARSE |
|
32 |
+/*# include <config.h>*/ |
|
33 |
+#endif |
|
34 |
+ |
|
35 |
+/* Specification. */ |
|
36 |
+#ifndef PRINTF_PARSE |
|
37 |
+# include "printf-parse.h" |
|
38 |
+#endif |
|
39 |
+ |
|
40 |
+/* Default parameters. */ |
|
41 |
+#ifndef PRINTF_PARSE |
|
42 |
+# define PRINTF_PARSE printf_parse |
|
43 |
+# define CHAR_T char |
|
44 |
+# define DIRECTIVE char_directive |
|
45 |
+# define DIRECTIVES char_directives |
|
46 |
+#endif |
|
47 |
+ |
|
48 |
+/* Get size_t, NULL. */ |
|
49 |
+#include <stddef.h> |
|
50 |
+ |
|
51 |
+/* Get intmax_t. */ |
|
52 |
+#if defined IN_LIBINTL || defined IN_LIBASPRINTF |
|
53 |
+# if HAVE_STDINT_H_WITH_UINTMAX |
|
54 |
+# include <stdint.h> |
|
55 |
+# endif |
|
56 |
+# if HAVE_INTTYPES_H_WITH_UINTMAX |
|
57 |
+# include <inttypes.h> |
|
58 |
+# endif |
|
59 |
+#else |
|
60 |
+# include <stdint.h> |
|
61 |
+#endif |
|
62 |
+ |
|
63 |
+/* malloc(), realloc(), free(). */ |
|
64 |
+#include <stdlib.h> |
|
65 |
+ |
|
66 |
+/* memcpy(). */ |
|
67 |
+#include <string.h> |
|
68 |
+ |
|
69 |
+/* errno. */ |
|
70 |
+#include <errno.h> |
|
71 |
+ |
|
72 |
+/* Checked size_t computations. */ |
|
73 |
+#include "xsize.h" |
|
74 |
+ |
|
75 |
+#if CHAR_T_ONLY_ASCII |
|
76 |
+/* c_isascii(). */ |
|
77 |
+# include "c-ctype.h" |
|
78 |
+#endif |
|
79 |
+ |
|
80 |
+#ifdef STATIC |
|
81 |
+STATIC |
|
82 |
+#endif |
|
83 |
+int |
|
84 |
+PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) |
|
85 |
+{ |
|
86 |
+ const CHAR_T *cp = format; /* pointer into format */ |
|
87 |
+ size_t arg_posn = 0; /* number of regular arguments consumed */ |
|
88 |
+ size_t d_allocated; /* allocated elements of d->dir */ |
|
89 |
+ size_t a_allocated; /* allocated elements of a->arg */ |
|
90 |
+ size_t max_width_length = 0; |
|
91 |
+ size_t max_precision_length = 0; |
|
92 |
+ |
|
93 |
+ d->count = 0; |
|
94 |
+ d_allocated = N_DIRECT_ALLOC_DIRECTIVES; |
|
95 |
+ d->dir = d->direct_alloc_dir; |
|
96 |
+ |
|
97 |
+ a->count = 0; |
|
98 |
+ a_allocated = N_DIRECT_ALLOC_ARGUMENTS; |
|
99 |
+ a->arg = a->direct_alloc_arg; |
|
100 |
+ |
|
101 |
+#define REGISTER_ARG(_index_,_type_) \ |
|
102 |
+ { \ |
|
103 |
+ size_t n = (_index_); \ |
|
104 |
+ if (n >= a_allocated) \ |
|
105 |
+ { \ |
|
106 |
+ size_t memory_size; \ |
|
107 |
+ argument *memory; \ |
|
108 |
+ \ |
|
109 |
+ a_allocated = xtimes (a_allocated, 2); \ |
|
110 |
+ if (a_allocated <= n) \ |
|
111 |
+ a_allocated = xsum (n, 1); \ |
|
112 |
+ memory_size = xtimes (a_allocated, sizeof (argument)); \ |
|
113 |
+ if (size_overflow_p (memory_size)) \ |
|
114 |
+ /* Overflow, would lead to out of memory. */ \ |
|
115 |
+ goto out_of_memory; \ |
|
116 |
+ memory = (argument *) (a->arg != a->direct_alloc_arg \ |
|
117 |
+ ? realloc (a->arg, memory_size) \ |
|
118 |
+ : malloc (memory_size)); \ |
|
119 |
+ if (memory == NULL) \ |
|
120 |
+ /* Out of memory. */ \ |
|
121 |
+ goto out_of_memory; \ |
|
122 |
+ if (a->arg == a->direct_alloc_arg) \ |
|
123 |
+ memcpy (memory, a->arg, a->count * sizeof (argument)); \ |
|
124 |
+ a->arg = memory; \ |
|
125 |
+ } \ |
|
126 |
+ while (a->count <= n) \ |
|
127 |
+ a->arg[a->count++].type = TYPE_NONE; \ |
|
128 |
+ if (a->arg[n].type == TYPE_NONE) \ |
|
129 |
+ a->arg[n].type = (_type_); \ |
|
130 |
+ else if (a->arg[n].type != (_type_)) \ |
|
131 |
+ /* Ambiguous type for positional argument. */ \ |
|
132 |
+ goto error; \ |
|
133 |
+ } |
|
134 |
+ |
|
135 |
+ while (*cp != '\0') |
|
136 |
+ { |
|
137 |
+ CHAR_T c = *cp++; |
|
138 |
+ if (c == '%') |
|
139 |
+ { |
|
140 |
+ size_t arg_index = ARG_NONE; |
|
141 |
+ DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */ |
|
142 |
+ |
|
143 |
+ /* Initialize the next directive. */ |
|
144 |
+ dp->dir_start = cp - 1; |
|
145 |
+ dp->flags = 0; |
|
146 |
+ dp->width_start = NULL; |
|
147 |
+ dp->width_end = NULL; |
|
148 |
+ dp->width_arg_index = ARG_NONE; |
|
149 |
+ dp->precision_start = NULL; |
|
150 |
+ dp->precision_end = NULL; |
|
151 |
+ dp->precision_arg_index = ARG_NONE; |
|
152 |
+ dp->arg_index = ARG_NONE; |
|
153 |
+ |
|
154 |
+ /* Test for positional argument. */ |
|
155 |
+ if (*cp >= '0' && *cp <= '9') |
|
156 |
+ { |
|
157 |
+ const CHAR_T *np; |
|
158 |
+ |
|
159 |
+ for (np = cp; *np >= '0' && *np <= '9'; np++) |
|
160 |
+ ; |
|
161 |
+ if (*np == '$') |
|
162 |
+ { |
|
163 |
+ size_t n = 0; |
|
164 |
+ |
|
165 |
+ for (np = cp; *np >= '0' && *np <= '9'; np++) |
|
166 |
+ n = xsum (xtimes (n, 10), *np - '0'); |
|
167 |
+ if (n == 0) |
|
168 |
+ /* Positional argument 0. */ |
|
169 |
+ goto error; |
|
170 |
+ if (size_overflow_p (n)) |
|
171 |
+ /* n too large, would lead to out of memory later. */ |
|
172 |
+ goto error; |
|
173 |
+ arg_index = n - 1; |
|
174 |
+ cp = np + 1; |
|
175 |
+ } |
|
176 |
+ } |
|
177 |
+ |
|
178 |
+ /* Read the flags. */ |
|
179 |
+ for (;;) |
|
180 |
+ { |
|
181 |
+ if (*cp == '\'') |
|
182 |
+ { |
|
183 |
+ dp->flags |= FLAG_GROUP; |
|
184 |
+ cp++; |
|
185 |
+ } |
|
186 |
+ else if (*cp == '-') |
|
187 |
+ { |
|
188 |
+ dp->flags |= FLAG_LEFT; |
|
189 |
+ cp++; |
|
190 |
+ } |
|
191 |
+ else if (*cp == '+') |
|
192 |
+ { |
|
193 |
+ dp->flags |= FLAG_SHOWSIGN; |
|
194 |
+ cp++; |
|
195 |
+ } |
|
196 |
+ else if (*cp == ' ') |
|
197 |
+ { |
|
198 |
+ dp->flags |= FLAG_SPACE; |
|
199 |
+ cp++; |
|
200 |
+ } |
|
201 |
+ else if (*cp == '#') |
|
202 |
+ { |
|
203 |
+ dp->flags |= FLAG_ALT; |
|
204 |
+ cp++; |
|
205 |
+ } |
|
206 |
+ else if (*cp == '0') |
|
207 |
+ { |
|
208 |
+ dp->flags |= FLAG_ZERO; |
|
209 |
+ cp++; |
|
210 |
+ } |
|
211 |
+#if __GLIBC__ >= 2 && !defined __UCLIBC__ |
|
212 |
+ else if (*cp == 'I') |
|
213 |
+ { |
|
214 |
+ dp->flags |= FLAG_LOCALIZED; |
|
215 |
+ cp++; |
|
216 |
+ } |
|
217 |
+#endif |
|
218 |
+ else |
|
219 |
+ break; |
|
220 |
+ } |
|
221 |
+ |
|
222 |
+ /* Parse the field width. */ |
|
223 |
+ if (*cp == '*') |
|
224 |
+ { |
|
225 |
+ dp->width_start = cp; |
|
226 |
+ cp++; |
|
227 |
+ dp->width_end = cp; |
|
228 |
+ if (max_width_length < 1) |
|
229 |
+ max_width_length = 1; |
|
230 |
+ |
|
231 |
+ /* Test for positional argument. */ |
|
232 |
+ if (*cp >= '0' && *cp <= '9') |
|
233 |
+ { |
|
234 |
+ const CHAR_T *np; |
|
235 |
+ |
|
236 |
+ for (np = cp; *np >= '0' && *np <= '9'; np++) |
|
237 |
+ ; |
|
238 |
+ if (*np == '$') |
|
239 |
+ { |
|
240 |
+ size_t n = 0; |
|
241 |
+ |
|
242 |
+ for (np = cp; *np >= '0' && *np <= '9'; np++) |
|
243 |
+ n = xsum (xtimes (n, 10), *np - '0'); |
|
244 |
+ if (n == 0) |
|
245 |
+ /* Positional argument 0. */ |
|
246 |
+ goto error; |
|
247 |
+ if (size_overflow_p (n)) |
|
248 |
+ /* n too large, would lead to out of memory later. */ |
|
249 |
+ goto error; |
|
250 |
+ dp->width_arg_index = n - 1; |
|
251 |
+ cp = np + 1; |
|
252 |
+ } |
|
253 |
+ } |
|
254 |
+ if (dp->width_arg_index == ARG_NONE) |
|
255 |
+ { |
|
256 |
+ dp->width_arg_index = arg_posn++; |
|
257 |
+ if (dp->width_arg_index == ARG_NONE) |
|
258 |
+ /* arg_posn wrapped around. */ |
|
259 |
+ goto error; |
|
260 |
+ } |
|
261 |
+ REGISTER_ARG (dp->width_arg_index, TYPE_INT); |
|
262 |
+ } |
|
263 |
+ else if (*cp >= '0' && *cp <= '9') |
|
264 |
+ { |
|
265 |
+ size_t width_length; |
|
266 |
+ |
|
267 |
+ dp->width_start = cp; |
|
268 |
+ for (; *cp >= '0' && *cp <= '9'; cp++) |
|
269 |
+ ; |
|
270 |
+ dp->width_end = cp; |
|
271 |
+ width_length = dp->width_end - dp->width_start; |
|
272 |
+ if (max_width_length < width_length) |
|
273 |
+ max_width_length = width_length; |
|
274 |
+ } |
|
275 |
+ |
|
276 |
+ /* Parse the precision. */ |
|
277 |
+ if (*cp == '.') |
|
278 |
+ { |
|
279 |
+ cp++; |
|
280 |
+ if (*cp == '*') |
|
281 |
+ { |
|
282 |
+ dp->precision_start = cp - 1; |
|
283 |
+ cp++; |
|
284 |
+ dp->precision_end = cp; |
|
285 |
+ if (max_precision_length < 2) |
|
286 |
+ max_precision_length = 2; |
|
287 |
+ |
|
288 |
+ /* Test for positional argument. */ |
|
289 |
+ if (*cp >= '0' && *cp <= '9') |
|
290 |
+ { |
|
291 |
+ const CHAR_T *np; |
|
292 |
+ |
|
293 |
+ for (np = cp; *np >= '0' && *np <= '9'; np++) |
|
294 |
+ ; |
|
295 |
+ if (*np == '$') |
|
296 |
+ { |
|
297 |
+ size_t n = 0; |
|
298 |
+ |
|
299 |
+ for (np = cp; *np >= '0' && *np <= '9'; np++) |
|
300 |
+ n = xsum (xtimes (n, 10), *np - '0'); |
|
301 |
+ if (n == 0) |
|
302 |
+ /* Positional argument 0. */ |
|
303 |
+ goto error; |
|
304 |
+ if (size_overflow_p (n)) |
|
305 |
+ /* n too large, would lead to out of memory |
|
306 |
+ later. */ |
|
307 |
+ goto error; |
|
308 |
+ dp->precision_arg_index = n - 1; |
|
309 |
+ cp = np + 1; |
|
310 |
+ } |
|
311 |
+ } |
|
312 |
+ if (dp->precision_arg_index == ARG_NONE) |
|
313 |
+ { |
|
314 |
+ dp->precision_arg_index = arg_posn++; |
|
315 |
+ if (dp->precision_arg_index == ARG_NONE) |
|
316 |
+ /* arg_posn wrapped around. */ |
|
317 |
+ goto error; |
|
318 |
+ } |
|
319 |
+ REGISTER_ARG (dp->precision_arg_index, TYPE_INT); |
|
320 |
+ } |
|
321 |
+ else |
|
322 |
+ { |
|
323 |
+ size_t precision_length; |
|
324 |
+ |
|
325 |
+ dp->precision_start = cp - 1; |
|
326 |
+ for (; *cp >= '0' && *cp <= '9'; cp++) |
|
327 |
+ ; |
|
328 |
+ dp->precision_end = cp; |
|
329 |
+ precision_length = dp->precision_end - dp->precision_start; |
|
330 |
+ if (max_precision_length < precision_length) |
|
331 |
+ max_precision_length = precision_length; |
|
332 |
+ } |
|
333 |
+ } |
|
334 |
+ |
|
335 |
+ { |
|
336 |
+ arg_type type; |
|
337 |
+ |
|
338 |
+ /* Parse argument type/size specifiers. */ |
|
339 |
+ { |
|
340 |
+ int flags = 0; |
|
341 |
+ |
|
342 |
+ for (;;) |
|
343 |
+ { |
|
344 |
+ if (*cp == 'h') |
|
345 |
+ { |
|
346 |
+ flags |= (1 << (flags & 1)); |
|
347 |
+ cp++; |
|
348 |
+ } |
|
349 |
+ else if (*cp == 'L') |
|
350 |
+ { |
|
351 |
+ flags |= 4; |
|
352 |
+ cp++; |
|
353 |
+ } |
|
354 |
+ else if (*cp == 'l') |
|
355 |
+ { |
|
356 |
+ flags += 8; |
|
357 |
+ cp++; |
|
358 |
+ } |
|
359 |
+ else if (*cp == 'j') |
|
360 |
+ { |
|
361 |
+ if (sizeof (intmax_t) > sizeof (long)) |
|
362 |
+ { |
|
363 |
+ /* intmax_t = long long */ |
|
364 |
+ flags += 16; |
|
365 |
+ } |
|
366 |
+ else if (sizeof (intmax_t) > sizeof (int)) |
|
367 |
+ { |
|
368 |
+ /* intmax_t = long */ |
|
369 |
+ flags += 8; |
|
370 |
+ } |
|
371 |
+ cp++; |
|
372 |
+ } |
|
373 |
+ else if (*cp == 'z' || *cp == 'Z') |
|
374 |
+ { |
|
375 |
+ /* 'z' is standardized in ISO C 99, but glibc uses 'Z' |
|
376 |
+ because the warning facility in gcc-2.95.2 understands |
|
377 |
+ only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */ |
|
378 |
+ if (sizeof (size_t) > sizeof (long)) |
|
379 |
+ { |
|
380 |
+ /* size_t = long long */ |
|
381 |
+ flags += 16; |
|
382 |
+ } |
|
383 |
+ else if (sizeof (size_t) > sizeof (int)) |
|
384 |
+ { |
|
385 |
+ /* size_t = long */ |
|
386 |
+ flags += 8; |
|
387 |
+ } |
|
388 |
+ cp++; |
|
389 |
+ } |
|
390 |
+ else if (*cp == 't') |
|
391 |
+ { |
|
392 |
+ if (sizeof (ptrdiff_t) > sizeof (long)) |
|
393 |
+ { |
|
394 |
+ /* ptrdiff_t = long long */ |
|
395 |
+ flags += 16; |
|
396 |
+ } |
|
397 |
+ else if (sizeof (ptrdiff_t) > sizeof (int)) |
|
398 |
+ { |
|
399 |
+ /* ptrdiff_t = long */ |
|
400 |
+ flags += 8; |
|
401 |
+ } |
|
402 |
+ cp++; |
|
403 |
+ } |
|
404 |
+#if defined __APPLE__ && defined __MACH__ |
|
405 |
+ /* On MacOS X 10.3, PRIdMAX is defined as "qd". |
|
406 |
+ We cannot change it to "lld" because PRIdMAX must also |
|
407 |
+ be understood by the system's printf routines. */ |
|
408 |
+ else if (*cp == 'q') |
|
409 |
+ { |
|
410 |
+ if (64 / 8 > sizeof (long)) |
|
411 |
+ { |
|
412 |
+ /* int64_t = long long */ |
|
413 |
+ flags += 16; |
|
414 |
+ } |
|
415 |
+ else |
|
416 |
+ { |
|
417 |
+ /* int64_t = long */ |
|
418 |
+ flags += 8; |
|
419 |
+ } |
|
420 |
+ cp++; |
|
421 |
+ } |
|
422 |
+#endif |
|
423 |
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
|
424 |
+ /* On native Win32, PRIdMAX is defined as "I64d". |
|
425 |
+ We cannot change it to "lld" because PRIdMAX must also |
|
426 |
+ be understood by the system's printf routines. */ |
|
427 |
+ else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4') |
|
428 |
+ { |
|
429 |
+ if (64 / 8 > sizeof (long)) |
|
430 |
+ { |
|
431 |
+ /* __int64 = long long */ |
|
432 |
+ flags += 16; |
|
433 |
+ } |
|
434 |
+ else |
|
435 |
+ { |
|
436 |
+ /* __int64 = long */ |
|
437 |
+ flags += 8; |
|
438 |
+ } |
|
439 |
+ cp += 3; |
|
440 |
+ } |
|
441 |
+#endif |
|
442 |
+ else |
|
443 |
+ break; |
|
444 |
+ } |
|
445 |
+ |
|
446 |
+ /* Read the conversion character. */ |
|
447 |
+ c = *cp++; |
|
448 |
+ switch (c) |
|
449 |
+ { |
|
450 |
+ case 'd': case 'i': |
|
451 |
+#if HAVE_LONG_LONG_INT |
|
452 |
+ /* If 'long long' exists and is larger than 'long': */ |
|
453 |
+ if (flags >= 16 || (flags & 4)) |
|
454 |
+ type = TYPE_LONGLONGINT; |
|
455 |
+ else |
|
456 |
+#endif |
|
457 |
+ /* If 'long long' exists and is the same as 'long', we parse |
|
458 |
+ "lld" into TYPE_LONGINT. */ |
|
459 |
+ if (flags >= 8) |
|
460 |
+ type = TYPE_LONGINT; |
|
461 |
+ else if (flags & 2) |
|
462 |
+ type = TYPE_SCHAR; |
|
463 |
+ else if (flags & 1) |
|
464 |
+ type = TYPE_SHORT; |
|
465 |
+ else |
|
466 |
+ type = TYPE_INT; |
|
467 |
+ break; |
|
468 |
+ case 'o': case 'u': case 'x': case 'X': |
|
469 |
+#if HAVE_LONG_LONG_INT |
|
470 |
+ /* If 'long long' exists and is larger than 'long': */ |
|
471 |
+ if (flags >= 16 || (flags & 4)) |
|
472 |
+ type = TYPE_ULONGLONGINT; |
|
473 |
+ else |
|
474 |
+#endif |
|
475 |
+ /* If 'unsigned long long' exists and is the same as |
|
476 |
+ 'unsigned long', we parse "llu" into TYPE_ULONGINT. */ |
|
477 |
+ if (flags >= 8) |
|
478 |
+ type = TYPE_ULONGINT; |
|
479 |
+ else if (flags & 2) |
|
480 |
+ type = TYPE_UCHAR; |
|
481 |
+ else if (flags & 1) |
|
482 |
+ type = TYPE_USHORT; |
|
483 |
+ else |
|
484 |
+ type = TYPE_UINT; |
|
485 |
+ break; |
|
486 |
+ case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': |
|
487 |
+ case 'a': case 'A': |
|
488 |
+ if (flags >= 16 || (flags & 4)) |
|
489 |
+ type = TYPE_LONGDOUBLE; |
|
490 |
+ else |
|
491 |
+ type = TYPE_DOUBLE; |
|
492 |
+ break; |
|
493 |
+ case 'c': |
|
494 |
+ if (flags >= 8) |
|
495 |
+#if HAVE_WINT_T |
|
496 |
+ type = TYPE_WIDE_CHAR; |
|
497 |
+#else |
|
498 |
+ goto error; |
|
499 |
+#endif |
|
500 |
+ else |
|
501 |
+ type = TYPE_CHAR; |
|
502 |
+ break; |
|
503 |
+#if HAVE_WINT_T |
|
504 |
+ case 'C': |
|
505 |
+ type = TYPE_WIDE_CHAR; |
|
506 |
+ c = 'c'; |
|
507 |
+ break; |
|
508 |
+#endif |
|
509 |
+ case 's': |
|
510 |
+ if (flags >= 8) |
|
511 |
+#if HAVE_WCHAR_T |
|
512 |
+ type = TYPE_WIDE_STRING; |
|
513 |
+#else |
|
514 |
+ goto error; |
|
515 |
+#endif |
|
516 |
+ else |
|
517 |
+ type = TYPE_STRING; |
|
518 |
+ break; |
|
519 |
+#if HAVE_WCHAR_T |
|
520 |
+ case 'S': |
|
521 |
+ type = TYPE_WIDE_STRING; |
|
522 |
+ c = 's'; |
|
523 |
+ break; |
|
524 |
+#endif |
|
525 |
+ case 'p': |
|
526 |
+ type = TYPE_POINTER; |
|
527 |
+ break; |
|
528 |
+ case 'n': |
|
529 |
+#if HAVE_LONG_LONG_INT |
|
530 |
+ /* If 'long long' exists and is larger than 'long': */ |
|
531 |
+ if (flags >= 16 || (flags & 4)) |
|
532 |
+ type = TYPE_COUNT_LONGLONGINT_POINTER; |
|
533 |
+ else |
|
534 |
+#endif |
|
535 |
+ /* If 'long long' exists and is the same as 'long', we parse |
|
536 |
+ "lln" into TYPE_COUNT_LONGINT_POINTER. */ |
|
537 |
+ if (flags >= 8) |
|
538 |
+ type = TYPE_COUNT_LONGINT_POINTER; |
|
539 |
+ else if (flags & 2) |
|
540 |
+ type = TYPE_COUNT_SCHAR_POINTER; |
|
541 |
+ else if (flags & 1) |
|
542 |
+ type = TYPE_COUNT_SHORT_POINTER; |
|
543 |
+ else |
|
544 |
+ type = TYPE_COUNT_INT_POINTER; |
|
545 |
+ break; |
|
546 |
+#if ENABLE_UNISTDIO |
|
547 |
+ /* The unistdio extensions. */ |
|
548 |
+ case 'U': |
|
549 |
+ if (flags >= 16) |
|
550 |
+ type = TYPE_U32_STRING; |
|
551 |
+ else if (flags >= 8) |
|
552 |
+ type = TYPE_U16_STRING; |
|
553 |
+ else |
|
554 |
+ type = TYPE_U8_STRING; |
|
555 |
+ break; |
|
556 |
+#endif |
|
557 |
+ case '%': |
|
558 |
+ type = TYPE_NONE; |
|
559 |
+ break; |
|
560 |
+ default: |
|
561 |
+ /* Unknown conversion character. */ |
|
562 |
+ goto error; |
|
563 |
+ } |
|
564 |
+ } |
|
565 |
+ |
|
566 |
+ if (type != TYPE_NONE) |
|
567 |
+ { |
|
568 |
+ dp->arg_index = arg_index; |
|
569 |
+ if (dp->arg_index == ARG_NONE) |
|
570 |
+ { |
|
571 |
+ dp->arg_index = arg_posn++; |
|
572 |
+ if (dp->arg_index == ARG_NONE) |
|
573 |
+ /* arg_posn wrapped around. */ |
|
574 |
+ goto error; |
|
575 |
+ } |
|
576 |
+ REGISTER_ARG (dp->arg_index, type); |
|
577 |
+ } |
|
578 |
+ dp->conversion = c; |
|
579 |
+ dp->dir_end = cp; |
|
580 |
+ } |
|
581 |
+ |
|
582 |
+ d->count++; |
|
583 |
+ if (d->count >= d_allocated) |
|
584 |
+ { |
|
585 |
+ size_t memory_size; |
|
586 |
+ DIRECTIVE *memory; |
|
587 |
+ |
|
588 |
+ d_allocated = xtimes (d_allocated, 2); |
|
589 |
+ memory_size = xtimes (d_allocated, sizeof (DIRECTIVE)); |
|
590 |
+ if (size_overflow_p (memory_size)) |
|
591 |
+ /* Overflow, would lead to out of memory. */ |
|
592 |
+ goto out_of_memory; |
|
593 |
+ memory = (DIRECTIVE *) (d->dir != d->direct_alloc_dir |
|
594 |
+ ? realloc (d->dir, memory_size) |
|
595 |
+ : malloc (memory_size)); |
|
596 |
+ if (memory == NULL) |
|
597 |
+ /* Out of memory. */ |
|
598 |
+ goto out_of_memory; |
|
599 |
+ if (d->dir == d->direct_alloc_dir) |
|
600 |
+ memcpy (memory, d->dir, d->count * sizeof (DIRECTIVE)); |
|
601 |
+ d->dir = memory; |
|
602 |
+ } |
|
603 |
+ } |
|
604 |
+#if CHAR_T_ONLY_ASCII |
|
605 |
+ else if (!c_isascii (c)) |
|
606 |
+ { |
|
607 |
+ /* Non-ASCII character. Not supported. */ |
|
608 |
+ goto error; |
|
609 |
+ } |
|
610 |
+#endif |
|
611 |
+ } |
|
612 |
+ d->dir[d->count].dir_start = cp; |
|
613 |
+ |
|
614 |
+ d->max_width_length = max_width_length; |
|
615 |
+ d->max_precision_length = max_precision_length; |
|
616 |
+ return 0; |
|
617 |
+ |
|
618 |
+error: |
|
619 |
+ if (a->arg != a->direct_alloc_arg) |
|
620 |
+ free (a->arg); |
|
621 |
+ if (d->dir != d->direct_alloc_dir) |
|
622 |
+ free (d->dir); |
|
623 |
+ errno = EINVAL; |
|
624 |
+ return -1; |
|
625 |
+ |
|
626 |
+out_of_memory: |
|
627 |
+ if (a->arg != a->direct_alloc_arg) |
|
628 |
+ free (a->arg); |
|
629 |
+ if (d->dir != d->direct_alloc_dir) |
|
630 |
+ free (d->dir); |
|
631 |
+ errno = ENOMEM; |
|
632 |
+ return -1; |
|
633 |
+} |
|
634 |
+ |
|
635 |
+#undef PRINTF_PARSE |
|
636 |
+#undef DIRECTIVES |
|
637 |
+#undef DIRECTIVE |
|
638 |
+#undef CHAR_T_ONLY_ASCII |
|
639 |
+#undef CHAR_T |
0 | 640 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,194 @@ |
1 |
+/* Parse printf format string. |
|
2 |
+ Copyright (C) 1999, 2002-2003, 2005, 2007, 2010-2011 Free Software |
|
3 |
+ Foundation, Inc. |
|
4 |
+ |
|
5 |
+ This program is free software; you can redistribute it and/or modify |
|
6 |
+ it under the terms of the GNU General Public License as published by |
|
7 |
+ the Free Software Foundation; either version 2, or (at your option) |
|
8 |
+ any later version. |
|
9 |
+ |
|
10 |
+ This program 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 |
|
13 |
+ GNU General Public License for more details. |
|
14 |
+ |
|
15 |
+ You should have received a copy of the GNU General Public License along |
|
16 |
+ with this program; if not, write to the Free Software Foundation, |
|
17 |
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
|
18 |
+ |
|
19 |
+#ifndef _PRINTF_PARSE_H |
|
20 |
+#define _PRINTF_PARSE_H |
|
21 |
+ |
|
22 |
+/* This file can be parametrized with the following macros: |
|
23 |
+ ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. |
|
24 |
+ STATIC Set to 'static' to declare the function static. */ |
|
25 |
+ |
|
26 |
+//#if HAVE_FEATURES_H |
|
27 |
+# include <features.h> /* for __GLIBC__, __UCLIBC__ */ |
|
28 |
+//#endif |
|
29 |
+ |
|
30 |
+#include "printf-args.h" |
|
31 |
+ |
|
32 |
+ |
|
33 |
+/* Flags */ |
|
34 |
+#define FLAG_GROUP 1 /* ' flag */ |
|
35 |
+#define FLAG_LEFT 2 /* - flag */ |
|
36 |
+#define FLAG_SHOWSIGN 4 /* + flag */ |
|
37 |
+#define FLAG_SPACE 8 /* space flag */ |
|
38 |
+#define FLAG_ALT 16 /* # flag */ |
|
39 |
+#define FLAG_ZERO 32 |
|
40 |
+#if __GLIBC__ >= 2 && !defined __UCLIBC__ |
|
41 |
+# define FLAG_LOCALIZED 64 /* I flag, uses localized digits */ |
|
42 |
+#endif |
|
43 |
+ |
|
44 |
+/* arg_index value indicating that no argument is consumed. */ |
|
45 |
+#define ARG_NONE (~(size_t)0) |
|
46 |
+ |
|
47 |
+/* xxx_directive: A parsed directive. |
|
48 |
+ xxx_directives: A parsed format string. */ |
|
49 |
+ |
|
50 |
+/* Number of directly allocated directives (no malloc() needed). */ |
|
51 |
+#define N_DIRECT_ALLOC_DIRECTIVES 7 |
|
52 |
+ |
|
53 |
+/* A parsed directive. */ |
|
54 |
+typedef struct |
|
55 |
+{ |
|
56 |
+ const char* dir_start; |
|
57 |
+ const char* dir_end; |
|
58 |
+ int flags; |
|
59 |
+ const char* width_start; |
|
60 |
+ const char* width_end; |
|
61 |
+ size_t width_arg_index; |
|
62 |
+ const char* precision_start; |
|
63 |
+ const char* precision_end; |
|
64 |
+ size_t precision_arg_index; |
|
65 |
+ char conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ |
|
66 |
+ size_t arg_index; |
|
67 |
+} |
|
68 |
+char_directive; |
|
69 |
+ |
|
70 |
+/* A parsed format string. */ |
|
71 |
+typedef struct |
|
72 |
+{ |
|
73 |
+ size_t count; |
|
74 |
+ char_directive *dir; |
|
75 |
+ size_t max_width_length; |
|
76 |
+ size_t max_precision_length; |
|
77 |
+ char_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; |
|
78 |
+} |
|
79 |
+char_directives; |
|
80 |
+ |
|
81 |
+#if ENABLE_UNISTDIO |
|
82 |
+ |
|
83 |
+/* A parsed directive. */ |
|
84 |
+typedef struct |
|
85 |
+{ |
|
86 |
+ const uint8_t* dir_start; |
|
87 |
+ const uint8_t* dir_end; |
|
88 |
+ int flags; |
|
89 |
+ const uint8_t* width_start; |
|
90 |
+ const uint8_t* width_end; |
|
91 |
+ size_t width_arg_index; |
|
92 |
+ const uint8_t* precision_start; |
|
93 |
+ const uint8_t* precision_end; |
|
94 |
+ size_t precision_arg_index; |
|
95 |
+ uint8_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ |
|
96 |
+ size_t arg_index; |
|
97 |
+} |
|
98 |
+u8_directive; |
|
99 |
+ |
|
100 |
+/* A parsed format string. */ |
|
101 |
+typedef struct |
|
102 |
+{ |
|
103 |
+ size_t count; |
|
104 |
+ u8_directive *dir; |
|
105 |
+ size_t max_width_length; |
|
106 |
+ size_t max_precision_length; |
|
107 |
+ u8_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; |
|
108 |
+} |
|
109 |
+u8_directives; |
|
110 |
+ |
|
111 |
+/* A parsed directive. */ |
|
112 |
+typedef struct |
|
113 |
+{ |
|
114 |
+ const uint16_t* dir_start; |
|
115 |
+ const uint16_t* dir_end; |
|
116 |
+ int flags; |
|
117 |
+ const uint16_t* width_start; |
|
118 |
+ const uint16_t* width_end; |
|
119 |
+ size_t width_arg_index; |
|
120 |
+ const uint16_t* precision_start; |
|
121 |
+ const uint16_t* precision_end; |
|
122 |
+ size_t precision_arg_index; |
|
123 |
+ uint16_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ |
|
124 |
+ size_t arg_index; |
|
125 |
+} |
|
126 |
+u16_directive; |
|
127 |
+ |
|
128 |
+/* A parsed format string. */ |
|
129 |
+typedef struct |
|
130 |
+{ |
|
131 |
+ size_t count; |
|
132 |
+ u16_directive *dir; |
|
133 |
+ size_t max_width_length; |
|
134 |
+ size_t max_precision_length; |
|
135 |
+ u16_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; |
|
136 |
+} |
|
137 |
+u16_directives; |
|
138 |
+ |
|
139 |
+/* A parsed directive. */ |
|
140 |
+typedef struct |
|
141 |
+{ |
|
142 |
+ const uint32_t* dir_start; |
|
143 |
+ const uint32_t* dir_end; |
|
144 |
+ int flags; |
|
145 |
+ const uint32_t* width_start; |
|
146 |
+ const uint32_t* width_end; |
|
147 |
+ size_t width_arg_index; |
|
148 |
+ const uint32_t* precision_start; |
|
149 |
+ const uint32_t* precision_end; |
|
150 |
+ size_t precision_arg_index; |
|
151 |
+ uint32_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ |
|
152 |
+ size_t arg_index; |
|
153 |
+} |
|
154 |
+u32_directive; |
|
155 |
+ |
|
156 |
+/* A parsed format string. */ |
|
157 |
+typedef struct |
|
158 |
+{ |
|
159 |
+ size_t count; |
|
160 |
+ u32_directive *dir; |
|
161 |
+ size_t max_width_length; |
|
162 |
+ size_t max_precision_length; |
|
163 |
+ u32_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; |
|
164 |
+} |
|
165 |
+u32_directives; |
|
166 |
+ |
|
167 |
+#endif |
|
168 |
+ |
|
169 |
+ |
|
170 |
+/* Parses the format string. Fills in the number N of directives, and fills |
|
171 |
+ in directives[0], ..., directives[N-1], and sets directives[N].dir_start |
|
172 |
+ to the end of the format string. Also fills in the arg_type fields of the |
|
173 |
+ arguments and the needed count of arguments. */ |
|
174 |
+#if ENABLE_UNISTDIO |
|
175 |
+extern int |
|
176 |
+ ulc_printf_parse (const char *format, char_directives *d, arguments *a); |
|
177 |
+extern int |
|
178 |
+ u8_printf_parse (const uint8_t *format, u8_directives *d, arguments *a); |
|
179 |
+extern int |
|
180 |
+ u16_printf_parse (const uint16_t *format, u16_directives *d, |
|
181 |
+ arguments *a); |
|
182 |
+extern int |
|
183 |
+ u32_printf_parse (const uint32_t *format, u32_directives *d, |
|
184 |
+ arguments *a); |
|
185 |
+#else |
|
186 |
+# ifdef STATIC |
|
187 |
+STATIC |
|
188 |
+# else |
|
189 |
+extern |
|
190 |
+# endif |
|
191 |
+int printf_parse (const char *format, char_directives *d, arguments *a); |
|
192 |
+#endif |
|
193 |
+ |
|
194 |
+#endif /* _PRINTF_PARSE_H */ |
0 | 195 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,5578 @@ |
1 |
+/* vsprintf with automatic memory allocation. |
|
2 |
+ Copyright (C) 1999, 2002-2011 Free Software Foundation, Inc. |
|
3 |
+ |
|
4 |
+ This program is free software; you can redistribute it and/or modify |
|
5 |
+ it under the terms of the GNU General Public License as published by |
|
6 |
+ the Free Software Foundation; either version 2, or (at your option) |
|
7 |
+ any later version. |
|
8 |
+ |
|
9 |
+ This program is distributed in the hope that it will be useful, |
|
10 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
+ GNU General Public License for more details. |
|
13 |
+ |
|
14 |
+ You should have received a copy of the GNU General Public License along |
|
15 |
+ with this program; if not, write to the Free Software Foundation, |
|
16 |
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
|
17 |
+ |
|
18 |
+/* This file can be parametrized with the following macros: |
|
19 |
+ VASNPRINTF The name of the function being defined. |
|
20 |
+ FCHAR_T The element type of the format string. |
|
21 |
+ DCHAR_T The element type of the destination (result) string. |
|
22 |
+ FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters |
|
23 |
+ in the format string are ASCII. MUST be set if |
|
24 |
+ FCHAR_T and DCHAR_T are not the same type. |
|
25 |
+ DIRECTIVE Structure denoting a format directive. |
|
26 |
+ Depends on FCHAR_T. |
|
27 |
+ DIRECTIVES Structure denoting the set of format directives of a |
|
28 |
+ format string. Depends on FCHAR_T. |
|
29 |
+ PRINTF_PARSE Function that parses a format string. |
|
30 |
+ Depends on FCHAR_T. |
|
31 |
+ DCHAR_CPY memcpy like function for DCHAR_T[] arrays. |
|
32 |
+ DCHAR_SET memset like function for DCHAR_T[] arrays. |
|
33 |
+ DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays. |
|
34 |
+ SNPRINTF The system's snprintf (or similar) function. |
|
35 |
+ This may be either snprintf or swprintf. |
|
36 |
+ TCHAR_T The element type of the argument and result string |
|
37 |
+ of the said SNPRINTF function. This may be either |
|
38 |
+ char or wchar_t. The code exploits that |
|
39 |
+ sizeof (TCHAR_T) | sizeof (DCHAR_T) and |
|
40 |
+ alignof (TCHAR_T) <= alignof (DCHAR_T). |
|
41 |
+ DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type. |
|
42 |
+ DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[]. |
|
43 |
+ DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t. |
|
44 |
+ DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t. |
|
45 |
+ DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */ |
|
46 |
+ |
|
47 |
+/* Tell glibc's <stdio.h> to provide a prototype for snprintf(). |
|
48 |
+ This must come before <config.h> because <config.h> may include |
|
49 |
+ <features.h>, and once <features.h> has been included, it's too late. */ |
|
50 |
+#ifndef _GNU_SOURCE |
|
51 |
+# define _GNU_SOURCE 1 |
|
52 |
+#endif |
|
53 |
+ |
|
54 |
+#ifndef VASNPRINTF |
|
55 |
+/*# include <config.h>*/ |
|
56 |
+#endif |
|