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