Commit 2db5c711 2db5c7115e5b37734993603c0381aab7e62c4be9 by Sergey Poznyakoff

Updated by gnulib-sync

1 parent 96aac328
1 /* Copyright (C) 1992, 1995, 1996, 1997, 2001 Free Software Foundation, Inc. 1 /* Copyright (C) 1992,1995-1999,2000-2004 Free Software Foundation, Inc.
2 This file based on setenv.c in the GNU C Library. 2 This file is part of the GNU C Library.
3 3
4 The GNU C Library is free software; you can redistribute it and/or 4 This program is free software; you can redistribute it and/or modify
5 modify it under the terms of the GNU Library General Public License as 5 it under the terms of the GNU General Public License as published by
6 published by the Free Software Foundation; either version 2 of the 6 the Free Software Foundation; either version 2, or (at your option)
7 License, or (at your option) any later version. 7 any later version.
8 8
9 The GNU C Library is distributed in the hope that it will be useful, 9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 Library General Public License for more details. 12 GNU General Public License for more details.
13 13
14 You should have received a copy of the GNU Library General Public 14 You should have received a copy of the GNU General Public License along
15 License along with the GNU C Library; see the file COPYING.LIB. If not, 15 with this program; if not, write to the Free Software Foundation,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 Boston, MA 02111-1307, USA. */
18 17
19 #if HAVE_CONFIG_H 18 #if HAVE_CONFIG_H
20 # include <config.h> 19 # include <config.h>
21 #endif 20 #endif
21 #include <alloca.h>
22 22
23 #include <errno.h> 23 #include <errno.h>
24 24 #ifndef __set_errno
25 #if HAVE_STDLIB_H 25 # define __set_errno(ev) ((errno) = (ev))
26 # include <stdlib.h>
27 #else
28 #include <sys/types.h> /* For `size_t' */
29 #include <stdio.h> /* For `NULL' */
30 #endif
31 #if HAVE_STRING_H
32 # include <string.h>
33 #endif 26 #endif
34 #if HAVE_UNISTD_H 27
28 #include <stdlib.h>
29 #include <string.h>
30 #if _LIBC || HAVE_UNISTD_H
35 # include <unistd.h> 31 # include <unistd.h>
36 #endif 32 #endif
37 33
38 #define __environ environ 34 #if !_LIBC
35 # include "allocsa.h"
36 #endif
37
38 #if !_LIBC
39 # define __environ environ
40 # ifndef HAVE_ENVIRON_DECL
39 extern char **environ; 41 extern char **environ;
42 # endif
43 #endif
40 44
41 /* LOCK and UNLOCK are defined as no-ops. This makes the libiberty 45 #if _LIBC
42 * implementation MT-Unsafe. */ 46 /* This lock protects against simultaneous modifications of `environ'. */
43 #define LOCK 47 # include <bits/libc-lock.h>
44 #define UNLOCK 48 __libc_lock_define_initialized (static, envlock)
49 # define LOCK __libc_lock_lock (envlock)
50 # define UNLOCK __libc_lock_unlock (envlock)
51 #else
52 # define LOCK
53 # define UNLOCK
54 #endif
55
56 /* In the GNU C library we must keep the namespace clean. */
57 #ifdef _LIBC
58 # define setenv __setenv
59 # define clearenv __clearenv
60 # define tfind __tfind
61 # define tsearch __tsearch
62 #endif
63
64 /* In the GNU C library implementation we try to be more clever and
65 allow arbitrarily many changes of the environment given that the used
66 values are from a small set. Outside glibc this will eat up all
67 memory after a while. */
68 #if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \
69 && defined __GNUC__)
70 # define USE_TSEARCH 1
71 # include <search.h>
72 typedef int (*compar_fn_t) (const void *, const void *);
73
74 /* This is a pointer to the root of the search tree with the known
75 values. */
76 static void *known_values;
77
78 # define KNOWN_VALUE(Str) \
79 ({ \
80 void *value = tfind (Str, &known_values, (compar_fn_t) strcmp); \
81 value != NULL ? *(char **) value : NULL; \
82 })
83 # define STORE_VALUE(Str) \
84 tsearch (Str, &known_values, (compar_fn_t) strcmp)
85
86 #else
87 # undef USE_TSEARCH
88
89 # define KNOWN_VALUE(Str) NULL
90 # define STORE_VALUE(Str) do { } while (0)
91
92 #endif
45 93
46 /* Below this point, it's verbatim code from the glibc-2.0 implementation */
47 94
48 /* If this variable is not a null pointer we allocated the current 95 /* If this variable is not a null pointer we allocated the current
49 environment. */ 96 environment. */
50 static char **last_environ; 97 static char **last_environ;
51 98
52 99
100 /* This function is used by `setenv' and `putenv'. The difference between
101 the two functions is that for the former must create a new string which
102 is then placed in the environment, while the argument of `putenv'
103 must be used directly. This is all complicated by the fact that we try
104 to reuse values once generated for a `setenv' call since we can never
105 free the strings. */
53 int 106 int
54 setenv (name, value, replace) 107 __add_to_environ (const char *name, const char *value, const char *combined,
55 const char *name; 108 int replace)
56 const char *value;
57 int replace;
58 { 109 {
59 register char **ep; 110 register char **ep;
60 register size_t size; 111 register size_t size;
61 const size_t namelen = strlen (name); 112 const size_t namelen = strlen (name);
62 const size_t vallen = strlen (value) + 1; 113 const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
63 114
64 LOCK; 115 LOCK;
65 116
117 /* We have to get the pointer now that we have the lock and not earlier
118 since another thread might have created a new environment. */
119 ep = __environ;
120
66 size = 0; 121 size = 0;
67 if (__environ != NULL) 122 if (ep != NULL)
68 for (ep = __environ; *ep != NULL; ++ep) 123 {
124 for (; *ep != NULL; ++ep)
69 if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') 125 if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
70 break; 126 break;
71 else 127 else
72 ++size; 128 ++size;
129 }
73 130
74 if (__environ == NULL || *ep == NULL) 131 if (ep == NULL || *ep == NULL)
75 { 132 {
76 char **new_environ; 133 char **new_environ;
77 if (__environ == last_environ && __environ != NULL) 134 #ifdef USE_TSEARCH
78 /* We allocated this space; we can extend it. */ 135 char *new_value;
79 new_environ = (char **) realloc (last_environ, 136 #endif
80 (size + 2) * sizeof (char *));
81 else
82 new_environ = (char **) malloc ((size + 2) * sizeof (char *));
83 137
138 /* We allocated this space; we can extend it. */
139 new_environ =
140 (char **) (last_environ == NULL
141 ? malloc ((size + 2) * sizeof (char *))
142 : realloc (last_environ, (size + 2) * sizeof (char *)));
84 if (new_environ == NULL) 143 if (new_environ == NULL)
85 { 144 {
86 UNLOCK; 145 UNLOCK;
87 return -1; 146 return -1;
88 } 147 }
89 148
90 new_environ[size] = malloc (namelen + 1 + vallen); 149 /* If the whole entry is given add it. */
91 if (new_environ[size] == NULL) 150 if (combined != NULL)
151 /* We must not add the string to the search tree since it belongs
152 to the user. */
153 new_environ[size] = (char *) combined;
154 else
92 { 155 {
93 free ((char *) new_environ); 156 /* See whether the value is already known. */
94 errno = ENOMEM; 157 #ifdef USE_TSEARCH
158 # ifdef _LIBC
159 new_value = (char *) alloca (namelen + 1 + vallen);
160 __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
161 value, vallen);
162 # else
163 new_value = (char *) allocsa (namelen + 1 + vallen);
164 if (new_value == NULL)
165 {
166 __set_errno (ENOMEM);
95 UNLOCK; 167 UNLOCK;
96 return -1; 168 return -1;
97 } 169 }
170 memcpy (new_value, name, namelen);
171 new_value[namelen] = '=';
172 memcpy (&new_value[namelen + 1], value, vallen);
173 # endif
98 174
99 if (__environ != last_environ) 175 new_environ[size] = KNOWN_VALUE (new_value);
100 memcpy ((char *) new_environ, (char *) __environ, 176 if (new_environ[size] == NULL)
101 size * sizeof (char *)); 177 #endif
178 {
179 new_environ[size] = (char *) malloc (namelen + 1 + vallen);
180 if (new_environ[size] == NULL)
181 {
182 #if defined USE_TSEARCH && !defined _LIBC
183 freesa (new_value);
184 #endif
185 __set_errno (ENOMEM);
186 UNLOCK;
187 return -1;
188 }
102 189
190 #ifdef USE_TSEARCH
191 memcpy (new_environ[size], new_value, namelen + 1 + vallen);
192 #else
103 memcpy (new_environ[size], name, namelen); 193 memcpy (new_environ[size], name, namelen);
104 new_environ[size][namelen] = '='; 194 new_environ[size][namelen] = '=';
105 memcpy (&new_environ[size][namelen + 1], value, vallen); 195 memcpy (&new_environ[size][namelen + 1], value, vallen);
196 #endif
197 /* And save the value now. We cannot do this when we remove
198 the string since then we cannot decide whether it is a
199 user string or not. */
200 STORE_VALUE (new_environ[size]);
201 }
202 #if defined USE_TSEARCH && !defined _LIBC
203 freesa (new_value);
204 #endif
205 }
206
207 if (__environ != last_environ)
208 memcpy ((char *) new_environ, (char *) __environ,
209 size * sizeof (char *));
106 210
107 new_environ[size + 1] = NULL; 211 new_environ[size + 1] = NULL;
108 212
...@@ -110,21 +214,63 @@ setenv (name, value, replace) ...@@ -110,21 +214,63 @@ setenv (name, value, replace)
110 } 214 }
111 else if (replace) 215 else if (replace)
112 { 216 {
113 size_t len = strlen (*ep); 217 char *np;
114 if (len + 1 < namelen + 1 + vallen) 218
219 /* Use the user string if given. */
220 if (combined != NULL)
221 np = (char *) combined;
222 else
115 { 223 {
116 /* The existing string is too short; malloc a new one. */ 224 #ifdef USE_TSEARCH
117 char *new = malloc (namelen + 1 + vallen); 225 char *new_value;
118 if (new == NULL) 226 # ifdef _LIBC
227 new_value = alloca (namelen + 1 + vallen);
228 __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
229 value, vallen);
230 # else
231 new_value = allocsa (namelen + 1 + vallen);
232 if (new_value == NULL)
119 { 233 {
234 __set_errno (ENOMEM);
120 UNLOCK; 235 UNLOCK;
121 return -1; 236 return -1;
122 } 237 }
123 *ep = new; 238 memcpy (new_value, name, namelen);
239 new_value[namelen] = '=';
240 memcpy (&new_value[namelen + 1], value, vallen);
241 # endif
242
243 np = KNOWN_VALUE (new_value);
244 if (np == NULL)
245 #endif
246 {
247 np = malloc (namelen + 1 + vallen);
248 if (np == NULL)
249 {
250 #if defined USE_TSEARCH && !defined _LIBC
251 freesa (new_value);
252 #endif
253 __set_errno (ENOMEM);
254 UNLOCK;
255 return -1;
124 } 256 }
125 memcpy (*ep, name, namelen); 257
126 (*ep)[namelen] = '='; 258 #ifdef USE_TSEARCH
127 memcpy (&(*ep)[namelen + 1], value, vallen); 259 memcpy (np, new_value, namelen + 1 + vallen);
260 #else
261 memcpy (np, name, namelen);
262 np[namelen] = '=';
263 memcpy (&np[namelen + 1], value, vallen);
264 #endif
265 /* And remember the value. */
266 STORE_VALUE (np);
267 }
268 #if defined USE_TSEARCH && !defined _LIBC
269 freesa (new_value);
270 #endif
271 }
272
273 *ep = np;
128 } 274 }
129 275
130 UNLOCK; 276 UNLOCK;
...@@ -132,25 +278,51 @@ setenv (name, value, replace) ...@@ -132,25 +278,51 @@ setenv (name, value, replace)
132 return 0; 278 return 0;
133 } 279 }
134 280
135 void 281 int
136 unsetenv (name) 282 setenv (const char *name, const char *value, int replace)
137 const char *name;
138 { 283 {
139 const size_t len = strlen (name); 284 return __add_to_environ (name, value, NULL, replace);
140 char **ep; 285 }
141 286
287 /* The `clearenv' was planned to be added to POSIX.1 but probably
288 never made it. Nevertheless the POSIX.9 standard (POSIX bindings
289 for Fortran 77) requires this function. */
290 int
291 clearenv (void)
292 {
142 LOCK; 293 LOCK;
143 294
144 for (ep = __environ; *ep; ++ep) 295 if (__environ == last_environ && __environ != NULL)
145 if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
146 { 296 {
147 /* Found it. Remove this pointer by moving later ones back. */ 297 /* We allocated this environment so we can free it. */
148 char **dp = ep; 298 free (__environ);
149 do 299 last_environ = NULL;
150 dp[0] = dp[1];
151 while (*dp++);
152 /* Continue the loop in case NAME appears again. */
153 } 300 }
154 301
302 /* Clear the environment pointer removes the whole environment. */
303 __environ = NULL;
304
155 UNLOCK; 305 UNLOCK;
306
307 return 0;
308 }
309
310 #ifdef _LIBC
311 static void
312 free_mem (void)
313 {
314 /* Remove all traces. */
315 clearenv ();
316
317 /* Now remove the search tree. */
318 __tdestroy (known_values, free);
319 known_values = NULL;
156 } 320 }
321 text_set_element (__libc_subfreeres, free_mem);
322
323
324 # undef setenv
325 # undef clearenv
326 weak_alias (__setenv, setenv)
327 weak_alias (__clearenv, clearenv)
328 #endif
......
1 1 /* Formatted output to strings.
2 /* 2 Copyright (C) 2004 Free Software Foundation, Inc.
3 Unix snprintf implementation. 3 Written by Simon Josefsson.
4 Version 1.3
5 4
6 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Library General Public License as published by 6 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2, or (at your option)
9 (at your option) any later version. 8 any later version.
10 9
11 This program is distributed in the hope that it will be useful, 10 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Library General Public License for more details. 13 GNU General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 Revision History:
21
22 1.3:
23 * add #include <config.h> ifdef HAVE_CONFIG_H
24 * cosmetic change, when exponent is 0 print xxxE+00
25 instead of xxxE-00
26 1.2:
27 * put the program under LGPL.
28 1.1:
29 * added changes from Miles Bader
30 * corrected a bug with %f
31 * added support for %#g
32 * added more comments :-)
33 1.0:
34 * supporting must ANSI syntaxic_sugars
35 0.0:
36 * suppot %s %c %d
37
38 THANKS(for the patches and ideas):
39 Miles Bader
40 Cyrille Rustom
41 Jacek Slabocewiz
42 Mike Parker(mouse)
43
44 */
45
46 #include "snprintf.h"
47
48 /*
49 * Find the nth power of 10
50 */
51 PRIVATE double
52 #ifdef __STDC__
53 pow_10(int n)
54 #else
55 pow_10(n)
56 int n;
57 #endif
58 {
59 int i;
60 double P;
61
62 if (n < 0)
63 for (i = 1, P = 1., n = -n ; i <= n ; i++) {P *= .1;}
64 else
65 for (i = 1, P = 1. ; i <= n ; i++) {P *= 10.0;}
66 return P;
67 }
68
69 /*
70 * Find the integral part of the log in base 10
71 * Note: this not a real log10()
72 I just need and approximation(integerpart) of x in:
73 10^x ~= r
74 * log_10(200) = 2;
75 * log_10(250) = 2;
76 */
77 PRIVATE int
78 #ifdef __STDC__
79 log_10(double r)
80 #else
81 log_10(r)
82 double r;
83 #endif
84 {
85 int i = 0;
86 double result = 1.;
87
88 if (r < 0.)
89 r = -r;
90
91 if (r < 1.) {
92 while (result >= r) {result *= .1; i++;}
93 return (-i);
94 } else {
95 while (result <= r) {result *= 10.; i++;}
96 return (i - 1);
97 }
98 }
99
100 /*
101 * This function return the fraction part of a double
102 * and set in ip the integral part.
103 * In many ways it resemble the modf() found on most Un*x
104 */
105 PRIVATE double
106 #ifdef __STDC__
107 integral(double real, double * ip)
108 #else
109 integral(real, ip)
110 double real;
111 double * ip;
112 #endif
113 {
114 int j;
115 double i, s, p;
116 double real_integral = 0.;
117
118 /* take care of the obvious */
119 /* equal to zero ? */
120 if (real == 0.) {
121 *ip = 0.;
122 return (0.);
123 }
124
125 /* negative number ? */
126 if (real < 0.)
127 real = -real;
128
129 /* a fraction ? */
130 if ( real < 1.) {
131 *ip = 0.;
132 return real;
133 }
134 /* the real work :-) */
135 for (j = log_10(real); j >= 0; j--) {
136 p = pow_10(j);
137 s = (real - real_integral)/p;
138 i = 0.;
139 while (i + 1. <= s) {i++;}
140 real_integral += i*p;
141 }
142 *ip = real_integral;
143 return (real - real_integral);
144 }
145
146 #define PRECISION 1.e-6
147 /*
148 * return an ascii representation of the integral part of the number
149 * and set fract to be an ascii representation of the fraction part
150 * the container for the fraction and the integral part or staticly
151 * declare with fix size
152 */
153 PRIVATE char *
154 #ifdef __STDC__
155 numtoa(double number, int base, int precision, char ** fract)
156 #else
157 numtoa(number, base, precision, fract)
158 double number;
159 int base;
160 int precision;
161 char ** fract;
162 #endif
163 {
164 register int i, j;
165 double ip, fp; /* integer and fraction part */
166 double fraction;
167 int digits = MAX_INT - 1;
168 static char integral_part[MAX_INT];
169 static char fraction_part[MAX_FRACT];
170 double sign;
171 int ch;
172
173 /* taking care of the obvious case: 0.0 */
174 if (number == 0.) {
175 integral_part[0] = '0';
176 integral_part[1] = '\0';
177 fraction_part[0] = '0';
178 fraction_part[1] = '\0';
179 return integral_part;
180 }
181
182 /* for negative numbers */
183 if ((sign = number) < 0.) {
184 number = -number;
185 digits--; /* sign consume one digit */
186 }
187
188 fraction = integral(number, &ip);
189 number = ip;
190 /* do the integral part */
191 if ( ip == 0.) {
192 integral_part[0] = '0';
193 i = 1;
194 } else {
195 for ( i = 0; i < digits && number != 0.; ++i) {
196 number /= base;
197 fp = integral(number, &ip);
198 ch = (int)((fp + PRECISION)*base); /* force to round */
199 integral_part[i] = (ch <= 9) ? ch + '0' : ch + 'a' - 10;
200 if (! isxdigit(integral_part[i])) /* bail out overflow !! */
201 break;
202 number = ip;
203 }
204 }
205
206 /* Oh No !! out of bound, ho well fill it up ! */
207 if (number != 0.)
208 for (i = 0; i < digits; ++i)
209 integral_part[i] = '9';
210 14
211 /* put the sign ? */ 15 You should have received a copy of the GNU General Public License along
212 if (sign < 0.) 16 with this program; if not, write to the Free Software Foundation,
213 integral_part[i++] = '-'; 17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
214 18
215 integral_part[i] = '\0'; 19 #ifdef HAVE_CONFIG_H
216 20 # include <config.h>
217 /* reverse every thing */
218 for ( i--, j = 0; j < i; j++, i--)
219 SWAP_INT(integral_part[i], integral_part[j]);
220
221 /* the fractionnal part */
222 for (i=0, fp=fraction; precision > 0 && i < MAX_FRACT ; i++, precision-- ) {
223 fraction_part[i] = (int)((fp + PRECISION)*10. + '0');
224 if (! isdigit(fraction_part[i])) /* underflow ? */
225 break;
226 fp = (fp*10.0) - (double)(long)((fp + PRECISION)*10.);
227 }
228 fraction_part[i] = '\0';
229
230 if (fract != (char **)0)
231 *fract = fraction_part;
232
233 return integral_part;
234
235 }
236
237 /* for %d and friends, it puts in holder
238 * the representation with the right padding
239 */
240 PRIVATE void
241 #ifdef __STDC__
242 decimal(struct DATA *p, double d)
243 #else
244 decimal(p, d)
245 struct DATA *p;
246 double d;
247 #endif 21 #endif
248 {
249 char *tmp;
250 22
251 tmp = itoa(d); 23 #include "snprintf.h"
252 p->width -= strlen(tmp);
253 PAD_RIGHT(p);
254 PUT_PLUS(d, p);
255 PUT_SPACE(d, p);
256 while (*tmp) { /* the integral */
257 PUT_CHAR(*tmp, p);
258 tmp++;
259 }
260 PAD_LEFT(p);
261 }
262
263 /* for %o octal representation */
264 PRIVATE void
265 #ifdef __STDC__
266 octal(struct DATA *p, double d)
267 #else
268 octal(p, d)
269 struct DATA *p;
270 double d;
271 #endif
272 {
273 char *tmp;
274
275 tmp = otoa(d);
276 p->width -= strlen(tmp);
277 PAD_RIGHT(p);
278 if (p->square == FOUND) /* had prefix '0' for octal */
279 PUT_CHAR('0', p);
280 while (*tmp) { /* octal */
281 PUT_CHAR(*tmp, p);
282 tmp++;
283 }
284 PAD_LEFT(p);
285 }
286
287 /* for %x %X hexadecimal representation */
288 PRIVATE void
289 #ifdef __STDC__
290 hexa(struct DATA *p, double d)
291 #else
292 hexa(p, d)
293 struct DATA *p;
294 double d;
295 #endif
296 {
297 char *tmp;
298
299 tmp = htoa(d);
300 p->width -= strlen(tmp);
301 PAD_RIGHT(p);
302 if (p->square == FOUND) { /* prefix '0x' for hexa */
303 PUT_CHAR('0', p); PUT_CHAR(*p->pf, p);
304 }
305 while (*tmp) { /* hexa */
306 PUT_CHAR((*p->pf == 'X' ? toupper(*tmp) : *tmp), p);
307 tmp++;
308 }
309 PAD_LEFT(p);
310 }
311
312 /* %s strings */
313 PRIVATE void
314 #ifdef __STDC__
315 strings(struct DATA *p, char *tmp)
316 #else
317 strings(p, tmp)
318 struct DATA *p;
319 char *tmp;
320 #endif
321 {
322 int i;
323
324 i = strlen(tmp);
325 if (p->precision != NOT_FOUND) /* the smallest number */
326 i = (i < p->precision ? i : p->precision);
327 p->width -= i;
328 PAD_RIGHT(p);
329 while (i-- > 0) { /* put the sting */
330 PUT_CHAR(*tmp, p);
331 tmp++;
332 }
333 PAD_LEFT(p);
334 }
335
336 /* %f or %g floating point representation */
337 PRIVATE void
338 #ifdef __STDC__
339 floating(struct DATA *p, double d)
340 #else
341 floating(p, d)
342 struct DATA *p;
343 double d;
344 #endif
345 {
346 char *tmp, *tmp2;
347 int i;
348
349 DEF_PREC(p);
350 d = ROUND(d, p);
351 tmp = dtoa(d, p->precision, &tmp2);
352 /* calculate the padding. 1 for the dot */
353 p->width = p->width -
354 ((d > 0. && p->justify == RIGHT) ? 1:0) -
355 ((p->space == FOUND) ? 1:0) -
356 strlen(tmp) - p->precision - 1;
357 PAD_RIGHT(p);
358 PUT_PLUS(d, p);
359 PUT_SPACE(d, p);
360 while (*tmp) { /* the integral */
361 PUT_CHAR(*tmp, p);
362 tmp++;
363 }
364 if (p->precision != 0 || p->square == FOUND)
365 PUT_CHAR('.', p); /* put the '.' */
366 if (*p->pf == 'g' || *p->pf == 'G') /* smash the trailing zeros */
367 for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
368 tmp2[i] = '\0';
369 for (; *tmp2; tmp2++)
370 PUT_CHAR(*tmp2, p); /* the fraction */
371
372 PAD_LEFT(p);
373 }
374
375 /* %e %E %g exponent representation */
376 PRIVATE void
377 #ifdef __STDC__
378 exponent(struct DATA *p, double d)
379 #else
380 exponent(p, d)
381 struct DATA *p;
382 double d;
383 #endif
384 {
385 char *tmp, *tmp2;
386 int j, i;
387
388 DEF_PREC(p);
389 j = log_10(d);
390 d = d / pow_10(j); /* get the Mantissa */
391 d = ROUND(d, p);
392 tmp = dtoa(d, p->precision, &tmp2);
393 /* 1 for unit, 1 for the '.', 1 for 'e|E',
394 * 1 for '+|-', 3 for 'exp' */
395 /* calculate how much padding need */
396 p->width = p->width -
397 ((d > 0. && p->justify == RIGHT) ? 1:0) -
398 ((p->space == FOUND) ? 1:0) - p->precision - 7;
399 PAD_RIGHT(p);
400 PUT_PLUS(d, p);
401 PUT_SPACE(d, p);
402 while (*tmp) {/* the integral */
403 PUT_CHAR(*tmp, p);
404 tmp++;
405 }
406 if (p->precision != 0 || p->square == FOUND)
407 PUT_CHAR('.', p); /* the '.' */
408 if (*p->pf == 'g' || *p->pf == 'G') /* smash the trailing zeros */
409 for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
410 tmp2[i] = '\0';
411 for (; *tmp2; tmp2++)
412 PUT_CHAR(*tmp2, p); /* the fraction */
413
414 if (*p->pf == 'g' || *p->pf == 'e') { /* the exponent put the 'e|E' */
415 PUT_CHAR('e', p);
416 } else
417 PUT_CHAR('E', p);
418 if (j >= 0) { /* the sign of the exp */
419 PUT_CHAR('+', p);
420 } else {
421 PUT_CHAR('-', p);
422 j = -j;
423 }
424 tmp = itoa((double)j);
425 if (j < 9) { /* need to pad the exponent with 0 '000' */
426 PUT_CHAR('0', p); PUT_CHAR('0', p);
427 } else if (j < 99)
428 PUT_CHAR('0', p);
429 while (*tmp) { /* the exponent */
430 PUT_CHAR(*tmp, p);
431 tmp++;
432 }
433 PAD_LEFT(p);
434 }
435
436 /* initialize the conversion specifiers */
437 PRIVATE void
438 #ifdef __STDC__
439 conv_flag(char * s, struct DATA * p)
440 #else
441 conv_flag(s, p)
442 char * s;
443 struct DATA * p;
444 #endif
445 {
446 char number[MAX_FIELD/2];
447 int i;
448
449 /* reset the flags. */
450 p->precision = p->width = NOT_FOUND;
451 p->star_w = p->star_p = NOT_FOUND;
452 p->square = p->space = NOT_FOUND;
453 p->a_long = p->justify = NOT_FOUND;
454 p->a_longlong = NOT_FOUND;
455 p->pad = ' ';
456
457 for(;s && *s ;s++) {
458 switch(*s) {
459 case ' ': p->space = FOUND; break;
460 case '#': p->square = FOUND; break;
461 case '*': if (p->width == NOT_FOUND)
462 p->width = p->star_w = FOUND;
463 else
464 p->precision = p->star_p = FOUND;
465 break;
466 case '+': p->justify = RIGHT; break;
467 case '-': p->justify = LEFT; break;
468 case '.': if (p->width == NOT_FOUND)
469 p->width = 0;
470 break;
471 case '0': p->pad = '0'; break;
472 case '1': case '2': case '3':
473 case '4': case '5': case '6':
474 case '7': case '8': case '9': /* gob all the digits */
475 for (i = 0; isdigit(*s); i++, s++)
476 if (i < MAX_FIELD/2 - 1)
477 number[i] = *s;
478 number[i] = '\0';
479 if (p->width == NOT_FOUND)
480 p->width = atoi(number);
481 else
482 p->precision = atoi(number);
483 s--; /* went to far go back */
484 break;
485 }
486 }
487 }
488
489 PUBLIC int
490 #ifdef __STDC__
491 vsnprintf(char *string, size_t length, const char * format, va_list args)
492 #else
493 vsnprintf(string, length, format, args)
494 char *string;
495 size_t length;
496 char * format;
497 va_list args;
498 #endif
499 {
500 struct DATA data;
501 char conv_field[MAX_FIELD];
502 double d; /* temporary holder */
503 int state;
504 int i;
505
506 data.length = length - 1; /* leave room for '\0' */
507 data.holder = string;
508 data.pf = format;
509 data.counter = 0;
510
511
512 /* sanity check, the string must be > 1 */
513 if (length < 1)
514 return -1;
515
516
517 for (; *data.pf && (data.counter < data.length); data.pf++) {
518 if ( *data.pf == '%' ) { /* we got a magic % cookie */
519 conv_flag((char *)0, &data); /* initialise format flags */
520 for (state = 1; *data.pf && state;) {
521 switch (*(++data.pf)) {
522 case '\0': /* a NULL here ? ? bail out */
523 *data.holder = '\0';
524 return data.counter;
525 break;
526 case 'f': /* float, double */
527 STAR_ARGS(&data);
528 if (data.a_long == FOUND)
529 d = va_arg(args, LONG_DOUBLE);
530 else
531 d = va_arg(args, double);
532 floating(&data, d);
533 state = 0;
534 break;
535 case 'g':
536 case 'G':
537 STAR_ARGS(&data);
538 DEF_PREC(&data);
539 if (data.a_long == FOUND)
540 d = va_arg(args, LONG_DOUBLE);
541 else
542 d = va_arg(args, double);
543 i = log_10(d);
544 /*
545 * for '%g|%G' ANSI: use f if exponent
546 * is in the range or [-4,p] exclusively
547 * else use %e|%E
548 */
549 if (-4 < i && i < data.precision)
550 floating(&data, d);
551 else
552 exponent(&data, d);
553 state = 0;
554 break;
555 case 'e':
556 case 'E': /* Exponent double */
557 STAR_ARGS(&data);
558 if (data.a_long == FOUND)
559 d = va_arg(args, LONG_DOUBLE);
560 else
561 d = va_arg(args, double);
562 exponent(&data, d);
563 state = 0;
564 break;
565 case 'u': /* unsigned decimal */
566 STAR_ARGS(&data);
567 if (data.a_longlong == FOUND)
568 d = va_arg(args, unsigned LONG_LONG);
569 else if (data.a_long == FOUND)
570 d = va_arg(args, unsigned long);
571 else
572 d = va_arg(args, unsigned int);
573 decimal(&data, d);
574 state = 0;
575 break;
576 case 'd': /* decimal */
577 STAR_ARGS(&data);
578 if (data.a_longlong == FOUND)
579 d = va_arg(args, LONG_LONG);
580 else if (data.a_long == FOUND)
581 d = va_arg(args, long);
582 else
583 d = va_arg(args, int);
584 decimal(&data, d);
585 state = 0;
586 break;
587 case 'o': /* octal */
588 STAR_ARGS(&data);
589 if (data.a_longlong == FOUND)
590 d = va_arg(args, LONG_LONG);
591 else if (data.a_long == FOUND)
592 d = va_arg(args, long);
593 else
594 d = va_arg(args, int);
595 octal(&data, d);
596 state = 0;
597 break;
598 case 'x':
599 case 'X': /* hexadecimal */
600 STAR_ARGS(&data);
601 if (data.a_longlong == FOUND)
602 d = va_arg(args, LONG_LONG);
603 else if (data.a_long == FOUND)
604 d = va_arg(args, long);
605 else
606 d = va_arg(args, int);
607 hexa(&data, d);
608 state = 0;
609 break;
610 case 'c': /* character */
611 d = va_arg(args, int);
612 PUT_CHAR(d, &data);
613 state = 0;
614 break;
615 case 's': /* string */
616 STAR_ARGS(&data);
617 strings(&data, va_arg(args, char *));
618 state = 0;
619 break;
620 case 'n':
621 *(va_arg(args, int *)) = data.counter; /* what's the count ? */
622 state = 0;
623 break;
624 case 'q':
625 data.a_longlong = FOUND;
626 break;
627 case 'L':
628 case 'l':
629 if (data.a_long == FOUND)
630 data.a_longlong = FOUND;
631 else
632 data.a_long = FOUND;
633 break;
634 case 'h':
635 break;
636 case '%': /* nothing just % */
637 PUT_CHAR('%', &data);
638 state = 0;
639 break;
640 case '#': case ' ': case '+': case '*':
641 case '-': case '.': case '0': case '1':
642 case '2': case '3': case '4': case '5':
643 case '6': case '7': case '8': case '9':
644 /* initialize width and precision */
645 for (i = 0; isflag(*data.pf); i++, data.pf++)
646 if (i < MAX_FIELD - 1)
647 conv_field[i] = *data.pf;
648 conv_field[i] = '\0';
649 conv_flag(conv_field, &data);
650 data.pf--; /* went to far go back */
651 break;
652 default:
653 /* is this an error ? maybe bail out */
654 state = 0;
655 break;
656 } /* end switch */
657 } /* end of for state */
658 } else { /* not % */
659 PUT_CHAR(*data.pf, &data); /* add the char the string */
660 }
661 }
662
663 *data.holder = '\0'; /* the end ye ! */
664 24
665 return data.counter; 25 #include <stdarg.h>
666 } 26 #include <stdlib.h>
27 #include <string.h>
667 28
668 #ifndef HAVE_SNPRINTF 29 #include "minmax.h"
30 #include "vasnprintf.h"
669 31
670 PUBLIC int 32 /* Print formatted output to string STR. Similar to sprintf, but
671 #if __STDC__ 33 additional length SIZE limit how much is written into STR. Returns
672 snprintf(char *string, size_t length, const char * format, ...) 34 string length of formatted string (which may be larger than SIZE).
673 #else 35 STR may be NULL, in which case nothing will be written. On error,
674 snprintf(string, length, format, va_alist) 36 return a negative value. */
675 char *string; 37 int
676 size_t length; 38 snprintf (char *str, size_t size, const char *format, ...)
677 char * format;
678 va_dcl
679 #endif
680 { 39 {
681 int rval; 40 char *output;
41 size_t len;
682 va_list args; 42 va_list args;
683 43
684 #if __STDC__ 44 va_start (args, format);
685 va_start(args, format); 45 len = size;
686 #else 46 output = vasnprintf (str, &len, format, args);
687 va_start(args); 47 va_end (args);
688 #endif
689
690 rval = vsnprintf (string, length, format, args);
691
692 va_end(args);
693
694 return rval;
695 }
696
697 #endif /* HAVE_SNPRINTF */
698
699
700 #ifdef DRIVER
701
702 #include <stdio.h>
703
704 /* set of small tests for snprintf() */
705 int main()
706 {
707 char holder[100];
708 int i;
709 48
710 /* 49 if (!output)
711 printf("Suite of test for snprintf:\n"); 50 return -1;
712 printf("a_format\n");
713 printf("printf() format\n");
714 printf("snprintf() format\n\n");
715 */
716 /* Checking the field widths */
717
718 printf("/%%d/, 336\n");
719 snprintf(holder, sizeof holder, "/%d/\n", 336);
720 printf("/%d/\n", 336);
721 printf("%s\n", holder);
722
723 printf("/%%2d/, 336\n");
724 snprintf(holder, sizeof holder, "/%2d/\n", 336);
725 printf("/%2d/\n", 336);
726 printf("%s\n", holder);
727
728 printf("/%%10d/, 336\n");
729 snprintf(holder, sizeof holder, "/%10d/\n", 336);
730 printf("/%10d/\n", 336);
731 printf("%s\n", holder);
732
733 printf("/%%-10d/, 336\n");
734 snprintf(holder, sizeof holder, "/%-10d/\n", 336);
735 printf("/%-10d/\n", 336);
736 printf("%s\n", holder);
737
738 /* long long */
739
740 printf("/%%lld/, 336\n");
741 snprintf(holder, sizeof holder, "/%lld/\n", (LONG_LONG)336);
742 printf("/%lld/\n", (LONG_LONG)336);
743 printf("%s\n", holder);
744
745 printf("/%%2qd/, 336\n");
746 snprintf(holder, sizeof holder, "/%2qd/\n", (LONG_LONG)336);
747 printf("/%2qd/\n", (LONG_LONG)336);
748 printf("%s\n", holder);
749
750 /* floating points */
751
752 printf("/%%f/, 1234.56\n");
753 snprintf(holder, sizeof holder, "/%f/\n", 1234.56);
754 printf("/%f/\n", 1234.56);
755 printf("%s\n", holder);
756
757 printf("/%%e/, 1234.56\n");
758 snprintf(holder, sizeof holder, "/%e/\n", 1234.56);
759 printf("/%e/\n", 1234.56);
760 printf("%s\n", holder);
761
762 printf("/%%4.2f/, 1234.56\n");
763 snprintf(holder, sizeof holder, "/%4.2f/\n", 1234.56);
764 printf("/%4.2f/\n", 1234.56);
765 printf("%s\n", holder);
766
767 printf("/%%3.1f/, 1234.56\n");
768 snprintf(holder, sizeof holder, "/%3.1f/\n", 1234.56);
769 printf("/%3.1f/\n", 1234.56);
770 printf("%s\n", holder);
771
772 printf("/%%10.3f/, 1234.56\n");
773 snprintf(holder, sizeof holder, "/%10.3f/\n", 1234.56);
774 printf("/%10.3f/\n", 1234.56);
775 printf("%s\n", holder);
776
777 printf("/%%10.3e/, 1234.56\n");
778 snprintf(holder, sizeof holder, "/%10.3e/\n", 1234.56);
779 printf("/%10.3e/\n", 1234.56);
780 printf("%s\n", holder);
781
782 printf("/%%+4.2f/, 1234.56\n");
783 snprintf(holder, sizeof holder, "/%+4.2f/\n", 1234.56);
784 printf("/%+4.2f/\n", 1234.56);
785 printf("%s\n", holder);
786
787 printf("/%%010.2f/, 1234.56\n");
788 snprintf(holder, sizeof holder, "/%010.2f/\n", 1234.56);
789 printf("/%010.2f/\n", 1234.56);
790 printf("%s\n", holder);
791
792 #define BLURB "Outstanding acting !"
793 /* strings precisions */
794
795 printf("/%%2s/, \"%s\"\n", BLURB);
796 snprintf(holder, sizeof holder, "/%2s/\n", BLURB);
797 printf("/%2s/\n", BLURB);
798 printf("%s\n", holder);
799
800 printf("/%%22s/ %s\n", BLURB);
801 snprintf(holder, sizeof holder, "/%22s/\n", BLURB);
802 printf("/%22s/\n", BLURB);
803 printf("%s\n", holder);
804
805 printf("/%%22.5s/ %s\n", BLURB);
806 snprintf(holder, sizeof holder, "/%22.5s/\n", BLURB);
807 printf("/%22.5s/\n", BLURB);
808 printf("%s\n", holder);
809
810 printf("/%%-22.5s/ %s\n", BLURB);
811 snprintf(holder, sizeof holder, "/%-22.5s/\n", BLURB);
812 printf("/%-22.5s/\n", BLURB);
813 printf("%s\n", holder);
814
815 /* see some flags */
816
817 printf("%%x %%X %%#x, 31, 31, 31\n");
818 snprintf(holder, sizeof holder, "%x %X %#x\n", 31, 31, 31);
819 printf("%x %X %#x\n", 31, 31, 31);
820 printf("%s\n", holder);
821
822 printf("**%%d**%% d**%% d**, 42, 42, -42\n");
823 snprintf(holder, sizeof holder, "**%d**% d**% d**\n", 42, 42, -42);
824 printf("**%d**% d**% d**\n", 42, 42, -42);
825 printf("%s\n", holder);
826
827 /* other flags */
828
829 printf("/%%g/, 31.4\n");
830 snprintf(holder, sizeof holder, "/%g/\n", 31.4);
831 printf("/%g/\n", 31.4);
832 printf("%s\n", holder);
833
834 printf("/%%.6g/, 31.4\n");
835 snprintf(holder, sizeof holder, "/%.6g/\n", 31.4);
836 printf("/%.6g/\n", 31.4);
837 printf("%s\n", holder);
838
839 printf("/%%.1G/, 31.4\n");
840 snprintf(holder, sizeof holder, "/%.1G/\n", 31.4);
841 printf("/%.1G/\n", 31.4);
842 printf("%s\n", holder);
843
844 printf("abc%%n\n");
845 printf("abc%n", &i); printf("%d\n", i);
846 snprintf(holder, sizeof holder, "abc%n", &i);
847 printf("%s", holder); printf("%d\n\n", i);
848
849 printf("%%*.*s --> 10.10\n");
850 snprintf(holder, sizeof holder, "%*.*s\n", 10, 10, BLURB);
851 printf("%*.*s\n", 10, 10, BLURB);
852 printf("%s\n", holder);
853 51
854 printf("%%%%%%%%\n"); 52 if (str != NULL)
855 snprintf(holder, sizeof holder, "%%%%\n"); 53 if (len > size - 1) /* equivalent to: (size > 0 && len >= size) */
856 printf("%%%%\n"); 54 str[size - 1] = '\0';
857 printf("%s\n", holder);
858 55
859 #define BIG "Hello this is a too big string for the buffer" 56 if (output != str)
860 /* printf("A buffer to small of 10, trying to put this:\n");*/ 57 free (output);
861 printf("<%%>, %s\n", BIG);
862 i = snprintf(holder, 10, "%s\n", BIG);
863 printf("<%s>\n", BIG);
864 printf("<%s>\n", holder);
865 58
866 return 0; 59 return len;
867 } 60 }
868 #endif
......
1 /* 1 /* Formatted output to strings.
2 Unix snprintf implementation. 2 Copyright (C) 2004 Free Software Foundation, Inc.
3 Version 1.3 3 Written by Simon Josefsson.
4 4
5 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Library General Public License as published by 6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2, or (at your option)
8 (at your option) any later version. 8 any later version.
9 9
10 This program is distributed in the hope that it will be useful, 10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Library General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU General Public License along
16 along with this program; if not, write to the Free Software 16 with this program; if not, write to the Free Software Foundation,
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 18
19 Revision History: 19 #ifndef SNPRINTF_H
20 see header of snprintf.c. 20 #define SNPRINTF_H
21 21
22 format: 22 /* Get snprintf declaration, if available. */
23 int snprintf(holder, sizeof_holder, format, ...) 23 #include <stdio.h>
24 24
25 Return values: 25 #if defined HAVE_DECL_SNPRINTF && !HAVE_DECL_SNPRINTF
26 (sizeof_holder - 1) 26 int snprintf (char *str, size_t size, const char *format, ...);
27
28
29 THANKS(for the patches and ideas):
30 Miles Bader
31 Cyrille Rustom
32 Jacek Slabocewiz
33 Mike Parker(mouse)
34
35 Alain Magloire: alainm@rcsm.ee.mcgill.ca
36 */
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #if __STDC__
43 #include <stdarg.h>
44 #else
45 #include <varargs.h>
46 #endif
47
48 #include <stdlib.h> /* for atoi() */
49 #include <ctype.h>
50
51
52 /*
53 * For the FLOATING POINT FORMAT :
54 * the challenge was finding a way to
55 * manipulate the Real numbers without having
56 * to resort to mathematical function(it
57 * would require to link with -lm) and not
58 * going down to the bit pattern(not portable)
59 *
60 * so a number, a real is:
61
62 real = integral + fraction
63
64 integral = ... + a(2)*10^2 + a(1)*10^1 + a(0)*10^0
65 fraction = b(1)*10^-1 + b(2)*10^-2 + ...
66
67 where:
68 0 <= a(i) => 9
69 0 <= b(i) => 9
70
71 from then it was simple math
72 */
73
74 /*
75 * size of the buffer for the integral part
76 * and the fraction part
77 */
78 #define MAX_INT 99 + 1 /* 1 for the null */
79 #define MAX_FRACT 29 + 1
80
81 /*
82 * If the compiler supports (long long)
83 */
84 #ifndef LONG_LONG
85 # define LONG_LONG long long
86 /*# define LONG_LONG int64_t*/
87 #endif
88
89 /*
90 * If the compiler supports (long double)
91 */
92 #ifndef LONG_DOUBLE
93 # define LONG_DOUBLE long double
94 /*# define LONG_DOUBLE double*/
95 #endif 27 #endif
96 28
97 /* 29 #endif /* SNPRINTF_H */
98 * numtoa() uses PRIVATE buffers to store the results,
99 * So this function is not reentrant
100 */
101 #define itoa(n) numtoa(n, 10, 0, (char **)0)
102 #define otoa(n) numtoa(n, 8, 0, (char **)0)
103 #define htoa(n) numtoa(n, 16, 0, (char **)0)
104 #define dtoa(n, p, f) numtoa(n, 10, p, f)
105
106 #define SWAP_INT(a,b) {int t; t = (a); (a) = (b); (b) = t;}
107
108 /* this struct holds everything we need */
109 struct DATA {
110 int length;
111 char *holder;
112 int counter;
113 #ifdef __STDC__
114 const char *pf;
115 #else
116 char *pf;
117 #endif
118 /* FLAGS */
119 int width, precision;
120 int justify; char pad;
121 int square, space, star_w, star_p, a_long, a_longlong;
122 };
123
124 #define PRIVATE static
125 #define PUBLIC
126 /* signature of the functions */
127 #ifdef __STDC__
128 /* the floating point stuff */
129 PRIVATE double pow_10(int);
130 PRIVATE int log_10(double);
131 PRIVATE double integral(double, double *);
132 PRIVATE char * numtoa(double, int, int, char **);
133
134 /* for the format */
135 PRIVATE void conv_flag(char *, struct DATA *);
136 PRIVATE void floating(struct DATA *, double);
137 PRIVATE void exponent(struct DATA *, double);
138 PRIVATE void decimal(struct DATA *, double);
139 PRIVATE void octal(struct DATA *, double);
140 PRIVATE void hexa(struct DATA *, double);
141 PRIVATE void strings(struct DATA *, char *);
142
143 #else
144 /* the floating point stuff */
145 PRIVATE double pow_10();
146 PRIVATE int log_10();
147 PRIVATE double integral();
148 PRIVATE char * numtoa();
149
150 /* for the format */
151 PRIVATE void conv_flag();
152 PRIVATE void floating();
153 PRIVATE void exponent();
154 PRIVATE void decimal();
155 PRIVATE void octal();
156 PRIVATE void hexa();
157 PRIVATE void strings();
158 #endif
159
160 /* those are defines specific to snprintf to hopefully
161 * make the code clearer :-)
162 */
163 #define RIGHT 1
164 #define LEFT 0
165 #define NOT_FOUND -1
166 #define FOUND 1
167 #define MAX_FIELD 15
168
169 /* the conversion flags */
170 #define isflag(c) ((c) == '#' || (c) == ' ' || \
171 (c) == '*' || (c) == '+' || \
172 (c) == '-' || (c) == '.' || \
173 isdigit(c))
174
175 /* round off to the precision */
176 #define ROUND(d, p) \
177 (d < 0.) ? \
178 d - pow_10(-(p)->precision) * 0.5 : \
179 d + pow_10(-(p)->precision) * 0.5
180
181 /* set default precision */
182 #define DEF_PREC(p) \
183 if ((p)->precision == NOT_FOUND) \
184 (p)->precision = 6
185
186 /* put a char */
187 #define PUT_CHAR(c, p) \
188 if ((p)->counter < (p)->length) { \
189 *(p)->holder++ = (c); \
190 (p)->counter++; \
191 }
192
193 #define PUT_PLUS(d, p) \
194 if ((d) > 0. && (p)->justify == RIGHT) \
195 PUT_CHAR('+', p)
196
197 #define PUT_SPACE(d, p) \
198 if ((p)->space == FOUND && (d) > 0.) \
199 PUT_CHAR(' ', p)
200
201 /* pad right */
202 #define PAD_RIGHT(p) \
203 if ((p)->width > 0 && (p)->justify != LEFT) \
204 for (; (p)->width > 0; (p)->width--) \
205 PUT_CHAR((p)->pad, p)
206
207 /* pad left */
208 #define PAD_LEFT(p) \
209 if ((p)->width > 0 && (p)->justify == LEFT) \
210 for (; (p)->width > 0; (p)->width--) \
211 PUT_CHAR((p)->pad, p)
212
213 /* if width and prec. in the args */
214 #define STAR_ARGS(p) \
215 if ((p)->star_w == FOUND) \
216 (p)->width = va_arg(args, int); \
217 if ((p)->star_p == FOUND) \
218 (p)->precision = va_arg(args, int)
......
1 /* Like vsprintf but provides a pointer to malloc'd storage, which must 1 /* Formatted output to strings.
2 be freed by the caller. 2 Copyright (C) 1999, 2002-2004 Free Software Foundation, Inc.
3 Copyright (C) 1994 Free Software Foundation, Inc.
4 3
5 This program is free software; you can redistribute it and/or modify 4 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 5 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) 6 the Free Software Foundation; either version 2, or (at your option)
8 any later version. 7 any later version.
9 8
10 This program is distributed in the hope that it will be useful, 9 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details. 12 GNU General Public License for more details.
14 13
15 You should have received a copy of the GNU General Public License 14 You should have received a copy of the GNU General Public License along
16 along with this program; if not, write to the Free Software 15 with this program; if not, write to the Free Software Foundation,
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 17
19 #ifdef HAVE_CONFIG_H 18 #ifdef HAVE_CONFIG_H
20 # include <config.h> 19 # include <config.h>
21 #endif 20 #endif
22 21
23 #include <stdio.h> 22 /* Specification. */
24 #include <string.h> 23 #include "vasprintf.h"
25 24
26 #if __STDC__ 25 #include <stdlib.h>
27 # include <stdarg.h>
28 #else
29 # include <varargs.h>
30 #endif
31
32 #ifdef TEST
33 int global_total_width;
34 #endif
35
36 unsigned long strtoul ();
37 char *malloc ();
38
39 static int
40 int_vasprintf (result, format, args)
41 char **result;
42 const char *format;
43 va_list *args;
44 {
45 const char *p = format;
46 /* Add one to make sure that it is never zero, which might cause malloc
47 to return NULL. */
48 int total_width = strlen (format) + 1;
49 va_list ap;
50
51 memcpy (&ap, args, sizeof (va_list));
52
53 while (*p != '\0')
54 {
55 if (*p++ == '%')
56 {
57 while (strchr ("-+ #0", *p))
58 ++p;
59 if (*p == '*')
60 {
61 ++p;
62 total_width += abs (va_arg (ap, int));
63 }
64 else
65 total_width += strtoul (p, &p, 10);
66 if (*p == '.')
67 {
68 ++p;
69 if (*p == '*')
70 {
71 ++p;
72 total_width += abs (va_arg (ap, int));
73 }
74 else
75 total_width += strtoul (p, &p, 10);
76 }
77 while (strchr ("hlL", *p))
78 ++p;
79 /* Should be big enough for any format specifier except %s. */
80 total_width += 30;
81 switch (*p)
82 {
83 case 'd':
84 case 'i':
85 case 'o':
86 case 'u':
87 case 'x':
88 case 'X':
89 case 'c':
90 (void) va_arg (ap, int);
91 break;
92 case 'f':
93 case 'e':
94 case 'E':
95 case 'g':
96 case 'G':
97 (void) va_arg (ap, double);
98 break;
99 case 's':
100 total_width += strlen (va_arg (ap, char *));
101 break;
102 case 'p':
103 case 'n':
104 (void) va_arg (ap, char *);
105 break;
106 }
107 }
108 }
109 #ifdef TEST
110 global_total_width = total_width;
111 #endif
112 *result = malloc (total_width);
113 if (*result != NULL)
114 return vsprintf (*result, format, *args);
115 else
116 return 0;
117 }
118
119 int
120 vasprintf (result, format, args)
121 char **result;
122 const char *format;
123 va_list args;
124 {
125 return int_vasprintf (result, format, &args);
126 }
127 26
128 int 27 #include "vasnprintf.h"
129 asprintf
130 #if __STDC__
131 (char **result, const char *format, ...)
132 #else
133 (result, va_alist)
134 char **result;
135 va_dcl
136 #endif
137 {
138 va_list args;
139 int done;
140
141 #if __STDC__
142 va_start (args, format);
143 #else
144 char *format;
145 va_start (args);
146 format = va_arg (args, char *);
147 #endif
148 done = vasprintf (result, format, args);
149 va_end (args);
150
151 return done;
152 }
153
154 #ifdef TEST
155 void
156 checkit
157 #if __STDC__
158 (const char* format, ...)
159 #else
160 (va_alist)
161 va_dcl
162 #endif
163 {
164 va_list args;
165 char *result;
166
167 #if __STDC__
168 va_start (args, format);
169 #else
170 char *format;
171 va_start (args);
172 format = va_arg (args, char *);
173 #endif
174 vasprintf (&result, format, args);
175 va_end (args);
176 if (strlen (result) < global_total_width)
177 printf ("PASS: ");
178 else
179 printf ("FAIL: ");
180 printf ("%d %s\n", global_total_width, result);
181 }
182 28
183 int 29 int
184 main () 30 vasprintf (char **resultp, const char *format, va_list args)
185 { 31 {
186 checkit ("%d", 0x12345678); 32 size_t length;
187 checkit ("%200d", 5); 33 char *result = vasnprintf (NULL, &length, format, args);
188 checkit ("%.300d", 6); 34 if (result == NULL)
189 checkit ("%100.150d", 7); 35 return -1;
190 checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\ 36
191 777777777777777777333333333333366666666666622222222222777777777777733333"); 37 *resultp = result;
192 checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx"); 38 /* Return the number of resulting bytes, excluding the trailing NUL.
39 If it wouldn't fit in an 'int', vasnprintf() would have returned NULL
40 and set errno to EOVERFLOW. */
41 return length;
193 } 42 }
194 #endif /* TEST */
......
1 /* xalloc.h -- malloc with out-of-memory checking 1 /* xalloc.h -- malloc with out-of-memory checking
2 Copyright (C) 1990-1998, 1999 Free Software Foundation, Inc. 2
3 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
3 5
4 This program is free software; you can redistribute it and/or modify 6 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 7 it under the terms of the GNU General Public License as published by
...@@ -18,14 +20,14 @@ ...@@ -18,14 +20,14 @@
18 #ifndef XALLOC_H_ 20 #ifndef XALLOC_H_
19 # define XALLOC_H_ 21 # define XALLOC_H_
20 22
21 # ifndef PARAMS 23 # include <stddef.h>
22 # if defined PROTOTYPES || (defined __STDC__ && __STDC__) 24
23 # define PARAMS(Args) Args 25
24 # else 26 # ifdef __cplusplus
25 # define PARAMS(Args) () 27 extern "C" {
26 # endif
27 # endif 28 # endif
28 29
30
29 # ifndef __attribute__ 31 # ifndef __attribute__
30 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ 32 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
31 # define __attribute__(x) 33 # define __attribute__(x)
...@@ -36,52 +38,42 @@ ...@@ -36,52 +38,42 @@
36 # define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) 38 # define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
37 # endif 39 # endif
38 40
39 /* Exit value when the requested amount of memory is not available. 41 /* This function is always triggered when memory is exhausted.
40 It is initialized to EXIT_FAILURE, but the caller may set it to 42 It must be defined by the application, either explicitly
41 some other value. */ 43 or by using gnulib's xalloc-die module. This is the
42 extern int xalloc_exit_failure;
43
44 /* If this pointer is non-zero, run the specified function upon each
45 allocation failure. It is initialized to zero. */
46 extern void (*xalloc_fail_func) PARAMS ((void));
47
48 /* If XALLOC_FAIL_FUNC is undefined or a function that returns, this
49 message must be non-NULL. It is translated via gettext.
50 The default value is "Memory exhausted". */
51 extern char *const xalloc_msg_memory_exhausted;
52
53 /* This function is always triggered when memory is exhausted. It is
54 in charge of honoring the three previous items. This is the
55 function to call when one wants the program to die because of a 44 function to call when one wants the program to die because of a
56 memory allocation failure. */ 45 memory allocation failure. */
57 extern void xalloc_die PARAMS ((void)) ATTRIBUTE_NORETURN; 46 extern void xalloc_die (void) ATTRIBUTE_NORETURN;
58 47
59 void *xmalloc PARAMS ((size_t n)); 48 void *xmalloc (size_t s);
60 void *xcalloc PARAMS ((size_t n, size_t s)); 49 void *xnmalloc (size_t n, size_t s);
61 void *xrealloc PARAMS ((void *p, size_t n)); 50 void *xzalloc (size_t s);
62 char *xstrdup PARAMS ((const char *str)); 51 void *xcalloc (size_t n, size_t s);
63 52 void *xrealloc (void *p, size_t s);
64 # define XMALLOC(Type, N_items) ((Type *) xmalloc (sizeof (Type) * (N_items))) 53 void *xnrealloc (void *p, size_t n, size_t s);
65 # define XCALLOC(Type, N_items) ((Type *) xcalloc (sizeof (Type), (N_items))) 54 void *x2realloc (void *p, size_t *pn);
66 # define XREALLOC(Ptr, Type, N_items) \ 55 void *x2nrealloc (void *p, size_t *pn, size_t s);
67 ((Type *) xrealloc ((void *) (Ptr), sizeof (Type) * (N_items))) 56 void *xmemdup (void const *p, size_t s);
68 57 char *xstrdup (char const *str);
69 /* Declare and alloc memory for VAR of type TYPE. */ 58
70 # define NEW(Type, Var) Type *(Var) = XMALLOC (Type, 1) 59 /* Return 1 if an array of N objects, each of size S, cannot exist due
71 60 to size arithmetic overflow. S must be positive and N must be
72 /* Free VAR only if non NULL. */ 61 nonnegative. This is a macro, not an inline function, so that it
73 # define XFREE(Var) \ 62 works correctly even when SIZE_MAX < N.
74 do { \ 63
75 if (Var) \ 64 By gnulib convention, SIZE_MAX represents overflow in size
76 free (Var); \ 65 calculations, so the conservative dividend to use here is
77 } while (0) 66 SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
78 67 However, malloc (SIZE_MAX) fails on all known hosts where
79 /* Return a pointer to a malloc'ed copy of the array SRC of NUM elements. */ 68 sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
80 # define CCLONE(Src, Num) \ 69 exactly-SIZE_MAX allocations on such hosts; this avoids a test and
81 (memcpy (xmalloc (sizeof (*Src) * (Num)), (Src), sizeof (*Src) * (Num))) 70 branch when S is known to be 1. */
82 71 # define xalloc_oversized(n, s) \
83 /* Return a malloc'ed copy of SRC. */ 72 ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
84 # define CLONE(Src) CCLONE (Src, 1) 73
74 # ifdef __cplusplus
75 }
76 # endif
85 77
86 78
87 #endif /* !XALLOC_H_ */ 79 #endif /* !XALLOC_H_ */
......
1 /* xmalloc.c -- malloc with out of memory checking 1 /* xmalloc.c -- malloc with out of memory checking
2 Copyright (C) 1990-1997, 98, 99 Free Software Foundation, Inc. 2
3 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
3 5
4 This program is free software; you can redistribute it and/or modify 6 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 7 it under the terms of the GNU General Public License as published by
...@@ -19,64 +21,31 @@ ...@@ -19,64 +21,31 @@
19 # include <config.h> 21 # include <config.h>
20 #endif 22 #endif
21 23
22 #include <sys/types.h>
23
24 #include <mailutils/error.h>
25
26 #if STDC_HEADERS
27 # include <stdlib.h>
28 #else
29 void *calloc ();
30 void *malloc ();
31 void *realloc ();
32 void free ();
33 #endif
34
35 #if ENABLE_NLS
36 # include <libintl.h>
37 # define _(Text) gettext (Text)
38 #else
39 # define textdomain(Domain)
40 # define _(Text) Text
41 #endif
42 #define N_(Text) Text
43
44 #include "error.h"
45 #include "xalloc.h" 24 #include "xalloc.h"
46 25
47 #ifndef EXIT_FAILURE 26 #include <stdlib.h>
48 # define EXIT_FAILURE 1 27 #include <string.h>
49 #endif
50
51 #ifndef HAVE_MALLOC
52 # error "you must run the autoconf test for a properly working malloc -- see malloc.m4"
53 #endif
54 28
55 #ifndef HAVE_REALLOC 29 #ifndef SIZE_MAX
56 # error "you must run the autoconf test for a properly working realloc -- see realloc.m4" 30 # define SIZE_MAX ((size_t) -1)
57 #endif 31 #endif
58 32
59 /* Exit value when the requested amount of memory is not available. 33 /* Allocate an array of N objects, each with S bytes of memory,
60 The caller may set it to some other value. */ 34 dynamically, with error checking. S must be nonzero. */
61 int xalloc_exit_failure = EXIT_FAILURE;
62
63 /* If non NULL, call this function when memory is exhausted. */
64 void (*xalloc_fail_func) PARAMS ((void)) = 0;
65 35
66 /* If XALLOC_FAIL_FUNC is NULL, or does return, display this message 36 static inline void *
67 before exiting when memory is exhausted. Goes through gettext. */ 37 xnmalloc_inline (size_t n, size_t s)
68 char *const xalloc_msg_memory_exhausted = N_("Memory exhausted"); 38 {
39 void *p;
40 if (xalloc_oversized (n, s) || (! (p = malloc (n * s)) && n != 0))
41 xalloc_die ();
42 return p;
43 }
69 44
70 void 45 void *
71 xalloc_die (void) 46 xnmalloc (size_t n, size_t s)
72 { 47 {
73 if (xalloc_fail_func) 48 return xnmalloc_inline (n, s);
74 (*xalloc_fail_func) ();
75 mu_error ("%s", _(xalloc_msg_memory_exhausted));
76 /* The `noreturn' cannot be given to error, since it may return if
77 its first argument is 0. To help compilers understand the
78 xalloc_die does terminate, call exit. */
79 exit (xalloc_exit_failure);
80 } 49 }
81 50
82 /* Allocate N bytes of memory dynamically, with error checking. */ 51 /* Allocate N bytes of memory dynamically, with error checking. */
...@@ -84,36 +53,177 @@ xalloc_die (void) ...@@ -84,36 +53,177 @@ xalloc_die (void)
84 void * 53 void *
85 xmalloc (size_t n) 54 xmalloc (size_t n)
86 { 55 {
87 void *p; 56 return xnmalloc_inline (n, 1);
57 }
58
59 /* Change the size of an allocated block of memory P to an array of N
60 objects each of S bytes, with error checking. S must be nonzero. */
88 61
89 p = malloc (n); 62 static inline void *
90 if (p == 0) 63 xnrealloc_inline (void *p, size_t n, size_t s)
64 {
65 if (xalloc_oversized (n, s) || (! (p = realloc (p, n * s)) && n != 0))
91 xalloc_die (); 66 xalloc_die ();
92 return p; 67 return p;
93 } 68 }
94 69
70 void *
71 xnrealloc (void *p, size_t n, size_t s)
72 {
73 return xnrealloc_inline (p, n, s);
74 }
75
95 /* Change the size of an allocated block of memory P to N bytes, 76 /* Change the size of an allocated block of memory P to N bytes,
96 with error checking. 77 with error checking. */
97 If P is NULL, run xmalloc. */
98 78
99 void * 79 void *
100 xrealloc (void *p, size_t n) 80 xrealloc (void *p, size_t n)
101 { 81 {
102 p = realloc (p, n); 82 return xnrealloc_inline (p, n, 1);
103 if (p == 0) 83 }
84
85
86 /* If P is null, allocate a block of at least *PN such objects;
87 otherwise, reallocate P so that it contains more than *PN objects
88 each of S bytes. *PN must be nonzero unless P is null, and S must
89 be nonzero. Set *PN to the new number of objects, and return the
90 pointer to the new block. *PN is never set to zero, and the
91 returned pointer is never null.
92
93 Repeated reallocations are guaranteed to make progress, either by
94 allocating an initial block with a nonzero size, or by allocating a
95 larger block.
96
97 In the following implementation, nonzero sizes are doubled so that
98 repeated reallocations have O(N log N) overall cost rather than
99 O(N**2) cost, but the specification for this function does not
100 guarantee that sizes are doubled.
101
102 Here is an example of use:
103
104 int *p = NULL;
105 size_t used = 0;
106 size_t allocated = 0;
107
108 void
109 append_int (int value)
110 {
111 if (used == allocated)
112 p = x2nrealloc (p, &allocated, sizeof *p);
113 p[used++] = value;
114 }
115
116 This causes x2nrealloc to allocate a block of some nonzero size the
117 first time it is called.
118
119 To have finer-grained control over the initial size, set *PN to a
120 nonzero value before calling this function with P == NULL. For
121 example:
122
123 int *p = NULL;
124 size_t used = 0;
125 size_t allocated = 0;
126 size_t allocated1 = 1000;
127
128 void
129 append_int (int value)
130 {
131 if (used == allocated)
132 {
133 p = x2nrealloc (p, &allocated1, sizeof *p);
134 allocated = allocated1;
135 }
136 p[used++] = value;
137 }
138
139 */
140
141 static inline void *
142 x2nrealloc_inline (void *p, size_t *pn, size_t s)
143 {
144 size_t n = *pn;
145
146 if (! p)
147 {
148 if (! n)
149 {
150 /* The approximate size to use for initial small allocation
151 requests, when the invoking code specifies an old size of
152 zero. 64 bytes is the largest "small" request for the
153 GNU C library malloc. */
154 enum { DEFAULT_MXFAST = 64 };
155
156 n = DEFAULT_MXFAST / s;
157 n += !n;
158 }
159 }
160 else
161 {
162 if (SIZE_MAX / 2 / s < n)
104 xalloc_die (); 163 xalloc_die ();
105 return p; 164 n *= 2;
165 }
166
167 *pn = n;
168 return xrealloc (p, n * s);
169 }
170
171 void *
172 x2nrealloc (void *p, size_t *pn, size_t s)
173 {
174 return x2nrealloc_inline (p, pn, s);
106 } 175 }
107 176
108 /* Allocate memory for N elements of S bytes, with error checking. */ 177 /* If P is null, allocate a block of at least *PN bytes; otherwise,
178 reallocate P so that it contains more than *PN bytes. *PN must be
179 nonzero unless P is null. Set *PN to the new block's size, and
180 return the pointer to the new block. *PN is never set to zero, and
181 the returned pointer is never null. */
182
183 void *
184 x2realloc (void *p, size_t *pn)
185 {
186 return x2nrealloc_inline (p, pn, 1);
187 }
188
189 /* Allocate S bytes of zeroed memory dynamically, with error checking.
190 There's no need for xnzalloc (N, S), since it would be equivalent
191 to xcalloc (N, S). */
192
193 void *
194 xzalloc (size_t s)
195 {
196 return memset (xmalloc (s), 0, s);
197 }
198
199 /* Allocate zeroed memory for N elements of S bytes, with error
200 checking. S must be nonzero. */
109 201
110 void * 202 void *
111 xcalloc (size_t n, size_t s) 203 xcalloc (size_t n, size_t s)
112 { 204 {
113 void *p; 205 void *p;
114 206 /* Test for overflow, since some calloc implementations don't have
115 p = calloc (n, s); 207 proper overflow checks. */
116 if (p == 0) 208 if (xalloc_oversized (n, s) || (! (p = calloc (n, s)) && n != 0))
117 xalloc_die (); 209 xalloc_die ();
118 return p; 210 return p;
119 } 211 }
212
213 /* Clone an object P of size S, with error checking. There's no need
214 for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
215 need for an arithmetic overflow check. */
216
217 void *
218 xmemdup (void const *p, size_t s)
219 {
220 return memcpy (xmalloc (s), p, s);
221 }
222
223 /* Clone STRING. */
224
225 char *
226 xstrdup (char const *string)
227 {
228 return xmemdup (string, strlen (string) + 1);
229 }
......
1 /* A more useful interface to strtol. 1 /* A more useful interface to strtol.
2 Copyright 1995, 1996, 1998, 1999 Free Software Foundation, Inc. 2
3 Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2003, 2004 Free
4 Software Foundation, Inc.
3 5
4 This program is free software; you can redistribute it and/or modify 6 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 7 it under the terms of the GNU General Public License as published by
...@@ -25,48 +27,32 @@ ...@@ -25,48 +27,32 @@
25 # define __strtol strtol 27 # define __strtol strtol
26 # define __strtol_t long int 28 # define __strtol_t long int
27 # define __xstrtol xstrtol 29 # define __xstrtol xstrtol
30 # define STRTOL_T_MINIMUM LONG_MIN
31 # define STRTOL_T_MAXIMUM LONG_MAX
28 #endif 32 #endif
29 33
30 /* Some pre-ANSI implementations (e.g. SunOS 4) 34 /* Some pre-ANSI implementations (e.g. SunOS 4)
31 need stderr defined if assertion checking is enabled. */ 35 need stderr defined if assertion checking is enabled. */
32 #include <stdio.h> 36 #include <stdio.h>
33 37
34 #if STDC_HEADERS
35 # include <stdlib.h>
36 #endif
37
38 #if HAVE_STRING_H
39 # include <string.h>
40 #else
41 # include <strings.h>
42 # ifndef strchr
43 # define strchr index
44 # endif
45 #endif
46
47 #include <assert.h> 38 #include <assert.h>
48 #include <ctype.h> 39 #include <ctype.h>
49
50 #include <errno.h> 40 #include <errno.h>
51 #ifndef errno 41 #include <limits.h>
52 extern int errno; 42 #include <stdlib.h>
53 #endif 43 #include <string.h>
54
55 #if HAVE_LIMITS_H
56 # include <limits.h>
57 #endif
58
59 #ifndef CHAR_BIT
60 # define CHAR_BIT 8
61 #endif
62 44
63 /* The extra casts work around common compiler bugs. */ 45 /* The extra casts work around common compiler bugs. */
64 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) 46 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
65 /* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
66 It is necessary at least when t == time_t. */
67 #define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \ 47 #define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
68 ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) 48 ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
69 #define TYPE_MAXIMUM(t) (~ (t) 0 - TYPE_MINIMUM (t)) 49 : (t) 0))
50 #define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
51
52 #ifndef STRTOL_T_MINIMUM
53 # define STRTOL_T_MINIMUM TYPE_MINIMUM (__strtol_t)
54 # define STRTOL_T_MAXIMUM TYPE_MAXIMUM (__strtol_t)
55 #endif
70 56
71 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) 57 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
72 # define IN_CTYPE_DOMAIN(c) 1 58 # define IN_CTYPE_DOMAIN(c) 1
...@@ -78,36 +64,38 @@ extern int errno; ...@@ -78,36 +64,38 @@ extern int errno;
78 64
79 #include "xstrtol.h" 65 #include "xstrtol.h"
80 66
81 #ifndef strtol 67 #if !HAVE_DECL_STRTOIMAX && !defined strtoimax
82 long int strtol (); 68 intmax_t strtoimax ();
83 #endif
84
85 #ifndef strtoul
86 unsigned long int strtoul ();
87 #endif 69 #endif
88 70
89 #ifndef strtoumax 71 #if !HAVE_DECL_STRTOUMAX && !defined strtoumax
90 uintmax_t strtoumax (); 72 uintmax_t strtoumax ();
91 #endif 73 #endif
92 74
93 static int 75 static strtol_error
94 bkm_scale (__strtol_t *x, int scale_factor) 76 bkm_scale (__strtol_t *x, int scale_factor)
95 { 77 {
96 __strtol_t product = *x * scale_factor; 78 if (TYPE_SIGNED (__strtol_t) && *x < STRTOL_T_MINIMUM / scale_factor)
97 if (*x != product / scale_factor) 79 {
98 return 1; 80 *x = STRTOL_T_MINIMUM;
99 *x = product; 81 return LONGINT_OVERFLOW;
100 return 0; 82 }
83 if (STRTOL_T_MAXIMUM / scale_factor < *x)
84 {
85 *x = STRTOL_T_MAXIMUM;
86 return LONGINT_OVERFLOW;
87 }
88 *x *= scale_factor;
89 return LONGINT_OK;
101 } 90 }
102 91
103 static int 92 static strtol_error
104 bkm_scale_by_power (__strtol_t *x, int base, int power) 93 bkm_scale_by_power (__strtol_t *x, int base, int power)
105 { 94 {
95 strtol_error err = LONGINT_OK;
106 while (power--) 96 while (power--)
107 if (bkm_scale (x, base)) 97 err |= bkm_scale (x, base);
108 return 1; 98 return err;
109
110 return 0;
111 } 99 }
112 100
113 /* FIXME: comment. */ 101 /* FIXME: comment. */
...@@ -119,6 +107,7 @@ __xstrtol (const char *s, char **ptr, int strtol_base, ...@@ -119,6 +107,7 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
119 char *t_ptr; 107 char *t_ptr;
120 char **p; 108 char **p;
121 __strtol_t tmp; 109 __strtol_t tmp;
110 strtol_error err = LONGINT_OK;
122 111
123 assert (0 <= strtol_base && strtol_base <= 36); 112 assert (0 <= strtol_base && strtol_base <= 36);
124 113
...@@ -127,18 +116,31 @@ __xstrtol (const char *s, char **ptr, int strtol_base, ...@@ -127,18 +116,31 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
127 if (! TYPE_SIGNED (__strtol_t)) 116 if (! TYPE_SIGNED (__strtol_t))
128 { 117 {
129 const char *q = s; 118 const char *q = s;
130 while (ISSPACE ((unsigned char) *q)) 119 unsigned char ch = *q;
131 ++q; 120 while (ISSPACE (ch))
132 if (*q == '-') 121 ch = *++q;
122 if (ch == '-')
133 return LONGINT_INVALID; 123 return LONGINT_INVALID;
134 } 124 }
135 125
136 errno = 0; 126 errno = 0;
137 tmp = __strtol (s, p, strtol_base); 127 tmp = __strtol (s, p, strtol_base);
138 if (errno != 0) 128
139 return LONGINT_OVERFLOW;
140 if (*p == s) 129 if (*p == s)
130 {
131 /* If there is no number but there is a valid suffix, assume the
132 number is 1. The string is invalid otherwise. */
133 if (valid_suffixes && **p && strchr (valid_suffixes, **p))
134 tmp = 1;
135 else
136 return LONGINT_INVALID;
137 }
138 else if (errno != 0)
139 {
140 if (errno != ERANGE)
141 return LONGINT_INVALID; 141 return LONGINT_INVALID;
142 err = LONGINT_OVERFLOW;
143 }
142 144
143 /* Let valid_suffixes == NULL mean `allow any suffix'. */ 145 /* Let valid_suffixes == NULL mean `allow any suffix'. */
144 /* FIXME: update all callers except the ones that allow suffixes 146 /* FIXME: update all callers except the ones that allow suffixes
...@@ -146,34 +148,39 @@ __xstrtol (const char *s, char **ptr, int strtol_base, ...@@ -146,34 +148,39 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
146 if (!valid_suffixes) 148 if (!valid_suffixes)
147 { 149 {
148 *val = tmp; 150 *val = tmp;
149 return LONGINT_OK; 151 return err;
150 } 152 }
151 153
152 if (**p != '\0') 154 if (**p != '\0')
153 { 155 {
154 int base = 1024; 156 int base = 1024;
155 int suffixes = 1; 157 int suffixes = 1;
156 int overflow; 158 strtol_error overflow;
157 159
158 if (!strchr (valid_suffixes, **p)) 160 if (!strchr (valid_suffixes, **p))
159 { 161 {
160 *val = tmp; 162 *val = tmp;
161 return LONGINT_INVALID_SUFFIX_CHAR; 163 return err | LONGINT_INVALID_SUFFIX_CHAR;
162 } 164 }
163 165
164 if (strchr (valid_suffixes, '0')) 166 if (strchr (valid_suffixes, '0'))
165 { 167 {
166 /* The ``valid suffix'' '0' is a special flag meaning that 168 /* The ``valid suffix'' '0' is a special flag meaning that
167 an optional second suffix is allowed, which can change 169 an optional second suffix is allowed, which can change
168 the base, e.g. "100MD" for 100 megabytes decimal. */ 170 the base. A suffix "B" (e.g. "100MB") stands for a power
171 of 1000, whereas a suffix "iB" (e.g. "100MiB") stands for
172 a power of 1024. If no suffix (e.g. "100M"), assume
173 power-of-1024. */
169 174
170 switch (p[0][1]) 175 switch (p[0][1])
171 { 176 {
172 case 'B': 177 case 'i':
173 suffixes++; 178 if (p[0][2] == 'B')
179 suffixes += 2;
174 break; 180 break;
175 181
176 case 'D': 182 case 'B':
183 case 'D': /* 'D' is obsolescent */
177 base = 1000; 184 base = 1000;
178 suffixes++; 185 suffixes++;
179 break; 186 break;
...@@ -194,28 +201,31 @@ __xstrtol (const char *s, char **ptr, int strtol_base, ...@@ -194,28 +201,31 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
194 overflow = 0; 201 overflow = 0;
195 break; 202 break;
196 203
197 case 'E': /* Exa */ 204 case 'E': /* exa or exbi */
198 overflow = bkm_scale_by_power (&tmp, base, 6); 205 overflow = bkm_scale_by_power (&tmp, base, 6);
199 break; 206 break;
200 207
201 case 'G': /* Giga */ 208 case 'G': /* giga or gibi */
209 case 'g': /* 'g' is undocumented; for compatibility only */
202 overflow = bkm_scale_by_power (&tmp, base, 3); 210 overflow = bkm_scale_by_power (&tmp, base, 3);
203 break; 211 break;
204 212
205 case 'k': /* kilo */ 213 case 'k': /* kilo */
214 case 'K': /* kibi */
206 overflow = bkm_scale_by_power (&tmp, base, 1); 215 overflow = bkm_scale_by_power (&tmp, base, 1);
207 break; 216 break;
208 217
209 case 'M': /* Mega */ 218 case 'M': /* mega or mebi */
210 case 'm': /* 'm' is undocumented; for backward compatibility only */ 219 case 'm': /* 'm' is undocumented; for compatibility only */
211 overflow = bkm_scale_by_power (&tmp, base, 2); 220 overflow = bkm_scale_by_power (&tmp, base, 2);
212 break; 221 break;
213 222
214 case 'P': /* Peta */ 223 case 'P': /* peta or pebi */
215 overflow = bkm_scale_by_power (&tmp, base, 5); 224 overflow = bkm_scale_by_power (&tmp, base, 5);
216 break; 225 break;
217 226
218 case 'T': /* Tera */ 227 case 'T': /* tera or tebi */
228 case 't': /* 't' is undocumented; for compatibility only */
219 overflow = bkm_scale_by_power (&tmp, base, 4); 229 overflow = bkm_scale_by_power (&tmp, base, 4);
220 break; 230 break;
221 231
...@@ -223,28 +233,27 @@ __xstrtol (const char *s, char **ptr, int strtol_base, ...@@ -223,28 +233,27 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
223 overflow = bkm_scale (&tmp, 2); 233 overflow = bkm_scale (&tmp, 2);
224 break; 234 break;
225 235
226 case 'Y': /* Yotta */ 236 case 'Y': /* yotta or 2**80 */
227 overflow = bkm_scale_by_power (&tmp, base, 8); 237 overflow = bkm_scale_by_power (&tmp, base, 8);
228 break; 238 break;
229 239
230 case 'Z': /* Zetta */ 240 case 'Z': /* zetta or 2**70 */
231 overflow = bkm_scale_by_power (&tmp, base, 7); 241 overflow = bkm_scale_by_power (&tmp, base, 7);
232 break; 242 break;
233 243
234 default: 244 default:
235 *val = tmp; 245 *val = tmp;
236 return LONGINT_INVALID_SUFFIX_CHAR; 246 return err | LONGINT_INVALID_SUFFIX_CHAR;
237 break;
238 } 247 }
239 248
240 if (overflow) 249 err |= overflow;
241 return LONGINT_OVERFLOW; 250 *p += suffixes;
242 251 if (**p)
243 (*p) += suffixes; 252 err |= LONGINT_INVALID_SUFFIX_CHAR;
244 } 253 }
245 254
246 *val = tmp; 255 *val = tmp;
247 return LONGINT_OK; 256 return err;
248 } 257 }
249 258
250 #ifdef TESTING_XSTRTO 259 #ifdef TESTING_XSTRTO
...@@ -255,7 +264,7 @@ __xstrtol (const char *s, char **ptr, int strtol_base, ...@@ -255,7 +264,7 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
255 char *program_name; 264 char *program_name;
256 265
257 int 266 int
258 main (int argc, char** argv) 267 main (int argc, char **argv)
259 { 268 {
260 strtol_error s_err; 269 strtol_error s_err;
261 int i; 270 int i;
......
1 /* A more useful interface to strtol.
2
3 Copyright (C) 1995, 1996, 1998, 1999, 2001, 2002, 2003, 2004 Free
4 Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
1 #ifndef XSTRTOL_H_ 20 #ifndef XSTRTOL_H_
2 # define XSTRTOL_H_ 1 21 # define XSTRTOL_H_ 1
3 22
4 # if HAVE_INTTYPES_H 23 # include "exitfail.h"
5 # include <inttypes.h> /* for uintmax_t */
6 # endif
7 24
8 # ifndef PARAMS 25 # if HAVE_INTTYPES_H
9 # if defined PROTOTYPES || (defined __STDC__ && __STDC__) 26 # include <inttypes.h>
10 # define PARAMS(Args) Args
11 # else
12 # define PARAMS(Args) ()
13 # endif 27 # endif
28 # if HAVE_STDINT_H
29 # include <stdint.h>
14 # endif 30 # endif
15 31
16 # ifndef _STRTOL_ERROR 32 # ifndef _STRTOL_ERROR
17 enum strtol_error 33 enum strtol_error
18 { 34 {
19 LONGINT_OK, LONGINT_INVALID, LONGINT_INVALID_SUFFIX_CHAR, LONGINT_OVERFLOW 35 LONGINT_OK = 0,
36
37 /* These two values can be ORed together, to indicate that both
38 errors occurred. */
39 LONGINT_OVERFLOW = 1,
40 LONGINT_INVALID_SUFFIX_CHAR = 2,
41
42 LONGINT_INVALID_SUFFIX_CHAR_WITH_OVERFLOW = (LONGINT_INVALID_SUFFIX_CHAR
43 | LONGINT_OVERFLOW),
44 LONGINT_INVALID = 4
20 }; 45 };
21 typedef enum strtol_error strtol_error; 46 typedef enum strtol_error strtol_error;
22 # endif 47 # endif
23 48
24 # define _DECLARE_XSTRTOL(name, type) \ 49 # define _DECLARE_XSTRTOL(name, type) \
25 strtol_error \ 50 strtol_error name (const char *, char **, int, type *, const char *);
26 name PARAMS ((const char *s, char **ptr, int base, \
27 type *val, const char *valid_suffixes));
28 _DECLARE_XSTRTOL (xstrtol, long int) 51 _DECLARE_XSTRTOL (xstrtol, long int)
29 _DECLARE_XSTRTOL (xstrtoul, unsigned long int) 52 _DECLARE_XSTRTOL (xstrtoul, unsigned long int)
53 _DECLARE_XSTRTOL (xstrtoimax, intmax_t)
30 _DECLARE_XSTRTOL (xstrtoumax, uintmax_t) 54 _DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
31 55
32 # define _STRTOL_ERROR(Exit_code, Str, Argument_type_string, Err) \ 56 # define _STRTOL_ERROR(Exit_code, Str, Argument_type_string, Err) \
...@@ -34,7 +58,7 @@ _DECLARE_XSTRTOL (xstrtoumax, uintmax_t) ...@@ -34,7 +58,7 @@ _DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
34 { \ 58 { \
35 switch ((Err)) \ 59 switch ((Err)) \
36 { \ 60 { \
37 case LONGINT_OK: \ 61 default: \
38 abort (); \ 62 abort (); \
39 \ 63 \
40 case LONGINT_INVALID: \ 64 case LONGINT_INVALID: \
...@@ -43,7 +67,8 @@ _DECLARE_XSTRTOL (xstrtoumax, uintmax_t) ...@@ -43,7 +67,8 @@ _DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
43 break; \ 67 break; \
44 \ 68 \
45 case LONGINT_INVALID_SUFFIX_CHAR: \ 69 case LONGINT_INVALID_SUFFIX_CHAR: \
46 error ((Exit_code), 0, "invalid character following %s `%s'", \ 70 case LONGINT_INVALID_SUFFIX_CHAR | LONGINT_OVERFLOW: \
71 error ((Exit_code), 0, "invalid character following %s in `%s'", \
47 (Argument_type_string), (Str)); \ 72 (Argument_type_string), (Str)); \
48 break; \ 73 break; \
49 \ 74 \
...@@ -56,7 +81,7 @@ _DECLARE_XSTRTOL (xstrtoumax, uintmax_t) ...@@ -56,7 +81,7 @@ _DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
56 while (0) 81 while (0)
57 82
58 # define STRTOL_FATAL_ERROR(Str, Argument_type_string, Err) \ 83 # define STRTOL_FATAL_ERROR(Str, Argument_type_string, Err) \
59 _STRTOL_ERROR (2, Str, Argument_type_string, Err) 84 _STRTOL_ERROR (exit_failure, Str, Argument_type_string, Err)
60 85
61 # define STRTOL_FAIL_WARN(Str, Argument_type_string, Err) \ 86 # define STRTOL_FAIL_WARN(Str, Argument_type_string, Err) \
62 _STRTOL_ERROR (0, Str, Argument_type_string, Err) 87 _STRTOL_ERROR (0, Str, Argument_type_string, Err)
......
1 ## $Id$ 1 # getopt.m4 serial 7
2 dnl Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
2 6
3 ## Check for getopt_long. This can't be done in AC_CHECK_FUNCS since 7 # The getopt module assume you want GNU getopt, with getopt_long etc,
4 ## the function can be present in different libraries (namely, libmysqlclient) 8 # rather than vanilla POSIX getopt. This means your your code should
5 ## but the necessary header files may be absent, thus AC_CHECK_FUNCS will 9 # always include <getopt.h> for the getopt prototypes.
6 ## mark function as existent, whereas the compilation will bail out.
7 10
8 AH_TEMPLATE(HAVE_GNU_GETOPT, [Define if your system has GNU getopt functions]) 11 AC_DEFUN([gl_GETOPT_SUBSTITUTE],
12 [
13 GETOPT_H=getopt.h
14 MU_LIBOBJ([getopt])
15 MU_LIBOBJ([getopt1])
16 AC_DEFINE([__GETOPT_PREFIX], [[rpl_]],
17 [Define to rpl_ if the getopt replacement functions and variables
18 should be used.])
19 AC_SUBST([GETOPT_H])
20 ])
9 21
10 AC_DEFUN([MU_REPLACE_GNU_GETOPT], 22 AC_DEFUN([gl_GETOPT],
11 [ 23 [
12 AC_CHECK_HEADER([getopt.h], 24 gl_PREREQ_GETOPT
13 mu_cv_have_getopt_h=yes
14 AC_DEFINE(HAVE_GETOPT_H,1,[Define if the system has getopt.h]),
15 mu_cv_have_getopt_h=no)
16 AC_CACHE_CHECK([for GNU getopt], mu_cv_have_gnu_getopt,
17 [
18 AC_TRY_RUN([
19 #include <unistd.h>
20 #ifdef HAVE_GETOPT_H
21 # include <getopt.h>
22 #endif
23 25
24 struct option longopt[] = { 26 if test -z "$GETOPT_H"; then
25 "help", no_argument, 0, 'h', 27 GETOPT_H=
26 (char*)0 28 AC_CHECK_HEADERS([getopt.h], [], [GETOPT_H=getopt.h])
27 }; 29 AC_CHECK_FUNCS([getopt_long_only], [], [GETOPT_H=getopt.h])
28 30
29 main(argc, argv) 31 dnl BSD getopt_long uses an incompatible method to reset option processing,
30 int argc; char **argv; 32 dnl and (as of 2004-10-15) mishandles optional option-arguments.
31 { 33 AC_CHECK_DECL([optreset], [GETOPT_H=getopt.h], [], [#include <getopt.h>])
32 getopt_long_only(argc, argv, "h", longopt, (int*)0);
33 return 0;
34 } ],
35 mu_cv_have_gnu_getopt=yes,
36 mu_cv_have_gnu_getopt=no,
37 mu_cv_have_gnu_getopt=no)])
38 34
39 if test x"$mu_cv_have_gnu_getopt" != xyes ; then 35 if test -n "$GETOPT_H"; then
40 mu_cv_have_getopt_h=no 36 gl_GETOPT_SUBSTITUTE
41 MU_LIBOBJ(getopt)
42 MU_LIBOBJ(getopt1)
43 else
44 AC_DEFINE(HAVE_GNU_GETOPT)
45 fi 37 fi
46 if test "$mu_cv_have_getopt_h" = no; then
47 MU_HEADER(getopt.h)
48 fi 38 fi
49 ]) 39 ])
50 40
51 41 # Prerequisites of lib/getopt*.
52 42 AC_DEFUN([gl_PREREQ_GETOPT], [:])
53
......
1 #serial 12 1 #serial 22
2
3 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004 Free
4 # Software Foundation, Inc.
5 #
6 # This file is free software; the Free Software Foundation
7 # gives unlimited permission to copy and/or distribute it,
8 # with or without modifications, as long as this notice is preserved.
2 9
3 dnl Initially derived from code in GNU grep. 10 dnl Initially derived from code in GNU grep.
4 dnl Mostly written by Jim Meyering. 11 dnl Mostly written by Jim Meyering.
5 12
6 dnl Usage: jm_INCLUDED_REGEX([lib/regex.c]) 13 AC_DEFUN([gl_REGEX],
14 [
15 gl_INCLUDED_REGEX([lib/regex.c])
16 ])
17
18 dnl Usage: gl_INCLUDED_REGEX([lib/regex.c])
7 dnl 19 dnl
8 AC_DEFUN([jm_INCLUDED_REGEX], 20 AC_DEFUN([gl_INCLUDED_REGEX],
9 [ 21 [
10 dnl Even packages that don't use regex.c can use this macro. 22 dnl Even packages that don't use regex.c can use this macro.
11 dnl Of course, for them it doesn't do anything. 23 dnl Of course, for them it doesn't do anything.
...@@ -22,6 +34,7 @@ AC_DEFUN([jm_INCLUDED_REGEX], ...@@ -22,6 +34,7 @@ AC_DEFUN([jm_INCLUDED_REGEX],
22 jm_cv_func_working_re_compile_pattern, 34 jm_cv_func_working_re_compile_pattern,
23 AC_TRY_RUN( 35 AC_TRY_RUN(
24 [#include <stdio.h> 36 [#include <stdio.h>
37 #include <string.h>
25 #include <regex.h> 38 #include <regex.h>
26 int 39 int
27 main () 40 main ()
...@@ -30,12 +43,14 @@ AC_DEFUN([jm_INCLUDED_REGEX], ...@@ -30,12 +43,14 @@ AC_DEFUN([jm_INCLUDED_REGEX],
30 const char *s; 43 const char *s;
31 struct re_registers regs; 44 struct re_registers regs;
32 re_set_syntax (RE_SYNTAX_POSIX_EGREP); 45 re_set_syntax (RE_SYNTAX_POSIX_EGREP);
46 memset (&regex, 0, sizeof (regex));
33 [s = re_compile_pattern ("a[[:@:>@:]]b\n", 9, &regex);] 47 [s = re_compile_pattern ("a[[:@:>@:]]b\n", 9, &regex);]
34 /* This should fail with _Invalid character class name_ error. */ 48 /* This should fail with _Invalid character class name_ error. */
35 if (!s) 49 if (!s)
36 exit (1); 50 exit (1);
37 51
38 /* This should succeed, but doesn't for e.g. glibc-2.1.3. */ 52 /* This should succeed, but doesn't for e.g. glibc-2.1.3. */
53 memset (&regex, 0, sizeof (regex));
39 s = re_compile_pattern ("{1", 2, &regex); 54 s = re_compile_pattern ("{1", 2, &regex);
40 55
41 if (s) 56 if (s)
...@@ -43,7 +58,8 @@ AC_DEFUN([jm_INCLUDED_REGEX], ...@@ -43,7 +58,8 @@ AC_DEFUN([jm_INCLUDED_REGEX],
43 58
44 /* The following example is derived from a problem report 59 /* The following example is derived from a problem report
45 against gawk from Jorge Stolfi <stolfi@ic.unicamp.br>. */ 60 against gawk from Jorge Stolfi <stolfi@ic.unicamp.br>. */
46 s = re_compile_pattern ("[[anù]]*n", 7, &regex); 61 memset (&regex, 0, sizeof (regex));
62 s = re_compile_pattern ("[[an\371]]*n", 7, &regex);
47 if (s) 63 if (s)
48 exit (1); 64 exit (1);
49 65
...@@ -51,6 +67,16 @@ AC_DEFUN([jm_INCLUDED_REGEX], ...@@ -51,6 +67,16 @@ AC_DEFUN([jm_INCLUDED_REGEX],
51 if (re_match (&regex, "an", 2, 0, &regs) != 2) 67 if (re_match (&regex, "an", 2, 0, &regs) != 2)
52 exit (1); 68 exit (1);
53 69
70 memset (&regex, 0, sizeof (regex));
71 s = re_compile_pattern ("x", 1, &regex);
72 if (s)
73 exit (1);
74
75 /* The version of regex.c in e.g. GNU libc-2.2.93 didn't
76 work with a negative RANGE argument. */
77 if (re_search (&regex, "wxy", 3, 2, -2, &regs) != 1)
78 exit (1);
79
54 exit (0); 80 exit (0);
55 } 81 }
56 ], 82 ],
...@@ -67,16 +93,34 @@ AC_DEFUN([jm_INCLUDED_REGEX], ...@@ -67,16 +93,34 @@ AC_DEFUN([jm_INCLUDED_REGEX],
67 ifelse(m4_sysval, 0, 93 ifelse(m4_sysval, 0,
68 [ 94 [
69 AC_ARG_WITH(included-regex, 95 AC_ARG_WITH(included-regex,
70 AC_HELP_STRING([--without-included-regex], 96 [ --without-included-regex don't compile regex; this is the default on
71 [don't compile regex; this is the default on systems with version 2 of the GNU C library (use with caution on other system)]), 97 systems with version 2 of the GNU C library
98 (use with caution on other system)],
72 jm_with_regex=$withval, 99 jm_with_regex=$withval,
73 jm_with_regex=$ac_use_included_regex) 100 jm_with_regex=$ac_use_included_regex)
74 if test "$jm_with_regex" = yes; then 101 if test "$jm_with_regex" = yes; then
75 MU_LIBOBJ(regex) 102 MU_LIBOBJ(regex)
76 MU_HEADER(regex.h) 103 gl_PREREQ_REGEX
77 MU_HEADER(posix/regex.h)
78 fi 104 fi
79 ], 105 ],
80 ) 106 )
81 ] 107 ]
82 ) 108 )
109
110 # Prerequisites of lib/regex.c.
111 AC_DEFUN([gl_PREREQ_REGEX],
112 [
113 dnl FIXME: Maybe provide a btowc replacement someday: Solaris 2.5.1 lacks it.
114 dnl FIXME: Check for wctype and iswctype, and and add -lw if necessary
115 dnl to get them.
116
117 dnl Persuade glibc <string.h> to declare mempcpy().
118 AC_REQUIRE([AC_GNU_SOURCE])
119
120 AC_REQUIRE([gl_C_RESTRICT])
121 AC_REQUIRE([AC_FUNC_ALLOCA])
122 AC_REQUIRE([AC_HEADER_STDC])
123 AC_CHECK_HEADERS_ONCE(wchar.h wctype.h)
124 AC_CHECK_FUNCS_ONCE(isascii mempcpy)
125 AC_CHECK_FUNCS(btowc)
126 ])
......
...@@ -3,20 +3,19 @@ ...@@ -3,20 +3,19 @@
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. 4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 This program is free software; you can redistribute it and/or modify
7 modify it under the terms of the GNU Library General Public License as 7 it under the terms of the GNU General Public License as published by
8 published by the Free Software Foundation; either version 2 of the 8 the Free Software Foundation; either version 2, or (at your option)
9 License, or (at your option) any later version. 9 any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 Library General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License along
17 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 with this program; if not, write to the Free Software Foundation,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20 19
21 /* If set by the user program, it should point to string that is the 20 /* If set by the user program, it should point to string that is the
22 bug-reporting address for the program. It will be printed by argp_help if 21 bug-reporting address for the program. It will be printed by argp_help if
......
1 /* Default definition for ARGP_ERR_EXIT_STATUS 1 /* Default definition for ARGP_ERR_EXIT_STATUS
2 Copyright (C) 1997, 2001 Free Software Foundation, Inc. 2 Copyright (C) 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. 4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 This program is free software; you can redistribute it and/or modify
7 modify it under the terms of the GNU Library General Public License as 7 it under the terms of the GNU General Public License as published by
8 published by the Free Software Foundation; either version 2 of the 8 the Free Software Foundation; either version 2, or (at your option)
9 License, or (at your option) any later version. 9 any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 Library General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License along
17 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 with this program; if not, write to the Free Software Foundation,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20 19
21 #ifdef HAVE_CONFIG_H 20 #ifdef HAVE_CONFIG_H
22 #include <config.h> 21 #include <config.h>
23 #endif 22 #endif
24 23
25 #ifdef HAVE_SYSEXITS_H
26 #include <sysexits.h> 24 #include <sysexits.h>
27 #endif
28
29 #ifndef EX_USAGE
30 #define EX_USAGE 64
31 #endif
32 25
33 #include "argp.h" 26 #include "argp.h"
34 27
......
1 /* Word-wrapping and line-truncating streams 1 /* Word-wrapping and line-truncating streams
2 Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc. 2 Copyright (C) 1997,1998,1999,2001,2002,2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. 4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 This program is free software; you can redistribute it and/or modify
7 modify it under the terms of the GNU Library General Public License as 7 it under the terms of the GNU General Public License as published by
8 published by the Free Software Foundation; either version 2 of the 8 the Free Software Foundation; either version 2, or (at your option)
9 License, or (at your option) any later version. 9 any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 Library General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License along
17 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 with this program; if not, write to the Free Software Foundation,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20 19
21 /* This package emulates glibc `line_wrap_stream' semantics for systems that 20 /* This package emulates glibc `line_wrap_stream' semantics for systems that
22 don't have that. */ 21 don't have that. */
...@@ -40,6 +39,12 @@ ...@@ -40,6 +39,12 @@
40 #define isblank(ch) ((ch)==' ' || (ch)=='\t') 39 #define isblank(ch) ((ch)==' ' || (ch)=='\t')
41 #endif 40 #endif
42 41
42 #if defined _LIBC && defined USE_IN_LIBIO
43 # include <wchar.h>
44 # include <libio/libioP.h>
45 # define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
46 #endif
47
43 #define INIT_BUF_SIZE 200 48 #define INIT_BUF_SIZE 200
44 #define PRINTF_SIZE_GUESS 150 49 #define PRINTF_SIZE_GUESS 150
45 50
...@@ -53,8 +58,10 @@ argp_fmtstream_t ...@@ -53,8 +58,10 @@ argp_fmtstream_t
53 __argp_make_fmtstream (FILE *stream, 58 __argp_make_fmtstream (FILE *stream,
54 size_t lmargin, size_t rmargin, ssize_t wmargin) 59 size_t lmargin, size_t rmargin, ssize_t wmargin)
55 { 60 {
56 argp_fmtstream_t fs = malloc (sizeof (struct argp_fmtstream)); 61 argp_fmtstream_t fs;
57 if (fs) 62
63 fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream));
64 if (fs != NULL)
58 { 65 {
59 fs->stream = stream; 66 fs->stream = stream;
60 67
...@@ -64,7 +71,7 @@ __argp_make_fmtstream (FILE *stream, ...@@ -64,7 +71,7 @@ __argp_make_fmtstream (FILE *stream,
64 fs->point_col = 0; 71 fs->point_col = 0;
65 fs->point_offs = 0; 72 fs->point_offs = 0;
66 73
67 fs->buf = malloc (INIT_BUF_SIZE); 74 fs->buf = (char *) malloc (INIT_BUF_SIZE);
68 if (! fs->buf) 75 if (! fs->buf)
69 { 76 {
70 free (fs); 77 free (fs);
...@@ -79,9 +86,12 @@ __argp_make_fmtstream (FILE *stream, ...@@ -79,9 +86,12 @@ __argp_make_fmtstream (FILE *stream,
79 86
80 return fs; 87 return fs;
81 } 88 }
89 #if 0
90 /* Not exported. */
82 #ifdef weak_alias 91 #ifdef weak_alias
83 weak_alias (__argp_make_fmtstream, argp_make_fmtstream) 92 weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
84 #endif 93 #endif
94 #endif
85 95
86 /* Flush FS to its stream, and free it (but don't close the stream). */ 96 /* Flush FS to its stream, and free it (but don't close the stream). */
87 void 97 void
...@@ -89,13 +99,23 @@ __argp_fmtstream_free (argp_fmtstream_t fs) ...@@ -89,13 +99,23 @@ __argp_fmtstream_free (argp_fmtstream_t fs)
89 { 99 {
90 __argp_fmtstream_update (fs); 100 __argp_fmtstream_update (fs);
91 if (fs->p > fs->buf) 101 if (fs->p > fs->buf)
92 fwrite (fs->buf, 1, fs->p - fs->buf, fs->stream); 102 {
103 #ifdef USE_IN_LIBIO
104 if (_IO_fwide (fs->stream, 0) > 0)
105 __fwprintf (fs->stream, L"%.*s", (int) (fs->p - fs->buf), fs->buf);
106 else
107 #endif
108 fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
109 }
93 free (fs->buf); 110 free (fs->buf);
94 free (fs); 111 free (fs);
95 } 112 }
113 #if 0
114 /* Not exported. */
96 #ifdef weak_alias 115 #ifdef weak_alias
97 weak_alias (__argp_fmtstream_free, argp_fmtstream_free) 116 weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
98 #endif 117 #endif
118 #endif
99 119
100 /* Process FS's buffer so that line wrapping is done from POINT_OFFS to the 120 /* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
101 end of its buffer. This code is mostly from glibc stdio/linewrap.c. */ 121 end of its buffer. This code is mostly from glibc stdio/linewrap.c. */
...@@ -129,7 +149,14 @@ __argp_fmtstream_update (argp_fmtstream_t fs) ...@@ -129,7 +149,14 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
129 /* No buffer space for spaces. Must flush. */ 149 /* No buffer space for spaces. Must flush. */
130 size_t i; 150 size_t i;
131 for (i = 0; i < pad; i++) 151 for (i = 0; i < pad; i++)
132 putc (' ', fs->stream); 152 {
153 #ifdef USE_IN_LIBIO
154 if (_IO_fwide (fs->stream, 0) > 0)
155 putwc_unlocked (L' ', fs->stream);
156 else
157 #endif
158 putc_unlocked (' ', fs->stream);
159 }
133 } 160 }
134 fs->point_col = pad; 161 fs->point_col = pad;
135 } 162 }
...@@ -245,9 +272,10 @@ __argp_fmtstream_update (argp_fmtstream_t fs) ...@@ -245,9 +272,10 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
245 at the end of the buffer, and NEXTLINE is in fact empty (and so 272 at the end of the buffer, and NEXTLINE is in fact empty (and so
246 we need not be careful to maintain its contents). */ 273 we need not be careful to maintain its contents). */
247 274
248 if (nextline == buf + len + 1 275 if ((nextline == buf + len + 1
249 ? fs->end - nl < fs->wmargin + 1 276 ? fs->end - nl < fs->wmargin + 1
250 : nextline - (nl + 1) < fs->wmargin) 277 : nextline - (nl + 1) < fs->wmargin)
278 && fs->p > nextline)
251 { 279 {
252 /* The margin needs more blanks than we removed. */ 280 /* The margin needs more blanks than we removed. */
253 if (fs->end - fs->p > fs->wmargin + 1) 281 if (fs->end - fs->p > fs->wmargin + 1)
...@@ -262,9 +290,17 @@ __argp_fmtstream_update (argp_fmtstream_t fs) ...@@ -262,9 +290,17 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
262 else 290 else
263 /* Output the first line so we can use the space. */ 291 /* Output the first line so we can use the space. */
264 { 292 {
293 #ifdef USE_IN_LIBIO
294 if (_IO_fwide (fs->stream, 0) > 0)
295 __fwprintf (fs->stream, L"%.*s\n",
296 (int) (nl - fs->buf), fs->buf);
297 else
298 #endif
299 {
265 if (nl > fs->buf) 300 if (nl > fs->buf)
266 fwrite (fs->buf, 1, nl - fs->buf, fs->stream); 301 fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
267 putc ('\n', fs->stream); 302 putc_unlocked ('\n', fs->stream);
303 }
268 len += buf - fs->buf; 304 len += buf - fs->buf;
269 nl = buf = fs->buf; 305 nl = buf = fs->buf;
270 } 306 }
...@@ -281,7 +317,12 @@ __argp_fmtstream_update (argp_fmtstream_t fs) ...@@ -281,7 +317,12 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
281 *nl++ = ' '; 317 *nl++ = ' ';
282 else 318 else
283 for (i = 0; i < fs->wmargin; ++i) 319 for (i = 0; i < fs->wmargin; ++i)
284 putc (' ', fs->stream); 320 #ifdef USE_IN_LIBIO
321 if (_IO_fwide (fs->stream, 0) > 0)
322 putwc_unlocked (L' ', fs->stream);
323 else
324 #endif
325 putc_unlocked (' ', fs->stream);
285 326
286 /* Copy the tail of the original buffer into the current buffer 327 /* Copy the tail of the original buffer into the current buffer
287 position. */ 328 position. */
...@@ -318,7 +359,15 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount) ...@@ -318,7 +359,15 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
318 /* Flush FS's buffer. */ 359 /* Flush FS's buffer. */
319 __argp_fmtstream_update (fs); 360 __argp_fmtstream_update (fs);
320 361
321 wrote = fwrite (fs->buf, 1, fs->p - fs->buf, fs->stream); 362 #ifdef USE_IN_LIBIO
363 if (_IO_fwide (fs->stream, 0) > 0)
364 {
365 __fwprintf (fs->stream, L"%.*s", (int) (fs->p - fs->buf), fs->buf);
366 wrote = fs->p - fs->buf;
367 }
368 else
369 #endif
370 wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
322 if (wrote == fs->p - fs->buf) 371 if (wrote == fs->p - fs->buf)
323 { 372 {
324 fs->p = fs->buf; 373 fs->p = fs->buf;
...@@ -335,12 +384,13 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount) ...@@ -335,12 +384,13 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
335 if ((size_t) (fs->end - fs->buf) < amount) 384 if ((size_t) (fs->end - fs->buf) < amount)
336 /* Gotta grow the buffer. */ 385 /* Gotta grow the buffer. */
337 { 386 {
338 size_t new_size = fs->end - fs->buf + amount; 387 size_t old_size = fs->end - fs->buf;
339 char *new_buf = realloc (fs->buf, new_size); 388 size_t new_size = old_size + amount;
389 char *new_buf;
340 390
341 if (! new_buf) 391 if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size)))
342 { 392 {
343 errno = ENOMEM; 393 __set_errno (ENOMEM);
344 return 0; 394 return 0;
345 } 395 }
346 396
...@@ -369,19 +419,22 @@ __argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...) ...@@ -369,19 +419,22 @@ __argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
369 419
370 va_start (args, fmt); 420 va_start (args, fmt);
371 avail = fs->end - fs->p; 421 avail = fs->end - fs->p;
372 out = vsnprintf (fs->p, avail, fmt, args); 422 out = __vsnprintf (fs->p, avail, fmt, args);
373 va_end (args); 423 va_end (args);
374 if (out >= avail) 424 if ((size_t) out >= avail)
375 size_guess = out + 1; 425 size_guess = out + 1;
376 } 426 }
377 while (out >= avail); 427 while ((size_t) out >= avail);
378 428
379 fs->p += out; 429 fs->p += out;
380 430
381 return out; 431 return out;
382 } 432 }
433 #if 0
434 /* Not exported. */
383 #ifdef weak_alias 435 #ifdef weak_alias
384 weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf) 436 weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
385 #endif 437 #endif
438 #endif
386 439
387 #endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */ 440 #endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */
......
1 /* Word-wrapping and line-truncating streams. 1 /* Word-wrapping and line-truncating streams.
2 Copyright (C) 1997, 2001 Free Software Foundation, Inc. 2 Copyright (C) 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. 4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 This program is free software; you can redistribute it and/or modify
7 modify it under the terms of the GNU Library General Public License as 7 it under the terms of the GNU General Public License as published by
8 published by the Free Software Foundation; either version 2 of the 8 the Free Software Foundation; either version 2, or (at your option)
9 License, or (at your option) any later version. 9 any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 Library General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License along
17 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 with this program; if not, write to the Free Software Foundation,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20 19
21 /* This package emulates glibc `line_wrap_stream' semantics for systems that 20 /* This package emulates glibc `line_wrap_stream' semantics for systems that
22 don't have that. If the system does have it, it is just a wrapper for 21 don't have that. If the system does have it, it is just a wrapper for
...@@ -34,6 +33,19 @@ ...@@ -34,6 +33,19 @@
34 #include <string.h> 33 #include <string.h>
35 #include <unistd.h> 34 #include <unistd.h>
36 35
36 #ifndef __attribute__
37 /* This feature is available in gcc versions 2.5 and later. */
38 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
39 # define __attribute__(Spec) /* empty */
40 # endif
41 /* The __-protected variants of `format' and `printf' attributes
42 are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
43 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || __STRICT_ANSI__
44 # define __format__ format
45 # define __printf__ printf
46 # endif
47 #endif
48
37 #if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \ 49 #if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \
38 || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H)) 50 || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H))
39 /* line_wrap_stream is available, so use that. */ 51 /* line_wrap_stream is available, so use that. */
...@@ -82,6 +94,9 @@ typedef FILE *argp_fmtstream_t; ...@@ -82,6 +94,9 @@ typedef FILE *argp_fmtstream_t;
82 #else /* !ARGP_FMTSTREAM_USE_LINEWRAP */ 94 #else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
83 /* Guess we have to define our own version. */ 95 /* Guess we have to define our own version. */
84 96
97 #ifndef __const
98 #define __const const
99 #endif
85 100
86 struct argp_fmtstream 101 struct argp_fmtstream
87 { 102 {
...@@ -122,20 +137,22 @@ extern void __argp_fmtstream_free (argp_fmtstream_t __fs); ...@@ -122,20 +137,22 @@ extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
122 extern void argp_fmtstream_free (argp_fmtstream_t __fs); 137 extern void argp_fmtstream_free (argp_fmtstream_t __fs);
123 138
124 extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs, 139 extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
125 const char *__fmt, ...); 140 __const char *__fmt, ...)
141 __attribute__ ((__format__ (printf, 2, 3)));
126 extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs, 142 extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
127 const char *__fmt, ...); 143 __const char *__fmt, ...)
144 __attribute__ ((__format__ (printf, 2, 3)));
128 145
129 extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); 146 extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
130 extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); 147 extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
131 148
132 extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); 149 extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
133 extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); 150 extern int argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
134 151
135 extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs, 152 extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
136 const char *__str, size_t __len); 153 __const char *__str, size_t __len);
137 extern size_t argp_fmtstream_write (argp_fmtstream_t __fs, 154 extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
138 const char *__str, size_t __len); 155 __const char *__str, size_t __len);
139 156
140 /* Access macros for various bits of state. */ 157 /* Access macros for various bits of state. */
141 #define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin) 158 #define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
...@@ -194,7 +211,7 @@ extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); ...@@ -194,7 +211,7 @@ extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
194 211
195 ARGP_FS_EI size_t 212 ARGP_FS_EI size_t
196 __argp_fmtstream_write (argp_fmtstream_t __fs, 213 __argp_fmtstream_write (argp_fmtstream_t __fs,
197 const char *__str, size_t __len) 214 __const char *__str, size_t __len)
198 { 215 {
199 if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len)) 216 if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
200 { 217 {
...@@ -207,7 +224,7 @@ __argp_fmtstream_write (argp_fmtstream_t __fs, ...@@ -207,7 +224,7 @@ __argp_fmtstream_write (argp_fmtstream_t __fs,
207 } 224 }
208 225
209 ARGP_FS_EI int 226 ARGP_FS_EI int
210 __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str) 227 __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str)
211 { 228 {
212 size_t __len = strlen (__str); 229 size_t __len = strlen (__str);
213 if (__len) 230 if (__len)
......
1 /* Real definitions for extern inline functions in argp-fmtstream.h 1 /* Real definitions for extern inline functions in argp-fmtstream.h
2 Copyright (C) 1997 Free Software Foundation, Inc. 2 Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. 4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 This program is free software; you can redistribute it and/or modify
7 modify it under the terms of the GNU Library General Public License as 7 it under the terms of the GNU General Public License as published by
8 published by the Free Software Foundation; either version 2 of the 8 the Free Software Foundation; either version 2, or (at your option)
9 License, or (at your option) any later version. 9 any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 Library General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License along
17 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 with this program; if not, write to the Free Software Foundation,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20 19
21 #ifdef HAVE_CONFIG_H 20 #ifdef HAVE_CONFIG_H
22 #include <config.h> 21 #include <config.h>
...@@ -24,9 +23,11 @@ ...@@ -24,9 +23,11 @@
24 23
25 #define ARGP_FS_EI 24 #define ARGP_FS_EI
26 #undef __OPTIMIZE__ 25 #undef __OPTIMIZE__
27 #define __OPTIMIZE__ 26 #define __OPTIMIZE__ 1
28 #include "argp-fmtstream.h" 27 #include "argp-fmtstream.h"
29 28
29 #if 0
30 /* Not exported. */
30 /* Add weak aliases. */ 31 /* Add weak aliases. */
31 #if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias) 32 #if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias)
32 33
...@@ -39,3 +40,4 @@ weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin) ...@@ -39,3 +40,4 @@ weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin)
39 weak_alias (__argp_fmtstream_point, argp_fmtstream_point) 40 weak_alias (__argp_fmtstream_point, argp_fmtstream_point)
40 41
41 #endif 42 #endif
43 #endif
......
1 /* Hierarchial argument parsing help output 1 /* Hierarchial argument parsing help output
2 Copyright (C) 1995,1996,1997,1998,1999,2000, 2001 Free Software Foundation, Inc. 2 Copyright (C) 1995-2003, 2004, 2005 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. 4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 This program is free software; you can redistribute it and/or modify
7 modify it under the terms of the GNU Library General Public License as 7 it under the terms of the GNU General Public License as published by
8 published by the Free Software Foundation; either version 2 of the 8 the Free Software Foundation; either version 2, or (at your option)
9 License, or (at your option) any later version. 9 any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 Library General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License along
17 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 with this program; if not, write to the Free Software Foundation,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20 19
21 #ifndef _GNU_SOURCE 20 #ifndef _GNU_SOURCE
22 # define _GNU_SOURCE 1 21 # define _GNU_SOURCE 1
...@@ -26,73 +25,35 @@ ...@@ -26,73 +25,35 @@
26 #include <config.h> 25 #include <config.h>
27 #endif 26 #endif
28 27
29 #include <mailutils/nls.h> 28 #include <alloca.h>
30 29 #include <errno.h>
31 #ifndef alloca
32 # ifdef __GNUC__
33 # define alloca __builtin_alloca
34 # define HAVE_ALLOCA 1
35 # else
36 # if defined HAVE_ALLOCA_H || defined _LIBC
37 # include <alloca.h>
38 # else
39 # ifdef _AIX
40 #pragma alloca
41 # else
42 # ifndef alloca
43 char *alloca ();
44 # endif
45 # endif
46 # endif
47 # endif
48 #endif
49
50 #include <stddef.h> 30 #include <stddef.h>
51 #include <stdlib.h> 31 #include <stdlib.h>
52 #include <string.h> 32 #include <string.h>
53 #include <assert.h> 33 #include <assert.h>
54 #include <stdarg.h> 34 #include <stdarg.h>
55 #ifdef HAVE_MALLOC_H
56 # include <malloc.h>
57 #endif
58 #include <ctype.h> 35 #include <ctype.h>
59 36 #include <limits.h>
60 #ifdef HAVE_STRINGS_H 37 #ifdef USE_IN_LIBIO
61 # include <strings.h> 38 # include <wchar.h>
62 #endif 39 #endif
63 40
64 #ifndef _ 41 #ifdef _LIBC
65 /* This is for other GNU distributions with internationalized messages. */
66 # if defined HAVE_LIBINTL_H || defined _LIBC
67 # include <libintl.h> 42 # include <libintl.h>
68 # ifdef _LIBC
69 # undef dgettext 43 # undef dgettext
70 # define dgettext(domain, msgid) __dcgettext (domain, msgid, LC_MESSAGES) 44 # define dgettext(domain, msgid) \
71 # endif 45 INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
72 # else 46 #else
73 # define dgettext(domain, msgid) (msgid) 47 # include "gettext.h"
74 # endif
75 #endif 48 #endif
76 49
77 #include "argp.h" 50 #include "argp.h"
78 #include "argp-fmtstream.h" 51 #include "argp-fmtstream.h"
79 #include "argp-namefrob.h" 52 #include "argp-namefrob.h"
80 53
81 #ifndef __P 54 #ifndef SIZE_MAX
82 # if defined PROTOTYPES || (defined __STDC__ && __STDC__) 55 # define SIZE_MAX ((size_t) -1)
83 # define __P(Args) Args
84 # else
85 # define __P(Args) ()
86 # endif
87 #endif
88
89 #if !HAVE_DECL_STRCHRNUL
90 extern char *strchrnul __P((const char *s, int c_in));
91 #endif 56 #endif
92 #if !HAVE_DECL_STRNDUP
93 extern char *strndup __P((const char *s, size_t n));
94 #endif
95
96 57
97 /* User-selectable (using an environment variable) formatting parameters. 58 /* User-selectable (using an environment variable) formatting parameters.
98 59
...@@ -267,6 +228,9 @@ fill_in_uparams (const struct argp_state *state) ...@@ -267,6 +228,9 @@ fill_in_uparams (const struct argp_state *state)
267 /* Returns true if OPT is an documentation-only entry. */ 228 /* Returns true if OPT is an documentation-only entry. */
268 #define odoc(opt) ((opt)->flags & OPTION_DOC) 229 #define odoc(opt) ((opt)->flags & OPTION_DOC)
269 230
231 /* Returns true if OPT should not be translated */
232 #define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS)
233
270 /* Returns true if OPT is the end-of-list marker for a list of options. */ 234 /* Returns true if OPT is the end-of-list marker for a list of options. */
271 #define oend(opt) __option_is_end (opt) 235 #define oend(opt) __option_is_end (opt)
272 236
...@@ -462,6 +426,8 @@ make_hol (const struct argp *argp, struct hol_cluster *cluster) ...@@ -462,6 +426,8 @@ make_hol (const struct argp *argp, struct hol_cluster *cluster)
462 hol->short_options = malloc (num_short_options + 1); 426 hol->short_options = malloc (num_short_options + 1);
463 427
464 assert (hol->entries && hol->short_options); 428 assert (hol->entries && hol->short_options);
429 if (SIZE_MAX <= UINT_MAX)
430 assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
465 431
466 /* Fill in the entries. */ 432 /* Fill in the entries. */
467 so = hol->short_options; 433 so = hol->short_options;
...@@ -566,7 +532,8 @@ hol_entry_short_iterate (const struct hol_entry *entry, ...@@ -566,7 +532,8 @@ hol_entry_short_iterate (const struct hol_entry *entry,
566 return val; 532 return val;
567 } 533 }
568 534
569 static int 535 static inline int
536 __attribute__ ((always_inline))
570 hol_entry_long_iterate (const struct hol_entry *entry, 537 hol_entry_long_iterate (const struct hol_entry *entry,
571 int (*func)(const struct argp_option *opt, 538 int (*func)(const struct argp_option *opt,
572 const struct argp_option *real, 539 const struct argp_option *real,
...@@ -590,7 +557,7 @@ hol_entry_long_iterate (const struct hol_entry *entry, ...@@ -590,7 +557,7 @@ hol_entry_long_iterate (const struct hol_entry *entry,
590 } 557 }
591 558
592 /* Iterator that returns true for the first short option. */ 559 /* Iterator that returns true for the first short option. */
593 static int 560 static inline int
594 until_short (const struct argp_option *opt, const struct argp_option *real, 561 until_short (const struct argp_option *opt, const struct argp_option *real,
595 const char *domain, void *cookie) 562 const char *domain, void *cookie)
596 { 563 {
...@@ -712,6 +679,11 @@ static int ...@@ -712,6 +679,11 @@ static int
712 canon_doc_option (const char **name) 679 canon_doc_option (const char **name)
713 { 680 {
714 int non_opt; 681 int non_opt;
682
683 if (!*name)
684 non_opt = 1;
685 else
686 {
715 /* Skip initial whitespace. */ 687 /* Skip initial whitespace. */
716 while (isspace (**name)) 688 while (isspace (**name))
717 (*name)++; 689 (*name)++;
...@@ -720,6 +692,7 @@ canon_doc_option (const char **name) ...@@ -720,6 +692,7 @@ canon_doc_option (const char **name)
720 /* Skip until part of name used for sorting. */ 692 /* Skip until part of name used for sorting. */
721 while (**name && !isalnum (**name)) 693 while (**name && !isalnum (**name))
722 (*name)++; 694 (*name)++;
695 }
723 return non_opt; 696 return non_opt;
724 } 697 }
725 698
...@@ -772,7 +745,7 @@ hol_entry_cmp (const struct hol_entry *entry1, ...@@ -772,7 +745,7 @@ hol_entry_cmp (const struct hol_entry *entry1,
772 return doc1 - doc2; 745 return doc1 - doc2;
773 else if (!short1 && !short2 && long1 && long2) 746 else if (!short1 && !short2 && long1 && long2)
774 /* Only long options. */ 747 /* Only long options. */
775 return strcasecmp (long1, long2); 748 return __strcasecmp (long1, long2);
776 else 749 else
777 /* Compare short/short, long/short, short/long, using the first 750 /* Compare short/short, long/short, short/long, using the first
778 character of long options. Entries without *any* valid 751 character of long options. Entries without *any* valid
...@@ -853,12 +826,16 @@ hol_append (struct hol *hol, struct hol *more) ...@@ -853,12 +826,16 @@ hol_append (struct hol *hol, struct hol *more)
853 char *short_options = 826 char *short_options =
854 malloc (hol_so_len + strlen (more->short_options) + 1); 827 malloc (hol_so_len + strlen (more->short_options) + 1);
855 828
856 memcpy (entries, hol->entries, 829 assert (entries && short_options);
857 hol->num_entries * sizeof (struct hol_entry)); 830 if (SIZE_MAX <= UINT_MAX)
858 memcpy (entries + hol->num_entries, more->entries, 831 assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
832
833 __mempcpy (__mempcpy (entries, hol->entries,
834 hol->num_entries * sizeof (struct hol_entry)),
835 more->entries,
859 more->num_entries * sizeof (struct hol_entry)); 836 more->num_entries * sizeof (struct hol_entry));
860 837
861 memcpy (short_options, hol->short_options, hol_so_len); 838 __mempcpy (short_options, hol->short_options, hol_so_len);
862 839
863 /* Fix up the short options pointers from HOL. */ 840 /* Fix up the short options pointers from HOL. */
864 for (e = entries, left = hol->num_entries; left > 0; e++, left--) 841 for (e = entries, left = hol->num_entries; left > 0; e++, left--)
...@@ -1078,9 +1055,8 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state, ...@@ -1078,9 +1055,8 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
1078 int old_wm = __argp_fmtstream_wmargin (stream); 1055 int old_wm = __argp_fmtstream_wmargin (stream);
1079 /* PEST is a state block holding some of our variables that we'd like to 1056 /* PEST is a state block holding some of our variables that we'd like to
1080 share with helper functions. */ 1057 share with helper functions. */
1081 /* Some loosing compiler can not handle this ... lets play nice. */
1082 /* struct pentry_state pest = { entry, stream, hhstate, 1, state }; */
1083 struct pentry_state pest; 1058 struct pentry_state pest;
1059
1084 pest.entry = entry; 1060 pest.entry = entry;
1085 pest.stream = stream; 1061 pest.stream = stream;
1086 pest.hhstate = hhstate; 1062 pest.hhstate = hhstate;
...@@ -1120,13 +1096,15 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state, ...@@ -1120,13 +1096,15 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
1120 { 1096 {
1121 __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col); 1097 __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
1122 for (opt = real, num = entry->num; num > 0; opt++, num--) 1098 for (opt = real, num = entry->num; num > 0; opt++, num--)
1123 if (opt->name && ovisible (opt)) 1099 if (opt->name && *opt->name && ovisible (opt))
1124 { 1100 {
1125 comma (uparams.doc_opt_col, &pest); 1101 comma (uparams.doc_opt_col, &pest);
1126 /* Calling gettext here isn't quite right, since sorting will 1102 /* Calling dgettext here isn't quite right, since sorting will
1127 have been done on the original; but documentation options 1103 have been done on the original; but documentation options
1128 should be pretty rare anyway... */ 1104 should be pretty rare anyway... */
1129 __argp_fmtstream_puts (stream, 1105 __argp_fmtstream_puts (stream,
1106 onotrans (opt) ?
1107 opt->name :
1130 dgettext (state->root_argp->argp_domain, 1108 dgettext (state->root_argp->argp_domain,
1131 opt->name)); 1109 opt->name));
1132 } 1110 }
...@@ -1406,7 +1384,7 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state, ...@@ -1406,7 +1384,7 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state,
1406 if (fdoc) 1384 if (fdoc)
1407 { 1385 {
1408 const char *cp = fdoc; 1386 const char *cp = fdoc;
1409 nl = strchrnul (cp, '\n'); 1387 nl = __strchrnul (cp, '\n');
1410 if (*nl != '\0') 1388 if (*nl != '\0')
1411 /* This is a `multi-level' args doc; advance to the correct position 1389 /* This is a `multi-level' args doc; advance to the correct position
1412 as determined by our state in LEVELS, and update LEVELS. */ 1390 as determined by our state in LEVELS, and update LEVELS. */
...@@ -1414,7 +1392,7 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state, ...@@ -1414,7 +1392,7 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state,
1414 int i; 1392 int i;
1415 multiple = 1; 1393 multiple = 1;
1416 for (i = 0; i < *our_level; i++) 1394 for (i = 0; i < *our_level; i++)
1417 cp = nl + 1, nl = strchrnul (cp, '\n'); 1395 cp = nl + 1, nl = __strchrnul (cp, '\n');
1418 (*levels)++; 1396 (*levels)++;
1419 } 1397 }
1420 1398
...@@ -1482,7 +1460,7 @@ argp_doc (const struct argp *argp, const struct argp_state *state, ...@@ -1482,7 +1460,7 @@ argp_doc (const struct argp *argp, const struct argp_state *state,
1482 { 1460 {
1483 if (inp_text_limit) 1461 if (inp_text_limit)
1484 /* Copy INP_TEXT so that it's nul-terminated. */ 1462 /* Copy INP_TEXT so that it's nul-terminated. */
1485 inp_text = strndup (inp_text, inp_text_limit); 1463 inp_text = __strndup (inp_text, inp_text_limit);
1486 input = __argp_input (argp, state); 1464 input = __argp_input (argp, state);
1487 text = 1465 text =
1488 (*argp->help_filter) (post 1466 (*argp->help_filter) (post
...@@ -1556,12 +1534,19 @@ _help (const struct argp *argp, const struct argp_state *state, FILE *stream, ...@@ -1556,12 +1534,19 @@ _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
1556 if (! stream) 1534 if (! stream)
1557 return; 1535 return;
1558 1536
1537 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1538 __flockfile (stream);
1539 #endif
1540
1559 if (! uparams.valid) 1541 if (! uparams.valid)
1560 fill_in_uparams (state); 1542 fill_in_uparams (state);
1561 1543
1562 fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0); 1544 fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
1563 if (! fs) 1545 if (! fs)
1564 { 1546 {
1547 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1548 __funlockfile (stream);
1549 #endif
1565 return; 1550 return;
1566 } 1551 }
1567 1552
...@@ -1669,6 +1654,10 @@ Try `%s --help' or `%s --usage' for more information.\n"), ...@@ -1669,6 +1654,10 @@ Try `%s --help' or `%s --usage' for more information.\n"),
1669 anything = 1; 1654 anything = 1;
1670 } 1655 }
1671 1656
1657 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1658 __funlockfile (stream);
1659 #endif
1660
1672 if (hol) 1661 if (hol)
1673 hol_free (hol); 1662 hol_free (hol);
1674 1663
...@@ -1680,12 +1669,34 @@ Try `%s --help' or `%s --usage' for more information.\n"), ...@@ -1680,12 +1669,34 @@ Try `%s --help' or `%s --usage' for more information.\n"),
1680 void __argp_help (const struct argp *argp, FILE *stream, 1669 void __argp_help (const struct argp *argp, FILE *stream,
1681 unsigned flags, char *name) 1670 unsigned flags, char *name)
1682 { 1671 {
1683 _help (argp, 0, stream, flags, name); 1672 struct argp_state state;
1673 memset (&state, 0, sizeof state);
1674 state.root_argp = argp;
1675 _help (argp, &state, stream, flags, name);
1684 } 1676 }
1685 #ifdef weak_alias 1677 #ifdef weak_alias
1686 weak_alias (__argp_help, argp_help) 1678 weak_alias (__argp_help, argp_help)
1687 #endif 1679 #endif
1688 1680
1681 #if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
1682 char *
1683 __argp_short_program_name (void)
1684 {
1685 # if HAVE_DECL_PROGRAM_INVOCATION_NAME
1686 char *name = strrchr (program_invocation_name, '/');
1687 return name ? name + 1 : program_invocation_name;
1688 # else
1689 /* FIXME: What now? Miles suggests that it is better to use NULL,
1690 but currently the value is passed on directly to fputs_unlocked,
1691 so that requires more changes. */
1692 # if __GNUC__
1693 # warning No reasonable value to return
1694 # endif /* __GNUC__ */
1695 return "";
1696 # endif
1697 }
1698 #endif
1699
1689 /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are 1700 /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
1690 from the set ARGP_HELP_*. */ 1701 from the set ARGP_HELP_*. */
1691 void 1702 void
...@@ -1697,7 +1708,7 @@ __argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags) ...@@ -1697,7 +1708,7 @@ __argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
1697 flags |= ARGP_HELP_LONG_ONLY; 1708 flags |= ARGP_HELP_LONG_ONLY;
1698 1709
1699 _help (state ? state->root_argp : 0, state, stream, flags, 1710 _help (state ? state->root_argp : 0, state, stream, flags,
1700 state ? state->name : program_invocation_short_name); 1711 state ? state->name : __argp_short_program_name ());
1701 1712
1702 if (!state || ! (state->flags & ARGP_NO_EXIT)) 1713 if (!state || ! (state->flags & ARGP_NO_EXIT))
1703 { 1714 {
...@@ -1726,19 +1737,47 @@ __argp_error (const struct argp_state *state, const char *fmt, ...) ...@@ -1726,19 +1737,47 @@ __argp_error (const struct argp_state *state, const char *fmt, ...)
1726 { 1737 {
1727 va_list ap; 1738 va_list ap;
1728 1739
1729 fputs (state ? state->name : program_invocation_short_name, 1740 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1730 stream); 1741 __flockfile (stream);
1731 putc (':', stream); 1742 #endif
1732 putc (' ', stream);
1733 1743
1734 va_start (ap, fmt); 1744 va_start (ap, fmt);
1745
1746 #ifdef USE_IN_LIBIO
1747 if (_IO_fwide (stream, 0) > 0)
1748 {
1749 char *buf;
1750
1751 if (__asprintf (&buf, fmt, ap) < 0)
1752 buf = NULL;
1753
1754 __fwprintf (stream, L"%s: %s\n",
1755 state ? state->name : __argp_short_program_name (),
1756 buf);
1757
1758 free (buf);
1759 }
1760 else
1761 #endif
1762 {
1763 fputs_unlocked (state
1764 ? state->name : __argp_short_program_name (),
1765 stream);
1766 putc_unlocked (':', stream);
1767 putc_unlocked (' ', stream);
1768
1735 vfprintf (stream, fmt, ap); 1769 vfprintf (stream, fmt, ap);
1736 va_end (ap);
1737 1770
1738 putc ('\n', stream); 1771 putc_unlocked ('\n', stream);
1772 }
1739 1773
1740 __argp_state_help (state, stream, ARGP_HELP_STD_ERR); 1774 __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
1741 1775
1776 va_end (ap);
1777
1778 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1779 __funlockfile (stream);
1780 #endif
1742 } 1781 }
1743 } 1782 }
1744 } 1783 }
...@@ -1764,29 +1803,88 @@ __argp_failure (const struct argp_state *state, int status, int errnum, ...@@ -1764,29 +1803,88 @@ __argp_failure (const struct argp_state *state, int status, int errnum,
1764 1803
1765 if (stream) 1804 if (stream)
1766 { 1805 {
1767 fputs (state ? state->name : program_invocation_short_name, 1806 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1807 __flockfile (stream);
1808 #endif
1809
1810 #ifdef USE_IN_LIBIO
1811 if (_IO_fwide (stream, 0) > 0)
1812 __fwprintf (stream, L"%s",
1813 state ? state->name : __argp_short_program_name ());
1814 else
1815 #endif
1816 fputs_unlocked (state
1817 ? state->name : __argp_short_program_name (),
1768 stream); 1818 stream);
1769 1819
1770 if (fmt) 1820 if (fmt)
1771 { 1821 {
1772 va_list ap; 1822 va_list ap;
1773 1823
1774 putc (':', stream);
1775 putc (' ', stream);
1776
1777 va_start (ap, fmt); 1824 va_start (ap, fmt);
1825 #ifdef USE_IN_LIBIO
1826 if (_IO_fwide (stream, 0) > 0)
1827 {
1828 char *buf;
1829
1830 if (__asprintf (&buf, fmt, ap) < 0)
1831 buf = NULL;
1832
1833 __fwprintf (stream, L": %s", buf);
1834
1835 free (buf);
1836 }
1837 else
1838 #endif
1839 {
1840 putc_unlocked (':', stream);
1841 putc_unlocked (' ', stream);
1842
1778 vfprintf (stream, fmt, ap); 1843 vfprintf (stream, fmt, ap);
1844 }
1845
1779 va_end (ap); 1846 va_end (ap);
1780 } 1847 }
1781 1848
1782 if (errnum) 1849 if (errnum)
1783 { 1850 {
1784 putc (':', stream); 1851 char buf[200];
1785 putc (' ', stream); 1852
1786 fputs (strerror (errnum), stream); 1853 #ifdef USE_IN_LIBIO
1854 if (_IO_fwide (stream, 0) > 0)
1855 __fwprintf (stream, L": %s",
1856 __strerror_r (errnum, buf, sizeof (buf)));
1857 else
1858 #endif
1859 {
1860 char const *s = NULL;
1861 putc_unlocked (':', stream);
1862 putc_unlocked (' ', stream);
1863 #if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P)
1864 s = __strerror_r (errnum, buf, sizeof buf);
1865 #elif HAVE_DECL_STRERROR_R
1866 if (__strerror_r (errnum, buf, sizeof buf) == 0)
1867 s = buf;
1868 #endif
1869 #if !_LIBC
1870 if (! s && ! (s = strerror (errnum)))
1871 s = dgettext (state->root_argp->argp_domain,
1872 "Unknown system error");
1873 #endif
1874 fputs (s, stream);
1875 }
1787 } 1876 }
1788 1877
1789 putc ('\n', stream); 1878 #ifdef USE_IN_LIBIO
1879 if (_IO_fwide (stream, 0) > 0)
1880 putwc_unlocked (L'\n', stream);
1881 else
1882 #endif
1883 putc_unlocked ('\n', stream);
1884
1885 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1886 __funlockfile (stream);
1887 #endif
1790 1888
1791 if (status && (!state || !(state->flags & ARGP_NO_EXIT))) 1889 if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
1792 exit (status); 1890 exit (status);
......
1 /* Name frobnication for compiling argp outside of glibc 1 /* Name frobnication for compiling argp outside of glibc
2 Copyright (C) 1997, 2001 Free Software Foundation, Inc. 2 Copyright (C) 1997, 2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. 4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 This program is free software; you can redistribute it and/or modify
7 modify it under the terms of the GNU Library General Public License as 7 it under the terms of the GNU General Public License as published by
8 published by the Free Software Foundation; either version 2 of the 8 the Free Software Foundation; either version 2, or (at your option)
9 License, or (at your option) any later version. 9 any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 Library General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License along
17 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 with this program; if not, write to the Free Software Foundation,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20 19
21 #if !_LIBC 20 #if !_LIBC
22 /* This code is written for inclusion in gnu-libc, and uses names in the 21 /* This code is written for inclusion in gnu-libc, and uses names in the
...@@ -77,12 +76,81 @@ ...@@ -77,12 +76,81 @@
77 #undef __argp_fmtstream_wmargin 76 #undef __argp_fmtstream_wmargin
78 #define __argp_fmtstream_wmargin argp_fmtstream_wmargin 77 #define __argp_fmtstream_wmargin argp_fmtstream_wmargin
79 78
79 #include "mempcpy.h"
80 #include "strcase.h"
81 #include "strchrnul.h"
82 #include "strndup.h"
83
80 /* normal libc functions we call */ 84 /* normal libc functions we call */
85 #undef __flockfile
86 #define __flockfile flockfile
87 #undef __funlockfile
88 #define __funlockfile funlockfile
89 #undef __mempcpy
90 #define __mempcpy mempcpy
81 #undef __sleep 91 #undef __sleep
82 #define __sleep sleep 92 #define __sleep sleep
83 #undef __strcasecmp 93 #undef __strcasecmp
84 #define __strcasecmp strcasecmp 94 #define __strcasecmp strcasecmp
95 #undef __strchrnul
96 #define __strchrnul strchrnul
97 #undef __strerror_r
98 #define __strerror_r strerror_r
99 #undef __strndup
100 #define __strndup strndup
85 #undef __vsnprintf 101 #undef __vsnprintf
86 #define __vsnprintf vsnprintf 102 #define __vsnprintf vsnprintf
87 103
104 #if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED
105 # define clearerr_unlocked(x) clearerr (x)
106 #endif
107 #if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED
108 # define feof_unlocked(x) feof (x)
109 # endif
110 #if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED
111 # define ferror_unlocked(x) ferror (x)
112 # endif
113 #if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED
114 # define fflush_unlocked(x) fflush (x)
115 # endif
116 #if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED
117 # define fgets_unlocked(x,y,z) fgets (x,y,z)
118 # endif
119 #if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED
120 # define fputc_unlocked(x,y) fputc (x,y)
121 # endif
122 #if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED
123 # define fputs_unlocked(x,y) fputs (x,y)
124 # endif
125 #if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED
126 # define fread_unlocked(w,x,y,z) fread (w,x,y,z)
127 # endif
128 #if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED
129 # define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
130 # endif
131 #if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED
132 # define getc_unlocked(x) getc (x)
133 # endif
134 #if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED
135 # define getchar_unlocked() getchar ()
136 # endif
137 #if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED
138 # define putc_unlocked(x,y) putc (x,y)
139 # endif
140 #if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED
141 # define putchar_unlocked(x) putchar (x)
142 # endif
143
144 extern char *__argp_basename (char *name);
145
88 #endif /* !_LIBC */ 146 #endif /* !_LIBC */
147
148 #ifndef __set_errno
149 #define __set_errno(e) (errno = (e))
150 #endif
151
152 #if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
153 # define __argp_short_program_name() (program_invocation_short_name)
154 #else
155 extern char *__argp_short_program_name (void);
156 #endif
......
1 /* Hierarchial argument parsing, layered over getopt 1 /* Hierarchial argument parsing, layered over getopt
2 Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 Free Software Foundation, Inc. 2 Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. 4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 This program is free software; you can redistribute it and/or modify
7 modify it under the terms of the GNU Library General Public License as 7 it under the terms of the GNU General Public License as published by
8 published by the Free Software Foundation; either version 2 of the 8 the Free Software Foundation; either version 2, or (at your option)
9 License, or (at your option) any later version. 9 any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 Library General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License along
17 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 with this program; if not, write to the Free Software Foundation,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20 19
21 #ifdef HAVE_CONFIG_H 20 #ifdef HAVE_CONFIG_H
22 #include <config.h> 21 #include <config.h>
23 #endif 22 #endif
24 23
24 #include <alloca.h>
25 #include <stddef.h>
25 #include <stdlib.h> 26 #include <stdlib.h>
26 #include <string.h> 27 #include <string.h>
27 #include <unistd.h> 28 #include <unistd.h>
28 #include <limits.h> 29 #include <limits.h>
29 #include <getopt.h> 30 #include <getopt.h>
31 #include <getopt_int.h>
30 32
31 #ifdef HAVE_STRINGS_H 33 #ifdef _LIBC
32 # include <strings.h>
33 #endif
34
35 #ifdef HAVE_ALLOCA_H
36 # include <alloca.h>
37 #endif
38
39 #include <mailutils/nls.h>
40
41 #ifndef _
42 /* This is for other GNU distributions with internationalized messages.
43 When compiling libc, the _ macro is predefined. */
44 # if defined HAVE_LIBINTL_H || defined _LIBC
45 # include <libintl.h> 34 # include <libintl.h>
46 # ifdef _LIBC
47 # undef dgettext 35 # undef dgettext
48 # define dgettext(domain, msgid) __dcgettext (domain, msgid, LC_MESSAGES) 36 # define dgettext(domain, msgid) \
49 # endif 37 INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
50 # else
51 # define dgettext(domain, msgid) (msgid)
52 # define gettext(msgid) (msgid)
53 # endif
54 #endif
55 #ifndef N_
56 # define N_(msgid) msgid
57 #endif
58
59 #if _LIBC - 0
60 #include <bits/libc-lock.h>
61 #else 38 #else
62 #ifdef HAVE_CTHREADS_H 39 # include "gettext.h"
63 #include <cthreads.h>
64 #endif 40 #endif
65 #endif /* _LIBC */ 41 #define N_(msgid) msgid
66 42
67 #include "argp.h" 43 #include "argp.h"
68 #include "argp-namefrob.h" 44 #include "argp-namefrob.h"
69 45
46 #define alignof(type) offsetof (struct { char c; type x; }, x)
47 #define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d))
48
70 /* Getopt return values. */ 49 /* Getopt return values. */
71 #define KEY_END (-1) /* The end of the options. */ 50 #define KEY_END (-1) /* The end of the options. */
72 #define KEY_ARG 1 /* A non-option argument. */ 51 #define KEY_ARG 1 /* A non-option argument. */
...@@ -92,7 +71,7 @@ ...@@ -92,7 +71,7 @@
92 for one second intervals, decrementing _ARGP_HANG until it's zero. Thus 71 for one second intervals, decrementing _ARGP_HANG until it's zero. Thus
93 you can force the program to continue by attaching a debugger and setting 72 you can force the program to continue by attaching a debugger and setting
94 it to 0 yourself. */ 73 it to 0 yourself. */
95 volatile int _argp_hang; 74 static volatile int _argp_hang;
96 75
97 #define OPT_PROGNAME -2 76 #define OPT_PROGNAME -2
98 #define OPT_USAGE -3 77 #define OPT_USAGE -3
...@@ -101,11 +80,11 @@ volatile int _argp_hang; ...@@ -101,11 +80,11 @@ volatile int _argp_hang;
101 static const struct argp_option argp_default_options[] = 80 static const struct argp_option argp_default_options[] =
102 { 81 {
103 {"help", '?', 0, 0, N_("Give this help list"), -1}, 82 {"help", '?', 0, 0, N_("Give this help list"), -1},
104 {"usage", OPT_USAGE, 0, 0, N_("Give a short usage message")}, 83 {"usage", OPT_USAGE, 0, 0, N_("Give a short usage message"), 0},
105 {"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, N_("Set the program name")}, 84 {"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, N_("Set the program name"), 0},
106 {"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN, 85 {"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
107 N_("Hang for SECS seconds (default 3600)")}, 86 N_("Hang for SECS seconds (default 3600)"), 0},
108 {0, 0} 87 {NULL, 0, 0, 0, NULL, 0}
109 }; 88 };
110 89
111 static error_t 90 static error_t
...@@ -122,31 +101,35 @@ argp_default_parser (int key, char *arg, struct argp_state *state) ...@@ -122,31 +101,35 @@ argp_default_parser (int key, char *arg, struct argp_state *state)
122 break; 101 break;
123 102
124 case OPT_PROGNAME: /* Set the program name. */ 103 case OPT_PROGNAME: /* Set the program name. */
104 #if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME
125 program_invocation_name = arg; 105 program_invocation_name = arg;
126 106 #endif
127 /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka 107 /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
128 __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined 108 __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
129 to be that, so we have to be a bit careful here.] */ 109 to be that, so we have to be a bit careful here.] */
130 arg = strrchr (arg, '/');
131 if (arg)
132 program_invocation_short_name = arg + 1;
133 else
134 program_invocation_short_name = program_invocation_name;
135 110
136 /* Update what we use for messages. */ 111 /* Update what we use for messages. */
137 state->name = program_invocation_short_name; 112 state->name = strrchr (arg, '/');
113 if (state->name)
114 state->name++;
115 else
116 state->name = arg;
117
118 #if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
119 program_invocation_short_name = state->name;
120 #endif
138 121
139 if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS)) 122 if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
140 == ARGP_PARSE_ARGV0) 123 == ARGP_PARSE_ARGV0)
141 /* Update what getopt uses too. */ 124 /* Update what getopt uses too. */
142 state->argv[0] = program_invocation_name; 125 state->argv[0] = arg;
143 126
144 break; 127 break;
145 128
146 case OPT_HANG: 129 case OPT_HANG:
147 _argp_hang = atoi (arg ? arg : "3600"); 130 _argp_hang = atoi (arg ? arg : "3600");
148 while (_argp_hang-- > 0) 131 while (_argp_hang-- > 0)
149 sleep (1); 132 __sleep (1);
150 break; 133 break;
151 134
152 default: 135 default:
...@@ -162,7 +145,7 @@ static const struct argp argp_default_argp = ...@@ -162,7 +145,7 @@ static const struct argp argp_default_argp =
162 static const struct argp_option argp_version_options[] = 145 static const struct argp_option argp_version_options[] =
163 { 146 {
164 {"version", 'V', 0, 0, N_("Print program version"), -1}, 147 {"version", 'V', 0, 0, N_("Print program version"), -1},
165 {0, 0} 148 {NULL, 0, 0, 0, NULL, 0}
166 }; 149 };
167 150
168 static error_t 151 static error_t
...@@ -208,41 +191,6 @@ find_long_option (struct option *long_options, const char *name) ...@@ -208,41 +191,6 @@ find_long_option (struct option *long_options, const char *name)
208 return -1; 191 return -1;
209 } 192 }
210 193
211 /* If we can, we regulate access to getopt, which is non-reentrant, with a
212 mutex. Since the case we're trying to guard against is two different
213 threads interfering, and it's possible that someone might want to call
214 argp_parse recursively (they're careful), we use a recursive lock if
215 possible. */
216
217 #if _LIBC - 0
218
219 __libc_lock_define_initialized_recursive (static, getopt_lock)
220 #define LOCK_GETOPT __libc_lock_lock_recursive (getopt_lock)
221 #define UNLOCK_GETOPT __libc_lock_unlock_recursive (getopt_lock)
222
223 #else /* !_LIBC */
224 #if defined(HAVE_CTHREADS_H)
225
226 static struct mutex getopt_lock = MUTEX_INITIALIZER;
227 #define LOCK_GETOPT mutex_lock (&getopt_lock)
228 #define UNLOCK_GETOPT mutex_unlock (&getopt_lock)
229
230 #else /* !HAVE_CTHREADS_H */
231
232 #define LOCK_GETOPT (void)0
233 #define UNLOCK_GETOPT (void)0
234
235 #endif /* HAVE_CTHREADS_H */
236 #endif /* _LIBC */
237
238 /* This hack to allow programs that know what's going on to call argp
239 recursively. If someday argp is changed not to use the non-reentrant
240 getopt interface, we can get rid of this shit. XXX */
241 void
242 _argp_unlock_xxx (void)
243 {
244 UNLOCK_GETOPT;
245 }
246 194
247 /* The state of a `group' during parsing. Each group corresponds to a 195 /* The state of a `group' during parsing. Each group corresponds to a
248 particular argp structure from the tree of such descending from the top 196 particular argp structure from the tree of such descending from the top
...@@ -304,6 +252,8 @@ struct parser ...@@ -304,6 +252,8 @@ struct parser
304 /* LONG_OPTS is the array of getop long option structures for the union of 252 /* LONG_OPTS is the array of getop long option structures for the union of
305 all the groups of options. */ 253 all the groups of options. */
306 struct option *long_opts; 254 struct option *long_opts;
255 /* OPT_DATA is the getopt data used for the re-entrant getopt. */
256 struct _getopt_data opt_data;
307 257
308 /* States of the various parsing groups. */ 258 /* States of the various parsing groups. */
309 struct group *groups; 259 struct group *groups;
...@@ -515,6 +465,12 @@ parser_init (struct parser *parser, const struct argp *argp, ...@@ -515,6 +465,12 @@ parser_init (struct parser *parser, const struct argp *argp,
515 error_t err = 0; 465 error_t err = 0;
516 struct group *group; 466 struct group *group;
517 struct parser_sizes szs; 467 struct parser_sizes szs;
468 struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
469 char *storage;
470 size_t glen, gsum;
471 size_t clen, csum;
472 size_t llen, lsum;
473 size_t slen, ssum;
518 474
519 szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1; 475 szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
520 szs.long_len = 0; 476 szs.long_len = 0;
...@@ -525,26 +481,33 @@ parser_init (struct parser *parser, const struct argp *argp, ...@@ -525,26 +481,33 @@ parser_init (struct parser *parser, const struct argp *argp,
525 calc_sizes (argp, &szs); 481 calc_sizes (argp, &szs);
526 482
527 /* Lengths of the various bits of storage used by PARSER. */ 483 /* Lengths of the various bits of storage used by PARSER. */
528 #define GLEN (szs.num_groups + 1) * sizeof (struct group) 484 glen = (szs.num_groups + 1) * sizeof (struct group);
529 #define CLEN (szs.num_child_inputs * sizeof (void *)) 485 clen = szs.num_child_inputs * sizeof (void *);
530 #define LLEN ((szs.long_len + 1) * sizeof (struct option)) 486 llen = (szs.long_len + 1) * sizeof (struct option);
531 #define SLEN (szs.short_len + 1) 487 slen = szs.short_len + 1;
532 488
533 parser->storage = malloc (GLEN + CLEN + LLEN + SLEN); 489 /* Sums of previous lengths, properly aligned. There's no need to
490 align gsum, since struct group is aligned at least as strictly as
491 void * (since it contains a void * member). And there's no need
492 to align lsum, since struct option is aligned at least as
493 strictly as char. */
494 gsum = glen;
495 csum = alignto (gsum + clen, alignof (struct option));
496 lsum = csum + llen;
497 ssum = lsum + slen;
498
499 parser->storage = malloc (ssum);
534 if (! parser->storage) 500 if (! parser->storage)
535 return ENOMEM; 501 return ENOMEM;
536 502
537 parser->groups = (struct group *) parser->storage; 503 storage = parser->storage;
538 /* To please Watcom CC 504 parser->groups = parser->storage;
539 parser->child_inputs = parser->storage + GLEN; 505 parser->child_inputs = (void **) (storage + gsum);
540 parser->long_opts = parser->storage + GLEN + CLEN; 506 parser->long_opts = (struct option *) (storage + csum);
541 parser->short_opts = parser->storage + GLEN + CLEN + LLEN; 507 parser->short_opts = storage + lsum;
542 */ 508 parser->opt_data = opt_data;
543 parser->child_inputs = (void **)((char*) parser->storage + GLEN); 509
544 parser->long_opts = (struct option *)((char*) parser->storage + GLEN + CLEN); 510 memset (parser->child_inputs, 0, clen);
545 parser->short_opts = (char*) parser->storage + GLEN + CLEN + LLEN;
546
547 memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
548 parser_convert (parser, argp, flags); 511 parser_convert (parser, argp, flags);
549 512
550 memset (&parser->state, 0, sizeof (struct argp_state)); 513 memset (&parser->state, 0, sizeof (struct argp_state));
...@@ -586,19 +549,16 @@ parser_init (struct parser *parser, const struct argp *argp, ...@@ -586,19 +549,16 @@ parser_init (struct parser *parser, const struct argp *argp,
586 if (err) 549 if (err)
587 return err; 550 return err;
588 551
589 /* Getopt is (currently) non-reentrant. */
590 LOCK_GETOPT;
591
592 if (parser->state.flags & ARGP_NO_ERRS) 552 if (parser->state.flags & ARGP_NO_ERRS)
593 { 553 {
594 opterr = 0; 554 parser->opt_data.opterr = 0;
595 if (parser->state.flags & ARGP_PARSE_ARGV0) 555 if (parser->state.flags & ARGP_PARSE_ARGV0)
596 /* getopt always skips ARGV[0], so we have to fake it out. As long 556 /* getopt always skips ARGV[0], so we have to fake it out. As long
597 as OPTERR is 0, then it shouldn't actually try to access it. */ 557 as OPTERR is 0, then it shouldn't actually try to access it. */
598 parser->state.argv--, parser->state.argc++; 558 parser->state.argv--, parser->state.argc++;
599 } 559 }
600 else 560 else
601 opterr = 1; /* Print error messages. */ 561 parser->opt_data.opterr = 1; /* Print error messages. */
602 562
603 if (parser->state.argv == argv && argv[0]) 563 if (parser->state.argv == argv && argv[0])
604 /* There's an argv[0]; use it for messages. */ 564 /* There's an argv[0]; use it for messages. */
...@@ -607,7 +567,7 @@ parser_init (struct parser *parser, const struct argp *argp, ...@@ -607,7 +567,7 @@ parser_init (struct parser *parser, const struct argp *argp,
607 parser->state.name = short_name ? short_name + 1 : argv[0]; 567 parser->state.name = short_name ? short_name + 1 : argv[0];
608 } 568 }
609 else 569 else
610 parser->state.name = program_invocation_short_name; 570 parser->state.name = __argp_short_program_name ();
611 571
612 return 0; 572 return 0;
613 } 573 }
...@@ -619,8 +579,6 @@ parser_finalize (struct parser *parser, ...@@ -619,8 +579,6 @@ parser_finalize (struct parser *parser,
619 { 579 {
620 struct group *group; 580 struct group *group;
621 581
622 UNLOCK_GETOPT;
623
624 if (err == EBADKEY && arg_ebadkey) 582 if (err == EBADKEY && arg_ebadkey)
625 /* Suppress errors generated by unparsed arguments. */ 583 /* Suppress errors generated by unparsed arguments. */
626 err = 0; 584 err = 0;
...@@ -782,7 +740,8 @@ parser_parse_opt (struct parser *parser, int opt, char *val) ...@@ -782,7 +740,8 @@ parser_parse_opt (struct parser *parser, int opt, char *val)
782 for (group = parser->groups; group < parser->egroup; group++) 740 for (group = parser->groups; group < parser->egroup; group++)
783 if (group->short_end > short_index) 741 if (group->short_end > short_index)
784 { 742 {
785 err = group_parse (group, &parser->state, opt, optarg); 743 err = group_parse (group, &parser->state, opt,
744 parser->opt_data.optarg);
786 break; 745 break;
787 } 746 }
788 } 747 }
...@@ -791,7 +750,8 @@ parser_parse_opt (struct parser *parser, int opt, char *val) ...@@ -791,7 +750,8 @@ parser_parse_opt (struct parser *parser, int opt, char *val)
791 the user value in order to preserve the sign. */ 750 the user value in order to preserve the sign. */
792 err = 751 err =
793 group_parse (&parser->groups[group_key - 1], &parser->state, 752 group_parse (&parser->groups[group_key - 1], &parser->state,
794 (opt << GROUP_BITS) >> GROUP_BITS, optarg); 753 (opt << GROUP_BITS) >> GROUP_BITS,
754 parser->opt_data.optarg);
795 755
796 if (err == EBADKEY) 756 if (err == EBADKEY)
797 /* At least currently, an option not recognized is an error in the 757 /* At least currently, an option not recognized is an error in the
...@@ -837,15 +797,20 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey) ...@@ -837,15 +797,20 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey)
837 if (parser->try_getopt && !parser->state.quoted) 797 if (parser->try_getopt && !parser->state.quoted)
838 /* Give getopt a chance to parse this. */ 798 /* Give getopt a chance to parse this. */
839 { 799 {
840 optind = parser->state.next; /* Put it back in OPTIND for getopt. */ 800 /* Put it back in OPTIND for getopt. */
841 optopt = KEY_END; /* Distinguish KEY_ERR from a real option. */ 801 parser->opt_data.optind = parser->state.next;
802 /* Distinguish KEY_ERR from a real option. */
803 parser->opt_data.optopt = KEY_END;
842 if (parser->state.flags & ARGP_LONG_ONLY) 804 if (parser->state.flags & ARGP_LONG_ONLY)
843 opt = getopt_long_only (parser->state.argc, parser->state.argv, 805 opt = _getopt_long_only_r (parser->state.argc, parser->state.argv,
844 parser->short_opts, parser->long_opts, 0); 806 parser->short_opts, parser->long_opts, 0,
807 &parser->opt_data);
845 else 808 else
846 opt = getopt_long (parser->state.argc, parser->state.argv, 809 opt = _getopt_long_r (parser->state.argc, parser->state.argv,
847 parser->short_opts, parser->long_opts, 0); 810 parser->short_opts, parser->long_opts, 0,
848 parser->state.next = optind; /* And see what getopt did. */ 811 &parser->opt_data);
812 /* And see what getopt did. */
813 parser->state.next = parser->opt_data.optind;
849 814
850 if (opt == KEY_END) 815 if (opt == KEY_END)
851 /* Getopt says there are no more options, so stop using 816 /* Getopt says there are no more options, so stop using
...@@ -861,7 +826,7 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey) ...@@ -861,7 +826,7 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey)
861 here, whatever happens. */ 826 here, whatever happens. */
862 parser->state.quoted = parser->state.next; 827 parser->state.quoted = parser->state.next;
863 } 828 }
864 else if (opt == KEY_ERR && optopt != KEY_END) 829 else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END)
865 /* KEY_ERR can have the same value as a valid user short 830 /* KEY_ERR can have the same value as a valid user short
866 option, but in the case of a real error, getopt sets OPTOPT 831 option, but in the case of a real error, getopt sets OPTOPT
867 to the offending character, which can never be KEY_END. */ 832 to the offending character, which can never be KEY_END. */
...@@ -887,15 +852,15 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey) ...@@ -887,15 +852,15 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey)
887 /* A non-option arg; simulate what getopt might have done. */ 852 /* A non-option arg; simulate what getopt might have done. */
888 { 853 {
889 opt = KEY_ARG; 854 opt = KEY_ARG;
890 optarg = parser->state.argv[parser->state.next++]; 855 parser->opt_data.optarg = parser->state.argv[parser->state.next++];
891 } 856 }
892 } 857 }
893 858
894 if (opt == KEY_ARG) 859 if (opt == KEY_ARG)
895 /* A non-option argument; try each parser in turn. */ 860 /* A non-option argument; try each parser in turn. */
896 err = parser_parse_arg (parser, optarg); 861 err = parser_parse_arg (parser, parser->opt_data.optarg);
897 else 862 else
898 err = parser_parse_opt (parser, opt, optarg); 863 err = parser_parse_opt (parser, opt, parser->opt_data.optarg);
899 864
900 if (err == EBADKEY) 865 if (err == EBADKEY)
901 *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG); 866 *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG);
......
...@@ -3,20 +3,19 @@ ...@@ -3,20 +3,19 @@
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. 4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 This program is free software; you can redistribute it and/or modify
7 modify it under the terms of the GNU Library General Public License as 7 it under the terms of the GNU General Public License as published by
8 published by the Free Software Foundation; either version 2 of the 8 the Free Software Foundation; either version 2, or (at your option)
9 License, or (at your option) any later version. 9 any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 Library General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License along
17 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 with this program; if not, write to the Free Software Foundation,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20 19
21 /* If set by the user program to a non-zero value, then a default option 20 /* If set by the user program to a non-zero value, then a default option
22 --version is added (unless the ARGP_NO_HELP flag is used), which will 21 --version is added (unless the ARGP_NO_HELP flag is used), which will
......
1 /* Default definition for ARGP_PROGRAM_VERSION_HOOK. 1 /* Default definition for ARGP_PROGRAM_VERSION_HOOK.
2 Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. 2 Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. 4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 This program is free software; you can redistribute it and/or modify
7 modify it under the terms of the GNU Library General Public License as 7 it under the terms of the GNU General Public License as published by
8 published by the Free Software Foundation; either version 2 of the 8 the Free Software Foundation; either version 2, or (at your option)
9 License, or (at your option) any later version. 9 any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 Library General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License along
17 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 with this program; if not, write to the Free Software Foundation,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20 19
21 #ifdef HAVE_CONFIG_H 20 #ifdef HAVE_CONFIG_H
22 #include <config.h> 21 #include <config.h>
...@@ -29,4 +28,4 @@ ...@@ -29,4 +28,4 @@
29 this function with a stream to print the version to and a pointer to the 28 this function with a stream to print the version to and a pointer to the
30 current parsing state, and then exits (unless the ARGP_NO_EXIT flag is 29 current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
31 used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ 30 used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
32 void (*argp_program_version_hook) (FILE *stream, struct argp_state *state); 31 void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = NULL;
......
1 /* Real definitions for extern inline functions in argp.h 1 /* Real definitions for extern inline functions in argp.h
2 Copyright (C) 1997, 1998, 2001 Free Software Foundation, Inc. 2 Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. 4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 This program is free software; you can redistribute it and/or modify
7 modify it under the terms of the GNU Library General Public License as 7 it under the terms of the GNU General Public License as published by
8 published by the Free Software Foundation; either version 2 of the 8 the Free Software Foundation; either version 2, or (at your option)
9 License, or (at your option) any later version. 9 any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 Library General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License along
17 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 with this program; if not, write to the Free Software Foundation,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20 19
21 #ifdef HAVE_CONFIG_H 20 #ifdef HAVE_CONFIG_H
22 #include <config.h> 21 #include <config.h>
23 #endif 22 #endif
24 23
24 #if defined _LIBC || defined HAVE_FEATURES_H
25 # include <features.h>
26 #endif
27
25 #ifndef __USE_EXTERN_INLINES 28 #ifndef __USE_EXTERN_INLINES
26 # define __USE_EXTERN_INLINES 1 29 # define __USE_EXTERN_INLINES 1
27 #endif 30 #endif
28 #define ARGP_EI 31 #define ARGP_EI
29 #undef __OPTIMIZE__ 32 #undef __OPTIMIZE__
30 #define __OPTIMIZE__ 33 #define __OPTIMIZE__ 1
31 #include "argp.h" 34 #include "argp.h"
32 35
33 /* Add weak aliases. */ 36 /* Add weak aliases. */
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* getline.c -- Replacement for GNU C library function getline
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 2
4 This library is free software; you can redistribute it and/or 3 Copyright (C) 1993, 1996, 1997, 1998, 2000, 2003, 2004 Free
5 modify it under the terms of the GNU Lesser General Public 4 Software Foundation, Inc.
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8 5
9 This library is distributed in the hope that it will be useful, 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 Lesser General Public License for more details. 14 GNU General Public License for more details.
13 15
14 You should have received a copy of the GNU Lesser General Public 16 You should have received a copy of the GNU General Public License
15 License along with this library; if not, write to the Free Software 17 along with this program; if not, write to the Free Software Foundation,
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 19
18 /* First implementation by Alain Magloire */ 20 /* Written by Jan Brittenson, bson@gnu.ai.mit.edu. */
19 21
20 #ifdef HAVE_CONFIG_H 22 #if HAVE_CONFIG_H
21 # include <config.h> 23 # include <config.h>
22 #endif 24 #endif
23 25
24 #include <unistd.h> 26 #include "getline.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 ssize_t
30 getline (char **lineptr, size_t *n, FILE *stream)
31 {
32 return getdelim (lineptr, n, '\n', stream);
33 }
34 27
35 #ifndef HAVE_GETDELIM 28 #if ! (defined __GNU_LIBRARY__ && HAVE_GETDELIM)
36 29
37 /* Default value for line length. */ 30 # include "getndelim2.h"
38 static const int line_size = 128;
39 31
40 ssize_t 32 ssize_t
41 getdelim (char **lineptr, size_t *n, int delim, FILE *stream) 33 getdelim (char **lineptr, size_t *linesize, int delimiter, FILE *stream)
42 { 34 {
43 int indx = 0; 35 return getndelim2 (lineptr, linesize, 0, GETNLINE_NO_LIMIT, delimiter, EOF,
44 int c; 36 stream);
45
46 /* Sanity checks. */
47 if (lineptr == NULL || n == NULL || stream == NULL)
48 return -1;
49
50 /* Allocate the line the first time. */
51 if (*lineptr == NULL)
52 {
53 *lineptr = malloc (line_size);
54 if (*lineptr == NULL)
55 return -1;
56 *n = line_size;
57 }
58
59 while ((c = getc (stream)) != EOF)
60 {
61 /* Check if more memory is needed. */
62 if (indx >= *n)
63 {
64 *lineptr = realloc (*lineptr, *n + line_size);
65 if (*lineptr == NULL)
66 return -1;
67 *n += line_size;
68 }
69
70 /* Push the result in the line. */
71 (*lineptr)[indx++] = c;
72
73 /* Bail out. */
74 if (c == delim)
75 break;
76 }
77
78 /* Make room for the null character. */
79 if (indx >= *n)
80 {
81 *lineptr = realloc (*lineptr, *n + line_size);
82 if (*lineptr == NULL)
83 return -1;
84 *n += line_size;
85 }
86
87 /* Null terminate the buffer. */
88 (*lineptr)[indx++] = 0;
89
90 /* The last line may not have the delimiter, we have to
91 * return what we got and the error will be seen on the
92 * next iteration. */
93 return (c == EOF && (indx - 1) == 0) ? -1 : indx - 1;
94 } 37 }
38 #endif
95 39
96 #endif /* HAVE_GETDELIM */ 40 ssize_t
97 41 getline (char **lineptr, size_t *linesize, FILE *stream)
98
99 #ifdef STANDALONE
100 int main(void)
101 { 42 {
102 FILE * fp; 43 return getdelim (lineptr, linesize, '\n', stream);
103 char * line = NULL;
104 size_t len = 0;
105 ssize_t read;
106 fp = fopen("/etc/passwd", "r");
107 if (fp == NULL)
108 exit(EXIT_FAILURE);
109 while ((read = getline(&line, &len, fp)) != -1) {
110 printf("Retrieved line of length %zu :\n", read);
111 printf("%s", line);
112 }
113 if (line)
114 free(line);
115 return EXIT_SUCCESS;
116 } 44 }
117 #endif
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* Replacement for GNU C library function getline
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 2
4 This library is free software; you can redistribute it and/or 3 Copyright (C) 1995, 1997, 1999, 2000, 2001, 2002, 2003 Free
5 modify it under the terms of the GNU Lesser General Public 4 Software Foundation, Inc.
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8 5
9 This library is distributed in the hope that it will be useful, 6 This program is free software; you can redistribute it and/or modify
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 7 it under the terms of the GNU General Public License as published by
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8 the Free Software Foundation; either version 2, or (at your option)
12 Lesser General Public License for more details. 9 any later version.
13 10
14 You should have received a copy of the GNU Lesser General Public 11 This program is distributed in the hope that it will be useful,
15 License along with this library; if not, write to the Free Software 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
17 15
18 #ifndef _GETLINE_H_ 16 You should have received a copy of the GNU General Public License
19 # define _GETLINE_H_ 1 17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 19
20 #ifndef GETLINE_H_
21 # define GETLINE_H_ 1
22
23 # include <stddef.h>
21 # include <stdio.h> 24 # include <stdio.h>
22 25
23 # ifndef PARAMS 26 /* Get ssize_t. */
24 # if defined (__GNUC__) || __STDC__ 27 # include <sys/types.h>
25 # define PARAMS(args) args
26 # else
27 # define PARAMS(args) ()
28 # endif
29 # endif
30 28
31 extern int getline PARAMS ((char **_lineptr, size_t *_n, FILE *_stream)); 29 /* glibc2 has these functions declared in <stdio.h>. Avoid redeclarations. */
30 # if __GLIBC__ < 2
32 31
33 extern int getdelim PARAMS ((char **_lineptr, size_t *_n, int _delimiter, FILE *_stream)); 32 extern ssize_t getline (char **_lineptr, size_t *_linesize, FILE *_stream);
33
34 extern ssize_t getdelim (char **_lineptr, size_t *_linesize, int _delimiter,
35 FILE *_stream);
36
37 # endif
34 38
35 #endif /* ! _GETLINE_H_ */ 39 #endif /* not GETLINE_H_ */
......
1 /* Getopt for GNU. 1 /* Getopt for GNU.
2 NOTE: The canonical source of this file is maintained with the GNU 2 NOTE: getopt is now part of the C library, so if you don't know what
3 C Library. Bugs can be reported to bug-glibc@gnu.org. 3 "Keep this file name-space clean" means, talk to drepper@gnu.org
4 4 before changing it!
5 Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 5 Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004
6 Free Software Foundation, Inc. 6 Free Software Foundation, Inc.
7 This file is part of the GNU C Library.
7 8
8 This program is free software; you can redistribute it and/or modify it 9 This program is free software; you can redistribute it and/or modify
9 under the terms of the GNU General Public License as published by the 10 it under the terms of the GNU General Public License as published by
10 Free Software Foundation; either version 2, or (at your option) any 11 the Free Software Foundation; either version 2, or (at your option)
11 later version. 12 any later version.
12 13
13 This program is distributed in the hope that it will be useful, 14 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 17 GNU General Public License for more details.
17 18
18 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License along
19 along with this program; if not, write to the Free Software Foundation, 20 with this program; if not, write to the Free Software Foundation,
20 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 21 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 22
22 /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. 23 /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
...@@ -29,35 +30,8 @@ ...@@ -29,35 +30,8 @@
29 # include <config.h> 30 # include <config.h>
30 #endif 31 #endif
31 32
32 #if !defined __STDC__ || !__STDC__
33 /* This is a separate conditional since some stdc systems
34 reject `defined (const)'. */
35 # ifndef const
36 # define const
37 # endif
38 #endif
39
40 #include <stdio.h> 33 #include <stdio.h>
41 34
42 /* Comment out all this code if we are using the GNU C Library, and are not
43 actually compiling the library itself. This code is part of the GNU C
44 Library, but also included in many other GNU distributions. Compiling
45 and linking in this code is a waste when using the GNU C library
46 (especially if it is a shared library). Rather than having every GNU
47 program understand `configure --with-gnu-libc' and omit the object files,
48 it is simpler to just do this in the source for each such file. */
49
50 #define GETOPT_INTERFACE_VERSION 2
51 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
52 # include <gnu-versions.h>
53 # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
54 # define ELIDE_CODE
55 # endif
56 #endif
57
58 #ifndef ELIDE_CODE
59
60
61 /* This needs to come after some library #include 35 /* This needs to come after some library #include
62 to get __GNU_LIBRARY__ defined. */ 36 to get __GNU_LIBRARY__ defined. */
63 #ifdef __GNU_LIBRARY__ 37 #ifdef __GNU_LIBRARY__
...@@ -67,40 +41,43 @@ ...@@ -67,40 +41,43 @@
67 # include <unistd.h> 41 # include <unistd.h>
68 #endif /* GNU C library. */ 42 #endif /* GNU C library. */
69 43
44 #include <string.h>
45
70 #ifdef VMS 46 #ifdef VMS
71 # include <unixlib.h> 47 # include <unixlib.h>
72 # if HAVE_STRING_H - 0
73 # include <string.h>
74 # endif
75 #endif 48 #endif
76 49
77 #ifndef _ 50 #ifdef _LIBC
78 /* This is for other GNU distributions with internationalized messages. */
79 # if defined HAVE_LIBINTL_H || defined _LIBC
80 # include <libintl.h> 51 # include <libintl.h>
81 # ifndef _ 52 #else
53 # include "gettext.h"
82 # define _(msgid) gettext (msgid) 54 # define _(msgid) gettext (msgid)
83 # endif
84 # else
85 # define _(msgid) (msgid)
86 # endif
87 #endif 55 #endif
88 56
89 /* This version of `getopt' appears to the caller like standard Unix `getopt' 57 #if defined _LIBC && defined USE_IN_LIBIO
90 but it behaves differently for the user, since it allows the user 58 # include <wchar.h>
91 to intersperse the options with the other arguments. 59 #endif
60
61 #ifndef attribute_hidden
62 # define attribute_hidden
63 #endif
92 64
93 As `getopt' works, it permutes the elements of ARGV so that, 65 /* Unlike standard Unix `getopt', functions like `getopt_long'
66 let the user intersperse the options with the other arguments.
67
68 As `getopt_long' works, it permutes the elements of ARGV so that,
94 when it is done, all the options precede everything else. Thus 69 when it is done, all the options precede everything else. Thus
95 all application programs are extended to handle flexible argument order. 70 all application programs are extended to handle flexible argument order.
96 71
97 Setting the environment variable POSIXLY_CORRECT disables permutation. 72 Using `getopt' or setting the environment variable POSIXLY_CORRECT
98 Then the behavior is completely standard. 73 disables permutation.
74 Then the application's behavior is completely standard.
99 75
100 GNU application programs can use a third alternative mode in which 76 GNU application programs can use a third alternative mode in which
101 they can distinguish the relative order of options and other arguments. */ 77 they can distinguish the relative order of options and other arguments. */
102 78
103 #include "getopt.h" 79 #include "getopt.h"
80 #include "getopt_int.h"
104 81
105 /* For communication from `getopt' to the caller. 82 /* For communication from `getopt' to the caller.
106 When `getopt' finds an option that takes an argument, 83 When `getopt' finds an option that takes an argument,
...@@ -125,21 +102,6 @@ char *optarg; ...@@ -125,21 +102,6 @@ char *optarg;
125 /* 1003.2 says this must be 1 before any call. */ 102 /* 1003.2 says this must be 1 before any call. */
126 int optind = 1; 103 int optind = 1;
127 104
128 /* Formerly, initialization of getopt depended on optind==0, which
129 causes problems with re-calling getopt as programs generally don't
130 know that. */
131
132 int __getopt_initialized;
133
134 /* The next char to be scanned in the option-element
135 in which the last option character we returned was found.
136 This allows us to pick up the scan where we left off.
137
138 If this is zero, or a null string, it means resume the scan
139 by advancing to the next ARGV-element. */
140
141 static char *nextchar;
142
143 /* Callers store zero here to inhibit the error message 105 /* Callers store zero here to inhibit the error message
144 for unrecognized options. */ 106 for unrecognized options. */
145 107
...@@ -151,57 +113,12 @@ int opterr = 1; ...@@ -151,57 +113,12 @@ int opterr = 1;
151 113
152 int optopt = '?'; 114 int optopt = '?';
153 115
154 /* Describe how to deal with options that follow non-option ARGV-elements. 116 /* Keep a global copy of all internal members of getopt_data. */
155
156 If the caller did not specify anything,
157 the default is REQUIRE_ORDER if the environment variable
158 POSIXLY_CORRECT is defined, PERMUTE otherwise.
159 117
160 REQUIRE_ORDER means don't recognize them as options; 118 static struct _getopt_data getopt_data;
161 stop option processing when the first non-option is seen.
162 This is what Unix does.
163 This mode of operation is selected by either setting the environment
164 variable POSIXLY_CORRECT, or using `+' as the first character
165 of the list of option characters.
166 119
167 PERMUTE is the default. We permute the contents of ARGV as we scan,
168 so that eventually all the non-options are at the end. This allows options
169 to be given in any order, even with programs that were not written to
170 expect this.
171 120
172 RETURN_IN_ORDER is an option available to programs that were written 121 #ifndef __GNU_LIBRARY__
173 to expect options and other ARGV-elements in any order and that care about
174 the ordering of the two. We describe each non-option ARGV-element
175 as if it were the argument of an option with character code 1.
176 Using `-' as the first character of the list of option characters
177 selects this mode of operation.
178
179 The special argument `--' forces an end of option-scanning regardless
180 of the value of `ordering'. In the case of RETURN_IN_ORDER, only
181 `--' can cause `getopt' to return -1 with `optind' != ARGC. */
182
183 static enum
184 {
185 REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
186 } ordering;
187
188 /* Value of POSIXLY_CORRECT environment variable. */
189 static char *posixly_correct;
190
191 #ifdef __GNU_LIBRARY__
192 /* We want to avoid inclusion of string.h with non-GNU libraries
193 because there are many ways it can cause trouble.
194 On some systems, it contains special magic macros that don't work
195 in GCC. */
196 # include <string.h>
197 # define my_index strchr
198 #else
199
200 # if HAVE_STRING_H
201 # include <string.h>
202 # else
203 # include <strings.h>
204 # endif
205 122
206 /* Avoid depending on library functions or files 123 /* Avoid depending on library functions or files
207 whose names are inconsistent. */ 124 whose names are inconsistent. */
...@@ -210,79 +127,34 @@ static char *posixly_correct; ...@@ -210,79 +127,34 @@ static char *posixly_correct;
210 extern char *getenv (); 127 extern char *getenv ();
211 #endif 128 #endif
212 129
213 static char *
214 my_index (str, chr)
215 const char *str;
216 int chr;
217 {
218 while (*str)
219 {
220 if (*str == chr)
221 return (char *) str;
222 str++;
223 }
224 return 0;
225 }
226
227 /* If using GCC, we can safely declare strlen this way.
228 If not using GCC, it is ok not to declare it. */
229 #ifdef __GNUC__
230 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
231 That was relevant to code that was here before. */
232 # if (!defined __STDC__ || !__STDC__) && !defined strlen
233 /* gcc with -traditional declares the built-in strlen to return int,
234 and has done so at least since version 2.4.5. -- rms. */
235 extern int strlen (const char *);
236 # endif /* not __STDC__ */
237 #endif /* __GNUC__ */
238
239 #endif /* not __GNU_LIBRARY__ */ 130 #endif /* not __GNU_LIBRARY__ */
240 131
241 /* Handle permutation of arguments. */
242
243 /* Describe the part of ARGV that contains non-options that have
244 been skipped. `first_nonopt' is the index in ARGV of the first of them;
245 `last_nonopt' is the index after the last of them. */
246
247 static int first_nonopt;
248 static int last_nonopt;
249
250 #ifdef _LIBC 132 #ifdef _LIBC
133 /* Stored original parameters.
134 XXX This is no good solution. We should rather copy the args so
135 that we can compare them later. But we must not use malloc(3). */
136 extern int __libc_argc;
137 extern char **__libc_argv;
138
251 /* Bash 2.0 gives us an environment variable containing flags 139 /* Bash 2.0 gives us an environment variable containing flags
252 indicating ARGV elements that should not be considered arguments. */ 140 indicating ARGV elements that should not be considered arguments. */
253 141
142 # ifdef USE_NONOPTION_FLAGS
254 /* Defined in getopt_init.c */ 143 /* Defined in getopt_init.c */
255 extern char *__getopt_nonoption_flags; 144 extern char *__getopt_nonoption_flags;
145 # endif
256 146
257 static int nonoption_flags_max_len; 147 # ifdef USE_NONOPTION_FLAGS
258 static int nonoption_flags_len;
259
260 static int original_argc;
261 static char *const *original_argv;
262
263 /* Make sure the environment variable bash 2.0 puts in the environment
264 is valid for the getopt call we must make sure that the ARGV passed
265 to getopt is that one passed to the process. */
266 static void
267 __attribute__ ((unused))
268 store_args_and_env (int argc, char *const *argv)
269 {
270 /* XXX This is no good solution. We should rather copy the args so
271 that we can compare them later. But we must not use malloc(3). */
272 original_argc = argc;
273 original_argv = argv;
274 }
275 # ifdef text_set_element
276 text_set_element (__libc_subinit, store_args_and_env);
277 # endif /* text_set_element */
278
279 # define SWAP_FLAGS(ch1, ch2) \ 148 # define SWAP_FLAGS(ch1, ch2) \
280 if (nonoption_flags_len > 0) \ 149 if (d->__nonoption_flags_len > 0) \
281 { \ 150 { \
282 char __tmp = __getopt_nonoption_flags[ch1]; \ 151 char __tmp = __getopt_nonoption_flags[ch1]; \
283 __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ 152 __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
284 __getopt_nonoption_flags[ch2] = __tmp; \ 153 __getopt_nonoption_flags[ch2] = __tmp; \
285 } 154 }
155 # else
156 # define SWAP_FLAGS(ch1, ch2)
157 # endif
286 #else /* !_LIBC */ 158 #else /* !_LIBC */
287 # define SWAP_FLAGS(ch1, ch2) 159 # define SWAP_FLAGS(ch1, ch2)
288 #endif /* _LIBC */ 160 #endif /* _LIBC */
...@@ -296,17 +168,12 @@ text_set_element (__libc_subinit, store_args_and_env); ...@@ -296,17 +168,12 @@ text_set_element (__libc_subinit, store_args_and_env);
296 `first_nonopt' and `last_nonopt' are relocated so that they describe 168 `first_nonopt' and `last_nonopt' are relocated so that they describe
297 the new indices of the non-options in ARGV after they are moved. */ 169 the new indices of the non-options in ARGV after they are moved. */
298 170
299 #if defined __STDC__ && __STDC__
300 static void exchange (char **);
301 #endif
302
303 static void 171 static void
304 exchange (argv) 172 exchange (char **argv, struct _getopt_data *d)
305 char **argv;
306 { 173 {
307 int bottom = first_nonopt; 174 int bottom = d->__first_nonopt;
308 int middle = last_nonopt; 175 int middle = d->__last_nonopt;
309 int top = optind; 176 int top = d->optind;
310 char *tem; 177 char *tem;
311 178
312 /* Exchange the shorter segment with the far end of the longer segment. 179 /* Exchange the shorter segment with the far end of the longer segment.
...@@ -314,23 +181,23 @@ exchange (argv) ...@@ -314,23 +181,23 @@ exchange (argv)
314 It leaves the longer segment in the right place overall, 181 It leaves the longer segment in the right place overall,
315 but it consists of two parts that need to be swapped next. */ 182 but it consists of two parts that need to be swapped next. */
316 183
317 #ifdef _LIBC 184 #if defined _LIBC && defined USE_NONOPTION_FLAGS
318 /* First make sure the handling of the `__getopt_nonoption_flags' 185 /* First make sure the handling of the `__getopt_nonoption_flags'
319 string can work normally. Our top argument must be in the range 186 string can work normally. Our top argument must be in the range
320 of the string. */ 187 of the string. */
321 if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) 188 if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
322 { 189 {
323 /* We must extend the array. The user plays games with us and 190 /* We must extend the array. The user plays games with us and
324 presents new arguments. */ 191 presents new arguments. */
325 char *new_str = malloc (top + 1); 192 char *new_str = malloc (top + 1);
326 if (new_str == NULL) 193 if (new_str == NULL)
327 nonoption_flags_len = nonoption_flags_max_len = 0; 194 d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
328 else 195 else
329 { 196 {
330 memset (__mempcpy (new_str, __getopt_nonoption_flags, 197 memset (__mempcpy (new_str, __getopt_nonoption_flags,
331 nonoption_flags_max_len), 198 d->__nonoption_flags_max_len),
332 '\0', top + 1 - nonoption_flags_max_len); 199 '\0', top + 1 - d->__nonoption_flags_max_len);
333 nonoption_flags_max_len = top + 1; 200 d->__nonoption_flags_max_len = top + 1;
334 __getopt_nonoption_flags = new_str; 201 __getopt_nonoption_flags = new_str;
335 } 202 }
336 } 203 }
...@@ -376,76 +243,71 @@ exchange (argv) ...@@ -376,76 +243,71 @@ exchange (argv)
376 243
377 /* Update records for the slots the non-options now occupy. */ 244 /* Update records for the slots the non-options now occupy. */
378 245
379 first_nonopt += (optind - last_nonopt); 246 d->__first_nonopt += (d->optind - d->__last_nonopt);
380 last_nonopt = optind; 247 d->__last_nonopt = d->optind;
381 } 248 }
382 249
383 /* Initialize the internal data when the first call is made. */ 250 /* Initialize the internal data when the first call is made. */
384 251
385 #if defined __STDC__ && __STDC__
386 static const char *_getopt_initialize (int, char *const *, const char *);
387 #endif
388 static const char * 252 static const char *
389 _getopt_initialize (argc, argv, optstring) 253 _getopt_initialize (int argc, char **argv, const char *optstring,
390 int argc; 254 int posixly_correct, struct _getopt_data *d)
391 char *const *argv;
392 const char *optstring;
393 { 255 {
394 /* Start processing options with ARGV-element 1 (since ARGV-element 0 256 /* Start processing options with ARGV-element 1 (since ARGV-element 0
395 is the program name); the sequence of previously skipped 257 is the program name); the sequence of previously skipped
396 non-option ARGV-elements is empty. */ 258 non-option ARGV-elements is empty. */
397 259
398 first_nonopt = last_nonopt = optind; 260 d->__first_nonopt = d->__last_nonopt = d->optind;
399 261
400 nextchar = NULL; 262 d->__nextchar = NULL;
401 263
402 posixly_correct = getenv ("POSIXLY_CORRECT"); 264 d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT");
403 265
404 /* Determine how to handle the ordering of options and nonoptions. */ 266 /* Determine how to handle the ordering of options and nonoptions. */
405 267
406 if (optstring[0] == '-') 268 if (optstring[0] == '-')
407 { 269 {
408 ordering = RETURN_IN_ORDER; 270 d->__ordering = RETURN_IN_ORDER;
409 ++optstring; 271 ++optstring;
410 } 272 }
411 else if (optstring[0] == '+') 273 else if (optstring[0] == '+')
412 { 274 {
413 ordering = REQUIRE_ORDER; 275 d->__ordering = REQUIRE_ORDER;
414 ++optstring; 276 ++optstring;
415 } 277 }
416 else if (posixly_correct != NULL) 278 else if (d->__posixly_correct)
417 ordering = REQUIRE_ORDER; 279 d->__ordering = REQUIRE_ORDER;
418 else 280 else
419 ordering = PERMUTE; 281 d->__ordering = PERMUTE;
420 282
421 #ifdef _LIBC 283 #if defined _LIBC && defined USE_NONOPTION_FLAGS
422 if (posixly_correct == NULL 284 if (!d->__posixly_correct
423 && argc == original_argc && argv == original_argv) 285 && argc == __libc_argc && argv == __libc_argv)
424 { 286 {
425 if (nonoption_flags_max_len == 0) 287 if (d->__nonoption_flags_max_len == 0)
426 { 288 {
427 if (__getopt_nonoption_flags == NULL 289 if (__getopt_nonoption_flags == NULL
428 || __getopt_nonoption_flags[0] == '\0') 290 || __getopt_nonoption_flags[0] == '\0')
429 nonoption_flags_max_len = -1; 291 d->__nonoption_flags_max_len = -1;
430 else 292 else
431 { 293 {
432 const char *orig_str = __getopt_nonoption_flags; 294 const char *orig_str = __getopt_nonoption_flags;
433 int len = nonoption_flags_max_len = strlen (orig_str); 295 int len = d->__nonoption_flags_max_len = strlen (orig_str);
434 if (nonoption_flags_max_len < argc) 296 if (d->__nonoption_flags_max_len < argc)
435 nonoption_flags_max_len = argc; 297 d->__nonoption_flags_max_len = argc;
436 __getopt_nonoption_flags = 298 __getopt_nonoption_flags =
437 (char *) malloc (nonoption_flags_max_len); 299 (char *) malloc (d->__nonoption_flags_max_len);
438 if (__getopt_nonoption_flags == NULL) 300 if (__getopt_nonoption_flags == NULL)
439 nonoption_flags_max_len = -1; 301 d->__nonoption_flags_max_len = -1;
440 else 302 else
441 memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), 303 memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
442 '\0', nonoption_flags_max_len - len); 304 '\0', d->__nonoption_flags_max_len - len);
443 } 305 }
444 } 306 }
445 nonoption_flags_len = nonoption_flags_max_len; 307 d->__nonoption_flags_len = d->__nonoption_flags_max_len;
446 } 308 }
447 else 309 else
448 nonoption_flags_len = 0; 310 d->__nonoption_flags_len = 0;
449 #endif 311 #endif
450 312
451 return optstring; 313 return optstring;
...@@ -493,10 +355,6 @@ _getopt_initialize (argc, argv, optstring) ...@@ -493,10 +355,6 @@ _getopt_initialize (argc, argv, optstring)
493 `flag' field is nonzero, the value of the option's `val' field 355 `flag' field is nonzero, the value of the option's `val' field
494 if the `flag' field is zero. 356 if the `flag' field is zero.
495 357
496 The elements of ARGV aren't really const, because we permute them.
497 But we pretend they're const in the prototype to be compatible
498 with other systems.
499
500 LONGOPTS is a vector of `struct option' terminated by an 358 LONGOPTS is a vector of `struct option' terminated by an
501 element containing a name which is zero. 359 element containing a name which is zero.
502 360
...@@ -505,73 +363,74 @@ _getopt_initialize (argc, argv, optstring) ...@@ -505,73 +363,74 @@ _getopt_initialize (argc, argv, optstring)
505 recent call. 363 recent call.
506 364
507 If LONG_ONLY is nonzero, '-' as well as '--' can introduce 365 If LONG_ONLY is nonzero, '-' as well as '--' can introduce
508 long-named options. */ 366 long-named options.
367
368 If POSIXLY_CORRECT is nonzero, behave as if the POSIXLY_CORRECT
369 environment variable were set. */
509 370
510 int 371 int
511 _getopt_internal (argc, argv, optstring, longopts, longind, long_only) 372 _getopt_internal_r (int argc, char **argv, const char *optstring,
512 int argc; 373 const struct option *longopts, int *longind,
513 char *const *argv; 374 int long_only, int posixly_correct, struct _getopt_data *d)
514 const char *optstring;
515 const struct option *longopts;
516 int *longind;
517 int long_only;
518 { 375 {
519 int print_errors = opterr; 376 int print_errors = d->opterr;
520 if (optstring[0] == ':') 377 if (optstring[0] == ':')
521 print_errors = 0; 378 print_errors = 0;
522 379
523 if (argc < 1) 380 if (argc < 1)
524 return -1; 381 return -1;
525 382
526 optarg = NULL; 383 d->optarg = NULL;
527 384
528 if (optind == 0 || !__getopt_initialized) 385 if (d->optind == 0 || !d->__initialized)
529 { 386 {
530 if (optind == 0) 387 if (d->optind == 0)
531 optind = 1; /* Don't scan ARGV[0], the program name. */ 388 d->optind = 1; /* Don't scan ARGV[0], the program name. */
532 optstring = _getopt_initialize (argc, argv, optstring); 389 optstring = _getopt_initialize (argc, argv, optstring,
533 __getopt_initialized = 1; 390 posixly_correct, d);
391 d->__initialized = 1;
534 } 392 }
535 393
536 /* Test whether ARGV[optind] points to a non-option argument. 394 /* Test whether ARGV[optind] points to a non-option argument.
537 Either it does not have option syntax, or there is an environment flag 395 Either it does not have option syntax, or there is an environment flag
538 from the shell indicating it is not an option. The later information 396 from the shell indicating it is not an option. The later information
539 is only used when the used in the GNU libc. */ 397 is only used when the used in the GNU libc. */
540 #ifdef _LIBC 398 #if defined _LIBC && defined USE_NONOPTION_FLAGS
541 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ 399 # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
542 || (optind < nonoption_flags_len \ 400 || (d->optind < d->__nonoption_flags_len \
543 && __getopt_nonoption_flags[optind] == '1')) 401 && __getopt_nonoption_flags[d->optind] == '1'))
544 #else 402 #else
545 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') 403 # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
546 #endif 404 #endif
547 405
548 if (nextchar == NULL || *nextchar == '\0') 406 if (d->__nextchar == NULL || *d->__nextchar == '\0')
549 { 407 {
550 /* Advance to the next ARGV-element. */ 408 /* Advance to the next ARGV-element. */
551 409
552 /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been 410 /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
553 moved back by the user (who may also have changed the arguments). */ 411 moved back by the user (who may also have changed the arguments). */
554 if (last_nonopt > optind) 412 if (d->__last_nonopt > d->optind)
555 last_nonopt = optind; 413 d->__last_nonopt = d->optind;
556 if (first_nonopt > optind) 414 if (d->__first_nonopt > d->optind)
557 first_nonopt = optind; 415 d->__first_nonopt = d->optind;
558 416
559 if (ordering == PERMUTE) 417 if (d->__ordering == PERMUTE)
560 { 418 {
561 /* If we have just processed some options following some non-options, 419 /* If we have just processed some options following some non-options,
562 exchange them so that the options come first. */ 420 exchange them so that the options come first. */
563 421
564 if (first_nonopt != last_nonopt && last_nonopt != optind) 422 if (d->__first_nonopt != d->__last_nonopt
565 exchange ((char **) argv); 423 && d->__last_nonopt != d->optind)
566 else if (last_nonopt != optind) 424 exchange ((char **) argv, d);
567 first_nonopt = optind; 425 else if (d->__last_nonopt != d->optind)
426 d->__first_nonopt = d->optind;
568 427
569 /* Skip any additional non-options 428 /* Skip any additional non-options
570 and extend the range of non-options previously skipped. */ 429 and extend the range of non-options previously skipped. */
571 430
572 while (optind < argc && NONOPTION_P) 431 while (d->optind < argc && NONOPTION_P)
573 optind++; 432 d->optind++;
574 last_nonopt = optind; 433 d->__last_nonopt = d->optind;
575 } 434 }
576 435
577 /* The special ARGV-element `--' means premature end of options. 436 /* The special ARGV-element `--' means premature end of options.
...@@ -579,28 +438,29 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -579,28 +438,29 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
579 then exchange with previous non-options as if it were an option, 438 then exchange with previous non-options as if it were an option,
580 then skip everything else like a non-option. */ 439 then skip everything else like a non-option. */
581 440
582 if (optind != argc && !strcmp (argv[optind], "--")) 441 if (d->optind != argc && !strcmp (argv[d->optind], "--"))
583 { 442 {
584 optind++; 443 d->optind++;
585 444
586 if (first_nonopt != last_nonopt && last_nonopt != optind) 445 if (d->__first_nonopt != d->__last_nonopt
587 exchange ((char **) argv); 446 && d->__last_nonopt != d->optind)
588 else if (first_nonopt == last_nonopt) 447 exchange ((char **) argv, d);
589 first_nonopt = optind; 448 else if (d->__first_nonopt == d->__last_nonopt)
590 last_nonopt = argc; 449 d->__first_nonopt = d->optind;
450 d->__last_nonopt = argc;
591 451
592 optind = argc; 452 d->optind = argc;
593 } 453 }
594 454
595 /* If we have done all the ARGV-elements, stop the scan 455 /* If we have done all the ARGV-elements, stop the scan
596 and back over any non-options that we skipped and permuted. */ 456 and back over any non-options that we skipped and permuted. */
597 457
598 if (optind == argc) 458 if (d->optind == argc)
599 { 459 {
600 /* Set the next-arg-index to point at the non-options 460 /* Set the next-arg-index to point at the non-options
601 that we previously skipped, so the caller will digest them. */ 461 that we previously skipped, so the caller will digest them. */
602 if (first_nonopt != last_nonopt) 462 if (d->__first_nonopt != d->__last_nonopt)
603 optind = first_nonopt; 463 d->optind = d->__first_nonopt;
604 return -1; 464 return -1;
605 } 465 }
606 466
...@@ -609,17 +469,17 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -609,17 +469,17 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
609 469
610 if (NONOPTION_P) 470 if (NONOPTION_P)
611 { 471 {
612 if (ordering == REQUIRE_ORDER) 472 if (d->__ordering == REQUIRE_ORDER)
613 return -1; 473 return -1;
614 optarg = argv[optind++]; 474 d->optarg = argv[d->optind++];
615 return 1; 475 return 1;
616 } 476 }
617 477
618 /* We have found another option-ARGV-element. 478 /* We have found another option-ARGV-element.
619 Skip the initial punctuation. */ 479 Skip the initial punctuation. */
620 480
621 nextchar = (argv[optind] + 1 481 d->__nextchar = (argv[d->optind] + 1
622 + (longopts != NULL && argv[optind][1] == '-')); 482 + (longopts != NULL && argv[d->optind][1] == '-'));
623 } 483 }
624 484
625 /* Decode the current option-ARGV-element. */ 485 /* Decode the current option-ARGV-element. */
...@@ -638,8 +498,9 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -638,8 +498,9 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
638 This distinction seems to be the most useful approach. */ 498 This distinction seems to be the most useful approach. */
639 499
640 if (longopts != NULL 500 if (longopts != NULL
641 && (argv[optind][1] == '-' 501 && (argv[d->optind][1] == '-'
642 || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) 502 || (long_only && (argv[d->optind][2]
503 || !strchr (optstring, argv[d->optind][1])))))
643 { 504 {
644 char *nameend; 505 char *nameend;
645 const struct option *p; 506 const struct option *p;
...@@ -649,15 +510,15 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -649,15 +510,15 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
649 int indfound = -1; 510 int indfound = -1;
650 int option_index; 511 int option_index;
651 512
652 for (nameend = nextchar; *nameend && *nameend != '='; nameend++) 513 for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
653 /* Do nothing. */ ; 514 /* Do nothing. */ ;
654 515
655 /* Test all long options for either exact match 516 /* Test all long options for either exact match
656 or abbreviated matches. */ 517 or abbreviated matches. */
657 for (p = longopts, option_index = 0; p->name; p++, option_index++) 518 for (p = longopts, option_index = 0; p->name; p++, option_index++)
658 if (!strncmp (p->name, nextchar, nameend - nextchar)) 519 if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
659 { 520 {
660 if ((unsigned int) (nameend - nextchar) 521 if ((unsigned int) (nameend - d->__nextchar)
661 == (unsigned int) strlen (p->name)) 522 == (unsigned int) strlen (p->name))
662 { 523 {
663 /* Exact match found. */ 524 /* Exact match found. */
...@@ -683,62 +544,158 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -683,62 +544,158 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
683 if (ambig && !exact) 544 if (ambig && !exact)
684 { 545 {
685 if (print_errors) 546 if (print_errors)
547 {
548 #if defined _LIBC && defined USE_IN_LIBIO
549 char *buf;
550
551 if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
552 argv[0], argv[d->optind]) >= 0)
553 {
554 _IO_flockfile (stderr);
555
556 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
557 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
558
559 if (_IO_fwide (stderr, 0) > 0)
560 __fwprintf (stderr, L"%s", buf);
561 else
562 fputs (buf, stderr);
563
564 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
565 _IO_funlockfile (stderr);
566
567 free (buf);
568 }
569 #else
686 fprintf (stderr, _("%s: option `%s' is ambiguous\n"), 570 fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
687 argv[0], argv[optind]); 571 argv[0], argv[d->optind]);
688 nextchar += strlen (nextchar); 572 #endif
689 optind++; 573 }
690 optopt = 0; 574 d->__nextchar += strlen (d->__nextchar);
575 d->optind++;
576 d->optopt = 0;
691 return '?'; 577 return '?';
692 } 578 }
693 579
694 if (pfound != NULL) 580 if (pfound != NULL)
695 { 581 {
696 option_index = indfound; 582 option_index = indfound;
697 optind++; 583 d->optind++;
698 if (*nameend) 584 if (*nameend)
699 { 585 {
700 /* Don't test has_arg with >, because some C compilers don't 586 /* Don't test has_arg with >, because some C compilers don't
701 allow it to be used on enums. */ 587 allow it to be used on enums. */
702 if (pfound->has_arg) 588 if (pfound->has_arg)
703 optarg = nameend + 1; 589 d->optarg = nameend + 1;
704 else 590 else
705 { 591 {
706 if (print_errors) 592 if (print_errors)
707 { 593 {
708 if (argv[optind - 1][1] == '-') 594 #if defined _LIBC && defined USE_IN_LIBIO
595 char *buf;
596 int n;
597 #endif
598
599 if (argv[d->optind - 1][1] == '-')
600 {
709 /* --option */ 601 /* --option */
710 fprintf (stderr, 602 #if defined _LIBC && defined USE_IN_LIBIO
711 _("%s: option `--%s' doesn't allow an argument\n"), 603 n = __asprintf (&buf, _("\
604 %s: option `--%s' doesn't allow an argument\n"),
605 argv[0], pfound->name);
606 #else
607 fprintf (stderr, _("\
608 %s: option `--%s' doesn't allow an argument\n"),
712 argv[0], pfound->name); 609 argv[0], pfound->name);
610 #endif
611 }
713 else 612 else
613 {
714 /* +option or -option */ 614 /* +option or -option */
715 fprintf (stderr, 615 #if defined _LIBC && defined USE_IN_LIBIO
716 _("%s: option `%c%s' doesn't allow an argument\n"), 616 n = __asprintf (&buf, _("\
717 argv[0], argv[optind - 1][0], pfound->name); 617 %s: option `%c%s' doesn't allow an argument\n"),
618 argv[0], argv[d->optind - 1][0],
619 pfound->name);
620 #else
621 fprintf (stderr, _("\
622 %s: option `%c%s' doesn't allow an argument\n"),
623 argv[0], argv[d->optind - 1][0],
624 pfound->name);
625 #endif
626 }
627
628 #if defined _LIBC && defined USE_IN_LIBIO
629 if (n >= 0)
630 {
631 _IO_flockfile (stderr);
632
633 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
634 ((_IO_FILE *) stderr)->_flags2
635 |= _IO_FLAGS2_NOTCANCEL;
636
637 if (_IO_fwide (stderr, 0) > 0)
638 __fwprintf (stderr, L"%s", buf);
639 else
640 fputs (buf, stderr);
641
642 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
643 _IO_funlockfile (stderr);
644
645 free (buf);
646 }
647 #endif
718 } 648 }
719 649
720 nextchar += strlen (nextchar); 650 d->__nextchar += strlen (d->__nextchar);
721 651
722 optopt = pfound->val; 652 d->optopt = pfound->val;
723 return '?'; 653 return '?';
724 } 654 }
725 } 655 }
726 else if (pfound->has_arg == 1) 656 else if (pfound->has_arg == 1)
727 { 657 {
728 if (optind < argc) 658 if (d->optind < argc)
729 optarg = argv[optind++]; 659 d->optarg = argv[d->optind++];
730 else 660 else
731 { 661 {
732 if (print_errors) 662 if (print_errors)
663 {
664 #if defined _LIBC && defined USE_IN_LIBIO
665 char *buf;
666
667 if (__asprintf (&buf, _("\
668 %s: option `%s' requires an argument\n"),
669 argv[0], argv[d->optind - 1]) >= 0)
670 {
671 _IO_flockfile (stderr);
672
673 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
674 ((_IO_FILE *) stderr)->_flags2
675 |= _IO_FLAGS2_NOTCANCEL;
676
677 if (_IO_fwide (stderr, 0) > 0)
678 __fwprintf (stderr, L"%s", buf);
679 else
680 fputs (buf, stderr);
681
682 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
683 _IO_funlockfile (stderr);
684
685 free (buf);
686 }
687 #else
733 fprintf (stderr, 688 fprintf (stderr,
734 _("%s: option `%s' requires an argument\n"), 689 _("%s: option `%s' requires an argument\n"),
735 argv[0], argv[optind - 1]); 690 argv[0], argv[d->optind - 1]);
736 nextchar += strlen (nextchar); 691 #endif
737 optopt = pfound->val; 692 }
693 d->__nextchar += strlen (d->__nextchar);
694 d->optopt = pfound->val;
738 return optstring[0] == ':' ? ':' : '?'; 695 return optstring[0] == ':' ? ':' : '?';
739 } 696 }
740 } 697 }
741 nextchar += strlen (nextchar); 698 d->__nextchar += strlen (d->__nextchar);
742 if (longind != NULL) 699 if (longind != NULL)
743 *longind = option_index; 700 *longind = option_index;
744 if (pfound->flag) 701 if (pfound->flag)
...@@ -753,23 +710,62 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -753,23 +710,62 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
753 or the option starts with '--' or is not a valid short 710 or the option starts with '--' or is not a valid short
754 option, then it's an error. 711 option, then it's an error.
755 Otherwise interpret it as a short option. */ 712 Otherwise interpret it as a short option. */
756 if (!long_only || argv[optind][1] == '-' 713 if (!long_only || argv[d->optind][1] == '-'
757 || my_index (optstring, *nextchar) == NULL) 714 || strchr (optstring, *d->__nextchar) == NULL)
758 { 715 {
759 if (print_errors) 716 if (print_errors)
760 { 717 {
761 if (argv[optind][1] == '-') 718 #if defined _LIBC && defined USE_IN_LIBIO
719 char *buf;
720 int n;
721 #endif
722
723 if (argv[d->optind][1] == '-')
724 {
762 /* --option */ 725 /* --option */
726 #if defined _LIBC && defined USE_IN_LIBIO
727 n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
728 argv[0], d->__nextchar);
729 #else
763 fprintf (stderr, _("%s: unrecognized option `--%s'\n"), 730 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
764 argv[0], nextchar); 731 argv[0], d->__nextchar);
732 #endif
733 }
765 else 734 else
735 {
766 /* +option or -option */ 736 /* +option or -option */
737 #if defined _LIBC && defined USE_IN_LIBIO
738 n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
739 argv[0], argv[d->optind][0], d->__nextchar);
740 #else
767 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), 741 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
768 argv[0], argv[optind][0], nextchar); 742 argv[0], argv[d->optind][0], d->__nextchar);
743 #endif
744 }
745
746 #if defined _LIBC && defined USE_IN_LIBIO
747 if (n >= 0)
748 {
749 _IO_flockfile (stderr);
750
751 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
752 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
753
754 if (_IO_fwide (stderr, 0) > 0)
755 __fwprintf (stderr, L"%s", buf);
756 else
757 fputs (buf, stderr);
758
759 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
760 _IO_funlockfile (stderr);
761
762 free (buf);
763 }
764 #endif
769 } 765 }
770 nextchar = (char *) ""; 766 d->__nextchar = (char *) "";
771 optind++; 767 d->optind++;
772 optopt = 0; 768 d->optopt = 0;
773 return '?'; 769 return '?';
774 } 770 }
775 } 771 }
...@@ -777,26 +773,63 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -777,26 +773,63 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
777 /* Look at and handle the next short option-character. */ 773 /* Look at and handle the next short option-character. */
778 774
779 { 775 {
780 char c = *nextchar++; 776 char c = *d->__nextchar++;
781 char *temp = my_index (optstring, c); 777 char *temp = strchr (optstring, c);
782 778
783 /* Increment `optind' when we start to process its last character. */ 779 /* Increment `optind' when we start to process its last character. */
784 if (*nextchar == '\0') 780 if (*d->__nextchar == '\0')
785 ++optind; 781 ++d->optind;
786 782
787 if (temp == NULL || c == ':') 783 if (temp == NULL || c == ':')
788 { 784 {
789 if (print_errors) 785 if (print_errors)
790 { 786 {
791 if (posixly_correct) 787 #if defined _LIBC && defined USE_IN_LIBIO
788 char *buf;
789 int n;
790 #endif
791
792 if (d->__posixly_correct)
793 {
792 /* 1003.2 specifies the format of this message. */ 794 /* 1003.2 specifies the format of this message. */
793 fprintf (stderr, _("%s: illegal option -- %c\n"), 795 #if defined _LIBC && defined USE_IN_LIBIO
796 n = __asprintf (&buf, _("%s: illegal option -- %c\n"),
794 argv[0], c); 797 argv[0], c);
798 #else
799 fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
800 #endif
801 }
795 else 802 else
796 fprintf (stderr, _("%s: invalid option -- %c\n"), 803 {
804 #if defined _LIBC && defined USE_IN_LIBIO
805 n = __asprintf (&buf, _("%s: invalid option -- %c\n"),
797 argv[0], c); 806 argv[0], c);
807 #else
808 fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
809 #endif
810 }
811
812 #if defined _LIBC && defined USE_IN_LIBIO
813 if (n >= 0)
814 {
815 _IO_flockfile (stderr);
816
817 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
818 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
819
820 if (_IO_fwide (stderr, 0) > 0)
821 __fwprintf (stderr, L"%s", buf);
822 else
823 fputs (buf, stderr);
824
825 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
826 _IO_funlockfile (stderr);
827
828 free (buf);
798 } 829 }
799 optopt = c; 830 #endif
831 }
832 d->optopt = c;
800 return '?'; 833 return '?';
801 } 834 }
802 /* Convenience. Treat POSIX -W foo same as long option --foo */ 835 /* Convenience. Treat POSIX -W foo same as long option --foo */
...@@ -811,22 +844,46 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -811,22 +844,46 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
811 int option_index; 844 int option_index;
812 845
813 /* This is an option that requires an argument. */ 846 /* This is an option that requires an argument. */
814 if (*nextchar != '\0') 847 if (*d->__nextchar != '\0')
815 { 848 {
816 optarg = nextchar; 849 d->optarg = d->__nextchar;
817 /* If we end this ARGV-element by taking the rest as an arg, 850 /* If we end this ARGV-element by taking the rest as an arg,
818 we must advance to the next element now. */ 851 we must advance to the next element now. */
819 optind++; 852 d->optind++;
820 } 853 }
821 else if (optind == argc) 854 else if (d->optind == argc)
822 { 855 {
823 if (print_errors) 856 if (print_errors)
824 { 857 {
825 /* 1003.2 specifies the format of this message. */ 858 /* 1003.2 specifies the format of this message. */
859 #if defined _LIBC && defined USE_IN_LIBIO
860 char *buf;
861
862 if (__asprintf (&buf,
863 _("%s: option requires an argument -- %c\n"),
864 argv[0], c) >= 0)
865 {
866 _IO_flockfile (stderr);
867
868 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
869 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
870
871 if (_IO_fwide (stderr, 0) > 0)
872 __fwprintf (stderr, L"%s", buf);
873 else
874 fputs (buf, stderr);
875
876 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
877 _IO_funlockfile (stderr);
878
879 free (buf);
880 }
881 #else
826 fprintf (stderr, _("%s: option requires an argument -- %c\n"), 882 fprintf (stderr, _("%s: option requires an argument -- %c\n"),
827 argv[0], c); 883 argv[0], c);
884 #endif
828 } 885 }
829 optopt = c; 886 d->optopt = c;
830 if (optstring[0] == ':') 887 if (optstring[0] == ':')
831 c = ':'; 888 c = ':';
832 else 889 else
...@@ -834,22 +891,23 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -834,22 +891,23 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
834 return c; 891 return c;
835 } 892 }
836 else 893 else
837 /* We already incremented `optind' once; 894 /* We already incremented `d->optind' once;
838 increment it again when taking next ARGV-elt as argument. */ 895 increment it again when taking next ARGV-elt as argument. */
839 optarg = argv[optind++]; 896 d->optarg = argv[d->optind++];
840 897
841 /* optarg is now the argument, see if it's in the 898 /* optarg is now the argument, see if it's in the
842 table of longopts. */ 899 table of longopts. */
843 900
844 for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) 901 for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
902 nameend++)
845 /* Do nothing. */ ; 903 /* Do nothing. */ ;
846 904
847 /* Test all long options for either exact match 905 /* Test all long options for either exact match
848 or abbreviated matches. */ 906 or abbreviated matches. */
849 for (p = longopts, option_index = 0; p->name; p++, option_index++) 907 for (p = longopts, option_index = 0; p->name; p++, option_index++)
850 if (!strncmp (p->name, nextchar, nameend - nextchar)) 908 if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
851 { 909 {
852 if ((unsigned int) (nameend - nextchar) == strlen (p->name)) 910 if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
853 { 911 {
854 /* Exact match found. */ 912 /* Exact match found. */
855 pfound = p; 913 pfound = p;
...@@ -870,10 +928,35 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -870,10 +928,35 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
870 if (ambig && !exact) 928 if (ambig && !exact)
871 { 929 {
872 if (print_errors) 930 if (print_errors)
931 {
932 #if defined _LIBC && defined USE_IN_LIBIO
933 char *buf;
934
935 if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
936 argv[0], argv[d->optind]) >= 0)
937 {
938 _IO_flockfile (stderr);
939
940 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
941 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
942
943 if (_IO_fwide (stderr, 0) > 0)
944 __fwprintf (stderr, L"%s", buf);
945 else
946 fputs (buf, stderr);
947
948 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
949 _IO_funlockfile (stderr);
950
951 free (buf);
952 }
953 #else
873 fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), 954 fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
874 argv[0], argv[optind]); 955 argv[0], argv[d->optind]);
875 nextchar += strlen (nextchar); 956 #endif
876 optind++; 957 }
958 d->__nextchar += strlen (d->__nextchar);
959 d->optind++;
877 return '?'; 960 return '?';
878 } 961 }
879 if (pfound != NULL) 962 if (pfound != NULL)
...@@ -884,33 +967,87 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -884,33 +967,87 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
884 /* Don't test has_arg with >, because some C compilers don't 967 /* Don't test has_arg with >, because some C compilers don't
885 allow it to be used on enums. */ 968 allow it to be used on enums. */
886 if (pfound->has_arg) 969 if (pfound->has_arg)
887 optarg = nameend + 1; 970 d->optarg = nameend + 1;
888 else 971 else
889 { 972 {
890 if (print_errors) 973 if (print_errors)
974 {
975 #if defined _LIBC && defined USE_IN_LIBIO
976 char *buf;
977
978 if (__asprintf (&buf, _("\
979 %s: option `-W %s' doesn't allow an argument\n"),
980 argv[0], pfound->name) >= 0)
981 {
982 _IO_flockfile (stderr);
983
984 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
985 ((_IO_FILE *) stderr)->_flags2
986 |= _IO_FLAGS2_NOTCANCEL;
987
988 if (_IO_fwide (stderr, 0) > 0)
989 __fwprintf (stderr, L"%s", buf);
990 else
991 fputs (buf, stderr);
992
993 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
994 _IO_funlockfile (stderr);
995
996 free (buf);
997 }
998 #else
891 fprintf (stderr, _("\ 999 fprintf (stderr, _("\
892 %s: option `-W %s' doesn't allow an argument\n"), 1000 %s: option `-W %s' doesn't allow an argument\n"),
893 argv[0], pfound->name); 1001 argv[0], pfound->name);
1002 #endif
1003 }
894 1004
895 nextchar += strlen (nextchar); 1005 d->__nextchar += strlen (d->__nextchar);
896 return '?'; 1006 return '?';
897 } 1007 }
898 } 1008 }
899 else if (pfound->has_arg == 1) 1009 else if (pfound->has_arg == 1)
900 { 1010 {
901 if (optind < argc) 1011 if (d->optind < argc)
902 optarg = argv[optind++]; 1012 d->optarg = argv[d->optind++];
903 else 1013 else
904 { 1014 {
905 if (print_errors) 1015 if (print_errors)
1016 {
1017 #if defined _LIBC && defined USE_IN_LIBIO
1018 char *buf;
1019
1020 if (__asprintf (&buf, _("\
1021 %s: option `%s' requires an argument\n"),
1022 argv[0], argv[d->optind - 1]) >= 0)
1023 {
1024 _IO_flockfile (stderr);
1025
1026 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
1027 ((_IO_FILE *) stderr)->_flags2
1028 |= _IO_FLAGS2_NOTCANCEL;
1029
1030 if (_IO_fwide (stderr, 0) > 0)
1031 __fwprintf (stderr, L"%s", buf);
1032 else
1033 fputs (buf, stderr);
1034
1035 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
1036 _IO_funlockfile (stderr);
1037
1038 free (buf);
1039 }
1040 #else
906 fprintf (stderr, 1041 fprintf (stderr,
907 _("%s: option `%s' requires an argument\n"), 1042 _("%s: option `%s' requires an argument\n"),
908 argv[0], argv[optind - 1]); 1043 argv[0], argv[d->optind - 1]);
909 nextchar += strlen (nextchar); 1044 #endif
1045 }
1046 d->__nextchar += strlen (d->__nextchar);
910 return optstring[0] == ':' ? ':' : '?'; 1047 return optstring[0] == ':' ? ':' : '?';
911 } 1048 }
912 } 1049 }
913 nextchar += strlen (nextchar); 1050 d->__nextchar += strlen (d->__nextchar);
914 if (longind != NULL) 1051 if (longind != NULL)
915 *longind = option_index; 1052 *longind = option_index;
916 if (pfound->flag) 1053 if (pfound->flag)
...@@ -920,7 +1057,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -920,7 +1057,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
920 } 1057 }
921 return pfound->val; 1058 return pfound->val;
922 } 1059 }
923 nextchar = NULL; 1060 d->__nextchar = NULL;
924 return 'W'; /* Let the application handle it. */ 1061 return 'W'; /* Let the application handle it. */
925 } 1062 }
926 if (temp[1] == ':') 1063 if (temp[1] == ':')
...@@ -928,35 +1065,59 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -928,35 +1065,59 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
928 if (temp[2] == ':') 1065 if (temp[2] == ':')
929 { 1066 {
930 /* This is an option that accepts an argument optionally. */ 1067 /* This is an option that accepts an argument optionally. */
931 if (*nextchar != '\0') 1068 if (*d->__nextchar != '\0')
932 { 1069 {
933 optarg = nextchar; 1070 d->optarg = d->__nextchar;
934 optind++; 1071 d->optind++;
935 } 1072 }
936 else 1073 else
937 optarg = NULL; 1074 d->optarg = NULL;
938 nextchar = NULL; 1075 d->__nextchar = NULL;
939 } 1076 }
940 else 1077 else
941 { 1078 {
942 /* This is an option that requires an argument. */ 1079 /* This is an option that requires an argument. */
943 if (*nextchar != '\0') 1080 if (*d->__nextchar != '\0')
944 { 1081 {
945 optarg = nextchar; 1082 d->optarg = d->__nextchar;
946 /* If we end this ARGV-element by taking the rest as an arg, 1083 /* If we end this ARGV-element by taking the rest as an arg,
947 we must advance to the next element now. */ 1084 we must advance to the next element now. */
948 optind++; 1085 d->optind++;
949 } 1086 }
950 else if (optind == argc) 1087 else if (d->optind == argc)
951 { 1088 {
952 if (print_errors) 1089 if (print_errors)
953 { 1090 {
954 /* 1003.2 specifies the format of this message. */ 1091 /* 1003.2 specifies the format of this message. */
1092 #if defined _LIBC && defined USE_IN_LIBIO
1093 char *buf;
1094
1095 if (__asprintf (&buf, _("\
1096 %s: option requires an argument -- %c\n"),
1097 argv[0], c) >= 0)
1098 {
1099 _IO_flockfile (stderr);
1100
1101 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
1102 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
1103
1104 if (_IO_fwide (stderr, 0) > 0)
1105 __fwprintf (stderr, L"%s", buf);
1106 else
1107 fputs (buf, stderr);
1108
1109 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
1110 _IO_funlockfile (stderr);
1111
1112 free (buf);
1113 }
1114 #else
955 fprintf (stderr, 1115 fprintf (stderr,
956 _("%s: option requires an argument -- %c\n"), 1116 _("%s: option requires an argument -- %c\n"),
957 argv[0], c); 1117 argv[0], c);
1118 #endif
958 } 1119 }
959 optopt = c; 1120 d->optopt = c;
960 if (optstring[0] == ':') 1121 if (optstring[0] == ':')
961 c = ':'; 1122 c = ':';
962 else 1123 else
...@@ -965,8 +1126,8 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -965,8 +1126,8 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
965 else 1126 else
966 /* We already incremented `optind' once; 1127 /* We already incremented `optind' once;
967 increment it again when taking next ARGV-elt as argument. */ 1128 increment it again when taking next ARGV-elt as argument. */
968 optarg = argv[optind++]; 1129 d->optarg = argv[d->optind++];
969 nextchar = NULL; 1130 d->__nextchar = NULL;
970 } 1131 }
971 } 1132 }
972 return c; 1133 return c;
...@@ -974,18 +1135,40 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ...@@ -974,18 +1135,40 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
974 } 1135 }
975 1136
976 int 1137 int
977 getopt (argc, argv, optstring) 1138 _getopt_internal (int argc, char **argv, const char *optstring,
978 int argc; 1139 const struct option *longopts, int *longind,
979 char *const *argv; 1140 int long_only, int posixly_correct)
980 const char *optstring; 1141 {
1142 int result;
1143
1144 getopt_data.optind = optind;
1145 getopt_data.opterr = opterr;
1146
1147 result = _getopt_internal_r (argc, argv, optstring, longopts, longind,
1148 long_only, posixly_correct, &getopt_data);
1149
1150 optind = getopt_data.optind;
1151 optarg = getopt_data.optarg;
1152 optopt = getopt_data.optopt;
1153
1154 return result;
1155 }
1156
1157 /* glibc gets a LSB-compliant getopt.
1158 Standalone applications get a POSIX-compliant getopt. */
1159 #if _LIBC
1160 enum { POSIXLY_CORRECT = 0 };
1161 #else
1162 enum { POSIXLY_CORRECT = 1 };
1163 #endif
1164
1165 int
1166 getopt (int argc, char *const *argv, const char *optstring)
981 { 1167 {
982 return _getopt_internal (argc, argv, optstring, 1168 return _getopt_internal (argc, (char **) argv, optstring, NULL, NULL, 0,
983 (const struct option *) 0, 1169 POSIXLY_CORRECT);
984 (int *) 0,
985 0);
986 } 1170 }
987 1171
988 #endif /* Not ELIDE_CODE. */
989 1172
990 #ifdef TEST 1173 #ifdef TEST
991 1174
...@@ -993,9 +1176,7 @@ getopt (argc, argv, optstring) ...@@ -993,9 +1176,7 @@ getopt (argc, argv, optstring)
993 the above definition of `getopt'. */ 1176 the above definition of `getopt'. */
994 1177
995 int 1178 int
996 main (argc, argv) 1179 main (int argc, char **argv)
997 int argc;
998 char **argv;
999 { 1180 {
1000 int c; 1181 int c;
1001 int digit_optind = 0; 1182 int digit_optind = 0;
......
1 /* getopt_long and getopt_long_only entry points for GNU getopt. 1 /* getopt_long and getopt_long_only entry points for GNU getopt.
2 Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 2 Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 NOTE: The canonical source of this file is maintained with the GNU C Library. 4 This file is part of the GNU C Library.
5 Bugs can be reported to bug-glibc@gnu.org.
6 5
7 This program is free software; you can redistribute it and/or modify it 6 This program is free software; you can redistribute it and/or modify
8 under the terms of the GNU General Public License as published by the 7 it under the terms of the GNU General Public License as published by
9 Free Software Foundation; either version 2, or (at your option) any 8 the Free Software Foundation; either version 2, or (at your option)
10 later version. 9 any later version.
11 10
12 This program is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 14 GNU General Public License for more details.
16 15
17 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License along
18 along with this program; if not, write to the Free Software Foundation, 17 with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 19
21 #ifdef HAVE_CONFIG_H 20 #ifdef HAVE_CONFIG_H
22 #include <config.h> 21 #include <config.h>
23 #endif 22 #endif
24 23
25 #include "getopt.h" 24 #ifdef _LIBC
26 25 # include <getopt.h>
27 #if !defined __STDC__ || !__STDC__ 26 #else
28 /* This is a separate conditional since some stdc systems 27 # include "getopt.h"
29 reject `defined (const)'. */
30 #ifndef const
31 #define const
32 #endif
33 #endif 28 #endif
29 #include "getopt_int.h"
34 30
35 #include <stdio.h> 31 #include <stdio.h>
36 32
37 /* Comment out all this code if we are using the GNU C Library, and are not
38 actually compiling the library itself. This code is part of the GNU C
39 Library, but also included in many other GNU distributions. Compiling
40 and linking in this code is a waste when using the GNU C library
41 (especially if it is a shared library). Rather than having every GNU
42 program understand `configure --with-gnu-libc' and omit the object files,
43 it is simpler to just do this in the source for each such file. */
44
45 #define GETOPT_INTERFACE_VERSION 2
46 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
47 #include <gnu-versions.h>
48 #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
49 #define ELIDE_CODE
50 #endif
51 #endif
52
53 #ifndef ELIDE_CODE
54
55
56 /* This needs to come after some library #include 33 /* This needs to come after some library #include
57 to get __GNU_LIBRARY__ defined. */ 34 to get __GNU_LIBRARY__ defined. */
58 #ifdef __GNU_LIBRARY__ 35 #ifdef __GNU_LIBRARY__
...@@ -64,14 +41,20 @@ ...@@ -64,14 +41,20 @@
64 #endif 41 #endif
65 42
66 int 43 int
67 getopt_long (argc, argv, options, long_options, opt_index) 44 getopt_long (int argc, char *__getopt_argv_const *argv, const char *options,
68 int argc; 45 const struct option *long_options, int *opt_index)
69 char *const *argv;
70 const char *options;
71 const struct option *long_options;
72 int *opt_index;
73 { 46 {
74 return _getopt_internal (argc, argv, options, long_options, opt_index, 0); 47 return _getopt_internal (argc, (char **) argv, options, long_options,
48 opt_index, 0, 0);
49 }
50
51 int
52 _getopt_long_r (int argc, char **argv, const char *options,
53 const struct option *long_options, int *opt_index,
54 struct _getopt_data *d)
55 {
56 return _getopt_internal_r (argc, argv, options, long_options, opt_index,
57 0, 0, d);
75 } 58 }
76 59
77 /* Like getopt_long, but '-' as well as '--' can indicate a long option. 60 /* Like getopt_long, but '-' as well as '--' can indicate a long option.
...@@ -80,27 +63,30 @@ getopt_long (argc, argv, options, long_options, opt_index) ...@@ -80,27 +63,30 @@ getopt_long (argc, argv, options, long_options, opt_index)
80 instead. */ 63 instead. */
81 64
82 int 65 int
83 getopt_long_only (argc, argv, options, long_options, opt_index) 66 getopt_long_only (int argc, char *__getopt_argv_const *argv,
84 int argc; 67 const char *options,
85 char *const *argv; 68 const struct option *long_options, int *opt_index)
86 const char *options;
87 const struct option *long_options;
88 int *opt_index;
89 { 69 {
90 return _getopt_internal (argc, argv, options, long_options, opt_index, 1); 70 return _getopt_internal (argc, (char **) argv, options, long_options,
71 opt_index, 1, 0);
91 } 72 }
92 73
74 int
75 _getopt_long_only_r (int argc, char **argv, const char *options,
76 const struct option *long_options, int *opt_index,
77 struct _getopt_data *d)
78 {
79 return _getopt_internal_r (argc, argv, options, long_options, opt_index,
80 1, 0, d);
81 }
93 82
94 #endif /* Not ELIDE_CODE. */
95 83
96 #ifdef TEST 84 #ifdef TEST
97 85
98 #include <stdio.h> 86 #include <stdio.h>
99 87
100 int 88 int
101 main (argc, argv) 89 main (int argc, char **argv)
102 int argc;
103 char **argv;
104 { 90 {
105 int c; 91 int c;
106 int digit_optind = 0; 92 int digit_optind = 0;
......
1 /* 1 /* md5.c - Functions to compute MD5 message digest of files or memory blocks
2 * This code implements the MD5 message-digest algorithm. 2 according to the definition of MD5 in RFC 1321 from April 1992.
3 * The algorithm is due to Ron Rivest. This code was 3 Copyright (C) 1995, 1996, 2001, 2003, 2004 Free Software Foundation, Inc.
4 * written by Colin Plumb in 1993, no copyright is claimed. 4 NOTE: The canonical source of this file is maintained with the GNU C
5 * This code is in the public domain; do with it what you wish. 5 Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
6 * 6
7 * Equivalent code is available from RSA Data Security, Inc. 7 This program is free software; you can redistribute it and/or modify it
8 * This code has been tested against that, and is equivalent, 8 under the terms of the GNU General Public License as published by the
9 * except that you don't need to include two pages of legalese 9 Free Software Foundation; either version 2, or (at your option) any
10 * with every copy. 10 later version.
11 * 11
12 * To compute the message digest of a chunk of bytes, declare an 12 This program is distributed in the hope that it will be useful,
13 * MD5Context structure, pass it to MD5Init, call MD5Update as 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * needed on buffers full of bytes, and then call MD5Final, which 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * will fill a supplied 16-byte array with the digest. 15 GNU General Public License for more details.
16 */ 16
17 /* 17 You should have received a copy of the GNU General Public License
18 * Modified (2001-01-31) to work on Sparcs <gray@Mirddin.farlep.net> 18 along with this program; if not, write to the Free Software Foundation,
19 */ 19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 #if defined(HAVE_CONFIG_H) 20
21 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
22
23 #ifdef HAVE_CONFIG_H
21 # include <config.h> 24 # include <config.h>
22 #endif 25 #endif
23 26
24 #define MD5_CRYPT 27 #include "md5.h"
28
29 #include <stddef.h>
30 #include <string.h>
31
32 #if USE_UNLOCKED_IO
33 # include "unlocked-io.h"
34 #endif
35
36 #ifdef _LIBC
37 # include <endian.h>
38 # if __BYTE_ORDER == __BIG_ENDIAN
39 # define WORDS_BIGENDIAN 1
40 # endif
41 /* We need to keep the namespace clean so define the MD5 function
42 protected using leading __ . */
43 # define md5_init_ctx __md5_init_ctx
44 # define md5_process_block __md5_process_block
45 # define md5_process_bytes __md5_process_bytes
46 # define md5_finish_ctx __md5_finish_ctx
47 # define md5_read_ctx __md5_read_ctx
48 # define md5_stream __md5_stream
49 # define md5_buffer __md5_buffer
50 #endif
51
52 #ifdef WORDS_BIGENDIAN
53 # define SWAP(n) \
54 (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
55 #else
56 # define SWAP(n) (n)
57 #endif
58
59 #define BLOCKSIZE 4096
60 /* Ensure that BLOCKSIZE is a multiple of 64. */
61 #if BLOCKSIZE % 64 != 0
62 /* FIXME-someday (soon?): use #error instead of this kludge. */
63 "invalid BLOCKSIZE"
64 #endif
65
66 /* This array contains the bytes used to pad the buffer to the next
67 64-byte boundary. (RFC 1321, 3.1: Step 1) */
68 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
25 69
26 #ifdef MD5_CRYPT
27 #include <string.h> /* for memcpy() */
28 #include <md5.h>
29 70
71 /* Initialize structure containing state of computation.
72 (RFC 1321, 3.3: Step 3) */
30 void 73 void
31 md5_calc(unsigned char *output, unsigned char *input, unsigned int inlen) 74 md5_init_ctx (struct md5_ctx *ctx)
32 { 75 {
33 MD5_CTX context; 76 ctx->A = 0x67452301;
77 ctx->B = 0xefcdab89;
78 ctx->C = 0x98badcfe;
79 ctx->D = 0x10325476;
34 80
35 MD5Init(&context); 81 ctx->total[0] = ctx->total[1] = 0;
36 MD5Update(&context, input, inlen); 82 ctx->buflen = 0;
37 MD5Final(output, &context);
38 } 83 }
39 84
85 /* Put result from CTX in first 16 bytes following RESBUF. The result
86 must be in little endian byte order.
40 87
41 static void 88 IMPORTANT: On some systems it is required that RESBUF is correctly
42 bytes_encode(unsigned char *output, uint32 *input, unsigned int len) 89 aligned for a 32 bits value. */
90 void *
91 md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
43 { 92 {
44 unsigned int i, j; 93 ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
94 ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
95 ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
96 ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
45 97
46 for (i = 0, j = 0; j < len; i++, j += 4) { 98 return resbuf;
47 output[j] = (unsigned char)(input[i] & 0xff);
48 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
49 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
50 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
51 }
52 } 99 }
53 100
54 static void 101 /* Process the remaining bytes in the internal buffer and the usual
55 bytes_decode(uint32 *output, unsigned char *input, unsigned int len) 102 prolog according to the standard and write the result to RESBUF.
103
104 IMPORTANT: On some systems it is required that RESBUF is correctly
105 aligned for a 32 bits value. */
106 void *
107 md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
56 { 108 {
57 unsigned int i, j; 109 /* Take yet unprocessed bytes into account. */
110 md5_uint32 bytes = ctx->buflen;
111 size_t pad;
112
113 /* Now count remaining bytes. */
114 ctx->total[0] += bytes;
115 if (ctx->total[0] < bytes)
116 ++ctx->total[1];
117
118 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
119 memcpy (&ctx->buffer[bytes], fillbuf, pad);
120
121 /* Put the 64-bit file length in *bits* at the end of the buffer. */
122 *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
123 *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
124 (ctx->total[0] >> 29));
125
126 /* Process last bytes. */
127 md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
58 128
59 for (i = 0, j = 0; j < len; i++, j += 4) 129 return md5_read_ctx (ctx, resbuf);
60 output[i] = ((uint32)input[j]) |
61 (((uint32)input[j+1]) << 8) |
62 (((uint32)input[j+2]) << 16) |
63 (((uint32)input[j+3]) << 24);
64 } 130 }
65 131
66 /* 132 /* Compute MD5 message digest for bytes read from STREAM. The
67 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 133 resulting message digest number will be written into the 16 bytes
68 * initialization constants. 134 beginning at RESBLOCK. */
69 */ 135 int
70 void 136 md5_stream (FILE *stream, void *resblock)
71 MD5Init(struct MD5Context *ctx)
72 { 137 {
73 ctx->buf[0] = 0x67452301; 138 struct md5_ctx ctx;
74 ctx->buf[1] = 0xefcdab89; 139 char buffer[BLOCKSIZE + 72];
75 ctx->buf[2] = 0x98badcfe; 140 size_t sum;
76 ctx->buf[3] = 0x10325476; 141
142 /* Initialize the computation context. */
143 md5_init_ctx (&ctx);
144
145 /* Iterate over full file contents. */
146 while (1)
147 {
148 /* We read the file in blocks of BLOCKSIZE bytes. One call of the
149 computation function processes the whole buffer so that with the
150 next round of the loop another block can be read. */
151 size_t n;
152 sum = 0;
153
154 /* Read block. Take care for partial reads. */
155 while (1)
156 {
157 n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
158
159 sum += n;
160
161 if (sum == BLOCKSIZE)
162 break;
163
164 if (n == 0)
165 {
166 /* Check for the error flag IFF N == 0, so that we don't
167 exit the loop after a partial read due to e.g., EAGAIN
168 or EWOULDBLOCK. */
169 if (ferror (stream))
170 return 1;
171 goto process_partial_block;
172 }
77 173
78 ctx->bits[0] = 0; 174 /* We've read at least one byte, so ignore errors. But always
79 ctx->bits[1] = 0; 175 check for EOF, since feof may be true even though N > 0.
80 } 176 Otherwise, we could end up calling fread after EOF. */
177 if (feof (stream))
178 goto process_partial_block;
179 }
81 180
82 /* 181 /* Process buffer with BLOCKSIZE bytes. Note that
83 * Update context to reflect the concatenation of another buffer full 182 BLOCKSIZE % 64 == 0
84 * of bytes.
85 */ 183 */
86 void 184 md5_process_block (buffer, BLOCKSIZE, &ctx);
87 MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) 185 }
88 {
89 uint32 t;
90 186
91 /* Update bitcount */ 187 process_partial_block:;
92 188
93 t = ctx->bits[0]; 189 /* Process any remaining bytes. */
94 if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) 190 if (sum > 0)
95 ctx->bits[1]++; /* Carry from low to high */ 191 md5_process_bytes (buffer, sum, &ctx);
96 ctx->bits[1] += len >> 29;
97 192
98 t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 193 /* Construct result in desired memory. */
99 /* Handle any leading odd-sized chunks */ 194 md5_finish_ctx (&ctx, resblock);
195 return 0;
196 }
100 197
101 if (t) { 198 /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
102 unsigned char *p = (unsigned char *) ctx->in + t; 199 result is always in little endian byte order, so that a byte-wise
103 t = 64 - t; 200 output yields to the wanted ASCII representation of the message
104 if (len < t) { 201 digest. */
105 memcpy(p, buf, len); 202 void *
106 return; 203 md5_buffer (const char *buffer, size_t len, void *resblock)
107 } 204 {
108 memcpy(p, buf, t); 205 struct md5_ctx ctx;
109 MD5Transform(ctx->buf, (uint32 *) ctx->in);
110 buf += t;
111 len -= t;
112 }
113 /* Process data in 64-byte chunks */
114 206
115 while (len >= 64) { 207 /* Initialize the computation context. */
116 memcpy(ctx->in, buf, 64); 208 md5_init_ctx (&ctx);
117 MD5Transform(ctx->buf, (uint32 const *) buf);
118 buf += 64;
119 len -= 64;
120 }
121 209
122 /* Handle any remaining bytes of data. */ 210 /* Process whole buffer but last len % 64 bytes. */
211 md5_process_bytes (buffer, len, &ctx);
123 212
124 memcpy(ctx->in, buf, len); 213 /* Put result in desired memory area. */
214 return md5_finish_ctx (&ctx, resblock);
125 } 215 }
126 216
127 /* 217
128 * Final wrapup - pad to 64-byte boundary with the bit pattern
129 * 1 0* (64-bit count of bits processed, MSB-first)
130 */
131 void 218 void
132 MD5Final(unsigned char digest[16], struct MD5Context *ctx) 219 md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
133 { 220 {
134 unsigned count; 221 /* When we already have some bits in our internal buffer concatenate
135 unsigned char *p; 222 both inputs first. */
136 223 if (ctx->buflen != 0)
137 /* Compute number of bytes mod 64 */ 224 {
138 count = (ctx->bits[0] >> 3) & 0x3F; 225 size_t left_over = ctx->buflen;
139 226 size_t add = 128 - left_over > len ? len : 128 - left_over;
140 /* Set the first char of padding to 0x80. This is safe since there is 227
141 always at least one byte free */ 228 memcpy (&ctx->buffer[left_over], buffer, add);
142 p = ctx->in + count; 229 ctx->buflen += add;
143 *p++ = 0x80; 230
144 231 if (ctx->buflen > 64)
145 /* Bytes of padding needed to make 64 bytes */ 232 {
146 count = 64 - 1 - count; 233 md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
147 234
148 /* Pad out to 56 mod 64 */ 235 ctx->buflen &= 63;
149 if (count < 8) { 236 /* The regions in the following copy operation cannot overlap. */
150 /* Two lots of padding: Pad the first block to 64 bytes */ 237 memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
151 memset(p, 0, count); 238 ctx->buflen);
152 MD5Transform(ctx->buf, (uint32 *) ctx->in);
153
154 /* Now fill the next block with 56 bytes */
155 memset(ctx->in, 0, 56);
156 } else {
157 /* Pad block to 56 bytes */
158 memset(p, 0, count - 8);
159 } 239 }
160 240
161 /* Append length in bits and transform */ 241 buffer = (const char *) buffer + add;
162 bytes_encode((unsigned char*)((uint32 *) ctx->in + 14), ctx->bits, 8); 242 len -= add;
163 MD5Transform(ctx->buf, (uint32 *) ctx->in); 243 }
164 bytes_encode(digest,ctx->buf,16);
165 memset((char *) ctx, 0, sizeof(ctx)); /* In case it's sensitive */
166 }
167
168 #ifndef ASM_MD5
169 244
170 /* The four core functions - F1 is optimized somewhat */ 245 /* Process available complete blocks. */
246 if (len >= 64)
247 {
248 #if !_STRING_ARCH_unaligned
249 # define alignof(type) offsetof (struct { char c; type x; }, x)
250 # define UNALIGNED_P(p) (((size_t) p) % alignof (md5_uint32) != 0)
251 if (UNALIGNED_P (buffer))
252 while (len > 64)
253 {
254 md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
255 buffer = (const char *) buffer + 64;
256 len -= 64;
257 }
258 else
259 #endif
260 {
261 md5_process_block (buffer, len & ~63, ctx);
262 buffer = (const char *) buffer + (len & ~63);
263 len &= 63;
264 }
265 }
171 266
172 /*#define F1(x, y, z) (x & y | ~x & z) */ 267 /* Move remaining bytes in internal buffer. */
173 #define F1(x, y, z) (z ^ (x & (y ^ z))) 268 if (len > 0)
174 #define F2(x, y, z) F1(z, x, y) 269 {
175 #define F3(x, y, z) (x ^ y ^ z) 270 size_t left_over = ctx->buflen;
176 #define F4(x, y, z) (y ^ (x | ~z)) 271
272 memcpy (&ctx->buffer[left_over], buffer, len);
273 left_over += len;
274 if (left_over >= 64)
275 {
276 md5_process_block (ctx->buffer, 64, ctx);
277 left_over -= 64;
278 memcpy (ctx->buffer, &ctx->buffer[64], left_over);
279 }
280 ctx->buflen = left_over;
281 }
282 }
177 283
178 /* This is the central step in the MD5 algorithm. */
179 #define MD5STEP(f, w, x, y, z, data, s) \
180 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x );
181 284
182 #if 0 285 /* These are the four functions used in the four steps of the MD5 algorithm
183 dump(char *label,unsigned char *p, int len) 286 and defined in the RFC 1321. The first function is a little bit optimized
184 { 287 (as found in Colin Plumbs public domain implementation). */
185 int i; 288 /* #define FF(b, c, d) ((b & c) | (~b & d)) */
186 return; 289 #define FF(b, c, d) (d ^ (b & (c ^ d)))
187 printf("dump: %s\n", label); 290 #define FG(b, c, d) FF (d, b, c)
188 for (i=0; i<len; i++) 291 #define FH(b, c, d) (b ^ c ^ d)
189 printf("%x\n", p[i]); 292 #define FI(b, c, d) (c ^ (b | ~d))
190 printf("--\n");
191 293
192 } 294 /* Process LEN bytes of BUFFER, accumulating context into CTX.
193 #endif 295 It is assumed that LEN % 64 == 0. */
194 296
195 /*
196 * The core of the MD5 algorithm, this alters an existing MD5 hash to
197 * reflect the addition of 16 longwords of new data. MD5Update blocks
198 * the data and converts bytes into longwords for this routine.
199 */
200 void 297 void
201 MD5Transform(uint32 buf[4], uint32 const cin[16]) 298 md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
202 { 299 {
203 register uint32 a, b, c, d; 300 md5_uint32 correct_words[16];
204 uint32 in[16]; 301 const md5_uint32 *words = buffer;
205 302 size_t nwords = len / sizeof (md5_uint32);
206 bytes_decode(in, (unsigned char *) cin, 64); 303 const md5_uint32 *endp = words + nwords;
207 304 md5_uint32 A = ctx->A;
208 a = buf[0]; 305 md5_uint32 B = ctx->B;
209 b = buf[1]; 306 md5_uint32 C = ctx->C;
210 c = buf[2]; 307 md5_uint32 D = ctx->D;
211 d = buf[3]; 308
212 309 /* First increment the byte count. RFC 1321 specifies the possible
213 MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 310 length of the file up to 2^64 bits. Here we only compute the
214 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 311 number of bytes. Do a double word increment. */
215 MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 312 ctx->total[0] += len;
216 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 313 if (ctx->total[0] < len)
217 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 314 ++ctx->total[1];
218 MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 315
219 MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 316 /* Process all bytes in the buffer with 64 bytes in each round of
220 MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 317 the loop. */
221 MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 318 while (words < endp)
222 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 319 {
223 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 320 md5_uint32 *cwp = correct_words;
224 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 321 md5_uint32 A_save = A;
225 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 322 md5_uint32 B_save = B;
226 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 323 md5_uint32 C_save = C;
227 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 324 md5_uint32 D_save = D;
228 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 325
229 326 /* First round: using the given function, the context and a constant
230 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 327 the next context is computed. Because the algorithms processing
231 MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 328 unit is a 32-bit word and it is determined to work on words in
232 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 329 little endian byte order we perhaps have to change the byte order
233 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 330 before the computation. To reduce the work for the next steps
234 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 331 we store the swapped words in the array CORRECT_WORDS. */
235 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 332
236 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 333 #define OP(a, b, c, d, s, T) \
237 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 334 do \
238 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 335 { \
239 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 336 a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
240 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 337 ++words; \
241 MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 338 a = rol (a, s); \
242 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 339 a += b; \
243 MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 340 } \
244 MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 341 while (0)
245 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 342
246 343 /* Before we start, one word to the strange constants.
247 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 344 They are defined in RFC 1321 as
248 MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 345
249 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 346 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64, or
250 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 347 perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'
251 MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 348 */
252 MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
253 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
254 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
255 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
256 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
257 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
258 MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
259 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
260 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
261 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
262 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
263
264 MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
265 MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
266 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
267 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
268 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
269 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
270 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
271 MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
272 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
273 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
274 MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
275 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
276 MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
277 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
278 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
279 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
280
281 buf[0] += a;
282 buf[1] += b;
283 buf[2] += c;
284 buf[3] += d;
285 }
286 349
287 #endif 350 /* Round 1. */
288 #endif /* MD5_CRYPT */ 351 OP (A, B, C, D, 7, 0xd76aa478);
352 OP (D, A, B, C, 12, 0xe8c7b756);
353 OP (C, D, A, B, 17, 0x242070db);
354 OP (B, C, D, A, 22, 0xc1bdceee);
355 OP (A, B, C, D, 7, 0xf57c0faf);
356 OP (D, A, B, C, 12, 0x4787c62a);
357 OP (C, D, A, B, 17, 0xa8304613);
358 OP (B, C, D, A, 22, 0xfd469501);
359 OP (A, B, C, D, 7, 0x698098d8);
360 OP (D, A, B, C, 12, 0x8b44f7af);
361 OP (C, D, A, B, 17, 0xffff5bb1);
362 OP (B, C, D, A, 22, 0x895cd7be);
363 OP (A, B, C, D, 7, 0x6b901122);
364 OP (D, A, B, C, 12, 0xfd987193);
365 OP (C, D, A, B, 17, 0xa679438e);
366 OP (B, C, D, A, 22, 0x49b40821);
367
368 /* For the second to fourth round we have the possibly swapped words
369 in CORRECT_WORDS. Redefine the macro to take an additional first
370 argument specifying the function to use. */
371 #undef OP
372 #define OP(f, a, b, c, d, k, s, T) \
373 do \
374 { \
375 a += f (b, c, d) + correct_words[k] + T; \
376 a = rol (a, s); \
377 a += b; \
378 } \
379 while (0)
380
381 /* Round 2. */
382 OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
383 OP (FG, D, A, B, C, 6, 9, 0xc040b340);
384 OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
385 OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
386 OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
387 OP (FG, D, A, B, C, 10, 9, 0x02441453);
388 OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
389 OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
390 OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
391 OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
392 OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
393 OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
394 OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
395 OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
396 OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
397 OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
398
399 /* Round 3. */
400 OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
401 OP (FH, D, A, B, C, 8, 11, 0x8771f681);
402 OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
403 OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
404 OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
405 OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
406 OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
407 OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
408 OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
409 OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
410 OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
411 OP (FH, B, C, D, A, 6, 23, 0x04881d05);
412 OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
413 OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
414 OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
415 OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
416
417 /* Round 4. */
418 OP (FI, A, B, C, D, 0, 6, 0xf4292244);
419 OP (FI, D, A, B, C, 7, 10, 0x432aff97);
420 OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
421 OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
422 OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
423 OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
424 OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
425 OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
426 OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
427 OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
428 OP (FI, C, D, A, B, 6, 15, 0xa3014314);
429 OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
430 OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
431 OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
432 OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
433 OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
434
435 /* Add the starting values of the context. */
436 A += A_save;
437 B += B_save;
438 C += C_save;
439 D += D_save;
440 }
441
442 /* Put checksum in context given as argument. */
443 ctx->A = A;
444 ctx->B = B;
445 ctx->C = C;
446 ctx->D = D;
447 }
......
1 #ifndef MD5_H 1 /* md5.h - Declaration of functions and data types used for MD5 sum
2 #define MD5_H 2 computing library functions.
3 3
4 #ifdef __alpha 4 Copyright (C) 1995, 1996, 1999, 2000, 2003, 2004 Free Software
5 typedef unsigned int uint32; 5 Foundation, Inc.
6 #else 6
7 typedef unsigned long uint32; 7 NOTE: The canonical source of this file is maintained with the GNU C
8 Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
9
10 This program is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
13 later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation,
22 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23
24 #ifndef _MD5_H
25 #define _MD5_H 1
26
27 #include <stdio.h>
28
29 #if HAVE_INTTYPES_H
30 # include <inttypes.h>
31 #endif
32 #if HAVE_STDINT_H || _LIBC
33 # include <stdint.h>
8 #endif 34 #endif
9 35
10 struct MD5Context { 36 typedef uint32_t md5_uint32;
11 uint32 buf[4]; 37
12 uint32 bits[2]; 38 /* Structure to save state of computation between the single steps. */
13 unsigned char in[64]; 39 struct md5_ctx
40 {
41 md5_uint32 A;
42 md5_uint32 B;
43 md5_uint32 C;
44 md5_uint32 D;
45
46 md5_uint32 total[2];
47 md5_uint32 buflen;
48 char buffer[128];
14 }; 49 };
15 50
16 void MD5Init(struct MD5Context *context); 51 /*
17 void MD5Update(struct MD5Context *context, unsigned char const *buf, 52 * The following three functions are build up the low level used in
18 unsigned len); 53 * the functions `md5_stream' and `md5_buffer'.
19 void MD5Final(unsigned char digest[16], struct MD5Context *context); 54 */
20 void MD5Transform(uint32 buf[4], uint32 const in[16]); 55
56 /* Initialize structure containing state of computation.
57 (RFC 1321, 3.3: Step 3) */
58 extern void md5_init_ctx (struct md5_ctx *ctx);
21 59
22 typedef struct MD5Context MD5_CTX; 60 /* Starting with the result of former calls of this function (or the
61 initialization function update the context for the next LEN bytes
62 starting at BUFFER.
63 It is necessary that LEN is a multiple of 64!!! */
64 extern void md5_process_block (const void *buffer, size_t len,
65 struct md5_ctx *ctx);
23 66
24 #endif /* !MD5_H */ 67 /* Starting with the result of former calls of this function (or the
68 initialization function update the context for the next LEN bytes
69 starting at BUFFER.
70 It is NOT required that LEN is a multiple of 64. */
71 extern void md5_process_bytes (const void *buffer, size_t len,
72 struct md5_ctx *ctx);
73
74 /* Process the remaining bytes in the buffer and put result from CTX
75 in first 16 bytes following RESBUF. The result is always in little
76 endian byte order, so that a byte-wise output yields to the wanted
77 ASCII representation of the message digest.
78
79 IMPORTANT: On some systems it is required that RESBUF be correctly
80 aligned for a 32 bits value. */
81 extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf);
82
83
84 /* Put result from CTX in first 16 bytes following RESBUF. The result is
85 always in little endian byte order, so that a byte-wise output yields
86 to the wanted ASCII representation of the message digest.
87
88 IMPORTANT: On some systems it is required that RESBUF is correctly
89 aligned for a 32 bits value. */
90 extern void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf);
91
92
93 /* Compute MD5 message digest for bytes read from STREAM. The
94 resulting message digest number will be written into the 16 bytes
95 beginning at RESBLOCK. */
96 extern int md5_stream (FILE *stream, void *resblock);
97
98 /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
99 result is always in little endian byte order, so that a byte-wise
100 output yields to the wanted ASCII representation of the message
101 digest. */
102 extern void *md5_buffer (const char *buffer, size_t len, void *resblock);
103
104 #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
105
106 #endif
......
This diff could not be displayed because it is too large.
1 /* Copyright (C) 1991,93,94,95,96,97,99,2000, 2001 Free Software Foundation, Inc. 1 /* Searching in a string.
2 Based on strlen implementation by Torbjorn Granlund (tege@sics.se), 2 Copyright (C) 2003 Free Software Foundation, Inc.
3 with help from Dan Sahlin (dan@sics.se) and
4 bug fix and commentary by Jim Blandy (jimb@ai.mit.edu);
5 adaptation to strchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
6 and implemented by Roland McGrath (roland@ai.mit.edu).
7 3
8 The GNU C Library is free software; you can redistribute it and/or 4 This program is free software; you can redistribute it and/or modify
9 modify it under the terms of the GNU Library General Public License as 5 it under the terms of the GNU General Public License as published by
10 published by the Free Software Foundation; either version 2 of the 6 the Free Software Foundation; either version 2, or (at your option)
11 License, or (at your option) any later version. 7 any later version.
12 8
13 The GNU C Library is distributed in the hope that it will be useful, 9 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 Library General Public License for more details. 12 GNU General Public License for more details.
17 13
18 You should have received a copy of the GNU Library General Public 14 You should have received a copy of the GNU General Public License
19 License along with the GNU C Library; see the file COPYING.LIB. If not, 15 along with this program; if not, write to the Free Software Foundation,
20 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 Boston, MA 02111-1307, USA. */
22 17
23 #include <string.h> 18 /* Specification. */
24 #include <stdlib.h> 19 #include "strchrnul.h"
25 20
26 /* Find the first occurrence of C in S or the final NUL byte. */ 21 /* Find the first occurrence of C in S or the final NUL byte. */
27 char * 22 char *
28 strchrnul (s, c_in) 23 strchrnul (const char *s, int c_in)
29 const char *s;
30 int c_in;
31 { 24 {
32 const char *char_ptr; 25 char c = c_in;
33 const unsigned long int *longword_ptr; 26 while (*s && (*s != c))
34 unsigned long int longword, magic_bits, charmask; 27 s++;
35 unsigned char c;
36 28
37 c = (unsigned char) c_in; 29 return (char *) s;
38
39 /* Handle the first few characters by reading one character at a time.
40 Do this until CHAR_PTR is aligned on a longword boundary. */
41 for (char_ptr = s; ((unsigned long int) char_ptr
42 & (sizeof (longword) - 1)) != 0;
43 ++char_ptr)
44 if (*char_ptr == c || *char_ptr == '\0')
45 return (void *) char_ptr;
46
47 /* All these elucidatory comments refer to 4-byte longwords,
48 but the theory applies equally well to 8-byte longwords. */
49
50 longword_ptr = (unsigned long int *) char_ptr;
51
52 /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
53 the "holes." Note that there is a hole just to the left of
54 each byte, with an extra at the end:
55
56 bits: 01111110 11111110 11111110 11111111
57 bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
58
59 The 1-bits make sure that carries propagate to the next 0-bit.
60 The 0-bits provide holes for carries to fall into. */
61 switch (sizeof (longword))
62 {
63 case 4: magic_bits = 0x7efefeffL; break;
64 case 8: magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; break;
65 default:
66 abort ();
67 }
68
69 /* Set up a longword, each of whose bytes is C. */
70 charmask = c | (c << 8);
71 charmask |= charmask << 16;
72 if (sizeof (longword) > 4)
73 /* Do the shift in two steps to avoid a warning if long has 32 bits. */
74 charmask |= (charmask << 16) << 16;
75 if (sizeof (longword) > 8)
76 abort ();
77
78 /* Instead of the traditional loop which tests each character,
79 we will test a longword at a time. The tricky part is testing
80 if *any of the four* bytes in the longword in question are zero. */
81 for (;;)
82 {
83 /* We tentatively exit the loop if adding MAGIC_BITS to
84 LONGWORD fails to change any of the hole bits of LONGWORD.
85
86 1) Is this safe? Will it catch all the zero bytes?
87 Suppose there is a byte with all zeros. Any carry bits
88 propagating from its left will fall into the hole at its
89 least significant bit and stop. Since there will be no
90 carry from its most significant bit, the LSB of the
91 byte to the left will be unchanged, and the zero will be
92 detected.
93
94 2) Is this worthwhile? Will it ignore everything except
95 zero bytes? Suppose every byte of LONGWORD has a bit set
96 somewhere. There will be a carry into bit 8. If bit 8
97 is set, this will carry into bit 16. If bit 8 is clear,
98 one of bits 9-15 must be set, so there will be a carry
99 into bit 16. Similarly, there will be a carry into bit
100 24. If one of bits 24-30 is set, there will be a carry
101 into bit 31, so all of the hole bits will be changed.
102
103 The one misfire occurs when bits 24-30 are clear and bit
104 31 is set; in this case, the hole at bit 31 is not
105 changed. If we had access to the processor carry flag,
106 we could close this loophole by putting the fourth hole
107 at bit 32!
108
109 So it ignores everything except 128's, when they're aligned
110 properly.
111
112 3) But wait! Aren't we looking for C as well as zero?
113 Good point. So what we do is XOR LONGWORD with a longword,
114 each of whose bytes is C. This turns each byte that is C
115 into a zero. */
116
117 longword = *longword_ptr++;
118
119 /* Add MAGIC_BITS to LONGWORD. */
120 if ((((longword + magic_bits)
121
122 /* Set those bits that were unchanged by the addition. */
123 ^ ~longword)
124
125 /* Look at only the hole bits. If any of the hole bits
126 are unchanged, most likely one of the bytes was a
127 zero. */
128 & ~magic_bits) != 0 ||
129
130 /* That caught zeroes. Now test for C. */
131 ((((longword ^ charmask) + magic_bits) ^ ~(longword ^ charmask))
132 & ~magic_bits) != 0)
133 {
134 /* Which of the bytes was C or zero?
135 If none of them were, it was a misfire; continue the search. */
136
137 const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
138
139 if (*cp == c || *cp == '\0')
140 return (char *) cp;
141 if (*++cp == c || *cp == '\0')
142 return (char *) cp;
143 if (*++cp == c || *cp == '\0')
144 return (char *) cp;
145 if (*++cp == c || *cp == '\0')
146 return (char *) cp;
147 if (sizeof (longword) > 4)
148 {
149 if (*++cp == c || *cp == '\0')
150 return (char *) cp;
151 if (*++cp == c || *cp == '\0')
152 return (char *) cp;
153 if (*++cp == c || *cp == '\0')
154 return (char *) cp;
155 if (*++cp == c || *cp == '\0')
156 return (char *) cp;
157 }
158 }
159 }
160
161 /* This should never happen. */
162 return NULL;
163 } 30 }
......
1 /* Copyright (C) 1996, 1997, 1998, 2001 Free Software Foundation, Inc. 1 /* Copyright (C) 1996, 1997, 1998, 2000, 2003 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 2
4 The GNU C Library is free software; you can redistribute it and/or 3 NOTE: The canonical source of this file is maintained with the GNU C Library.
5 modify it under the terms of the GNU Library General Public License as 4 Bugs can be reported to bug-glibc@prep.ai.mit.edu.
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8 5
9 The GNU C Library is distributed in the hope that it will be useful, 6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 Library General Public License for more details. 14 GNU General Public License for more details.
13 15
14 You should have received a copy of the GNU Library General Public 16 You should have received a copy of the GNU General Public License
15 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 along with this program; if not, write to the Free Software Foundation,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 Boston, MA 02111-1307, USA. */
18 19
19 #ifdef HAVE_CONFIG_H 20 #ifdef HAVE_CONFIG_H
20 # include "config.h" 21 # include "config.h"
21 #endif 22 #endif
22 23
23 #include <stdio.h> 24 #include <stdlib.h>
24 #include <sys/types.h> 25 #include <string.h>
26
27 #ifndef HAVE_DECL_STRNLEN
28 "this configure-time declaration test was not run"
29 #endif
30 #if !HAVE_DECL_STRNLEN
31 size_t strnlen ();
32 #endif
33
34 #undef __strndup
35 #undef strndup
25 36
26 #if defined _LIBC || defined STDC_HEADERS 37 #ifndef weak_alias
27 # include <stdlib.h> 38 # define __strndup strndup
28 # include <string.h>
29 #else
30 char *malloc ();
31 #endif 39 #endif
32 40
33 char * 41 char *
34 strndup (s, n) 42 __strndup (const char *s, size_t n)
35 const char *s;
36 size_t n;
37 { 43 {
38 size_t len = strnlen (s, n); 44 size_t len = strnlen (s, n);
39 char *nouveau = malloc (len + 1); 45 char *new = malloc (len + 1);
40 46
41 if (nouveau == NULL) 47 if (new == NULL)
42 return NULL; 48 return NULL;
43 49
44 nouveau[len] = '\0'; 50 new[len] = '\0';
45 return (char *) memcpy (nouveau, s, len); 51 return memcpy (new, s, len);
46 } 52 }
53 #ifdef weak_alias
54 weak_alias (__strndup, strndup)
55 #endif
......
1 /* Find the length of STRING, but scan at most MAXLEN characters. 1 /* Find the length of STRING, but scan at most MAXLEN characters.
2 Copyright (C) 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc. 2 Copyright (C) 1996, 1997, 1998, 2000-2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 4
5 The GNU C Library is free software; you can redistribute it and/or 5 This program is free software; you can redistribute it and/or modify
6 modify it under the terms of the GNU Library General Public License as 6 it under the terms of the GNU General Public License as published by
7 published by the Free Software Foundation; either version 2 of the 7 the Free Software Foundation; either version 2, or (at your option)
8 License, or (at your option) any later version. 8 any later version.
9 9
10 The GNU C Library is distributed in the hope that it will be useful, 10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 Library General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public 15 You should have received a copy of the GNU General Public License along
16 License along with the GNU C Library; see the file COPYING.LIB. If not, 16 with this program; if not, write to the Free Software Foundation,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 Boston, MA 02111-1307, USA. */ 18
19 #if HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22 #undef strnlen
19 23
20 #include <string.h> 24 #include <string.h>
21 25
26 #undef __strnlen
27 #undef strnlen
28
29 #ifndef _LIBC
30 # define strnlen rpl_strnlen
31 #endif
32
33 #ifndef weak_alias
34 # define __strnlen strnlen
35 #endif
36
22 /* Find the length of STRING, but scan at most MAXLEN characters. 37 /* Find the length of STRING, but scan at most MAXLEN characters.
23 If no '\0' terminator is found in that many characters, return MAXLEN. */ 38 If no '\0' terminator is found in that many characters, return MAXLEN. */
24 39
25 size_t 40 size_t
26 strnlen (const char *string, size_t maxlen) 41 __strnlen (const char *string, size_t maxlen)
27 { 42 {
28 const char *end = memchr (string, '\0', maxlen); 43 const char *end = memchr (string, '\0', maxlen);
29 return end ? (size_t) (end - string) : maxlen; 44 return end ? (size_t) (end - string) : maxlen;
30 } 45 }
46 #ifdef weak_alias
47 weak_alias (__strnlen, strnlen)
48 #endif
......
1 /* Reentrant string tokenizer. Generic version. 1 /* Reentrant string tokenizer. Generic version.
2 Copyright (C) 1991, 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc. 2 Copyright (C) 1991,1996-1999,2001,2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 4
5 The GNU C Library is free software; you can redistribute it and/or 5 This program is free software; you can redistribute it and/or modify
6 modify it under the terms of the GNU Library General Public License as 6 it under the terms of the GNU General Public License as published by
7 published by the Free Software Foundation; either version 2 of the 7 the Free Software Foundation; either version 2, or (at your option)
8 License, or (at your option) any later version. 8 any later version.
9 9
10 The GNU C Library is distributed in the hope that it will be useful, 10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 Library General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public 15 You should have received a copy of the GNU General Public License along
16 License along with the GNU C Library; see the file COPYING.LIB. If not, 16 with this program; if not, write to the Free Software Foundation,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 Boston, MA 02111-1307, USA. */ 18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
19 22
20 #include <string.h> 23 #include <string.h>
21 24
25 #undef strtok_r
26 #undef __strtok_r
27
28 #ifndef _LIBC
29 /* Get specification. */
30 # include "strtok_r.h"
31 # define __strtok_r strtok_r
32 # define __rawmemchr strchr
33 #endif
34
22 /* Parse S into tokens separated by characters in DELIM. 35 /* Parse S into tokens separated by characters in DELIM.
23 If S is NULL, the saved pointer in SAVE_PTR is used as 36 If S is NULL, the saved pointer in SAVE_PTR is used as
24 the next starting point. For example: 37 the next starting point. For example:
...@@ -30,10 +43,7 @@ ...@@ -30,10 +43,7 @@
30 // s = "abc\0-def\0" 43 // s = "abc\0-def\0"
31 */ 44 */
32 char * 45 char *
33 strtok_r (s, delim, save_ptr) 46 __strtok_r (char *s, const char *delim, char **save_ptr)
34 char *s;
35 const char *delim;
36 char **save_ptr;
37 { 47 {
38 char *token; 48 char *token;
39 49
...@@ -53,8 +63,7 @@ strtok_r (s, delim, save_ptr) ...@@ -53,8 +63,7 @@ strtok_r (s, delim, save_ptr)
53 s = strpbrk (token, delim); 63 s = strpbrk (token, delim);
54 if (s == NULL) 64 if (s == NULL)
55 /* This token finishes the string. */ 65 /* This token finishes the string. */
56 /* *save_ptr = __rawmemchr (token, '\0'); */ 66 *save_ptr = __rawmemchr (token, '\0');
57 *save_ptr = token + strlen (token);
58 else 67 else
59 { 68 {
60 /* Terminate the token and make *SAVE_PTR point past it. */ 69 /* Terminate the token and make *SAVE_PTR point past it. */
...@@ -63,4 +72,7 @@ strtok_r (s, delim, save_ptr) ...@@ -63,4 +72,7 @@ strtok_r (s, delim, save_ptr)
63 } 72 }
64 return token; 73 return token;
65 } 74 }
66 /* weak_alias (__strtok_r, strtok_r) */ 75 #ifdef weak_alias
76 libc_hidden_def (__strtok_r)
77 weak_alias (__strtok_r, strtok_r)
78 #endif
......