Commit 814d040e 814d040e0eb3a82d3bad476c8cd846a01f610f0a by Sergey Poznyakoff

Added to the repository by gnulib-sync

1 parent 48442c8f
1 /* Safe automatic memory allocation.
2 Copyright (C) 2003 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2003.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 /* Specification. */
24 #include "allocsa.h"
25
26 /* The speed critical point in this file is freesa() applied to an alloca()
27 result: it must be fast, to match the speed of alloca(). The speed of
28 mallocsa() and freesa() in the other case are not critical, because they
29 are only invoked for big memory sizes. */
30
31 #if HAVE_ALLOCA
32
33 /* Store the mallocsa() results in a hash table. This is needed to reliably
34 distinguish a mallocsa() result and an alloca() result.
35
36 Although it is possible that the same pointer is returned by alloca() and
37 by mallocsa() at different times in the same application, it does not lead
38 to a bug in freesa(), because:
39 - Before a pointer returned by alloca() can point into malloc()ed memory,
40 the function must return, and once this has happened the programmer must
41 not call freesa() on it anyway.
42 - Before a pointer returned by mallocsa() can point into the stack, it
43 must be freed. The only function that can free it is freesa(), and
44 when freesa() frees it, it also removes it from the hash table. */
45
46 #define MAGIC_NUMBER 0x1415fb4a
47 #define MAGIC_SIZE sizeof (int)
48 /* This is how the header info would look like without any alignment
49 considerations. */
50 struct preliminary_header { void *next; char room[MAGIC_SIZE]; };
51 /* But the header's size must be a multiple of sa_alignment_max. */
52 #define HEADER_SIZE \
53 (((sizeof (struct preliminary_header) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max)
54 struct header { void *next; char room[HEADER_SIZE - sizeof (struct preliminary_header) + MAGIC_SIZE]; };
55 /* Verify that HEADER_SIZE == sizeof (struct header). */
56 typedef int verify1[2 * (HEADER_SIZE == sizeof (struct header)) - 1];
57 /* We make the hash table quite big, so that during lookups the probability
58 of empty hash buckets is quite high. There is no need to make the hash
59 table resizable, because when the hash table gets filled so much that the
60 lookup becomes slow, it means that the application has memory leaks. */
61 #define HASH_TABLE_SIZE 257
62 static void * mallocsa_results[HASH_TABLE_SIZE];
63
64 #endif
65
66 void *
67 mallocsa (size_t n)
68 {
69 #if HAVE_ALLOCA
70 /* Allocate one more word, that serves as an indicator for malloc()ed
71 memory, so that freesa() of an alloca() result is fast. */
72 size_t nplus = n + HEADER_SIZE;
73
74 if (nplus >= n)
75 {
76 char *p = (char *) malloc (nplus);
77
78 if (p != NULL)
79 {
80 size_t slot;
81
82 p += HEADER_SIZE;
83
84 /* Put a magic number into the indicator word. */
85 ((int *) p)[-1] = MAGIC_NUMBER;
86
87 /* Enter p into the hash table. */
88 slot = (unsigned long) p % HASH_TABLE_SIZE;
89 ((struct header *) (p - HEADER_SIZE))->next = mallocsa_results[slot];
90 mallocsa_results[slot] = p;
91
92 return p;
93 }
94 }
95 /* Out of memory. */
96 return NULL;
97 #else
98 # if !MALLOC_0_IS_NONNULL
99 if (n == 0)
100 n = 1;
101 # endif
102 return malloc (n);
103 #endif
104 }
105
106 #if HAVE_ALLOCA
107 void
108 freesa (void *p)
109 {
110 /* mallocsa() may have returned NULL. */
111 if (p != NULL)
112 {
113 /* Attempt to quickly distinguish the mallocsa() result - which has
114 a magic indicator word - and the alloca() result - which has an
115 uninitialized indicator word. It is for this test that sa_increment
116 additional bytes are allocated in the alloca() case. */
117 if (((int *) p)[-1] == MAGIC_NUMBER)
118 {
119 /* Looks like a mallocsa() result. To see whether it really is one,
120 perform a lookup in the hash table. */
121 size_t slot = (unsigned long) p % HASH_TABLE_SIZE;
122 void **chain = &mallocsa_results[slot];
123 for (; *chain != NULL;)
124 {
125 if (*chain == p)
126 {
127 /* Found it. Remove it from the hash table and free it. */
128 char *p_begin = (char *) p - HEADER_SIZE;
129 *chain = ((struct header *) p_begin)->next;
130 free (p_begin);
131 return;
132 }
133 chain = &((struct header *) ((char *) *chain - HEADER_SIZE))->next;
134 }
135 }
136 /* At this point, we know it was not a mallocsa() result. */
137 }
138 }
139 #endif
1 /* Safe automatic memory allocation.
2 Copyright (C) 2003-2004 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2003.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 #ifndef _ALLOCSA_H
20 #define _ALLOCSA_H
21
22 #include <alloca.h>
23 #include <stddef.h>
24 #include <stdlib.h>
25
26 /* safe_alloca(N) is equivalent to alloca(N) when it is safe to call
27 alloca(N); otherwise it returns NULL. It either returns N bytes of
28 memory allocated on the stack, that lasts until the function returns,
29 or NULL.
30 Use of safe_alloca should be avoided:
31 - inside arguments of function calls - undefined behaviour,
32 - in inline functions - the allocation may actually last until the
33 calling function returns.
34 */
35 #if HAVE_ALLOCA
36 /* The OS usually guarantees only one guard page at the bottom of the stack,
37 and a page size can be as small as 4096 bytes. So we cannot safely
38 allocate anything larger than 4096 bytes. Also care for the possibility
39 of a few compiler-allocated temporary stack slots.
40 This must be a macro, not an inline function. */
41 # define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL)
42 #else
43 # define safe_alloca(N) ((N), NULL)
44 #endif
45
46 /* allocsa(N) is a safe variant of alloca(N). It allocates N bytes of
47 memory allocated on the stack, that must be freed using freesa() before
48 the function returns. Upon failure, it returns NULL. */
49 #if HAVE_ALLOCA
50 # define allocsa(N) \
51 ((N) < 4032 - sa_increment \
52 ? (void *) ((char *) alloca ((N) + sa_increment) + sa_increment) \
53 : mallocsa (N))
54 #else
55 # define allocsa(N) \
56 mallocsa (N)
57 #endif
58 extern void * mallocsa (size_t n);
59
60 /* Free a block of memory allocated through allocsa(). */
61 #if HAVE_ALLOCA
62 extern void freesa (void *p);
63 #else
64 # define freesa free
65 #endif
66
67 /* Maybe we should also define a variant
68 nallocsa (size_t n, size_t s) - behaves like allocsa (n * s)
69 If this would be useful in your application. please speak up. */
70
71
72 /* ------------------- Auxiliary, non-public definitions ------------------- */
73
74 /* Determine the alignment of a type at compile time. */
75 #if defined __GNUC__
76 # define sa_alignof __alignof__
77 #elif defined __cplusplus
78 template <class type> struct sa_alignof_helper { char __slot1; type __slot2; };
79 # define sa_alignof(type) offsetof (sa_alignof_helper<type>, __slot2)
80 #elif defined __hpux
81 /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof
82 values. */
83 # define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
84 #else
85 # define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2)
86 #endif
87
88 enum
89 {
90 /* The desired alignment of memory allocations is the maximum alignment
91 among all elementary types. */
92 sa_alignment_long = sa_alignof (long),
93 sa_alignment_double = sa_alignof (double),
94 #ifdef HAVE_LONG_LONG
95 sa_alignment_longlong = sa_alignof (long long),
96 #endif
97 #ifdef HAVE_LONG_DOUBLE
98 sa_alignment_longdouble = sa_alignof (long double),
99 #endif
100 sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1)
101 #ifdef HAVE_LONG_LONG
102 | (sa_alignment_longlong - 1)
103 #endif
104 #ifdef HAVE_LONG_DOUBLE
105 | (sa_alignment_longdouble - 1)
106 #endif
107 ) + 1,
108 /* The increment that guarantees room for a magic word must be >= sizeof (int)
109 and a multiple of sa_alignment_max. */
110 sa_increment = ((sizeof (int) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max
111 };
112
113 #endif /* _ALLOCSA_H */
1 # Suppress a valgrind message about use of uninitialized memory in freesa().
2 # This use is OK because it provides only a speedup.
3 {
4 freesa
5 Memcheck:Cond
6 fun:freesa
7 }
1 /* Error handler for noninteractive utilities
2 Copyright (C) 1990-1998, 2000-2003, 2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include "error.h"
26
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #if !_LIBC && ENABLE_NLS
33 # include "gettext.h"
34 #endif
35
36 #ifdef _LIBC
37 # include <wchar.h>
38 # define mbsrtowcs __mbsrtowcs
39 #endif
40
41 #if USE_UNLOCKED_IO
42 # include "unlocked-io.h"
43 #endif
44
45 #ifndef _
46 # define _(String) String
47 #endif
48
49 /* If NULL, error will flush stdout, then print on stderr the program
50 name, a colon and a space. Otherwise, error will call this
51 function without parameters instead. */
52 void (*error_print_progname) (void);
53
54 /* This variable is incremented each time `error' is called. */
55 unsigned int error_message_count;
56
57 #ifdef _LIBC
58 /* In the GNU C library, there is a predefined variable for this. */
59
60 # define program_name program_invocation_name
61 # include <errno.h>
62 # include <libio/libioP.h>
63
64 /* In GNU libc we want do not want to use the common name `error' directly.
65 Instead make it a weak alias. */
66 extern void __error (int status, int errnum, const char *message, ...)
67 __attribute__ ((__format__ (__printf__, 3, 4)));
68 extern void __error_at_line (int status, int errnum, const char *file_name,
69 unsigned int line_number, const char *message,
70 ...)
71 __attribute__ ((__format__ (__printf__, 5, 6)));;
72 # define error __error
73 # define error_at_line __error_at_line
74
75 # include <libio/iolibio.h>
76 # define fflush(s) INTUSE(_IO_fflush) (s)
77 # undef putc
78 # define putc(c, fp) INTUSE(_IO_putc) (c, fp)
79
80 # include <bits/libc-lock.h>
81
82 #else /* not _LIBC */
83
84 # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
85 # ifndef HAVE_DECL_STRERROR_R
86 "this configure-time declaration test was not run"
87 # endif
88 char *strerror_r ();
89 # endif
90
91 # ifndef SIZE_MAX
92 # define SIZE_MAX ((size_t) -1)
93 # endif
94
95 /* The calling program should define program_name and set it to the
96 name of the executing program. */
97 extern char *program_name;
98
99 # if HAVE_STRERROR_R || defined strerror_r
100 # define __strerror_r strerror_r
101 # endif
102 #endif /* not _LIBC */
103
104 static void
105 print_errno_message (int errnum)
106 {
107 char const *s = NULL;
108
109 #if defined HAVE_STRERROR_R || _LIBC
110 char errbuf[1024];
111 # if STRERROR_R_CHAR_P || _LIBC
112 s = __strerror_r (errnum, errbuf, sizeof errbuf);
113 # else
114 if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
115 s = errbuf;
116 # endif
117 #endif
118
119 #if !_LIBC
120 if (! s && ! (s = strerror (errnum)))
121 s = _("Unknown system error");
122 #endif
123
124 #if _LIBC
125 if (_IO_fwide (stderr, 0) > 0)
126 {
127 __fwprintf (stderr, L": %s", s);
128 return;
129 }
130 #endif
131
132 fprintf (stderr, ": %s", s);
133 }
134
135 static void
136 error_tail (int status, int errnum, const char *message, va_list args)
137 {
138 #if _LIBC
139 if (_IO_fwide (stderr, 0) > 0)
140 {
141 # define ALLOCA_LIMIT 2000
142 size_t len = strlen (message) + 1;
143 const wchar_t *wmessage = L"out of memory";
144 wchar_t *wbuf = (len < ALLOCA_LIMIT
145 ? alloca (len * sizeof *wbuf)
146 : len <= SIZE_MAX / sizeof *wbuf
147 ? malloc (len * sizeof *wbuf)
148 : NULL);
149
150 if (wbuf)
151 {
152 size_t res;
153 mbstate_t st;
154 const char *tmp = message;
155 memset (&st, '\0', sizeof (st));
156 res = mbsrtowcs (wbuf, &tmp, len, &st);
157 wmessage = res == (size_t) -1 ? L"???" : wbuf;
158 }
159
160 __vfwprintf (stderr, wmessage, args);
161 if (! (len < ALLOCA_LIMIT))
162 free (wbuf);
163 }
164 else
165 #endif
166 vfprintf (stderr, message, args);
167 va_end (args);
168
169 ++error_message_count;
170 if (errnum)
171 print_errno_message (errnum);
172 #if _LIBC
173 if (_IO_fwide (stderr, 0) > 0)
174 putwc (L'\n', stderr);
175 else
176 #endif
177 putc ('\n', stderr);
178 fflush (stderr);
179 if (status)
180 exit (status);
181 }
182
183
184 /* Print the program name and error message MESSAGE, which is a printf-style
185 format string with optional args.
186 If ERRNUM is nonzero, print its corresponding system error message.
187 Exit with status STATUS if it is nonzero. */
188 void
189 error (int status, int errnum, const char *message, ...)
190 {
191 va_list args;
192
193 #if defined _LIBC && defined __libc_ptf_call
194 /* We do not want this call to be cut short by a thread
195 cancellation. Therefore disable cancellation for now. */
196 int state = PTHREAD_CANCEL_ENABLE;
197 __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
198 0);
199 #endif
200
201 fflush (stdout);
202 #ifdef _LIBC
203 _IO_flockfile (stderr);
204 #endif
205 if (error_print_progname)
206 (*error_print_progname) ();
207 else
208 {
209 #if _LIBC
210 if (_IO_fwide (stderr, 0) > 0)
211 __fwprintf (stderr, L"%s: ", program_name);
212 else
213 #endif
214 fprintf (stderr, "%s: ", program_name);
215 }
216
217 va_start (args, message);
218 error_tail (status, errnum, message, args);
219
220 #ifdef _LIBC
221 _IO_funlockfile (stderr);
222 # ifdef __libc_ptf_call
223 __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
224 # endif
225 #endif
226 }
227
228 /* Sometimes we want to have at most one error per line. This
229 variable controls whether this mode is selected or not. */
230 int error_one_per_line;
231
232 void
233 error_at_line (int status, int errnum, const char *file_name,
234 unsigned int line_number, const char *message, ...)
235 {
236 va_list args;
237
238 if (error_one_per_line)
239 {
240 static const char *old_file_name;
241 static unsigned int old_line_number;
242
243 if (old_line_number == line_number
244 && (file_name == old_file_name
245 || strcmp (old_file_name, file_name) == 0))
246 /* Simply return and print nothing. */
247 return;
248
249 old_file_name = file_name;
250 old_line_number = line_number;
251 }
252
253 #if defined _LIBC && defined __libc_ptf_call
254 /* We do not want this call to be cut short by a thread
255 cancellation. Therefore disable cancellation for now. */
256 int state = PTHREAD_CANCEL_ENABLE;
257 __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
258 0);
259 #endif
260
261 fflush (stdout);
262 #ifdef _LIBC
263 _IO_flockfile (stderr);
264 #endif
265 if (error_print_progname)
266 (*error_print_progname) ();
267 else
268 {
269 #if _LIBC
270 if (_IO_fwide (stderr, 0) > 0)
271 __fwprintf (stderr, L"%s: ", program_name);
272 else
273 #endif
274 fprintf (stderr, "%s:", program_name);
275 }
276
277 if (file_name != NULL)
278 {
279 #if _LIBC
280 if (_IO_fwide (stderr, 0) > 0)
281 __fwprintf (stderr, L"%s:%d: ", file_name, line_number);
282 else
283 #endif
284 fprintf (stderr, "%s:%d: ", file_name, line_number);
285 }
286
287 va_start (args, message);
288 error_tail (status, errnum, message, args);
289
290 #ifdef _LIBC
291 _IO_funlockfile (stderr);
292 # ifdef __libc_ptf_call
293 __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
294 # endif
295 #endif
296 }
297
298 #ifdef _LIBC
299 /* Make the weak alias. */
300 # undef error
301 # undef error_at_line
302 weak_alias (__error, error)
303 weak_alias (__error_at_line, error_at_line)
304 #endif
1 /* exit() function.
2 Copyright (C) 1995, 2001 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 #ifndef _EXIT_H
19 #define _EXIT_H
20
21 /* Get exit() declaration. */
22 #include <stdlib.h>
23
24 /* Some systems do not define EXIT_*, even with STDC_HEADERS. */
25 #ifndef EXIT_SUCCESS
26 # define EXIT_SUCCESS 0
27 #endif
28 #ifndef EXIT_FAILURE
29 # define EXIT_FAILURE 1
30 #endif
31
32 #endif /* _EXIT_H */
1 /* Failure exit status
2
3 Copyright (C) 2002, 2003 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING.
17 If not, write to the Free Software Foundation,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #if HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include "exitfail.h"
25 #include "exit.h"
26
27 int volatile exit_failure = EXIT_FAILURE;
1 /* Failure exit status
2
3 Copyright (C) 2002 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING.
17 If not, write to the Free Software Foundation,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 extern int volatile exit_failure;
1 /* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003
2 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 #ifndef _FNMATCH_H
19 # define _FNMATCH_H 1
20
21 # ifdef __cplusplus
22 extern "C" {
23 # endif
24
25 /* We #undef these before defining them because some losing systems
26 (HP-UX A.08.07 for example) define these in <unistd.h>. */
27 # undef FNM_PATHNAME
28 # undef FNM_NOESCAPE
29 # undef FNM_PERIOD
30
31 /* Bits set in the FLAGS argument to `fnmatch'. */
32 # define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
33 # define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
34 # define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
35
36 # if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
37 # define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
38 # define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
39 # define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
40 # define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */
41 # endif
42
43 /* Value returned by `fnmatch' if STRING does not match PATTERN. */
44 # define FNM_NOMATCH 1
45
46 /* This value is returned if the implementation does not support
47 `fnmatch'. Since this is not the case here it will never be
48 returned but the conformance test suites still require the symbol
49 to be defined. */
50 # ifdef _XOPEN_SOURCE
51 # define FNM_NOSYS (-1)
52 # endif
53
54 /* Match NAME against the filename pattern PATTERN,
55 returning zero if it matches, FNM_NOMATCH if not. */
56 extern int fnmatch (const char *__pattern, const char *__name,
57 int __flags);
58
59 # ifdef __cplusplus
60 }
61 # endif
62
63 #endif /* fnmatch.h */
1 /* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004
2 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 /* Match STRING against the filename pattern PATTERN, returning zero if
19 it matches, nonzero if not. */
20 static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
21 const CHAR *string_end, bool no_leading_period, int flags)
22 internal_function;
23 static const CHAR *END (const CHAR *patternp) internal_function;
24
25 static int
26 internal_function
27 FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,
28 bool no_leading_period, int flags)
29 {
30 register const CHAR *p = pattern, *n = string;
31 register UCHAR c;
32 #ifdef _LIBC
33 # if WIDE_CHAR_VERSION
34 const char *collseq = (const char *)
35 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
36 # else
37 const UCHAR *collseq = (const UCHAR *)
38 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
39 # endif
40 #endif
41
42 while ((c = *p++) != L('\0'))
43 {
44 bool new_no_leading_period = false;
45 c = FOLD (c);
46
47 switch (c)
48 {
49 case L('?'):
50 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
51 {
52 int res;
53
54 res = EXT (c, p, n, string_end, no_leading_period,
55 flags);
56 if (res != -1)
57 return res;
58 }
59
60 if (n == string_end)
61 return FNM_NOMATCH;
62 else if (*n == L('/') && (flags & FNM_FILE_NAME))
63 return FNM_NOMATCH;
64 else if (*n == L('.') && no_leading_period)
65 return FNM_NOMATCH;
66 break;
67
68 case L('\\'):
69 if (!(flags & FNM_NOESCAPE))
70 {
71 c = *p++;
72 if (c == L('\0'))
73 /* Trailing \ loses. */
74 return FNM_NOMATCH;
75 c = FOLD (c);
76 }
77 if (n == string_end || FOLD ((UCHAR) *n) != c)
78 return FNM_NOMATCH;
79 break;
80
81 case L('*'):
82 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
83 {
84 int res;
85
86 res = EXT (c, p, n, string_end, no_leading_period,
87 flags);
88 if (res != -1)
89 return res;
90 }
91
92 if (n != string_end && *n == L('.') && no_leading_period)
93 return FNM_NOMATCH;
94
95 for (c = *p++; c == L('?') || c == L('*'); c = *p++)
96 {
97 if (*p == L('(') && (flags & FNM_EXTMATCH) != 0)
98 {
99 const CHAR *endp = END (p);
100 if (endp != p)
101 {
102 /* This is a pattern. Skip over it. */
103 p = endp;
104 continue;
105 }
106 }
107
108 if (c == L('?'))
109 {
110 /* A ? needs to match one character. */
111 if (n == string_end)
112 /* There isn't another character; no match. */
113 return FNM_NOMATCH;
114 else if (*n == L('/')
115 && __builtin_expect (flags & FNM_FILE_NAME, 0))
116 /* A slash does not match a wildcard under
117 FNM_FILE_NAME. */
118 return FNM_NOMATCH;
119 else
120 /* One character of the string is consumed in matching
121 this ? wildcard, so *??? won't match if there are
122 less than three characters. */
123 ++n;
124 }
125 }
126
127 if (c == L('\0'))
128 /* The wildcard(s) is/are the last element of the pattern.
129 If the name is a file name and contains another slash
130 this means it cannot match, unless the FNM_LEADING_DIR
131 flag is set. */
132 {
133 int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
134
135 if (flags & FNM_FILE_NAME)
136 {
137 if (flags & FNM_LEADING_DIR)
138 result = 0;
139 else
140 {
141 if (MEMCHR (n, L('/'), string_end - n) == NULL)
142 result = 0;
143 }
144 }
145
146 return result;
147 }
148 else
149 {
150 const CHAR *endp;
151
152 endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L('/') : L('\0'),
153 string_end - n);
154 if (endp == NULL)
155 endp = string_end;
156
157 if (c == L('[')
158 || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0
159 && (c == L('@') || c == L('+') || c == L('!'))
160 && *p == L('(')))
161 {
162 int flags2 = ((flags & FNM_FILE_NAME)
163 ? flags : (flags & ~FNM_PERIOD));
164 bool no_leading_period2 = no_leading_period;
165
166 for (--p; n < endp; ++n, no_leading_period2 = false)
167 if (FCT (p, n, string_end, no_leading_period2, flags2)
168 == 0)
169 return 0;
170 }
171 else if (c == L('/') && (flags & FNM_FILE_NAME))
172 {
173 while (n < string_end && *n != L('/'))
174 ++n;
175 if (n < string_end && *n == L('/')
176 && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags)
177 == 0))
178 return 0;
179 }
180 else
181 {
182 int flags2 = ((flags & FNM_FILE_NAME)
183 ? flags : (flags & ~FNM_PERIOD));
184 int no_leading_period2 = no_leading_period;
185
186 if (c == L('\\') && !(flags & FNM_NOESCAPE))
187 c = *p;
188 c = FOLD (c);
189 for (--p; n < endp; ++n, no_leading_period2 = false)
190 if (FOLD ((UCHAR) *n) == c
191 && (FCT (p, n, string_end, no_leading_period2, flags2)
192 == 0))
193 return 0;
194 }
195 }
196
197 /* If we come here no match is possible with the wildcard. */
198 return FNM_NOMATCH;
199
200 case L('['):
201 {
202 /* Nonzero if the sense of the character class is inverted. */
203 register bool not;
204 CHAR cold;
205 UCHAR fn;
206
207 if (posixly_correct == 0)
208 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
209
210 if (n == string_end)
211 return FNM_NOMATCH;
212
213 if (*n == L('.') && no_leading_period)
214 return FNM_NOMATCH;
215
216 if (*n == L('/') && (flags & FNM_FILE_NAME))
217 /* `/' cannot be matched. */
218 return FNM_NOMATCH;
219
220 not = (*p == L('!') || (posixly_correct < 0 && *p == L('^')));
221 if (not)
222 ++p;
223
224 fn = FOLD ((UCHAR) *n);
225
226 c = *p++;
227 for (;;)
228 {
229 if (!(flags & FNM_NOESCAPE) && c == L('\\'))
230 {
231 if (*p == L('\0'))
232 return FNM_NOMATCH;
233 c = FOLD ((UCHAR) *p);
234 ++p;
235
236 if (c == fn)
237 goto matched;
238 }
239 else if (c == L('[') && *p == L(':'))
240 {
241 /* Leave room for the null. */
242 CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
243 size_t c1 = 0;
244 #if defined _LIBC || WIDE_CHAR_SUPPORT
245 wctype_t wt;
246 #endif
247 const CHAR *startp = p;
248
249 for (;;)
250 {
251 if (c1 == CHAR_CLASS_MAX_LENGTH)
252 /* The name is too long and therefore the pattern
253 is ill-formed. */
254 return FNM_NOMATCH;
255
256 c = *++p;
257 if (c == L(':') && p[1] == L(']'))
258 {
259 p += 2;
260 break;
261 }
262 if (c < L('a') || c >= L('z'))
263 {
264 /* This cannot possibly be a character class name.
265 Match it as a normal range. */
266 p = startp;
267 c = L('[');
268 goto normal_bracket;
269 }
270 str[c1++] = c;
271 }
272 str[c1] = L('\0');
273
274 #if defined _LIBC || WIDE_CHAR_SUPPORT
275 wt = IS_CHAR_CLASS (str);
276 if (wt == 0)
277 /* Invalid character class name. */
278 return FNM_NOMATCH;
279
280 # if defined _LIBC && ! WIDE_CHAR_VERSION
281 /* The following code is glibc specific but does
282 there a good job in speeding up the code since
283 we can avoid the btowc() call. */
284 if (_ISCTYPE ((UCHAR) *n, wt))
285 goto matched;
286 # else
287 if (ISWCTYPE (BTOWC ((UCHAR) *n), wt))
288 goto matched;
289 # endif
290 #else
291 if ((STREQ (str, L("alnum")) && ISALNUM ((UCHAR) *n))
292 || (STREQ (str, L("alpha")) && ISALPHA ((UCHAR) *n))
293 || (STREQ (str, L("blank")) && ISBLANK ((UCHAR) *n))
294 || (STREQ (str, L("cntrl")) && ISCNTRL ((UCHAR) *n))
295 || (STREQ (str, L("digit")) && ISDIGIT ((UCHAR) *n))
296 || (STREQ (str, L("graph")) && ISGRAPH ((UCHAR) *n))
297 || (STREQ (str, L("lower")) && ISLOWER ((UCHAR) *n))
298 || (STREQ (str, L("print")) && ISPRINT ((UCHAR) *n))
299 || (STREQ (str, L("punct")) && ISPUNCT ((UCHAR) *n))
300 || (STREQ (str, L("space")) && ISSPACE ((UCHAR) *n))
301 || (STREQ (str, L("upper")) && ISUPPER ((UCHAR) *n))
302 || (STREQ (str, L("xdigit")) && ISXDIGIT ((UCHAR) *n)))
303 goto matched;
304 #endif
305 c = *p++;
306 }
307 #ifdef _LIBC
308 else if (c == L('[') && *p == L('='))
309 {
310 UCHAR str[1];
311 uint32_t nrules =
312 _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
313 const CHAR *startp = p;
314
315 c = *++p;
316 if (c == L('\0'))
317 {
318 p = startp;
319 c = L('[');
320 goto normal_bracket;
321 }
322 str[0] = c;
323
324 c = *++p;
325 if (c != L('=') || p[1] != L(']'))
326 {
327 p = startp;
328 c = L('[');
329 goto normal_bracket;
330 }
331 p += 2;
332
333 if (nrules == 0)
334 {
335 if ((UCHAR) *n == str[0])
336 goto matched;
337 }
338 else
339 {
340 const int32_t *table;
341 # if WIDE_CHAR_VERSION
342 const int32_t *weights;
343 const int32_t *extra;
344 # else
345 const unsigned char *weights;
346 const unsigned char *extra;
347 # endif
348 const int32_t *indirect;
349 int32_t idx;
350 const UCHAR *cp = (const UCHAR *) str;
351
352 /* This #include defines a local function! */
353 # if WIDE_CHAR_VERSION
354 # include <locale/weightwc.h>
355 # else
356 # include <locale/weight.h>
357 # endif
358
359 # if WIDE_CHAR_VERSION
360 table = (const int32_t *)
361 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
362 weights = (const int32_t *)
363 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
364 extra = (const int32_t *)
365 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
366 indirect = (const int32_t *)
367 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
368 # else
369 table = (const int32_t *)
370 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
371 weights = (const unsigned char *)
372 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
373 extra = (const unsigned char *)
374 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
375 indirect = (const int32_t *)
376 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
377 # endif
378
379 idx = findidx (&cp);
380 if (idx != 0)
381 {
382 /* We found a table entry. Now see whether the
383 character we are currently at has the same
384 equivalance class value. */
385 int len = weights[idx];
386 int32_t idx2;
387 const UCHAR *np = (const UCHAR *) n;
388
389 idx2 = findidx (&np);
390 if (idx2 != 0 && len == weights[idx2])
391 {
392 int cnt = 0;
393
394 while (cnt < len
395 && (weights[idx + 1 + cnt]
396 == weights[idx2 + 1 + cnt]))
397 ++cnt;
398
399 if (cnt == len)
400 goto matched;
401 }
402 }
403 }
404
405 c = *p++;
406 }
407 #endif
408 else if (c == L('\0'))
409 /* [ (unterminated) loses. */
410 return FNM_NOMATCH;
411 else
412 {
413 bool is_range = false;
414
415 #ifdef _LIBC
416 bool is_seqval = false;
417
418 if (c == L('[') && *p == L('.'))
419 {
420 uint32_t nrules =
421 _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
422 const CHAR *startp = p;
423 size_t c1 = 0;
424
425 while (1)
426 {
427 c = *++p;
428 if (c == L('.') && p[1] == L(']'))
429 {
430 p += 2;
431 break;
432 }
433 if (c == '\0')
434 return FNM_NOMATCH;
435 ++c1;
436 }
437
438 /* We have to handling the symbols differently in
439 ranges since then the collation sequence is
440 important. */
441 is_range = *p == L('-') && p[1] != L('\0');
442
443 if (nrules == 0)
444 {
445 /* There are no names defined in the collation
446 data. Therefore we only accept the trivial
447 names consisting of the character itself. */
448 if (c1 != 1)
449 return FNM_NOMATCH;
450
451 if (!is_range && *n == startp[1])
452 goto matched;
453
454 cold = startp[1];
455 c = *p++;
456 }
457 else
458 {
459 int32_t table_size;
460 const int32_t *symb_table;
461 # ifdef WIDE_CHAR_VERSION
462 char str[c1];
463 size_t strcnt;
464 # else
465 # define str (startp + 1)
466 # endif
467 const unsigned char *extra;
468 int32_t idx;
469 int32_t elem;
470 int32_t second;
471 int32_t hash;
472
473 # ifdef WIDE_CHAR_VERSION
474 /* We have to convert the name to a single-byte
475 string. This is possible since the names
476 consist of ASCII characters and the internal
477 representation is UCS4. */
478 for (strcnt = 0; strcnt < c1; ++strcnt)
479 str[strcnt] = startp[1 + strcnt];
480 # endif
481
482 table_size =
483 _NL_CURRENT_WORD (LC_COLLATE,
484 _NL_COLLATE_SYMB_HASH_SIZEMB);
485 symb_table = (const int32_t *)
486 _NL_CURRENT (LC_COLLATE,
487 _NL_COLLATE_SYMB_TABLEMB);
488 extra = (const unsigned char *)
489 _NL_CURRENT (LC_COLLATE,
490 _NL_COLLATE_SYMB_EXTRAMB);
491
492 /* Locate the character in the hashing table. */
493 hash = elem_hash (str, c1);
494
495 idx = 0;
496 elem = hash % table_size;
497 second = hash % (table_size - 2);
498 while (symb_table[2 * elem] != 0)
499 {
500 /* First compare the hashing value. */
501 if (symb_table[2 * elem] == hash
502 && c1 == extra[symb_table[2 * elem + 1]]
503 && memcmp (str,
504 &extra[symb_table[2 * elem + 1]
505 + 1], c1) == 0)
506 {
507 /* Yep, this is the entry. */
508 idx = symb_table[2 * elem + 1];
509 idx += 1 + extra[idx];
510 break;
511 }
512
513 /* Next entry. */
514 elem += second;
515 }
516
517 if (symb_table[2 * elem] != 0)
518 {
519 /* Compare the byte sequence but only if
520 this is not part of a range. */
521 # ifdef WIDE_CHAR_VERSION
522 int32_t *wextra;
523
524 idx += 1 + extra[idx];
525 /* Adjust for the alignment. */
526 idx = (idx + 3) & ~3;
527
528 wextra = (int32_t *) &extra[idx + 4];
529 # endif
530
531 if (! is_range)
532 {
533 # ifdef WIDE_CHAR_VERSION
534 for (c1 = 0;
535 (int32_t) c1 < wextra[idx];
536 ++c1)
537 if (n[c1] != wextra[1 + c1])
538 break;
539
540 if ((int32_t) c1 == wextra[idx])
541 goto matched;
542 # else
543 for (c1 = 0; c1 < extra[idx]; ++c1)
544 if (n[c1] != extra[1 + c1])
545 break;
546
547 if (c1 == extra[idx])
548 goto matched;
549 # endif
550 }
551
552 /* Get the collation sequence value. */
553 is_seqval = true;
554 # ifdef WIDE_CHAR_VERSION
555 cold = wextra[1 + wextra[idx]];
556 # else
557 /* Adjust for the alignment. */
558 idx += 1 + extra[idx];
559 idx = (idx + 3) & ~4;
560 cold = *((int32_t *) &extra[idx]);
561 # endif
562
563 c = *p++;
564 }
565 else if (c1 == 1)
566 {
567 /* No valid character. Match it as a
568 single byte. */
569 if (!is_range && *n == str[0])
570 goto matched;
571
572 cold = str[0];
573 c = *p++;
574 }
575 else
576 return FNM_NOMATCH;
577 }
578 }
579 else
580 # undef str
581 #endif
582 {
583 c = FOLD (c);
584 normal_bracket:
585
586 /* We have to handling the symbols differently in
587 ranges since then the collation sequence is
588 important. */
589 is_range = (*p == L('-') && p[1] != L('\0')
590 && p[1] != L(']'));
591
592 if (!is_range && c == fn)
593 goto matched;
594
595 cold = c;
596 c = *p++;
597 }
598
599 if (c == L('-') && *p != L(']'))
600 {
601 #if _LIBC
602 /* We have to find the collation sequence
603 value for C. Collation sequence is nothing
604 we can regularly access. The sequence
605 value is defined by the order in which the
606 definitions of the collation values for the
607 various characters appear in the source
608 file. A strange concept, nowhere
609 documented. */
610 uint32_t fcollseq;
611 uint32_t lcollseq;
612 UCHAR cend = *p++;
613
614 # ifdef WIDE_CHAR_VERSION
615 /* Search in the `names' array for the characters. */
616 fcollseq = __collseq_table_lookup (collseq, fn);
617 if (fcollseq == ~((uint32_t) 0))
618 /* XXX We don't know anything about the character
619 we are supposed to match. This means we are
620 failing. */
621 goto range_not_matched;
622
623 if (is_seqval)
624 lcollseq = cold;
625 else
626 lcollseq = __collseq_table_lookup (collseq, cold);
627 # else
628 fcollseq = collseq[fn];
629 lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
630 # endif
631
632 is_seqval = false;
633 if (cend == L('[') && *p == L('.'))
634 {
635 uint32_t nrules =
636 _NL_CURRENT_WORD (LC_COLLATE,
637 _NL_COLLATE_NRULES);
638 const CHAR *startp = p;
639 size_t c1 = 0;
640
641 while (1)
642 {
643 c = *++p;
644 if (c == L('.') && p[1] == L(']'))
645 {
646 p += 2;
647 break;
648 }
649 if (c == '\0')
650 return FNM_NOMATCH;
651 ++c1;
652 }
653
654 if (nrules == 0)
655 {
656 /* There are no names defined in the
657 collation data. Therefore we only
658 accept the trivial names consisting
659 of the character itself. */
660 if (c1 != 1)
661 return FNM_NOMATCH;
662
663 cend = startp[1];
664 }
665 else
666 {
667 int32_t table_size;
668 const int32_t *symb_table;
669 # ifdef WIDE_CHAR_VERSION
670 char str[c1];
671 size_t strcnt;
672 # else
673 # define str (startp + 1)
674 # endif
675 const unsigned char *extra;
676 int32_t idx;
677 int32_t elem;
678 int32_t second;
679 int32_t hash;
680
681 # ifdef WIDE_CHAR_VERSION
682 /* We have to convert the name to a single-byte
683 string. This is possible since the names
684 consist of ASCII characters and the internal
685 representation is UCS4. */
686 for (strcnt = 0; strcnt < c1; ++strcnt)
687 str[strcnt] = startp[1 + strcnt];
688 # endif
689
690 table_size =
691 _NL_CURRENT_WORD (LC_COLLATE,
692 _NL_COLLATE_SYMB_HASH_SIZEMB);
693 symb_table = (const int32_t *)
694 _NL_CURRENT (LC_COLLATE,
695 _NL_COLLATE_SYMB_TABLEMB);
696 extra = (const unsigned char *)
697 _NL_CURRENT (LC_COLLATE,
698 _NL_COLLATE_SYMB_EXTRAMB);
699
700 /* Locate the character in the hashing
701 table. */
702 hash = elem_hash (str, c1);
703
704 idx = 0;
705 elem = hash % table_size;
706 second = hash % (table_size - 2);
707 while (symb_table[2 * elem] != 0)
708 {
709 /* First compare the hashing value. */
710 if (symb_table[2 * elem] == hash
711 && (c1
712 == extra[symb_table[2 * elem + 1]])
713 && memcmp (str,
714 &extra[symb_table[2 * elem + 1]
715 + 1], c1) == 0)
716 {
717 /* Yep, this is the entry. */
718 idx = symb_table[2 * elem + 1];
719 idx += 1 + extra[idx];
720 break;
721 }
722
723 /* Next entry. */
724 elem += second;
725 }
726
727 if (symb_table[2 * elem] != 0)
728 {
729 /* Compare the byte sequence but only if
730 this is not part of a range. */
731 # ifdef WIDE_CHAR_VERSION
732 int32_t *wextra;
733
734 idx += 1 + extra[idx];
735 /* Adjust for the alignment. */
736 idx = (idx + 3) & ~4;
737
738 wextra = (int32_t *) &extra[idx + 4];
739 # endif
740 /* Get the collation sequence value. */
741 is_seqval = true;
742 # ifdef WIDE_CHAR_VERSION
743 cend = wextra[1 + wextra[idx]];
744 # else
745 /* Adjust for the alignment. */
746 idx += 1 + extra[idx];
747 idx = (idx + 3) & ~4;
748 cend = *((int32_t *) &extra[idx]);
749 # endif
750 }
751 else if (symb_table[2 * elem] != 0 && c1 == 1)
752 {
753 cend = str[0];
754 c = *p++;
755 }
756 else
757 return FNM_NOMATCH;
758 }
759 # undef str
760 }
761 else
762 {
763 if (!(flags & FNM_NOESCAPE) && cend == L('\\'))
764 cend = *p++;
765 if (cend == L('\0'))
766 return FNM_NOMATCH;
767 cend = FOLD (cend);
768 }
769
770 /* XXX It is not entirely clear to me how to handle
771 characters which are not mentioned in the
772 collation specification. */
773 if (
774 # ifdef WIDE_CHAR_VERSION
775 lcollseq == 0xffffffff ||
776 # endif
777 lcollseq <= fcollseq)
778 {
779 /* We have to look at the upper bound. */
780 uint32_t hcollseq;
781
782 if (is_seqval)
783 hcollseq = cend;
784 else
785 {
786 # ifdef WIDE_CHAR_VERSION
787 hcollseq =
788 __collseq_table_lookup (collseq, cend);
789 if (hcollseq == ~((uint32_t) 0))
790 {
791 /* Hum, no information about the upper
792 bound. The matching succeeds if the
793 lower bound is matched exactly. */
794 if (lcollseq != fcollseq)
795 goto range_not_matched;
796
797 goto matched;
798 }
799 # else
800 hcollseq = collseq[cend];
801 # endif
802 }
803
804 if (lcollseq <= hcollseq && fcollseq <= hcollseq)
805 goto matched;
806 }
807 # ifdef WIDE_CHAR_VERSION
808 range_not_matched:
809 # endif
810 #else
811 /* We use a boring value comparison of the character
812 values. This is better than comparing using
813 `strcoll' since the latter would have surprising
814 and sometimes fatal consequences. */
815 UCHAR cend = *p++;
816
817 if (!(flags & FNM_NOESCAPE) && cend == L('\\'))
818 cend = *p++;
819 if (cend == L('\0'))
820 return FNM_NOMATCH;
821
822 /* It is a range. */
823 if (cold <= fn && fn <= cend)
824 goto matched;
825 #endif
826
827 c = *p++;
828 }
829 }
830
831 if (c == L(']'))
832 break;
833 }
834
835 if (!not)
836 return FNM_NOMATCH;
837 break;
838
839 matched:
840 /* Skip the rest of the [...] that already matched. */
841 do
842 {
843 ignore_next:
844 c = *p++;
845
846 if (c == L('\0'))
847 /* [... (unterminated) loses. */
848 return FNM_NOMATCH;
849
850 if (!(flags & FNM_NOESCAPE) && c == L('\\'))
851 {
852 if (*p == L('\0'))
853 return FNM_NOMATCH;
854 /* XXX 1003.2d11 is unclear if this is right. */
855 ++p;
856 }
857 else if (c == L('[') && *p == L(':'))
858 {
859 int c1 = 0;
860 const CHAR *startp = p;
861
862 while (1)
863 {
864 c = *++p;
865 if (++c1 == CHAR_CLASS_MAX_LENGTH)
866 return FNM_NOMATCH;
867
868 if (*p == L(':') && p[1] == L(']'))
869 break;
870
871 if (c < L('a') || c >= L('z'))
872 {
873 p = startp;
874 goto ignore_next;
875 }
876 }
877 p += 2;
878 c = *p++;
879 }
880 else if (c == L('[') && *p == L('='))
881 {
882 c = *++p;
883 if (c == L('\0'))
884 return FNM_NOMATCH;
885 c = *++p;
886 if (c != L('=') || p[1] != L(']'))
887 return FNM_NOMATCH;
888 p += 2;
889 c = *p++;
890 }
891 else if (c == L('[') && *p == L('.'))
892 {
893 ++p;
894 while (1)
895 {
896 c = *++p;
897 if (c == '\0')
898 return FNM_NOMATCH;
899
900 if (*p == L('.') && p[1] == L(']'))
901 break;
902 }
903 p += 2;
904 c = *p++;
905 }
906 }
907 while (c != L(']'));
908 if (not)
909 return FNM_NOMATCH;
910 }
911 break;
912
913 case L('+'):
914 case L('@'):
915 case L('!'):
916 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
917 {
918 int res;
919
920 res = EXT (c, p, n, string_end, no_leading_period, flags);
921 if (res != -1)
922 return res;
923 }
924 goto normal_match;
925
926 case L('/'):
927 if (NO_LEADING_PERIOD (flags))
928 {
929 if (n == string_end || c != (UCHAR) *n)
930 return FNM_NOMATCH;
931
932 new_no_leading_period = true;
933 break;
934 }
935 /* FALLTHROUGH */
936 default:
937 normal_match:
938 if (n == string_end || c != FOLD ((UCHAR) *n))
939 return FNM_NOMATCH;
940 }
941
942 no_leading_period = new_no_leading_period;
943 ++n;
944 }
945
946 if (n == string_end)
947 return 0;
948
949 if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L('/'))
950 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
951 return 0;
952
953 return FNM_NOMATCH;
954 }
955
956
957 static const CHAR *
958 internal_function
959 END (const CHAR *pattern)
960 {
961 const CHAR *p = pattern;
962
963 while (1)
964 if (*++p == L('\0'))
965 /* This is an invalid pattern. */
966 return pattern;
967 else if (*p == L('['))
968 {
969 /* Handle brackets special. */
970 if (posixly_correct == 0)
971 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
972
973 /* Skip the not sign. We have to recognize it because of a possibly
974 following ']'. */
975 if (*++p == L('!') || (posixly_correct < 0 && *p == L('^')))
976 ++p;
977 /* A leading ']' is recognized as such. */
978 if (*p == L(']'))
979 ++p;
980 /* Skip over all characters of the list. */
981 while (*p != L(']'))
982 if (*p++ == L('\0'))
983 /* This is no valid pattern. */
984 return pattern;
985 }
986 else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@')
987 || *p == L('!')) && p[1] == L('('))
988 p = END (p + 1);
989 else if (*p == L(')'))
990 break;
991
992 return p + 1;
993 }
994
995
996 static int
997 internal_function
998 EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
999 bool no_leading_period, int flags)
1000 {
1001 const CHAR *startp;
1002 size_t level;
1003 struct patternlist
1004 {
1005 struct patternlist *next;
1006 CHAR str[1];
1007 } *list = NULL;
1008 struct patternlist **lastp = &list;
1009 size_t pattern_len = STRLEN (pattern);
1010 const CHAR *p;
1011 const CHAR *rs;
1012 enum { ALLOCA_LIMIT = 8000 };
1013
1014 /* Parse the pattern. Store the individual parts in the list. */
1015 level = 0;
1016 for (startp = p = pattern + 1; ; ++p)
1017 if (*p == L('\0'))
1018 /* This is an invalid pattern. */
1019 return -1;
1020 else if (*p == L('['))
1021 {
1022 /* Handle brackets special. */
1023 if (posixly_correct == 0)
1024 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
1025
1026 /* Skip the not sign. We have to recognize it because of a possibly
1027 following ']'. */
1028 if (*++p == L('!') || (posixly_correct < 0 && *p == L('^')))
1029 ++p;
1030 /* A leading ']' is recognized as such. */
1031 if (*p == L(']'))
1032 ++p;
1033 /* Skip over all characters of the list. */
1034 while (*p != L(']'))
1035 if (*p++ == L('\0'))
1036 /* This is no valid pattern. */
1037 return -1;
1038 }
1039 else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@')
1040 || *p == L('!')) && p[1] == L('('))
1041 /* Remember the nesting level. */
1042 ++level;
1043 else if (*p == L(')'))
1044 {
1045 if (level-- == 0)
1046 {
1047 /* This means we found the end of the pattern. */
1048 #define NEW_PATTERN \
1049 struct patternlist *newp; \
1050 size_t plen; \
1051 size_t plensize; \
1052 size_t newpsize; \
1053 \
1054 plen = (opt == L('?') || opt == L('@') \
1055 ? pattern_len \
1056 : p - startp + 1); \
1057 plensize = plen * sizeof (CHAR); \
1058 newpsize = offsetof (struct patternlist, str) + plensize; \
1059 if ((size_t) -1 / sizeof (CHAR) < plen \
1060 || newpsize < offsetof (struct patternlist, str) \
1061 || ALLOCA_LIMIT <= newpsize) \
1062 return -1; \
1063 newp = (struct patternlist *) alloca (newpsize); \
1064 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
1065 newp->next = NULL; \
1066 *lastp = newp; \
1067 lastp = &newp->next
1068 NEW_PATTERN;
1069 break;
1070 }
1071 }
1072 else if (*p == L('|'))
1073 {
1074 if (level == 0)
1075 {
1076 NEW_PATTERN;
1077 startp = p + 1;
1078 }
1079 }
1080 assert (list != NULL);
1081 assert (p[-1] == L(')'));
1082 #undef NEW_PATTERN
1083
1084 switch (opt)
1085 {
1086 case L('*'):
1087 if (FCT (p, string, string_end, no_leading_period, flags) == 0)
1088 return 0;
1089 /* FALLTHROUGH */
1090
1091 case L('+'):
1092 do
1093 {
1094 for (rs = string; rs <= string_end; ++rs)
1095 /* First match the prefix with the current pattern with the
1096 current pattern. */
1097 if (FCT (list->str, string, rs, no_leading_period,
1098 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0
1099 /* This was successful. Now match the rest with the rest
1100 of the pattern. */
1101 && (FCT (p, rs, string_end,
1102 rs == string
1103 ? no_leading_period
1104 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1105 flags & FNM_FILE_NAME
1106 ? flags : flags & ~FNM_PERIOD) == 0
1107 /* This didn't work. Try the whole pattern. */
1108 || (rs != string
1109 && FCT (pattern - 1, rs, string_end,
1110 rs == string
1111 ? no_leading_period
1112 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1113 flags & FNM_FILE_NAME
1114 ? flags : flags & ~FNM_PERIOD) == 0)))
1115 /* It worked. Signal success. */
1116 return 0;
1117 }
1118 while ((list = list->next) != NULL);
1119
1120 /* None of the patterns lead to a match. */
1121 return FNM_NOMATCH;
1122
1123 case L('?'):
1124 if (FCT (p, string, string_end, no_leading_period, flags) == 0)
1125 return 0;
1126 /* FALLTHROUGH */
1127
1128 case L('@'):
1129 do
1130 /* I cannot believe it but `strcat' is actually acceptable
1131 here. Match the entire string with the prefix from the
1132 pattern list and the rest of the pattern following the
1133 pattern list. */
1134 if (FCT (STRCAT (list->str, p), string, string_end,
1135 no_leading_period,
1136 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
1137 /* It worked. Signal success. */
1138 return 0;
1139 while ((list = list->next) != NULL);
1140
1141 /* None of the patterns lead to a match. */
1142 return FNM_NOMATCH;
1143
1144 case L('!'):
1145 for (rs = string; rs <= string_end; ++rs)
1146 {
1147 struct patternlist *runp;
1148
1149 for (runp = list; runp != NULL; runp = runp->next)
1150 if (FCT (runp->str, string, rs, no_leading_period,
1151 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
1152 break;
1153
1154 /* If none of the patterns matched see whether the rest does. */
1155 if (runp == NULL
1156 && (FCT (p, rs, string_end,
1157 rs == string
1158 ? no_leading_period
1159 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1160 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
1161 == 0))
1162 /* This is successful. */
1163 return 0;
1164 }
1165
1166 /* None of the patterns together with the rest of the pattern
1167 lead to a match. */
1168 return FNM_NOMATCH;
1169
1170 default:
1171 assert (! "Invalid extended matching operator");
1172 break;
1173 }
1174
1175 return -1;
1176 }
1177
1178
1179 #undef FOLD
1180 #undef CHAR
1181 #undef UCHAR
1182 #undef INT
1183 #undef FCT
1184 #undef EXT
1185 #undef END
1186 #undef MEMPCPY
1187 #undef MEMCHR
1188 #undef STRCOLL
1189 #undef STRLEN
1190 #undef STRCAT
1191 #undef L
1192 #undef BTOWC
1 /* getpass.h -- Read a password of arbitrary length from /dev/tty or stdin.
2 Copyright (C) 2004 Free Software Foundation, Inc.
3 Contributed by Simon Josefsson <jas@extundo.com>, 2004.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 #ifndef GETPASS_H
20 #define GETPASS_H
21
22 /* Get getpass declaration, if available. */
23 #include <unistd.h>
24
25 #if defined HAVE_DECL_GETPASS && !HAVE_DECL_GETPASS
26 /* Read a password of arbitrary length from /dev/tty or stdin. */
27 char *getpass (const char *prompt);
28
29 #endif
30
31 #endif /* GETPASS_H */
1 /* Setting environment variables.
2 Copyright (C) 2001-2004 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 #if HAVE_SETENV || HAVE_UNSETENV
19
20 /* Get setenv(), unsetenv() declarations. */
21 # include <stdlib.h>
22
23 #endif
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29 #if !HAVE_SETENV
30
31 /* Set NAME to VALUE in the environment.
32 If REPLACE is nonzero, overwrite an existing value. */
33 extern int setenv (const char *name, const char *value, int replace);
34
35 #endif
36
37 #if HAVE_UNSETENV
38
39 # if VOID_UNSETENV
40 /* On some systems, unsetenv() returns void.
41 This is the case for FreeBSD 4.8, NetBSD 1.6, OpenBSD 3.4. */
42 # define unsetenv(name) ((unsetenv)(name), 0)
43 # endif
44
45 #else
46
47 /* Remove the variable NAME from the environment. */
48 extern int unsetenv (const char *name);
49
50 #endif
51
52 #ifdef __cplusplus
53 }
54 #endif
1 /* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
2 Written by Bruno Haible <haible@clisp.cons.org>, 2001.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 #ifndef _STDBOOL_H
19 #define _STDBOOL_H
20
21 /* ISO C 99 <stdbool.h> for platforms that lack it. */
22
23 /* Usage suggestions:
24
25 Programs that use <stdbool.h> should be aware of some limitations
26 and standards compliance issues.
27
28 Standards compliance:
29
30 - <stdbool.h> must be #included before 'bool', 'false', 'true'
31 can be used.
32
33 - You cannot assume that sizeof (bool) == 1.
34
35 - Programs should not undefine the macros bool, true, and false,
36 as C99 lists that as an "obsolescent feature".
37
38 Limitations of this substitute, when used in a C89 environment:
39
40 - <stdbool.h> must be #included before the '_Bool' type can be used.
41
42 - You cannot assume that _Bool is a typedef; it might be a macro.
43
44 - In C99, casts and automatic conversions to '_Bool' or 'bool' are
45 performed in such a way that every nonzero value gets converted
46 to 'true', and zero gets converted to 'false'. This doesn't work
47 with this substitute. With this substitute, only the values 0 and 1
48 give the expected result when converted to _Bool' or 'bool'.
49
50 Also, it is suggested that programs use 'bool' rather than '_Bool';
51 this isn't required, but 'bool' is more common. */
52
53
54 /* 7.16. Boolean type and values */
55
56 /* BeOS <sys/socket.h> already #defines false 0, true 1. We use the same
57 definitions below, but temporarily we have to #undef them. */
58 #ifdef __BEOS__
59 # include <OS.h> /* defines bool but not _Bool */
60 # undef false
61 # undef true
62 #endif
63
64 /* For the sake of symbolic names in gdb, we define true and false as
65 enum constants, not only as macros.
66 It is tempting to write
67 typedef enum { false = 0, true = 1 } _Bool;
68 so that gdb prints values of type 'bool' symbolically. But if we do
69 this, values of type '_Bool' may promote to 'int' or 'unsigned int'
70 (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int'
71 (see ISO C 99 6.3.1.1.(2)). So we add a negative value to the
72 enum; this ensures that '_Bool' promotes to 'int'. */
73 #if !(defined __cplusplus || defined __BEOS__)
74 # if !@HAVE__BOOL@
75 # if defined __SUNPRO_C && (__SUNPRO_C < 0x550 || __STDC__ == 1)
76 /* Avoid stupid "warning: _Bool is a keyword in ISO C99". */
77 # define _Bool signed char
78 enum { false = 0, true = 1 };
79 # else
80 typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;
81 # endif
82 # endif
83 #else
84 typedef bool _Bool;
85 #endif
86 #define bool _Bool
87
88 /* The other macros must be usable in preprocessor directives. */
89 #define false 0
90 #define true 1
91 #define __bool_true_false_are_defined 1
92
93 #endif /* _STDBOOL_H */
1 /* Copyright (C) 1992,1995-1999,2000-2002 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 #if HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #if !_LIBC
24 # if !defined errno && !defined HAVE_ERRNO_DECL
25 extern int errno;
26 # endif
27 # define __set_errno(ev) ((errno) = (ev))
28 #endif
29
30 #include <stdlib.h>
31 #include <string.h>
32 #if _LIBC || HAVE_UNISTD_H
33 # include <unistd.h>
34 #endif
35
36 #if !_LIBC
37 # define __environ environ
38 # ifndef HAVE_ENVIRON_DECL
39 extern char **environ;
40 # endif
41 #endif
42
43 #if _LIBC
44 /* This lock protects against simultaneous modifications of `environ'. */
45 # include <bits/libc-lock.h>
46 __libc_lock_define_initialized (static, envlock)
47 # define LOCK __libc_lock_lock (envlock)
48 # define UNLOCK __libc_lock_unlock (envlock)
49 #else
50 # define LOCK
51 # define UNLOCK
52 #endif
53
54 /* In the GNU C library we must keep the namespace clean. */
55 #ifdef _LIBC
56 # define unsetenv __unsetenv
57 #endif
58
59
60 int
61 unsetenv (const char *name)
62 {
63 size_t len;
64 char **ep;
65
66 if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
67 {
68 __set_errno (EINVAL);
69 return -1;
70 }
71
72 len = strlen (name);
73
74 LOCK;
75
76 ep = __environ;
77 while (*ep != NULL)
78 if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
79 {
80 /* Found it. Remove this pointer by moving later ones back. */
81 char **dp = ep;
82
83 do
84 dp[0] = dp[1];
85 while (*dp++);
86 /* Continue the loop in case NAME appears again. */
87 }
88 else
89 ++ep;
90
91 UNLOCK;
92
93 return 0;
94 }
95
96 #ifdef _LIBC
97 # undef unsetenv
98 weak_alias (__unsetenv, unsetenv)
99 #endif
1 /* vsprintf with automatic memory allocation.
2 Copyright (C) 2002-2003 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 #ifndef _VASPRINTF_H
19 #define _VASPRINTF_H
20
21 #if HAVE_VASPRINTF
22
23 /* Get asprintf(), vasprintf() declarations. */
24 #include <stdio.h>
25
26 #else
27
28 /* Get va_list. */
29 #include <stdarg.h>
30
31 #ifndef __attribute__
32 /* This feature is available in gcc versions 2.5 and later. */
33 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
34 # define __attribute__(Spec) /* empty */
35 # endif
36 /* The __-protected variants of `format' and `printf' attributes
37 are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
38 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
39 # define __format__ format
40 # define __printf__ printf
41 # endif
42 #endif
43
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47
48 /* Write formatted output to a string dynamically allocated with malloc().
49 If the memory allocation succeeds, store the address of the string in
50 *RESULT and return the number of resulting bytes, excluding the trailing
51 NUL. Upon memory allocation error, or some other error, return -1. */
52 extern int asprintf (char **result, const char *format, ...)
53 __attribute__ ((__format__ (__printf__, 2, 3)));
54 extern int vasprintf (char **result, const char *format, va_list args)
55 __attribute__ ((__format__ (__printf__, 2, 0)));
56
57 #ifdef __cplusplus
58 }
59 #endif
60
61 #endif
62
63 #endif /* _VASPRINTF_H */
1 /* xsize.h -- Checked size_t computations.
2
3 Copyright (C) 2003 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 #ifndef _XSIZE_H
20 #define _XSIZE_H
21
22 /* Get size_t. */
23 #include <stddef.h>
24
25 /* Get SIZE_MAX. */
26 #include <limits.h>
27 #if HAVE_STDINT_H
28 # include <stdint.h>
29 #endif
30
31 /* The size of memory objects is often computed through expressions of
32 type size_t. Example:
33 void* p = malloc (header_size + n * element_size).
34 These computations can lead to overflow. When this happens, malloc()
35 returns a piece of memory that is way too small, and the program then
36 crashes while attempting to fill the memory.
37 To avoid this, the functions and macros in this file check for overflow.
38 The convention is that SIZE_MAX represents overflow.
39 malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc
40 implementation that uses mmap --, it's recommended to use size_overflow_p()
41 or size_in_bounds_p() before invoking malloc().
42 The example thus becomes:
43 size_t size = xsum (header_size, xtimes (n, element_size));
44 void *p = (size_in_bounds_p (size) ? malloc (size) : NULL);
45 */
46
47 /* Convert an arbitrary value >= 0 to type size_t. */
48 #define xcast_size_t(N) \
49 ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX)
50
51 /* Sum of two sizes, with overflow check. */
52 static inline size_t
53 #if __GNUC__ >= 3
54 __attribute__ ((__pure__))
55 #endif
56 xsum (size_t size1, size_t size2)
57 {
58 size_t sum = size1 + size2;
59 return (sum >= size1 ? sum : SIZE_MAX);
60 }
61
62 /* Sum of three sizes, with overflow check. */
63 static inline size_t
64 #if __GNUC__ >= 3
65 __attribute__ ((__pure__))
66 #endif
67 xsum3 (size_t size1, size_t size2, size_t size3)
68 {
69 return xsum (xsum (size1, size2), size3);
70 }
71
72 /* Sum of four sizes, with overflow check. */
73 static inline size_t
74 #if __GNUC__ >= 3
75 __attribute__ ((__pure__))
76 #endif
77 xsum4 (size_t size1, size_t size2, size_t size3, size_t size4)
78 {
79 return xsum (xsum (xsum (size1, size2), size3), size4);
80 }
81
82 /* Maximum of two sizes, with overflow check. */
83 static inline size_t
84 #if __GNUC__ >= 3
85 __attribute__ ((__pure__))
86 #endif
87 xmax (size_t size1, size_t size2)
88 {
89 /* No explicit check is needed here, because for any n:
90 max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */
91 return (size1 >= size2 ? size1 : size2);
92 }
93
94 /* Multiplication of a count with an element size, with overflow check.
95 The count must be >= 0 and the element size must be > 0.
96 This is a macro, not an inline function, so that it works correctly even
97 when N is of a wider tupe and N > SIZE_MAX. */
98 #define xtimes(N, ELSIZE) \
99 ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX)
100
101 /* Check for overflow. */
102 #define size_overflow_p(SIZE) \
103 ((SIZE) == SIZE_MAX)
104 /* Check against overflow. */
105 #define size_in_bounds_p(SIZE) \
106 ((SIZE) != SIZE_MAX)
107
108 #endif /* _XSIZE_H */