(limits_syms): Add missing symbols.
[kopensolaris-gnu/glibc.git] / posix / annexc.c
1 /* Copyright (C) 1998 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
9    The GNU C Library 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 GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with the GNU C Library; see the file COPYING.LIB.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18
19 #include <ctype.h>
20 #include <fnmatch.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25
26 #define TMPFILE             "/tmp/macros"
27 #define HEADER_MAX          256
28
29 /* <aio.h>.  */
30 static const char *const aio_syms[] =
31 {
32   "AIO_ALLDONE", "AIO_CANCELED", "AIO_NOTCANCELED", "LIO_NOP", "LIO_NOWAIT",
33   "LIO_READ", "LIO_WAIT", "LIO_WRITE",
34   /* From <fcntl.h>.  */
35   "FD_CLOEXEC", "F_DUPFD", "F_GETFD", "F_GETFL", "F_GETLK", "F_RDLCK",
36   "F_SETFD", "F_SETFL", "F_SETLK", "F_SETLKW", "F_UNLCK", "F_WRLCK",
37   "O_ACCMODE", "O_APPEND", "O_CREAT", "O_DSYNC", "O_EXCL", "O_NOCTTY",
38   "O_NONBLOCK", "O_RDONLY", "O_RDWR", "O_RSYNC", "O_SYNC", "O_TRUNC",
39   "O_WRONLY",
40   /* From <signal.h>.  */
41   "SA_NOCLDSTOP", "SA_SIGINFO", "SIGABRT", "SIGALRM", "SIGBUS", "SIGCHLD",
42   "SIGCONT", "SIGEV_NONE", "SIGEV_SIGNAL", "SIGEV_SIGNAL", "SIGEV_THREAD",
43   "SIGFPE", "SIGHUP", "SIGILL", "SIGINT", "SIGKILL", "SIGPIPE", "SIGQUIT",
44   "SIGRTMAX", "SIGRTMIN", "SIGSEGV", "SIGSTOP", "SIGTERM", "SIGTSTP",
45   "SIGTTIN", "SIGTTOU", "SIGUSR1", "SIGUSR2", "SIG_BLOCK", "SIG_DFL",
46   "SIG_ERR", "SIG_IGN", "SIG_SETMASK", "SIG_UNBLOCK", "SI_ASYNCIO",
47   "SI_MESGQ", "SI_QUEUE", "SI_TIMER", "SI_USER"
48 };
49 static const char *const aio_maybe[] =
50 {
51   "aio_cancel", "aio_error", "aio_fsync", "aio_read", "aio_return",
52   "aio_suspend", "aio_write", "lio_listio",
53   /* From <fcntl.h>.  */
54   "creat", "fcntl", "open", "SEEK_CUR", "SEEK_END", "SEEK_SET", "S_IRGRP",
55   "S_IROTH", "S_IRUSR", "S_IRWXG", "S_IRWXO", "S_IRWXU", "S_ISBLK",
56   "S_ISCHR", "S_ISDIR", "S_ISFIFO", "S_ISGID", "S_ISREG", "S_ISUID",
57   "S_IWGRP", "S_IWOTH", "S_IWUSR", "S_IXGRP", "S_IXOTH", "S_IXUSR",
58   /* From <signal.h>.  */
59   "kill", "raise", "sigaction", "sigaddset", "sigdelset", "sigemptyset",
60   "sigfillset", "sigismember", "signal", "sigpending", "sigprocmask",
61   "sigqueue", "sigsuspend", "sigtimedwait", "sigwait", "sigwaitinfo"
62 };
63
64 /* <assert.h>.  */
65 static const char *const assert_syms[] =
66 {
67   "assert"
68 };
69 static const char *const assert_maybe[] =
70 {
71 };
72
73 /* <ctype.h>.   */
74 static const char *const ctype_syms[] =
75 {
76 };
77 static const char *const ctype_maybe[] =
78 {
79   "isalnum", "isalpha", "iscntrl", "isdigit", "isgraph", "islower",
80   "isprint", "ispunct", "isspace", "isupper", "isxdigit", "tolower",
81   "toupper"
82 };
83
84 /* <dirent.h>.  */
85 static const char *const dirent_syms[] =
86 {
87 };
88 static const char *const dirent_maybe[] =
89 {
90   "closedir", "opendir", "readdir", "readdir_r", "rewinddir"
91 };
92
93 /* <errno.h>.  */
94 static const char *const errno_syms[] =
95 {
96   "E2BIG", "EACCES", "EAGAIN", "EBADF", "EBADMSG", "EBUSY", "ECANCELED",
97   "ECHILD", "EDEADLK", "EDOM", "EEXIST", "EFAULT", "EFBIG", "EINPROGRESS",
98   "EINTR", "EINVAL", "EIO", "EISDIR", "EMFILE", "EMLINK", "EMSGSIZE",
99   "ENAMETOOLONG", "ENFILE", "ENODEV", "ENOENT", "ENOEXEC", "ENOLCK",
100   "ENOMEM", "ENOSPC", "ENOSYS", "ENOTDIR", "ENOTEMPTY", "ENOTSUP",
101   "ENOTTY", "ENXIO", "EPERM", "EPIPE", "ERANGE", "EROFS", "ESPIPE",
102   "ESRCH", "ETIMEDOUT", "EXDEV"
103 };
104 static const char *const errno_maybe[] =
105 {
106   "errno", "E*"
107 };
108
109 /* <fcntl.h>.  */
110 static const char *const fcntl_syms[] =
111 {
112   "FD_CLOEXEC", "F_DUPFD", "F_GETFD", "F_GETFL", "F_GETLK", "F_RDLCK",
113   "F_SETFD", "F_SETFL", "F_SETLK", "F_SETLKW", "F_UNLCK", "F_WRLCK",
114   "O_ACCMODE", "O_APPEND", "O_CREAT", "O_DSYNC", "O_EXCL", "O_NOCTTY",
115   "O_NONBLOCK", "O_RDONLY", "O_RDWR", "O_RSYNC", "O_SYNC", "O_TRUNC",
116   "O_WRONLY"
117 };
118 static const char *const fcntl_maybe[] =
119 {
120   "creat", "fcntl", "open", "SEEK_CUR", "SEEK_END", "SEEK_SET", "S_IRGRP",
121   "S_IROTH", "S_IRUSR", "S_IRWXG", "S_IRWXO", "S_IRWXU", "S_ISBLK",
122   "S_ISCHR", "S_ISDIR", "S_ISFIFO", "S_ISGID", "S_ISREG", "S_ISUID",
123   "S_IWGRP", "S_IWOTH", "S_IWUSR", "S_IXGRP", "S_IXOTH", "S_IXUSR"
124 };
125
126 /* <float.h>.  */
127 static const char *const float_syms[] =
128 {
129   "DBL_DIG", "DBL_EPSILON", "DBL_MANT_DIG", "DBL_MAX", "DBL_MAX_10_EXP",
130   "DBL_MAX_EXP", "DBL_MIN", "DBL_MIN_10_EXP", "DBL_MIN_EXP", "FLT_DIG",
131   "FLT_EPSILON", "FLT_MANT_DIG", "FLT_MAX", "FLT_MAX_10_EXP", "FLT_MAX_EXP",
132   "FLT_MIN", "FLT_MIN_10_EXP", "FLT_MIN_EXP", "FLT_RADIX", "FLT_ROUNDS",
133   "LDBL_DIG", "LDBL_EPSILON", "LDBL_MANT_DIG", "LDBL_MAX", "LDBL_MAX_10_EXP",
134   "LDBL_MAX_EXP", "LDBL_MIN", "LDBL_MIN_10_EXP", "LDBL_MIN_EXP"
135 };
136 static const char *const float_maybe[] =
137 {
138 };
139
140 /* <grp.h>.  */
141 static const char *const grp_syms[] =
142 {
143 };
144 static const char *const grp_maybe[] =
145 {
146   "getgrgid", "getgrgid_r", "getgrnam", "getgrnam_r"
147 };
148
149 /* <limits.h>.  */
150 static const char *const limits_syms[] =
151 {
152   "_POSIX_AIO_LISTIO_MAX", "_POSIX_AIO_MAX", "_POSIX_ARG_MAX",
153   "_POSIX_CHILD_MAX", "_POSIX_CLOCKRES_MAX", "_POSIX_DELAYTIMER_MAX",
154   "_POSIX_LINK_MAX", "_POSIX_LOGIN_NAME_MAX", "_POSIX_MAX_CANON",
155   "_POSIX_MAX_INPUT", "_POSIX_MQ_OPEN_MAX", "_POSIX_MQ_PRIO_MAX",
156   "_POSIX_NAME_MAX", "_POSIX_NGROUPS_MAX", "_POSIX_OPEN_MAX",
157   "_POSIX_PATH_MAX", "_POSIX_PIPE_BUF", "_POSIX_RTSIG_MAX",
158   "_POSIX_SEM_NSEMS_MAX", "_POSIX_SEM_VALUE_MAX", "_POSIX_SIGQUEUE_MAX",
159   "_POSIX_SSIZE_MAX", "_POSIX_STREAM_MAX",
160   "_POSIX_THREAD_DESTRUCTOR_ITERATIONS", "_POSIX_THREAD_KEYS_MAX",
161   "_POSIX_THREAD_THREADS_MAX", "_POSIX_TIMER_MAX", "_POSIX_TTY_NAME_MAX",
162   "_POSIX_TZNAME_MAX", "_POSIX_THREAD_DESTRUCTOR_ITERATIONS",
163   "CHAR_BIT", "CHAR_MAX", "CHAR_MIN", "INT_MAX", "INT_MIN", "LONG_MAX",
164   "LONG_MIN", "MB_LEN_MAX", "NGROUPS_MAX", "PAGESIZE", "SCHAR_MAX",
165   "SCHAR_MIN", "SHRT_MAX", "SHRT_MIN", "UCHAR_MAX", "UINT_MAX",
166   "ULONG_MAX", "USHRT_MAX"
167 };
168 static const char *const limits_maybe[] =
169 {
170   "AIO_LISTIO_MAX", "AIO_MAX", "ARG_MAX", "CHILD_MAX", "DELAYTIMER_MAX",
171   "LINK_MAX", "LOGIN_NAME_MAX", "LONG_MAX", "LONG_MIN", "MAX_CANON",
172   "MAX_INPUT", "MQ_OPEN_MAX", "MQ_PRIO_MAX", "NAME_MAX", "OPEN_MAX",
173   "PATH_MAX", "PIPE_BUF", "RTSIG_MAX", "PTHREAD_DESTRUCTOR_ITERATIONS",
174   "PTHREAD_KEYS_MAX", "PTHREAD_STACK_MIN", "PTHREAD_THREADS_MAX"
175 };
176
177 /* <locale.h>.  */
178 static const char *const locale_syms[] =
179 {
180   "LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC",
181   "LC_TIME", "NULL"
182 };
183 static const char *const locale_maybe[] =
184 {
185   "LC_*", "localeconv", "setlocale"
186 };
187
188 /* <math.h>.  */
189 static const char *const math_syms[] =
190 {
191   "HUGE_VAL"
192 };
193 static const char *const math_maybe[] =
194 {
195   "acos", "asin", "atan2", "atan", "ceil", "cos", "cosh", "exp",
196   "fabs", "floor", "fmod", "frexp", "ldexp", "log10", "log", "modf",
197   "pow", "sin", "sinh", "sqrt", "tan", "tanh",
198   "acosf", "asinf", "atan2f", "atanf", "ceilf", "cosf", "coshf", "expf",
199   "fabsf", "floorf", "fmodf", "frexpf", "ldexpf", "log10f", "logf", "modff",
200   "powf", "sinf", "sinhf", "sqrtf", "tanf", "tanhf",
201   "acosl", "asinl", "atan2l", "atanl", "ceill", "cosl", "coshl", "expl",
202   "fabsl", "floorl", "fmodl", "frexpl", "ldexpl", "log10l", "logl", "modfl",
203   "powl", "sinl", "sinhl", "sqrtl", "tanl", "tanhl"
204 };
205
206 /* <mqueue.h>.  */
207 static const char *const mqueue_syms[] =
208 {
209 };
210 static const char *const mqueue_maybe[] =
211 {
212   "mq_close", "mq_getattr", "mq_notify", "mq_open", "mq_receive",
213   "mq_send", "mq_setattr", "mq_unlink"
214 };
215
216 /* <pthread.h>.  */
217 static const char *const pthread_syms[] =
218 {
219   "PTHREAD_CANCELED", "PTHREAD_CANCEL_ASYNCHRONOUS",
220   "PTHREAD_CANCEL_DEFERRED", "PTHREAD_CANCEL_DISABLE", "PTHREAD_CANCEL_ENABLE",
221   "PTHREAD_COND_INITIALIZER", "PTHREAD_CREATE_DETACHED",
222   "PTHREAD_CREATE_JOINABLE", "PTHREAD_EXPLICIT_SCHED",
223   "PTHREAD_INHERIT_SCHED", "PTHREAD_MUTEX_INITIALIZER",
224   "PTHREAD_ONCE_INIT", "PTHREAD_PRIO_INHERIT", "PTHREAD_PRIO_NONE",
225   "PTHREAD_PRIO_PROTECT", "PTHREAD_PROCESS_PRIVATE",
226   "PTHREAD_PROCESS_SHARED", "PTHREAD_SCOPE_PROCESS", "PTHREAD_SCOPE_SYSTEM",
227   /* These come from <sched.h>.  */
228   "SCHED_FIFO", "SCHED_OTHER", "SCHED_RR",
229   /* These come from <time.h>.  */
230   "CLK_TCK", "CLOCKS_PER_SEC", "CLOCK_REALTIME", "NULL", "TIMER_ABSTIME"
231 };
232 static const char *const pthread_maybe[] =
233 {
234   "pthread_atfork", "pthread_attr_destroy", "pthread_attr_getdetachstate",
235   "pthread_attr_getinheritsched", "pthread_attr_getschedparam",
236   "pthread_attr_getschedpolicy", "pthread_attr_getscope",
237   "pthread_attr_getstackaddr", "pthread_attr_getstacksize",
238   "pthread_attr_init", "pthread_attr_setdetachstate",
239   "pthread_attr_setinheritsched", "pthread_attr_setschedparam",
240   "pthread_attr_setschedpolicy", "pthread_attr_setscope",
241   "pthread_attr_setstackaddr", "pthread_attr_setstacksize",
242   "pthread_cleanup_pop", "pthread_cleanup_push", "pthread_cond_broadcast",
243   "pthread_cond_destroy", "pthread_cond_init", "pthread_cond_signal",
244   "pthread_cond_timedwait", "pthread_cond_wait", "pthread_condattr_destroy",
245   "pthread_condattr_getpshared", "pthread_condattr_init",
246   "pthread_condattr_setpshared", "pthread_create", "pthread_detach",
247   "pthread_equal", "pthread_exit", "pthread_getspecific", "pthread_join",
248   "pthread_key_create", "pthread_key_destroy", "pthread_kill",
249   "pthread_mutex_destroy", "pthread_mutex_getprioceiling",
250   "pthread_mutex_init", "pthread_mutex_lock", "pthread_mutex_setprioceiling",
251   "pthread_mutex_trylock", "pthread_mutex_unlock", "pthread_mutexattr_destroy",
252   "pthread_mutexattr_getprioceiling", "pthread_mutexattr_getprotocol",
253   "pthread_mutexattr_getpshared", "pthread_mutexattr_init",
254   "pthread_mutexattr_setprioceiling", "pthread_mutexattr_setprotocol",
255   "pthread_mutexattr_setpshared", "pthread_once", "pthread_self",
256   "pthread_setcancelstate", "pthread_setcanceltype", "pthread_setspecific",
257   "pthread_sigmask", "pthread_testcancel"
258   /* These come from <sched.h>.  */
259   "sched_get_priority_max", "sched_get_priority_min",
260   "sched_get_rr_interval", "sched_getparam", "sched_getscheduler",
261   "sched_setparam", "sched_setscheduler", "sched_yield",
262   /* These come from <time.h>.  */
263   "asctime", "asctime_r", "clock", "clock_getres", "clock_gettime",
264   "clock_settime", "ctime", "ctime_r", "difftime", "gmtime", "gmtime_r",
265   "localtime", "localtime_r", "mktime", "nanosleep", "strftime", "time",
266   "timer_create", "timer_delete", "timer_getoverrun", "timer_gettime",
267   "timer_settime", "tzset"
268 };
269
270 /* <pwd.h>.  */
271 static const char *const pwd_syms[] =
272 {
273 };
274 static const char *const pwd_maybe[] =
275 {
276   "getpwnam", "getpwnam_r", "getpwuid", "getpwuid_r"
277 };
278
279 /* <sched.h>.  */
280 static const char *const sched_syms[] =
281 {
282   "SCHED_FIFO", "SCHED_OTHER", "SCHED_RR",
283 };
284 static const char *const sched_maybe[] =
285 {
286   "sched_get_priority_max", "sched_get_priority_min",
287   "sched_get_rr_interval", "sched_getparam", "sched_getscheduler",
288   "sched_setparam", "sched_setscheduler", "sched_yield",
289   /* These come from <time.h>.  */
290   "CLK_TCK", "CLOCKS_PER_SEC", "CLOCK_REALTIME", "NULL", "TIMER_ABSTIME"
291   "asctime", "asctime_r", "clock", "clock_getres", "clock_gettime",
292   "clock_settime", "ctime", "ctime_r", "difftime", "gmtime", "gmtime_r",
293   "localtime", "localtime_r", "mktime", "nanosleep", "strftime", "time",
294   "timer_create", "timer_delete", "timer_getoverrun", "timer_gettime",
295   "timer_settime", "tzset"
296 };
297
298 /* <semaphore.h>.  */
299 static const char *const semaphore_syms[] =
300 {
301 };
302 static const char *const semaphore_maybe[] =
303 {
304   "sem_close", "sem_destroy", "sem_getvalue", "sem_init", "sem_open",
305   "sen_post", "sem_trywait", "sem_unlink", "sem_wait"
306 };
307
308 /* <setjmp.h>.  */
309 static const char *const setjmp_syms[] =
310 {
311 };
312 static const char *const setjmp_maybe[] =
313 {
314   "longjmp", "setjmp", "siglongjmp", "sigsetjmp"
315 };
316
317 /* <signal.h>.  */
318 static const char *const signal_syms[] =
319 {
320   "SA_NOCLDSTOP", "SA_SIGINFO", "SIGABRT", "SIGALRM", "SIGBUS", "SIGCHLD",
321   "SIGCONT", "SIGEV_NONE", "SIGEV_SIGNAL", "SIGEV_THREAD",
322   "SIGFPE", "SIGHUP", "SIGILL", "SIGINT", "SIGKILL", "SIGPIPE", "SIGQUIT",
323   "SIGRTMAX", "SIGRTMIN", "SIGSEGV", "SIGSTOP", "SIGTERM", "SIGTSTP",
324   "SIGTTIN", "SIGTTOU", "SIGUSR1", "SIGUSR2", "SIG_BLOCK", "SIG_DFL",
325   "SIG_ERR", "SIG_IGN", "SIG_SETMASK", "SIG_UNBLOCK", "SI_ASYNCIO",
326   "SI_MESGQ", "SI_QUEUE", "SI_TIMER", "SI_USER"
327 };
328 static const char *const signal_maybe[] =
329 {
330   "kill", "raise", "sigaction", "sigaddset", "sigdelset", "sigemptyset",
331   "sigfillset", "sigismember", "signal", "sigpending", "sigprocmask",
332   "sigqueue", "sigsuspend", "sigtimedwait", "sigwait", "sigwaitinfo"
333 };
334
335 /* <stdarg.h>.  */
336 static const char *const stdarg_syms[] =
337 {
338   "va_arg", "va_end", "va_start"
339 };
340 static const char *const stdarg_maybe[] =
341 {
342   "va_list"
343 };
344
345 /* <stddef.h>.  */
346 static const char *const stddef_syms[] =
347 {
348   "NULL", "offsetof"
349 };
350 static const char *const stddef_maybe[] =
351 {
352 };
353
354 /* <stdio.h>.  */
355 static const char *const stdio_syms[] =
356 {
357   "BUFSIZ", "EOF", "FILENAME_MAX", "FOPEN_MAX", "L_ctermid", "L_cuserid",
358   "L_tmpnam", "NULL", "SEEK_CUR", "SEEK_END", "SEEK_SET", "STREAM_MAX",
359   "TMP_MAX", "stderr", "stdin", "stdout", "_IOFBF", "_IOLBF", "_IONBF"
360 };
361 static const char *const stdio_maybe[] =
362 {
363   "clearerr", "fclose", "fdopen", "feof", "ferror", "fflush", "fgetc",
364   "fgetpos", "fgets", "fileno", "flockfile", "fopen", "fprintf", "fputc",
365   "fputs", "fread", "freopen", "fscanf", "fseek", "fsetpos", "ftell",
366   "ftrylockfile", "funlockfile", "fwrite", "getc", "getchar",
367   "getchar_unlocked", "getc_unlocked", "gets", "perror", "printf", "putc",
368   "putchar", "putchar_unlocked", "putc_unlocked", "puts", "remove", "rename",
369   "rewind", "scanf", "setbuf", "setvbuf", "sprintf", "sscanf", "tmpfile",
370   "tmpnam", "ungetc", "vfprintf", "vprintf", "vsprintf"
371 };
372
373 /* <stdlib.h>.  */
374 static const char *const stdlib_syms[] =
375 {
376   "EXIT_FAILURE", "EXIT_SUCCESS", "MB_CUR_MAX", "NULL", "RAND_MAX"
377 };
378 static const char *const stdlib_maybe[] =
379 {
380   "abort", "abs", "atexit", "atof", "atoi", "atol", "bsearch", "calloc",
381   "div", "exit", "free", "getenv", "labs", "ldiv", "malloc", "mblen",
382   "mbstowcs", "mbtowc", "qsort", "rand", "rand_r", "realloc", "srand",
383   "strtod", "strtol", "strtoul", "system", "wcstombs", "wctomb"
384 };
385
386 /* <string.h>.  */
387 static const char *const string_syms[] =
388 {
389   "NULL"
390 };
391 static const char *const string_maybe[] =
392 {
393   "memchr", "memcmp", "memcpy", "memmove", "memset", "strcat", "strchr",
394   "strcmp", "strcoll", "strcpy", "strcspn", "strerror", "strlen",
395   "strncat", "strncmp", "strncpy", "strpbrk", "strrchr", "strspn",
396   "strstr", "strtok", "strtok_r", "strxfrm"
397 };
398
399 /* <sys/mman.h>.  */
400 static const char *const mman_syms[] =
401 {
402   "MAP_FAILED", "MAP_FIXED", "MAP_PRIVATE", "MAP_SHARED", "MCL_CURRENT",
403   "MCL_FUTURE", "MS_ASYNC", "MS_INVALIDATE", "MS_SYNC", "PROT_EXEC",
404   "PROT_NONE", "PROT_READ", "PROT_WRITE"
405 };
406 static const char *const mman_maybe[] =
407 {
408   "mlock", "mlockall", "mmap", "mprotect", "msync", "munlock", "munlockall",
409   "munmap", "shm_open", "shm_unlock"
410 };
411
412 /* <sys/stat.h>.  */
413 static const char *const stat_syms[] =
414 {
415   "S_IRGRP", "S_IROTH", "S_IRUSR", "S_IRWXG", "S_IRWXO", "S_IRWXU",
416   "S_ISBLK", "S_ISCHR", "S_ISDIR", "S_ISFIFO", "S_ISGID", "S_ISREG",
417   "S_ISUID", "S_IWGRP", "S_IWOTH", "S_IWUSR", "S_IXGRP", "S_IXOTH",
418   "S_IXUSR", "S_TYPEISMQ", "S_TYPEISSEM", "S_TYPEISSHM"
419 };
420 static const char *const stat_maybe[] =
421 {
422   "chmod", "fchmod", "fstat", "mkdir", "mkfifo", "stat", "umask"
423 };
424
425 /* <sys/times.h>.  */
426 static const char *const times_syms[] =
427 {
428 };
429 static const char *const times_maybe[] =
430 {
431   "times"
432 };
433
434 /* <sys/types.h>.  */
435 static const char *const types_syms[] =
436 {
437 };
438 static const char *const types_maybe[] =
439 {
440 };
441
442 /* <sys/utsname.h>.  */
443 static const char *const utsname_syms[] =
444 {
445 };
446 static const char *const utsname_maybe[] =
447 {
448   "uname"
449 };
450
451 /* <sys/wait.h>.  */
452 static const char *const wait_syms[] =
453 {
454   "WEXITSTATUS", "WIFEXITED", "WIFSIGNALED", "WIFSTOPPED", "WNOHANG",
455   "WSTOPSIG", "WTERMSIG", "WUNTRACED"
456 };
457 static const char *const wait_maybe[] =
458 {
459   "wait", "waitpid"
460 };
461
462 /* <termios.h>.  */
463 static const char *const termios_syms[] =
464 {
465   "B0", "B110", "B1200", "B134", "B150", "B1800", "B19200", "B200", "B2400",
466   "B300", "B38400", "B4800", "B50", "B600", "B75", "B9600", "BRKINT", "CLOCAL",
467   "CREAD", "CS5", "CS6", "CS7", "CS8", "CSIZE", "CSTOPN", "ECHO", "ECHOE",
468   "ECHOK", "ECHONL", "HUPCL", "ICANON", "ICRNL", "IEXTEN", "IGNBRK", "IGNCR",
469   "IGNPAR", "INCLR", "INPCK", "ISIG", "ISTRIP", "IXOFF", "IXON", "NCCS",
470   "NOFLSH", "OPOST", "PARENB", "PARMRK", "PARODD", "TCIFLUSH", "TCIOFF",
471   "TCIOFLUSH", "TCOFLUSH", "TCOOFF", "TCOON", "TCSADRAIN", "TCSAFLUSH",
472   "TCSANOW", "TOSTOP", "VEOF", "VEOL", "VERASE", "VINTR", "VKILL", "VMIN",
473   "VQUIT", "VSTART", "VSTOP", "VSUSP", "VTIME"
474 };
475 static const char *const termios_maybe[] =
476 {
477   "cfgetispeed", "cfgetospeed", "cfsetispeed", "cfsetospeed", "tcdrain",
478   "tcflow", "tcflush", "tcgetattr", "tcsendbrk", "tcsetattr"
479 };
480
481 /* <time.h>.  */
482 static const char *const time_syms[] =
483 {
484   "CLK_TCK", "CLOCKS_PER_SEC", "CLOCK_REALTIME", "NULL", "TIMER_ABSTIME"
485 };
486 static const char *const time_maybe[] =
487 {
488   "asctime", "asctime_r", "clock", "clock_getres", "clock_gettime",
489   "clock_settime", "ctime", "ctime_r", "difftime", "gmtime", "gmtime_r",
490   "localtime", "localtime_r", "mktime", "nanosleep", "strftime", "time",
491   "timer_create", "timer_delete", "timer_getoverrun", "timer_gettime",
492   "timer_settime", "tzset"
493 };
494
495 /* <unistd.h>.  */
496 static const char *const unistd_syms[] =
497 {
498   "F_OK", "NULL", "R_OK", "SEEK_CUR", "SEEK_END", "SEEK_SET", "STDERR_FILENO",
499   "STDIN_FILENO", "STDOUT_FILENO", "W_OK", "X_OK",
500   "_PC_ASYNC_IO", "_PC_CHOWN_RESTRICTED", "_PC_LINK_MAX", "_PC_MAX_CANON",
501   "_PC_MAX_INPUT", "_PC_NAME_MAX", "_PC_NO_TRUNC", "_PC_PATH_MAX",
502   "_PC_PIPE_BUF", "_PC_PRIO_IO", "_PC_SYNC_IO", "_PC_VDISABLE",
503   "_SC_AIO_LISTIO_MAX", "_SC_AIO_MAX", "_SC_AIO_PRIO_DELTA_MAX",
504   "_SC_ARG_MAX", "_SC_ASYNCHRONOUS_IO", "_SC_CHILD_MAX", "_SC_CLK_TCK",
505   "_SC_DELAYTIMER_MAX", "_SC_FSYNC", "_SC_GETGR_R_SIZE_MAX",
506   "_SC_GETPW_R_SIZE_MAX", "_SC_JOB_CONTROL", "_SC_LOGIN_NAME_MAX",
507   "_SC_MAPPED_FILES", "_SC_MEMLOCK", "_SC_MEMLOCK_RANGE",
508   "_SC_MEMORY_PROTECTION", "_SC_MESSAGE_PASSING", "_SC_MQ_OPEN_MAX",
509   "_SC_MQ_PRIO_MAX", "_SC_NGROUPS_MAX", "_SC_OPEN_MAX", "_SC_PAGESIZE",
510   "_SC_PRIORITIZED_IO", "_SC_PRIORITY_SCHEDULING", "_SC_REALTIME_SIGNALS",
511   "_SC_RTSIG_MAX", "_SC_SAVED_IDS", "_SC_SEMAPHORES", "_SC_SEM_NSEMS_MAX",
512   "_SC_SEM_VALUE_MAX", "_SC_SHARED_MEMORY_OBJECTS", "_SC_SIGQUEUE_MAX",
513   "_SC_STREAM_MAX", "_SC_SYNCHRONIZED_IO", "_SC_THREADS",
514   "_SC_THREAD_ATTR_STACKADDR", "_SC_THREAD_ATTR_STACKSIZE",
515   "_SC_THREAD_DESTRUCTOR_ITERATIONS", "_SC_THREAD_PRIO_INHERIT",
516   "_SC_THREAD_PRIORITY_SCHEDULING", "_SC_THREAD_PRIO_PROTECT",
517   "_SC_THREAD_PROCESS_SHARED", "_SC_THREAD_SAFE_FUNCTIONS",
518   "_SC_THREAD_STACK_MIN", "_SC_THREAD_THREADS_MAX", "_SC_TIMERS",
519   "_SC_TIMER_MAX", "_SC_TTY_NAME_MAX", "_SC_TZNAME_MAX", "_SC_VERSION"
520 };
521 static const char *const unistd_maybe[] =
522 {
523   "_POSIX_ASYNCHRONOUS_IO", "_POSIX_ASYNC_IO", "_POSIX_CHOWN_RESTRICTED",
524   "_POSIX_FSYNC", "_POSIX_JOB_CONTROL", "_POSIX_MAPPED_FILES",
525   "_POSIX_MEMLOCK", "_POSIX_MEMLOCK_RANGE", "_MEMORY_PROTECTION",
526   "_POSIX_MESSAGE_PASSING", "_POSIX_NO_TRUNC", "_POSIX_PRIORITIZED_IO",
527   "_POSIX_PRIORITY_SCHEDULING", "_POSIX_PRIO_IO", "_POSIX_REATIME_SIGNALS",
528   "_POSIX_SAVED_IDS", "_POSIX_SEMAPHORES", "_POSIX_SHARED_MEMORY_OBJECTS",
529   "_POSIX_SYNCHRONIZED_IO", "_POSIX_SYNC_IO", "_POSIX_THREADS",
530   "_POSIX_THREAD_ATTR_STACKADDR", "_POSIX_THREAD_ATTR_STACKSIZE",
531   "_POSIX_THREAD_PRIO_INHERIT", "_POSIX_THREAD_PRIO_PROTECT",
532   "_POSIX_THREAD_PROCESS_SHARED", "_POSIX_THREAD_SAFE_FUNCTIONS",
533   "_POSIX_THREAD_PRIORITY_SCHEDULING", "_POSIX_TIMERS",
534   "_POSIX_VDISABLE", "_POSIX_VERSION",
535   "_exit", "access", "alarm", "chdir", "chown", "close", "ctermid", "cuserid",
536   "dup2", "dup", "execl", "execle", "execlp", "execv", "execve", "execvp",
537   "fdatasync", "fork", "fpathconf", "fsync", "ftruncate", "getcwd", "getegid",
538   "geteuid", "getgid", "getgroups", "getlogin", "getlogin_r", "getpgrp",
539   "getpid", "getppid", "getuid", "isatty", "link", "lseek", "pathconf",
540   "pause", "pipe", "read", "rmdir", "setgid", "setgpid", "setsid", "setuid",
541   "sleep", "sleep", "sysconf", "tcgetpgrp", "tcsetpgrp", "ttyname",
542   "ttyname_r", "unlink", "write"
543 };
544
545 /* <utime.h>.  */
546 static const char *const utime_syms[] =
547 {
548 };
549 static const char *const utime_maybe[] =
550 {
551   "utime"
552 };
553
554
555 static struct header
556 {
557   const char *name;
558   const char *const *syms;
559   size_t nsyms;
560   const char *const *maybe;
561   size_t nmaybe;
562   const char *subset;
563 } headers[] =
564 {
565 #define H(n) \
566   { #n ".h", n##_syms, sizeof (n##_syms) / sizeof (n##_syms[0]), \
567     n##_maybe, sizeof (n##_maybe) / sizeof (n##_maybe[0]), NULL }
568 #define Hc(n, s) \
569   { #n ".h", n##_syms, sizeof (n##_syms) / sizeof (n##_syms[0]), \
570     n##_maybe, sizeof (n##_maybe) / sizeof (n##_maybe[0]), s }
571 #define Hs(n) \
572   { "sys/" #n ".h", n##_syms, sizeof (n##_syms) / sizeof (n##_syms[0]), \
573     n##_maybe, sizeof (n##_maybe) / sizeof (n##_maybe[0]), NULL }
574   H(aio),
575   H(assert),
576   H(ctype),
577   H(dirent),
578   H(errno),
579   H(fcntl),
580   H(float),
581   H(grp),
582   H(limits),
583   H(locale),
584   H(math),
585   Hc(mqueue, "_POSIX_MESSAGE_PASSING"),
586   H(pthread),
587   H(pwd),
588   H(sched),
589   H(semaphore),
590   H(setjmp),
591   H(signal),
592   H(stdarg),
593   H(stddef),
594   H(stdio),
595   H(stdlib),
596   H(string),
597   Hs(mman),
598   Hs(stat),
599   Hs(times),
600   Hs(types),
601   Hs(utsname),
602   Hs(wait),
603   H(termios),
604   H(time),
605   H(unistd),
606   H(utime)
607 };
608
609 #define NUMBER_OF_HEADERS              (sizeof headers / sizeof *headers)
610
611
612 /* Format string to build command to invoke compiler.  */
613 static const char fmt[] = "\
614 echo \"#include <%s>\" |\
615 %s -E -dM -D_POSIX_SOURCE -D_LIBC %s \
616 -isystem `%s --print-prog-name=include` - > %s";
617
618 static const char testfmt[] = "\
619 echo \"#include <unistd.h>\n#ifndef %s\n#error not defined\n#endif\n\" |\
620 %s -E -dM -D_POSIX_SOURCE -D_LIBC %s \
621 -isystem `%s --print-prog-name=include` - 2> /dev/null > %s";
622
623
624 /* The compiler we use (given on the command line).  */
625 const char *CC;
626 /* The -I parameters for CC to find all headers.  */
627 const char *INC;
628
629 static char *xstrndup (const char *, size_t);
630 static const char **get_null_defines (void);
631 static int check_header (const struct header *, const char **);
632
633 int
634 main (int argc, char *argv[])
635 {
636   int h;
637   int result = 0;
638   const char **ignore_list;
639
640   CC = argc > 1 ? argv[1] : "gcc";
641   INC = argc > 2 ? argv[2] : "";
642
643   if (system (NULL) == 0)
644     {
645       puts ("Sorry, no command processor.");
646       return EXIT_FAILURE;
647     }
648
649   /* First get list of symbols which are defined by the compiler.  */
650   ignore_list = get_null_defines ();
651
652   fputs ("Tested files:\n", stdout);
653
654   for (h = 0; h < NUMBER_OF_HEADERS; ++h)
655     result |= check_header (&headers[h], ignore_list);
656
657   /* The test suite should return errors but for now this is not
658      practical.  Give a warning and ask the user to correct the bugs.  */
659   return result;
660 }
661
662
663 static char *
664 xstrndup (const char *s, size_t n)
665 {
666   size_t len = n;
667   char *new = malloc (len + 1);
668
669   if (new == NULL)
670     return NULL;
671
672   new[len] = '\0';
673   return memcpy (new, s, len);
674 }
675
676
677 static const char **
678 get_null_defines (void)
679 {
680   char line[BUFSIZ], *command;
681   char **result = NULL;
682   size_t result_len = 0;
683   size_t result_max = 0;
684   FILE *input;
685   int first = 1;
686
687   command = malloc (sizeof fmt + sizeof "/dev/null" + 2 * strlen (CC)
688                     + strlen (INC) + strlen (TMPFILE));
689
690   if (command == NULL)
691     {
692       puts ("No more memory.");
693       exit (1);
694     }
695
696   sprintf (command, fmt, "/dev/null", CC, INC, CC, TMPFILE);
697
698   if (system (command))
699     {
700       puts ("system() returned nonzero");
701       return NULL;
702     }
703   free (command);
704   input = fopen (TMPFILE, "r");
705
706   if (input == NULL)
707     {
708       printf ("Could not read %s: ", TMPFILE);
709       perror (NULL);
710       return NULL;
711     }
712
713   while (fgets (line, sizeof line, input) != NULL)
714     {
715       char *start;
716       if (strlen (line) < 9 || line[7] != ' ')
717         { /* "#define A" */
718           printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n",
719                   line);
720           continue;
721         }
722       if (line[8] == '_')
723         /* It's a safe identifier.  */
724         continue;
725       if (result_len == result_max)
726         {
727           result_max += 10;
728           result = realloc (result, result_max * sizeof (char **));
729           if (result == NULL)
730             {
731               puts ("No more memory.");
732               exit (1);
733             }
734         }
735       start = &line[8];
736       result[result_len++] = xstrndup (start, strcspn (start, " ("));
737
738       if (first)
739         {
740           fputs ("The following identifiers will be ignored since the compiler defines them\nby default:\n", stdout);
741           first = 0;
742         }
743       puts (result[result_len - 1]);
744     }
745   if (result_len == result_max)
746     {
747       result_max += 1;
748       result = realloc (result, result_max * sizeof (char **));
749       if (result == NULL)
750         {
751           puts ("No more memory.");
752           exit (1);
753         }
754     }
755   result[result_len] = NULL;
756   fclose (input);
757   remove (TMPFILE);
758
759   return (const char **) result;
760 }
761
762
763 static int
764 check_header (const struct header *header, const char **except)
765 {
766   char line[BUFSIZ], *command;
767   FILE *input;
768   int result = 0;
769   int found[header->nsyms];
770   int i;
771
772   memset (found, '\0', header->nsyms * sizeof (int));
773   command = alloca (sizeof fmt + strlen (header->name) + 2 * strlen (CC)
774                     + strlen (INC) + strlen (TMPFILE));
775
776
777   if (command == NULL)
778     {
779       puts ("No more memory.");
780       exit (1);
781     }
782
783   printf ("=== %s ===\n", header->name);
784   sprintf (command, fmt, header->name, CC, INC, CC, TMPFILE);
785
786   /* First see whether this subset is supported at all.  */
787   if (header->subset != NULL)
788     {
789       sprintf (line, testfmt, header->subset, CC, INC, CC, TMPFILE);
790       if (system (line))
791         {
792           printf ("!! not available\n");
793           return 0;
794         }
795     }
796
797   if (system (command))
798     {
799       puts ("system() returned nonzero");
800       result = 1;
801     }
802   input = fopen (TMPFILE, "r");
803
804   if (input == NULL)
805     {
806       printf ("Could not read %s: ", TMPFILE);
807       perror (NULL);
808       return 1;
809     }
810
811   while (fgets (line, sizeof line, input) != NULL)
812     {
813       const char **ignore;
814       if (strlen (line) < 9 || line[7] != ' ')
815         { /* "#define A" */
816           printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n",
817                   line);
818           result = 1;
819           continue;
820         }
821
822       /* Find next char after the macro identifier; this can be either
823          a space or an open parenthesis.  */
824       line[8 + strcspn (&line[8], " (")] = '\0';
825
826       /* Now check whether it's one of the required macros.  */
827       for (i = 0; i < header->nsyms; ++i)
828         if (!strcmp (&line[8], header->syms[i]))
829           break;
830       if (i < header->nsyms)
831         {
832           found[i] = 1;
833           continue;
834         }
835
836       /* Symbols starting with "_" are ok.  */
837       if (line[8] == '_')
838         continue;
839
840       /* Maybe one of the symbols which are always defined.  */
841       for (ignore = except; *ignore != NULL; ++ignore)
842         if (! strcmp (&line[8], *ignore))
843           break;
844       if (*ignore != NULL)
845         continue;
846
847       /* Otherwise the symbol better should match one of the following.  */
848       for (i = 0; i < header->nmaybe; ++i)
849         if (fnmatch (header->maybe[i], &line[8], 0) == 0)
850           break;
851       if (i < header->nmaybe)
852         continue;
853
854       printf ("*  invalid macro `%s'\n", &line[8]);
855       result |= 1;
856     }
857   fclose (input);
858   remove (TMPFILE);
859
860   for (i = 0; i < header->nsyms; ++i)
861     if (found[i] == 0)
862       printf ("** macro `%s' not defined\n", header->syms[i]);
863
864   return result;
865 }