Update.
[glibc.git] / posix / annexc.c
blobcd387fe6ca57fbb4370edd9306b16137d57faf62
1 /* Copyright (C) 1998 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
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.
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.
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. */
19 #include <ctype.h>
20 #include <fnmatch.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
26 #define TMPFILE "/tmp/macros"
27 #define HEADER_MAX 256
29 /* <aio.h>. */
30 static const char *const aio_syms[] =
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"
49 static const char *const aio_maybe[] =
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"
64 /* <assert.h>. */
65 static const char *const assert_syms[] =
67 "assert"
69 static const char *const assert_maybe[] =
73 /* <ctype.h>. */
74 static const char *const ctype_syms[] =
77 static const char *const ctype_maybe[] =
79 "isalnum", "isalpha", "iscntrl", "isdigit", "isgraph", "islower",
80 "isprint", "ispunct", "isspace", "isupper", "isxdigit", "tolower",
81 "toupper"
84 /* <dirent.h>. */
85 static const char *const dirent_syms[] =
88 static const char *const dirent_maybe[] =
90 "closedir", "opendir", "readdir", "readdir_r", "rewinddir"
93 /* <errno.h>. */
94 static const char *const errno_syms[] =
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"
104 static const char *const errno_maybe[] =
106 "errno", "E*"
109 /* <fcntl.h>. */
110 static const char *const fcntl_syms[] =
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"
118 static const char *const fcntl_maybe[] =
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"
126 /* <float.h>. */
127 static const char *const float_syms[] =
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"
136 static const char *const float_maybe[] =
140 /* <grp.h>. */
141 static const char *const grp_syms[] =
144 static const char *const grp_maybe[] =
146 "getgrgid", "getgrgid_r", "getgrnam", "getgrnam_r"
149 /* <limits.h>. */
150 static const char *const limits_syms[] =
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", "MB_LEN_MAX",
164 "NGROUPS_MAX", "PAGESIZE", "SCHAR_MIN", "SCHAR_MAX"
166 static const char *const limits_maybe[] =
168 "AIO_LISTIO_MAX", "AIO_MAX", "ARG_MAX", "CHILD_MAX", "DELAYTIMER_MAX",
169 "LINK_MAX", "LOGIN_NAME_MAX", "LONG_MAX", "LONG_MIN", "MAX_CANON",
170 "MAX_INPUT", "MQ_OPEN_MAX", "MQ_PRIO_MAX", "NAME_MAX", "OPEN_MAX",
171 "PATH_MAX", "PIPE_BUF", "RTSIG_MAX", "PTHREAD_DESTRUCTOR_ITERATIONS",
172 "PTHREAD_KEYS_MAX", "PTHREAD_STACK_MIN", "PTHREAD_THREADS_MAX"
175 /* <locale.h>. */
176 static const char *const locale_syms[] =
178 "LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC",
179 "LC_TIME", "NULL"
181 static const char *const locale_maybe[] =
183 "LC_*", "localeconv", "setlocale"
186 /* <math.h>. */
187 static const char *const math_syms[] =
189 "HUGE_VAL"
191 static const char *const math_maybe[] =
193 "acos", "asin", "atan2", "atan", "ceil", "cos", "cosh", "exp",
194 "fabs", "floor", "fmod", "frexp", "ldexp", "log10", "log", "modf",
195 "pow", "sin", "sinh", "sqrt", "tan", "tanh",
196 "acosf", "asinf", "atan2f", "atanf", "ceilf", "cosf", "coshf", "expf",
197 "fabsf", "floorf", "fmodf", "frexpf", "ldexpf", "log10f", "logf", "modff",
198 "powf", "sinf", "sinhf", "sqrtf", "tanf", "tanhf",
199 "acosl", "asinl", "atan2l", "atanl", "ceill", "cosl", "coshl", "expl",
200 "fabsl", "floorl", "fmodl", "frexpl", "ldexpl", "log10l", "logl", "modfl",
201 "powl", "sinl", "sinhl", "sqrtl", "tanl", "tanhl"
204 /* <mqueue.h>. */
205 static const char *const mqueue_syms[] =
208 static const char *const mqueue_maybe[] =
210 "mq_close", "mq_getattr", "mq_notify", "mq_open", "mq_receive",
211 "mq_send", "mq_setattr", "mq_unlink"
214 /* <pthread.h>. */
215 static const char *const pthread_syms[] =
217 "PTHREAD_CANCELED", "PTHREAD_CANCEL_ASYNCHRONOUS",
218 "PTHREAD_CANCEL_DEFERRED", "PTHREAD_CANCEL_DISABLE", "PTHREAD_CANCEL_ENABLE",
219 "PTHREAD_COND_INITIALIZER", "PTHREAD_CREATE_DETACHED",
220 "PTHREAD_CREATE_JOINABLE", "PTHREAD_EXPLICIT_SCHED",
221 "PTHREAD_INHERIT_SCHED", "PTHREAD_MUTEX_INITIALIZER",
222 "PTHREAD_ONCE_INIT", "PTHREAD_PRIO_INHERIT", "PTHREAD_PRIO_NONE",
223 "PTHREAD_PRIO_PROTECT", "PTHREAD_PROCESS_PRIVATE",
224 "PTHREAD_PROCESS_SHARED", "PTHREAD_SCOPE_PROCESS", "PTHREAD_SCOPE_SYSTEM",
225 /* These come from <sched.h>. */
226 "SCHED_FIFO", "SCHED_OTHER", "SCHED_RR",
227 /* These come from <time.h>. */
228 "CLK_TCK", "CLOCKS_PER_SEC", "CLOCK_REALTIME", "NULL", "TIMER_ABSTIME"
230 static const char *const pthread_maybe[] =
232 "pthread_atfork", "pthread_attr_destroy", "pthread_attr_getdetachstate",
233 "pthread_attr_getinheritsched", "pthread_attr_getschedparam",
234 "pthread_attr_getschedpolicy", "pthread_attr_getscope",
235 "pthread_attr_getstackaddr", "pthread_attr_getstacksize",
236 "pthread_attr_init", "pthread_attr_setdetachstate",
237 "pthread_attr_setinheritsched", "pthread_attr_setschedparam",
238 "pthread_attr_setschedpolicy", "pthread_attr_setscope",
239 "pthread_attr_setstackaddr", "pthread_attr_setstacksize",
240 "pthread_cleanup_pop", "pthread_cleanup_push", "pthread_cond_broadcast",
241 "pthread_cond_destroy", "pthread_cond_init", "pthread_cond_signal",
242 "pthread_cond_timedwait", "pthread_cond_wait", "pthread_condattr_destroy",
243 "pthread_condattr_getpshared", "pthread_condattr_init",
244 "pthread_condattr_setpshared", "pthread_create", "pthread_detach",
245 "pthread_equal", "pthread_exit", "pthread_getspecific", "pthread_join",
246 "pthread_key_create", "pthread_key_destroy", "pthread_kill",
247 "pthread_mutex_destroy", "pthread_mutex_getprioceiling",
248 "pthread_mutex_init", "pthread_mutex_lock", "pthread_mutex_setprioceiling",
249 "pthread_mutex_trylock", "pthread_mutex_unlock", "pthread_mutexattr_destroy",
250 "pthread_mutexattr_getprioceiling", "pthread_mutexattr_getprotocol",
251 "pthread_mutexattr_getpshared", "pthread_mutexattr_init",
252 "pthread_mutexattr_setprioceiling", "pthread_mutexattr_setprotocol",
253 "pthread_mutexattr_setpshared", "pthread_once", "pthread_self",
254 "pthread_setcancelstate", "pthread_setcanceltype", "pthread_setspecific",
255 "pthread_sigmask", "pthread_testcancel"
256 /* These come from <sched.h>. */
257 "sched_get_priority_max", "sched_get_priority_min",
258 "sched_get_rr_interval", "sched_getparam", "sched_getscheduler",
259 "sched_setparam", "sched_setscheduler", "sched_yield",
260 /* These come from <time.h>. */
261 "asctime", "asctime_r", "clock", "clock_getres", "clock_gettime",
262 "clock_settime", "ctime", "ctime_r", "difftime", "gmtime", "gmtime_r",
263 "localtime", "localtime_r", "mktime", "nanosleep", "strftime", "time",
264 "timer_create", "timer_delete", "timer_getoverrun", "timer_gettime",
265 "timer_settime", "tzset"
268 /* <pwd.h>. */
269 static const char *const pwd_syms[] =
272 static const char *const pwd_maybe[] =
274 "getpwnam", "getpwnam_r", "getpwuid", "getpwuid_r"
277 /* <sched.h>. */
278 static const char *const sched_syms[] =
280 "SCHED_FIFO", "SCHED_OTHER", "SCHED_RR",
282 static const char *const sched_maybe[] =
284 "sched_get_priority_max", "sched_get_priority_min",
285 "sched_get_rr_interval", "sched_getparam", "sched_getscheduler",
286 "sched_setparam", "sched_setscheduler", "sched_yield",
287 /* These come from <time.h>. */
288 "CLK_TCK", "CLOCKS_PER_SEC", "CLOCK_REALTIME", "NULL", "TIMER_ABSTIME"
289 "asctime", "asctime_r", "clock", "clock_getres", "clock_gettime",
290 "clock_settime", "ctime", "ctime_r", "difftime", "gmtime", "gmtime_r",
291 "localtime", "localtime_r", "mktime", "nanosleep", "strftime", "time",
292 "timer_create", "timer_delete", "timer_getoverrun", "timer_gettime",
293 "timer_settime", "tzset"
296 /* <semaphore.h>. */
297 static const char *const semaphore_syms[] =
300 static const char *const semaphore_maybe[] =
302 "sem_close", "sem_destroy", "sem_getvalue", "sem_init", "sem_open",
303 "sen_post", "sem_trywait", "sem_unlink", "sem_wait"
306 /* <setjmp.h>. */
307 static const char *const setjmp_syms[] =
310 static const char *const setjmp_maybe[] =
312 "longjmp", "setjmp", "siglongjmp", "sigsetjmp"
315 /* <signal.h>. */
316 static const char *const signal_syms[] =
318 "SA_NOCLDSTOP", "SA_SIGINFO", "SIGABRT", "SIGALRM", "SIGBUS", "SIGCHLD",
319 "SIGCONT", "SIGEV_NONE", "SIGEV_SIGNAL", "SIGEV_THREAD",
320 "SIGFPE", "SIGHUP", "SIGILL", "SIGINT", "SIGKILL", "SIGPIPE", "SIGQUIT",
321 "SIGRTMAX", "SIGRTMIN", "SIGSEGV", "SIGSTOP", "SIGTERM", "SIGTSTP",
322 "SIGTTIN", "SIGTTOU", "SIGUSR1", "SIGUSR2", "SIG_BLOCK", "SIG_DFL",
323 "SIG_ERR", "SIG_IGN", "SIG_SETMASK", "SIG_UNBLOCK", "SI_ASYNCIO",
324 "SI_MESGQ", "SI_QUEUE", "SI_TIMER", "SI_USER"
326 static const char *const signal_maybe[] =
328 "kill", "raise", "sigaction", "sigaddset", "sigdelset", "sigemptyset",
329 "sigfillset", "sigismember", "signal", "sigpending", "sigprocmask",
330 "sigqueue", "sigsuspend", "sigtimedwait", "sigwait", "sigwaitinfo"
333 /* <stdarg.h>. */
334 static const char *const stdarg_syms[] =
336 "va_arg", "va_end", "va_list", "va_start"
338 static const char *const stdarg_maybe[] =
342 /* <stddef.h>. */
343 static const char *const stddef_syms[] =
345 "NULL", "offsetof"
347 static const char *const stddef_maybe[] =
351 /* <stdio.h>. */
352 static const char *const stdio_syms[] =
354 "BUFSIZ", "EOF", "FILENAME_MAX", "L_ctermid", "L_cuserid", "L_tmpnam",
355 "NULL", "SEEK_CUR", "SEEK_END", "SEEK_SET", "STREAM_MAX", "TMP_MAX",
356 "stderr", "stdin", "stdout", "_IOFBF", "_IOLBF", "_IONBF"
358 static const char *const stdio_maybe[] =
360 "clearerr", "fclose", "fdopen", "feof", "ferror", "fflush", "fgetc",
361 "fgetpos", "fgets", "fileno", "flockfile", "fopen", "fprintf", "fputc",
362 "fputs", "fread", "freopen", "fscanf", "fseek", "fsetpos", "ftell",
363 "ftrylockfile", "funlockfile", "fwrite", "getc", "getchar",
364 "getchar_unlocked", "getc_unlocked", "gets", "perror", "printf", "putc",
365 "putchar", "putchar_unlocked", "putc_unlocked", "puts", "remove", "rename",
366 "rewind", "scanf", "setbuf", "setvbuf", "sprintf", "sscanf", "tmpfile",
367 "tmpnam", "ungetc", "vfprintf", "vprintf", "vsprintf"
370 /* <stdlib.h>. */
371 static const char *const stdlib_syms[] =
373 "EXIT_FAILURE", "EXIT_SUCCESS", "MB_CUR_MAX", "NULL", "RAND_MAX"
375 static const char *const stdlib_maybe[] =
377 "abort", "abs", "atexit", "atof", "atoi", "atol", "bsearch", "calloc",
378 "div", "exit", "free", "getenv", "labs", "ldiv", "malloc", "mblen",
379 "mbstowcs", "mbtowc", "qsort", "rand", "rand_r", "realloc", "srand",
380 "strtod", "strtol", "strtoul", "system", "wcstombs", "wctomb"
383 /* <string.h>. */
384 static const char *const string_syms[] =
386 "NULL"
388 static const char *const string_maybe[] =
390 "memchr", "memcmp", "memcpy", "memmove", "memset", "strcat", "strchr",
391 "strcmp", "strcoll", "strcpy", "strcspn", "strerror", "strlen",
392 "strncat", "strncmp", "strncpy", "strpbrk", "strrchr", "strspn",
393 "strstr", "strtok", "strtok_r", "strxfrm"
396 /* <sys/mman.h>. */
397 static const char *const mman_syms[] =
399 "MAP_FAILED", "MAP_FIXED", "MAP_PRIVATE", "MAP_SHARED", "MCL_CURRENT",
400 "MCL_FUTURE", "MS_ASYNC", "MS_INVALIDATE", "MS_SYNC", "PROT_EXEC",
401 "PROT_NONE", "PROT_READ", "PROT_WRITE"
403 static const char *const mman_maybe[] =
405 "mlock", "mlockall", "mmap", "mprotect", "msync", "munlock", "munlockall",
406 "munmap", "shm_open", "shm_unlock"
409 /* <sys/stat.h>. */
410 static const char *const stat_syms[] =
412 "S_IRGRP", "S_IROTH", "S_IRUSR", "S_IRWXG", "S_IRWXO", "S_IRWXU",
413 "S_ISBLK", "S_ISCHR", "S_ISDIR", "S_ISFIFO", "S_ISGID", "S_ISREG",
414 "S_ISUID", "S_IWGRP", "S_IWOTH", "S_IWUSR", "S_IXGRP", "S_IXOTH",
415 "S_IXUSR", "S_TYPEISMQ", "S_TYPEISSEM", "S_TYPEISSHM"
417 static const char *const stat_maybe[] =
419 "chmod", "fchmod", "fstat", "mkdir", "mkfifo", "stat", "umask"
422 /* <sys/times.h>. */
423 static const char *const times_syms[] =
426 static const char *const times_maybe[] =
428 "times"
431 /* <sys/types.h>. */
432 static const char *const types_syms[] =
435 static const char *const types_maybe[] =
439 /* <sys/utsname.h>. */
440 static const char *const utsname_syms[] =
443 static const char *const utsname_maybe[] =
445 "uname"
448 /* <sys/wait.h>. */
449 static const char *const wait_syms[] =
451 "WEXITSTATUS", "WIFEXITED", "WIFSIGNALED", "WIFSTOPPED", "WNOHANG",
452 "WSTOPSIG", "WTERMSIG", "WUNTRACED"
454 static const char *const wait_maybe[] =
456 "wait", "waitpid"
459 /* <termios.h>. */
460 static const char *const termios_syms[] =
462 "B0", "B110", "B1200", "B134", "B150", "B1800", "B19200", "B200", "B2400",
463 "B300", "B38400", "B4800", "B50", "B600", "B75", "B9600", "BRKINT", "CLOCAL",
464 "CREAD", "CS5", "CS6", "CS7", "CS8", "CSIZE", "CSTOPN", "ECHO", "ECHOE",
465 "ECHOK", "ECHONL", "HUPCL", "ICANON", "ICRNL", "IEXTEN", "IGNBRK", "IGNCR",
466 "IGNPAR", "INCLR", "INPCK", "ISIG", "ISTRIP", "IXOFF", "IXON", "NCCS",
467 "NOFLSH", "OPOST", "PARENB", "PARMRK", "PARODD", "TCIFLUSH", "TCIOFF",
468 "TCIOFLUSH", "TCOFLUSH", "TCOOFF", "TCOON", "TCSADRAIN", "TCSAFLUSH",
469 "TCSANOW", "TOSTOP", "VEOF", "VEOL", "VERASE", "VINTR", "VKILL", "VMIN",
470 "VQUIT", "VSTART", "VSTOP", "VSUSP", "VTIME"
472 static const char *const termios_maybe[] =
474 "cfgetispeed", "cfgetospeed", "cfsetispeed", "cfsetospeed", "tcdrain",
475 "tcflow", "tcflush", "tcgetattr", "tcsendbrk", "tcsetattr"
478 /* <time.h>. */
479 static const char *const time_syms[] =
481 "CLK_TCK", "CLOCKS_PER_SEC", "CLOCK_REALTIME", "NULL", "TIMER_ABSTIME"
483 static const char *const time_maybe[] =
485 "asctime", "asctime_r", "clock", "clock_getres", "clock_gettime",
486 "clock_settime", "ctime", "ctime_r", "difftime", "gmtime", "gmtime_r",
487 "localtime", "localtime_r", "mktime", "nanosleep", "strftime", "time",
488 "timer_create", "timer_delete", "timer_getoverrun", "timer_gettime",
489 "timer_settime", "tzset"
492 /* <unistd.h>. */
493 static const char *const unistd_syms[] =
495 "F_OK", "NULL", "R_OK", "SEEK_CUR", "SEEK_END", "SEEK_SET", "STDERR_FILENO",
496 "STDIN_FILENO", "STDOUT_FILENO", "W_OK", "X_OK",
497 "_PC_ASYNC_IO", "_PC_CHOWN_RESTRICTED", "_PC_LINK_MAX", "_PC_MAX_CANON",
498 "_PC_MAX_INPUT", "_PC_NAME_MAX", "_PC_NO_TRUNC", "_PC_PATH_MAX",
499 "_PC_PIPE_BUF", "_PC_PRIO_IO", "_PC_SYNC_IO", "_PC_VDISABLE",
500 "_SC_AIO_LISTIO_MAX", "_SC_AIO_MAX", "_SC_AIO_PRIO_DELTA_MAX",
501 "_SC_ARG_MAX", "_SC_ASYNCHRONOUS_IO", "_SC_CHILD_MAX", "_SC_CLK_TCK",
502 "_SC_DELAYTIMER_MAX", "_SC_FSYNC", "_SC_GETGR_R_SIZE_MAX",
503 "_SC_GETPW_R_SIZE_MAX", "_SC_JOB_CONTROL", "_SC_LOGIN_NAME_MAX",
504 "_SC_MAPPED_FILES", "_SC_MEMLOCK", "_SC_MEMLOCK_RANGE",
505 "_SC_MEMORY_PROTECTION", "_SC_MESSAGE_PASSING", "_SC_MQ_OPEN_MAX",
506 "_SC_MQ_PRIO_MAX", "_SC_NGROUPS_MAX", "_SC_OPEN_MAX", "_SC_PAGESIZE",
507 "_SC_PRIORITIZED_IO", "_SC_PRIORITY_SCHEDULING", "_SC_REALTIME_SIGNALS",
508 "_SC_RTSIG_MAX", "_SC_SAVED_IDS", "_SC_SEMAPHORES", "_SC_SEM_NSEMS_MAX",
509 "_SC_SEM_VALUE_MAX", "_SC_SHARED_MEMORY_OBJECTS", "_SC_SIGQUEUE_MAX",
510 "_SC_STREAM_MAX", "_SC_SYNCHRONIZED_IO", "_SC_THREADS",
511 "_SC_THREAD_ATTR_STACKADDR", "_SC_THREAD_ATTR_STACKSIZE",
512 "_SC_THREAD_DESTRUCTOR_ITERATIONS", "_SC_THREAD_PRIO_INHERIT",
513 "_SC_THREAD_PRIORITY_SCHEDULING", "_SC_THREAD_PRIO_PROTECT",
514 "_SC_THREAD_PROCESS_SHARED", "_SC_THREAD_SAFE_FUNCTIONS",
515 "_SC_THREAD_STACK_MIN", "_SC_THREAD_THREADS_MAX", "_SC_TIMERS",
516 "_SC_TIMER_MAX", "_SC_TTY_NAME_MAX", "_SC_TZNAME_MAX", "_SC_VERSION"
518 static const char *const unistd_maybe[] =
520 "_POSIX_ASYNCHRONOUS_IO", "_POSIX_ASYNC_IO", "_POSIX_CHOWN_RESTRICTED",
521 "_POSIX_FSYNC", "_POSIX_JOB_CONTROL", "_POSIX_MAPPED_FILES",
522 "_POSIX_MEMLOCK", "_POSIX_MEMLOCK_RANGE", "_MEMORY_PROTECTION",
523 "_POSIX_MESSAGE_PASSING", "_POSIX_NO_TRUNC", "_POSIX_PRIORITIZED_IO",
524 "_POSIX_PRIORITY_SCHEDULING", "_POSIX_PRIO_IO", "_POSIX_REATIME_SIGNALS",
525 "_POSIX_SAVED_IDS", "_POSIX_SEMAPHORES", "_POSIX_SHARED_MEMORY_OBJECTS",
526 "_POSIX_SYNCHRONIZED_IO", "_POSIX_SYNC_IO", "_POSIX_THREADS",
527 "_POSIX_THREAD_ATTR_STACKADDR", "_POSIX_THREAD_ATTR_STACKSIZE",
528 "_POSIX_THREAD_PRIO_INHERIT", "_POSIX_THREAD_PRIO_PROTECT",
529 "_POSIX_THREAD_PROCESS_SHARED", "_POSIX_THREAD_SAFE_FUNCTIONS",
530 "_POSIX_THREAD_PRIORITY_SCHEDULING", "_POSIX_TIMERS",
531 "_POSIX_VDISABLE", "_POSIX_VERSION",
532 "_exit", "access", "alarm", "chdir", "chown", "close", "ctermid", "cuserid",
533 "dup2", "dup", "execl", "execle", "execlp", "execv", "execve", "execvp",
534 "fdatasync", "fork", "fpathconf", "fsync", "ftruncate", "getcwd", "getegid",
535 "geteuid", "getgid", "getgroups", "getlogin", "getlogin_r", "getpgrp",
536 "getpid", "getppid", "getuid", "isatty", "link", "lseek", "pathconf",
537 "pause", "pipe", "read", "rmdir", "setgid", "setgpid", "setsid", "setuid",
538 "sleep", "sleep", "sysconf", "tcgetpgrp", "tcsetpgrp", "ttyname",
539 "ttyname_r", "unlink", "write"
542 /* <utime.h>. */
543 static const char *const utime_syms[] =
546 static const char *const utime_maybe[] =
548 "utime"
552 static struct header
554 const char *name;
555 const char *const *syms;
556 size_t nsyms;
557 const char *const *maybe;
558 size_t nmaybe;
559 const char *subset;
560 } headers[] =
562 #define H(n) \
563 { #n ".h", n##_syms, sizeof (n##_syms) / sizeof (n##_syms[0]), \
564 n##_maybe, sizeof (n##_maybe) / sizeof (n##_maybe[0]), NULL }
565 #define Hc(n, s) \
566 { #n ".h", n##_syms, sizeof (n##_syms) / sizeof (n##_syms[0]), \
567 n##_maybe, sizeof (n##_maybe) / sizeof (n##_maybe[0]), s }
568 #define Hs(n) \
569 { "sys/" #n ".h", n##_syms, sizeof (n##_syms) / sizeof (n##_syms[0]), \
570 n##_maybe, sizeof (n##_maybe) / sizeof (n##_maybe[0]), NULL }
571 H(aio),
572 H(assert),
573 H(ctype),
574 H(dirent),
575 H(errno),
576 H(fcntl),
577 H(float),
578 H(grp),
579 H(limits),
580 H(locale),
581 H(math),
582 Hc(mqueue, "_POSIX_MESSAGE_PASSING"),
583 H(pthread),
584 H(pwd),
585 H(sched),
586 H(semaphore),
587 H(setjmp),
588 H(signal),
589 H(stdarg),
590 H(stddef),
591 H(stdio),
592 H(stdlib),
593 H(string),
594 Hs(mman),
595 Hs(stat),
596 Hs(times),
597 Hs(types),
598 Hs(utsname),
599 Hs(wait),
600 H(termios),
601 H(time),
602 H(unistd),
603 H(utime)
606 #define NUMBER_OF_HEADERS (sizeof headers / sizeof *headers)
609 /* Format string to build command to invoke compiler. */
610 static const char fmt[] = "\
611 echo \"#include <%s>\" |\
612 %s -E -dM -D_POSIX_SOURCE -D_LIBC %s \
613 -isystem `%s --print-prog-name=include` - > %s";
615 static const char testfmt[] = "\
616 echo \"#include <unistd.h>\n#ifndef %s\n#error not defined\n#endif\n\" |\
617 %s -E -dM -D_POSIX_SOURCE -D_LIBC %s \
618 -isystem `%s --print-prog-name=include` - 2> /dev/null > %s";
621 /* The compiler we use (given on the command line). */
622 const char *CC;
623 /* The -I parameters for CC to find all headers. */
624 const char *INC;
626 static char *xstrndup (const char *, size_t);
627 static const char **get_null_defines (void);
628 static int check_header (const struct header *, const char **);
631 main (int argc, char *argv[])
633 int h;
634 int result = 0;
635 const char **ignore_list;
637 CC = argc > 1 ? argv[1] : "gcc";
638 INC = argc > 2 ? argv[2] : "";
640 if (system (NULL) == 0)
642 puts ("Sorry, no command processor.");
643 return EXIT_FAILURE;
646 /* First get list of symbols which are defined by the compiler. */
647 ignore_list = get_null_defines ();
649 fputs ("Tested files:\n", stdout);
651 for (h = 0; h < NUMBER_OF_HEADERS; ++h)
652 result |= check_header (&headers[h], ignore_list);
654 /* The test suite should return errors but for now this is not
655 practical. Give a warning and ask the user to correct the bugs. */
656 return result;
660 static char *
661 xstrndup (const char *s, size_t n)
663 size_t len = n;
664 char *new = malloc (len + 1);
666 if (new == NULL)
667 return NULL;
669 new[len] = '\0';
670 return memcpy (new, s, len);
674 static const char **
675 get_null_defines (void)
677 char line[BUFSIZ], *command;
678 char **result = NULL;
679 size_t result_len = 0;
680 size_t result_max = 0;
681 FILE *input;
682 int first = 1;
684 command = malloc (sizeof fmt + sizeof "/dev/null" + 2 * strlen (CC)
685 + strlen (INC) + strlen (TMPFILE));
687 if (command == NULL)
689 puts ("No more memory.");
690 exit (1);
693 sprintf (command, fmt, "/dev/null", CC, INC, CC, TMPFILE);
695 if (system (command))
697 puts ("system() returned nonzero");
698 return NULL;
700 free (command);
701 input = fopen (TMPFILE, "r");
703 if (input == NULL)
705 printf ("Could not read %s: ", TMPFILE);
706 perror (NULL);
707 return NULL;
710 while (fgets (line, sizeof line, input) != NULL)
712 char *start;
713 if (strlen (line) < 9 || line[7] != ' ')
714 { /* "#define A" */
715 printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n",
716 line);
717 continue;
719 if (line[8] == '_')
720 /* It's a safe identifier. */
721 continue;
722 if (result_len == result_max)
724 result_max += 10;
725 result = realloc (result, result_max * sizeof (char **));
726 if (result == NULL)
728 puts ("No more memory.");
729 exit (1);
732 start = &line[8];
733 result[result_len++] = xstrndup (start, strcspn (start, " ("));
735 if (first)
737 fputs ("The following identifiers will be ignored since the compiler defines them\nby default:\n", stdout);
738 first = 0;
740 puts (result[result_len - 1]);
742 if (result_len == result_max)
744 result_max += 1;
745 result = realloc (result, result_max * sizeof (char **));
746 if (result == NULL)
748 puts ("No more memory.");
749 exit (1);
752 result[result_len] = NULL;
753 fclose (input);
754 remove (TMPFILE);
756 return (const char **) result;
760 static int
761 check_header (const struct header *header, const char **except)
763 char line[BUFSIZ], *command;
764 FILE *input;
765 int result = 0;
766 int found[header->nsyms];
767 int i;
769 memset (found, '\0', header->nsyms * sizeof (int));
770 command = alloca (sizeof fmt + strlen (header->name) + 2 * strlen (CC)
771 + strlen (INC) + strlen (TMPFILE));
774 if (command == NULL)
776 puts ("No more memory.");
777 exit (1);
780 printf ("=== %s ===\n", header->name);
781 sprintf (command, fmt, header->name, CC, INC, CC, TMPFILE);
783 /* First see whether this subset is supported at all. */
784 if (header->subset != NULL)
786 sprintf (line, testfmt, header->subset, CC, INC, CC, TMPFILE);
787 if (system (line))
789 printf ("!! not available\n");
790 return 0;
794 if (system (command))
796 puts ("system() returned nonzero");
797 result = 1;
799 input = fopen (TMPFILE, "r");
801 if (input == NULL)
803 printf ("Could not read %s: ", TMPFILE);
804 perror (NULL);
805 return 1;
808 while (fgets (line, sizeof line, input) != NULL)
810 const char **ignore;
811 if (strlen (line) < 9 || line[7] != ' ')
812 { /* "#define A" */
813 printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n",
814 line);
815 result = 1;
816 continue;
819 /* Find next char after the macro identifier; this can be either
820 a space or an open parenthesis. */
821 line[8 + strcspn (&line[8], " (")] = '\0';
823 /* Now check whether it's one of the required macros. */
824 for (i = 0; i < header->nsyms; ++i)
825 if (!strcmp (&line[8], header->syms[i]))
826 break;
827 if (i < header->nsyms)
829 found[i] = 1;
830 continue;
833 /* Symbols starting with "_" are ok. */
834 if (line[8] == '_')
835 continue;
837 /* Maybe one of the symbols which are always defined. */
838 for (ignore = except; *ignore != NULL; ++ignore)
839 if (! strcmp (&line[8], *ignore))
840 break;
841 if (*ignore != NULL)
842 continue;
844 /* Otherwise the symbol better should match one of the following. */
845 for (i = 0; i < header->nmaybe; ++i)
846 if (fnmatch (header->maybe[i], &line[8], 0) == 0)
847 break;
848 if (i < header->nmaybe)
849 continue;
851 printf ("* invalid macro `%s'\n", &line[8]);
852 result |= 1;
854 fclose (input);
855 remove (TMPFILE);
857 for (i = 0; i < header->nsyms; ++i)
858 if (found[i] == 0)
859 printf ("** macro `%s' not defined\n", header->syms[i]);
861 return result;