Update.
[glibc.git] / posix / annexc.c
blob56af0a52b5831b1eb117798484f6d1d3bf59bd53
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", "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"
168 static const char *const limits_maybe[] =
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"
177 /* <locale.h>. */
178 static const char *const locale_syms[] =
180 "LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC",
181 "LC_TIME", "NULL"
183 static const char *const locale_maybe[] =
185 "LC_*", "localeconv", "setlocale"
188 /* <math.h>. */
189 static const char *const math_syms[] =
191 "HUGE_VAL"
193 static const char *const math_maybe[] =
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"
206 /* <mqueue.h>. */
207 static const char *const mqueue_syms[] =
210 static const char *const mqueue_maybe[] =
212 "mq_close", "mq_getattr", "mq_notify", "mq_open", "mq_receive",
213 "mq_send", "mq_setattr", "mq_unlink"
216 /* <pthread.h>. */
217 static const char *const pthread_syms[] =
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"
232 static const char *const pthread_maybe[] =
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"
270 /* <pwd.h>. */
271 static const char *const pwd_syms[] =
274 static const char *const pwd_maybe[] =
276 "getpwnam", "getpwnam_r", "getpwuid", "getpwuid_r"
279 /* <sched.h>. */
280 static const char *const sched_syms[] =
282 "SCHED_FIFO", "SCHED_OTHER", "SCHED_RR",
284 static const char *const sched_maybe[] =
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"
298 /* <semaphore.h>. */
299 static const char *const semaphore_syms[] =
302 static const char *const semaphore_maybe[] =
304 "sem_close", "sem_destroy", "sem_getvalue", "sem_init", "sem_open",
305 "sen_post", "sem_trywait", "sem_unlink", "sem_wait"
308 /* <setjmp.h>. */
309 static const char *const setjmp_syms[] =
312 static const char *const setjmp_maybe[] =
314 "longjmp", "setjmp", "siglongjmp", "sigsetjmp"
317 /* <signal.h>. */
318 static const char *const signal_syms[] =
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"
328 static const char *const signal_maybe[] =
330 "kill", "raise", "sigaction", "sigaddset", "sigdelset", "sigemptyset",
331 "sigfillset", "sigismember", "signal", "sigpending", "sigprocmask",
332 "sigqueue", "sigsuspend", "sigtimedwait", "sigwait", "sigwaitinfo"
335 /* <stdarg.h>. */
336 static const char *const stdarg_syms[] =
338 "va_arg", "va_end", "va_start"
340 static const char *const stdarg_maybe[] =
342 "va_list"
345 /* <stddef.h>. */
346 static const char *const stddef_syms[] =
348 "NULL", "offsetof"
350 static const char *const stddef_maybe[] =
354 /* <stdio.h>. */
355 static const char *const stdio_syms[] =
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"
361 static const char *const stdio_maybe[] =
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"
373 /* <stdlib.h>. */
374 static const char *const stdlib_syms[] =
376 "EXIT_FAILURE", "EXIT_SUCCESS", "MB_CUR_MAX", "NULL", "RAND_MAX"
378 static const char *const stdlib_maybe[] =
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"
386 /* <string.h>. */
387 static const char *const string_syms[] =
389 "NULL"
391 static const char *const string_maybe[] =
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"
399 /* <sys/mman.h>. */
400 static const char *const mman_syms[] =
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"
406 static const char *const mman_maybe[] =
408 "mlock", "mlockall", "mmap", "mprotect", "msync", "munlock", "munlockall",
409 "munmap", "shm_open", "shm_unlock"
412 /* <sys/stat.h>. */
413 static const char *const stat_syms[] =
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"
420 static const char *const stat_maybe[] =
422 "chmod", "fchmod", "fstat", "mkdir", "mkfifo", "stat", "umask"
425 /* <sys/times.h>. */
426 static const char *const times_syms[] =
429 static const char *const times_maybe[] =
431 "times"
434 /* <sys/types.h>. */
435 static const char *const types_syms[] =
438 static const char *const types_maybe[] =
442 /* <sys/utsname.h>. */
443 static const char *const utsname_syms[] =
446 static const char *const utsname_maybe[] =
448 "uname"
451 /* <sys/wait.h>. */
452 static const char *const wait_syms[] =
454 "WEXITSTATUS", "WIFEXITED", "WIFSIGNALED", "WIFSTOPPED", "WNOHANG",
455 "WSTOPSIG", "WTERMSIG", "WUNTRACED"
457 static const char *const wait_maybe[] =
459 "wait", "waitpid"
462 /* <termios.h>. */
463 static const char *const termios_syms[] =
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"
475 static const char *const termios_maybe[] =
477 "cfgetispeed", "cfgetospeed", "cfsetispeed", "cfsetospeed", "tcdrain",
478 "tcflow", "tcflush", "tcgetattr", "tcsendbrk", "tcsetattr"
481 /* <time.h>. */
482 static const char *const time_syms[] =
484 "CLK_TCK", "CLOCKS_PER_SEC", "CLOCK_REALTIME", "NULL", "TIMER_ABSTIME"
486 static const char *const time_maybe[] =
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"
495 /* <unistd.h>. */
496 static const char *const unistd_syms[] =
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"
521 static const char *const unistd_maybe[] =
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"
545 /* <utime.h>. */
546 static const char *const utime_syms[] =
549 static const char *const utime_maybe[] =
551 "utime"
555 static struct header
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[] =
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)
609 #define NUMBER_OF_HEADERS (sizeof headers / sizeof *headers)
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";
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";
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;
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 **);
634 main (int argc, char *argv[])
636 int h;
637 int result = 0;
638 const char **ignore_list;
640 CC = argc > 1 ? argv[1] : "gcc";
641 INC = argc > 2 ? argv[2] : "";
643 if (system (NULL) == 0)
645 puts ("Sorry, no command processor.");
646 return EXIT_FAILURE;
649 /* First get list of symbols which are defined by the compiler. */
650 ignore_list = get_null_defines ();
652 fputs ("Tested files:\n", stdout);
654 for (h = 0; h < NUMBER_OF_HEADERS; ++h)
655 result |= check_header (&headers[h], ignore_list);
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;
663 static char *
664 xstrndup (const char *s, size_t n)
666 size_t len = n;
667 char *new = malloc (len + 1);
669 if (new == NULL)
670 return NULL;
672 new[len] = '\0';
673 return memcpy (new, s, len);
677 static const char **
678 get_null_defines (void)
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;
687 command = malloc (sizeof fmt + sizeof "/dev/null" + 2 * strlen (CC)
688 + strlen (INC) + strlen (TMPFILE));
690 if (command == NULL)
692 puts ("No more memory.");
693 exit (1);
696 sprintf (command, fmt, "/dev/null", CC, INC, CC, TMPFILE);
698 if (system (command))
700 puts ("system() returned nonzero");
701 return NULL;
703 free (command);
704 input = fopen (TMPFILE, "r");
706 if (input == NULL)
708 printf ("Could not read %s: ", TMPFILE);
709 perror (NULL);
710 return NULL;
713 while (fgets (line, sizeof line, input) != NULL)
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;
722 if (line[8] == '_')
723 /* It's a safe identifier. */
724 continue;
725 if (result_len == result_max)
727 result_max += 10;
728 result = realloc (result, result_max * sizeof (char **));
729 if (result == NULL)
731 puts ("No more memory.");
732 exit (1);
735 start = &line[8];
736 result[result_len++] = xstrndup (start, strcspn (start, " ("));
738 if (first)
740 fputs ("The following identifiers will be ignored since the compiler defines them\nby default:\n", stdout);
741 first = 0;
743 puts (result[result_len - 1]);
745 if (result_len == result_max)
747 result_max += 1;
748 result = realloc (result, result_max * sizeof (char **));
749 if (result == NULL)
751 puts ("No more memory.");
752 exit (1);
755 result[result_len] = NULL;
756 fclose (input);
757 remove (TMPFILE);
759 return (const char **) result;
763 static int
764 check_header (const struct header *header, const char **except)
766 char line[BUFSIZ], *command;
767 FILE *input;
768 int result = 0;
769 int found[header->nsyms];
770 int i;
772 memset (found, '\0', header->nsyms * sizeof (int));
773 command = alloca (sizeof fmt + strlen (header->name) + 2 * strlen (CC)
774 + strlen (INC) + strlen (TMPFILE));
777 if (command == NULL)
779 puts ("No more memory.");
780 exit (1);
783 printf ("=== %s ===\n", header->name);
784 sprintf (command, fmt, header->name, CC, INC, CC, TMPFILE);
786 /* First see whether this subset is supported at all. */
787 if (header->subset != NULL)
789 sprintf (line, testfmt, header->subset, CC, INC, CC, TMPFILE);
790 if (system (line))
792 printf ("!! not available\n");
793 return 0;
797 if (system (command))
799 puts ("system() returned nonzero");
800 result = 1;
802 input = fopen (TMPFILE, "r");
804 if (input == NULL)
806 printf ("Could not read %s: ", TMPFILE);
807 perror (NULL);
808 return 1;
811 while (fgets (line, sizeof line, input) != NULL)
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;
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';
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)
832 found[i] = 1;
833 continue;
836 /* Symbols starting with "_" are ok. */
837 if (line[8] == '_')
838 continue;
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;
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;
854 printf ("* invalid macro `%s'\n", &line[8]);
855 result |= 1;
857 fclose (input);
858 remove (TMPFILE);
860 for (i = 0; i < header->nsyms; ++i)
861 if (found[i] == 0)
862 printf ("** macro `%s' not defined\n", header->syms[i]);
864 return result;