| xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 1 | /* Copyright (C) 1998-2016 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 Lesser General Public | 
|  | 6 | License as published by the Free Software Foundation; either | 
|  | 7 | version 2.1 of the 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 | Lesser General Public License for more details. | 
|  | 13 |  | 
|  | 14 | You should have received a copy of the GNU Lesser General Public | 
|  | 15 | License along with the GNU C Library; if not, see | 
|  | 16 | <http://www.gnu.org/licenses/>.  */ | 
|  | 17 |  | 
|  | 18 | #include <ctype.h> | 
|  | 19 | #include <fnmatch.h> | 
|  | 20 | #include <stdio.h> | 
|  | 21 | #include <stdlib.h> | 
|  | 22 | #include <string.h> | 
|  | 23 | #include <unistd.h> | 
|  | 24 | #include <signal.h> | 
|  | 25 | #include <sys/wait.h> | 
|  | 26 |  | 
|  | 27 | #define HEADER_MAX          256 | 
|  | 28 |  | 
|  | 29 | static const char *macrofile; | 
|  | 30 |  | 
|  | 31 | /* <aio.h>.  */ | 
|  | 32 | static const char *const aio_syms[] = | 
|  | 33 | { | 
|  | 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" | 
|  | 50 | }; | 
|  | 51 | static const char *const aio_maybe[] = | 
|  | 52 | { | 
|  | 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" | 
|  | 64 | }; | 
|  | 65 |  | 
|  | 66 | /* <assert.h>.  */ | 
|  | 67 | static const char *const assert_syms[] = | 
|  | 68 | { | 
|  | 69 | "assert" | 
|  | 70 | }; | 
|  | 71 | static const char *const assert_maybe[] = | 
|  | 72 | { | 
|  | 73 | }; | 
|  | 74 |  | 
|  | 75 | /* <ctype.h>.   */ | 
|  | 76 | static const char *const ctype_syms[] = | 
|  | 77 | { | 
|  | 78 | }; | 
|  | 79 | static const char *const ctype_maybe[] = | 
|  | 80 | { | 
|  | 81 | "isalnum", "isalpha", "iscntrl", "isdigit", "isgraph", "islower", | 
|  | 82 | "isprint", "ispunct", "isspace", "isupper", "isxdigit", "tolower", | 
|  | 83 | "toupper" | 
|  | 84 | }; | 
|  | 85 |  | 
|  | 86 | /* <dirent.h>.  */ | 
|  | 87 | static const char *const dirent_syms[] = | 
|  | 88 | { | 
|  | 89 | }; | 
|  | 90 | static const char *const dirent_maybe[] = | 
|  | 91 | { | 
|  | 92 | "closedir", "opendir", "readdir", "readdir_r", "rewinddir" | 
|  | 93 | }; | 
|  | 94 |  | 
|  | 95 | /* <errno.h>.  */ | 
|  | 96 | static const char *const errno_syms[] = | 
|  | 97 | { | 
|  | 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" | 
|  | 105 | }; | 
|  | 106 | static const char *const errno_maybe[] = | 
|  | 107 | { | 
|  | 108 | "errno", "E*" | 
|  | 109 | }; | 
|  | 110 |  | 
|  | 111 | /* <fcntl.h>.  */ | 
|  | 112 | static const char *const fcntl_syms[] = | 
|  | 113 | { | 
|  | 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" | 
|  | 119 | }; | 
|  | 120 | static const char *const fcntl_maybe[] = | 
|  | 121 | { | 
|  | 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" | 
|  | 126 | }; | 
|  | 127 |  | 
|  | 128 | /* <float.h>.  */ | 
|  | 129 | static const char *const float_syms[] = | 
|  | 130 | { | 
|  | 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" | 
|  | 137 | }; | 
|  | 138 | static const char *const float_maybe[] = | 
|  | 139 | { | 
|  | 140 | }; | 
|  | 141 |  | 
|  | 142 | /* <grp.h>.  */ | 
|  | 143 | static const char *const grp_syms[] = | 
|  | 144 | { | 
|  | 145 | }; | 
|  | 146 | static const char *const grp_maybe[] = | 
|  | 147 | { | 
|  | 148 | "getgrgid", "getgrgid_r", "getgrnam", "getgrnam_r" | 
|  | 149 | }; | 
|  | 150 |  | 
|  | 151 | /* <limits.h>.  */ | 
|  | 152 | static const char *const limits_syms[] = | 
|  | 153 | { | 
|  | 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" | 
|  | 169 | }; | 
|  | 170 | static const char *const limits_maybe[] = | 
|  | 171 | { | 
|  | 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" | 
|  | 177 | }; | 
|  | 178 |  | 
|  | 179 | /* <locale.h>.  */ | 
|  | 180 | static const char *const locale_syms[] = | 
|  | 181 | { | 
|  | 182 | "LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC", | 
|  | 183 | "LC_TIME", "NULL" | 
|  | 184 | }; | 
|  | 185 | static const char *const locale_maybe[] = | 
|  | 186 | { | 
|  | 187 | "LC_*", "localeconv", "setlocale" | 
|  | 188 | }; | 
|  | 189 |  | 
|  | 190 | /* <math.h>.  */ | 
|  | 191 | static const char *const math_syms[] = | 
|  | 192 | { | 
|  | 193 | "HUGE_VAL" | 
|  | 194 | }; | 
|  | 195 | static const char *const math_maybe[] = | 
|  | 196 | { | 
|  | 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" | 
|  | 206 | }; | 
|  | 207 |  | 
|  | 208 | /* <mqueue.h>.  */ | 
|  | 209 | static const char *const mqueue_syms[] = | 
|  | 210 | { | 
|  | 211 | }; | 
|  | 212 | static const char *const mqueue_maybe[] = | 
|  | 213 | { | 
|  | 214 | "mq_close", "mq_getattr", "mq_notify", "mq_open", "mq_receive", | 
|  | 215 | "mq_send", "mq_setattr", "mq_unlink" | 
|  | 216 | }; | 
|  | 217 |  | 
|  | 218 | /* <pthread.h>.  */ | 
|  | 219 | static const char *const pthread_syms[] = | 
|  | 220 | { | 
|  | 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" | 
|  | 233 | }; | 
|  | 234 | static const char *const pthread_maybe[] = | 
|  | 235 | { | 
|  | 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" | 
|  | 270 | }; | 
|  | 271 |  | 
|  | 272 | /* <pwd.h>.  */ | 
|  | 273 | static const char *const pwd_syms[] = | 
|  | 274 | { | 
|  | 275 | }; | 
|  | 276 | static const char *const pwd_maybe[] = | 
|  | 277 | { | 
|  | 278 | "getpwnam", "getpwnam_r", "getpwuid", "getpwuid_r" | 
|  | 279 | }; | 
|  | 280 |  | 
|  | 281 | /* <sched.h>.  */ | 
|  | 282 | static const char *const sched_syms[] = | 
|  | 283 | { | 
|  | 284 | "SCHED_FIFO", "SCHED_OTHER", "SCHED_RR", | 
|  | 285 | }; | 
|  | 286 | static const char *const sched_maybe[] = | 
|  | 287 | { | 
|  | 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" | 
|  | 298 | }; | 
|  | 299 |  | 
|  | 300 | /* <semaphore.h>.  */ | 
|  | 301 | static const char *const semaphore_syms[] = | 
|  | 302 | { | 
|  | 303 | }; | 
|  | 304 | static const char *const semaphore_maybe[] = | 
|  | 305 | { | 
|  | 306 | "sem_close", "sem_destroy", "sem_getvalue", "sem_init", "sem_open", | 
|  | 307 | "sen_post", "sem_trywait", "sem_unlink", "sem_wait" | 
|  | 308 | }; | 
|  | 309 |  | 
|  | 310 | /* <setjmp.h>.  */ | 
|  | 311 | static const char *const setjmp_syms[] = | 
|  | 312 | { | 
|  | 313 | }; | 
|  | 314 | static const char *const setjmp_maybe[] = | 
|  | 315 | { | 
|  | 316 | "longjmp", "setjmp", "siglongjmp", "sigsetjmp" | 
|  | 317 | }; | 
|  | 318 |  | 
|  | 319 | /* <signal.h>.  */ | 
|  | 320 | static const char *const signal_syms[] = | 
|  | 321 | { | 
|  | 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" | 
|  | 329 | }; | 
|  | 330 | static const char *const signal_maybe[] = | 
|  | 331 | { | 
|  | 332 | "kill", "raise", "sigaction", "sigaddset", "sigdelset", "sigemptyset", | 
|  | 333 | "sigfillset", "sigismember", "signal", "sigpending", "sigprocmask", | 
|  | 334 | "sigqueue", "sigsuspend", "sigtimedwait", "sigwait", "sigwaitinfo" | 
|  | 335 | }; | 
|  | 336 |  | 
|  | 337 | /* <stdarg.h>.  */ | 
|  | 338 | static const char *const stdarg_syms[] = | 
|  | 339 | { | 
|  | 340 | "va_arg", "va_end", "va_start" | 
|  | 341 | }; | 
|  | 342 | static const char *const stdarg_maybe[] = | 
|  | 343 | { | 
|  | 344 | "va_list" | 
|  | 345 | }; | 
|  | 346 |  | 
|  | 347 | /* <stddef.h>.  */ | 
|  | 348 | static const char *const stddef_syms[] = | 
|  | 349 | { | 
|  | 350 | "NULL", "offsetof" | 
|  | 351 | }; | 
|  | 352 | static const char *const stddef_maybe[] = | 
|  | 353 | { | 
|  | 354 | }; | 
|  | 355 |  | 
|  | 356 | /* <stdio.h>.  */ | 
|  | 357 | static const char *const stdio_syms[] = | 
|  | 358 | { | 
|  | 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" | 
|  | 362 | }; | 
|  | 363 | static const char *const stdio_maybe[] = | 
|  | 364 | { | 
|  | 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" | 
|  | 373 | }; | 
|  | 374 |  | 
|  | 375 | /* <stdlib.h>.  */ | 
|  | 376 | static const char *const stdlib_syms[] = | 
|  | 377 | { | 
|  | 378 | "EXIT_FAILURE", "EXIT_SUCCESS", "MB_CUR_MAX", "NULL", "RAND_MAX" | 
|  | 379 | }; | 
|  | 380 | static const char *const stdlib_maybe[] = | 
|  | 381 | { | 
|  | 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" | 
|  | 386 | }; | 
|  | 387 |  | 
|  | 388 | /* <string.h>.  */ | 
|  | 389 | static const char *const string_syms[] = | 
|  | 390 | { | 
|  | 391 | "NULL" | 
|  | 392 | }; | 
|  | 393 | static const char *const string_maybe[] = | 
|  | 394 | { | 
|  | 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" | 
|  | 399 | }; | 
|  | 400 |  | 
|  | 401 | /* <sys/mman.h>.  */ | 
|  | 402 | static const char *const mman_syms[] = | 
|  | 403 | { | 
|  | 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" | 
|  | 407 | }; | 
|  | 408 | static const char *const mman_maybe[] = | 
|  | 409 | { | 
|  | 410 | "mlock", "mlockall", "mmap", "mprotect", "msync", "munlock", "munlockall", | 
|  | 411 | "munmap", "shm_open", "shm_unlock" | 
|  | 412 | }; | 
|  | 413 |  | 
|  | 414 | /* <sys/stat.h>.  */ | 
|  | 415 | static const char *const stat_syms[] = | 
|  | 416 | { | 
|  | 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" | 
|  | 421 | }; | 
|  | 422 | static const char *const stat_maybe[] = | 
|  | 423 | { | 
|  | 424 | "chmod", "fchmod", "fstat", "mkdir", "mkfifo", "stat", "umask" | 
|  | 425 | }; | 
|  | 426 |  | 
|  | 427 | /* <sys/times.h>.  */ | 
|  | 428 | static const char *const times_syms[] = | 
|  | 429 | { | 
|  | 430 | }; | 
|  | 431 | static const char *const times_maybe[] = | 
|  | 432 | { | 
|  | 433 | "times" | 
|  | 434 | }; | 
|  | 435 |  | 
|  | 436 | /* <sys/types.h>.  */ | 
|  | 437 | static const char *const types_syms[] = | 
|  | 438 | { | 
|  | 439 | }; | 
|  | 440 | static const char *const types_maybe[] = | 
|  | 441 | { | 
|  | 442 | }; | 
|  | 443 |  | 
|  | 444 | /* <sys/utsname.h>.  */ | 
|  | 445 | static const char *const utsname_syms[] = | 
|  | 446 | { | 
|  | 447 | }; | 
|  | 448 | static const char *const utsname_maybe[] = | 
|  | 449 | { | 
|  | 450 | "uname" | 
|  | 451 | }; | 
|  | 452 |  | 
|  | 453 | /* <sys/wait.h>.  */ | 
|  | 454 | static const char *const wait_syms[] = | 
|  | 455 | { | 
|  | 456 | "WEXITSTATUS", "WIFEXITED", "WIFSIGNALED", "WIFSTOPPED", "WNOHANG", | 
|  | 457 | "WSTOPSIG", "WTERMSIG", "WUNTRACED" | 
|  | 458 | }; | 
|  | 459 | static const char *const wait_maybe[] = | 
|  | 460 | { | 
|  | 461 | "wait", "waitpid" | 
|  | 462 | }; | 
|  | 463 |  | 
|  | 464 | /* <termios.h>.  */ | 
|  | 465 | static const char *const termios_syms[] = | 
|  | 466 | { | 
|  | 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" | 
|  | 476 | }; | 
|  | 477 | static const char *const termios_maybe[] = | 
|  | 478 | { | 
|  | 479 | "cfgetispeed", "cfgetospeed", "cfsetispeed", "cfsetospeed", "tcdrain", | 
|  | 480 | "tcflow", "tcflush", "tcgetattr", "tcsendbrk", "tcsetattr" | 
|  | 481 | }; | 
|  | 482 |  | 
|  | 483 | /* <time.h>.  */ | 
|  | 484 | static const char *const time_syms[] = | 
|  | 485 | { | 
|  | 486 | "CLK_TCK", "CLOCKS_PER_SEC", "CLOCK_REALTIME", "NULL", "TIMER_ABSTIME" | 
|  | 487 | }; | 
|  | 488 | static const char *const time_maybe[] = | 
|  | 489 | { | 
|  | 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" | 
|  | 495 | }; | 
|  | 496 |  | 
|  | 497 | /* <unistd.h>.  */ | 
|  | 498 | static const char *const unistd_syms[] = | 
|  | 499 | { | 
|  | 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" | 
|  | 522 | }; | 
|  | 523 | static const char *const unistd_maybe[] = | 
|  | 524 | { | 
|  | 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" | 
|  | 545 | }; | 
|  | 546 |  | 
|  | 547 | /* <utime.h>.  */ | 
|  | 548 | static const char *const utime_syms[] = | 
|  | 549 | { | 
|  | 550 | }; | 
|  | 551 | static const char *const utime_maybe[] = | 
|  | 552 | { | 
|  | 553 | "utime" | 
|  | 554 | }; | 
|  | 555 |  | 
|  | 556 |  | 
|  | 557 | static struct header | 
|  | 558 | { | 
|  | 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[] = | 
|  | 566 | { | 
|  | 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) | 
|  | 609 | }; | 
|  | 610 |  | 
|  | 611 | #define NUMBER_OF_HEADERS              (sizeof headers / sizeof *headers) | 
|  | 612 |  | 
|  | 613 |  | 
|  | 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 %s \ | 
|  | 618 | -isystem `%s --print-prog-name=include` - > %s"; | 
|  | 619 |  | 
|  | 620 | static const char testfmt[] = "\ | 
|  | 621 | echo \"#include <unistd.h>\n#if !defined %s || %s == -1\n#error not defined\n#endif\n\" |\ | 
|  | 622 | %s -E -dM -D_POSIX_SOURCE %s \ | 
|  | 623 | -isystem `%s --print-prog-name=include` - 2> /dev/null > %s"; | 
|  | 624 |  | 
|  | 625 |  | 
|  | 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; | 
|  | 630 |  | 
|  | 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 *); | 
|  | 635 |  | 
|  | 636 | int | 
|  | 637 | main (int argc, char *argv[]) | 
|  | 638 | { | 
|  | 639 | int h; | 
|  | 640 | int result = 0; | 
|  | 641 | const char **ignore_list; | 
|  | 642 |  | 
|  | 643 | CC = argc > 1 ? argv[1] : "gcc"; | 
|  | 644 | INC = argc > 2 ? argv[2] : ""; | 
|  | 645 |  | 
|  | 646 | if (system (NULL) == 0) | 
|  | 647 | { | 
|  | 648 | puts ("Sorry, no command processor."); | 
|  | 649 | return EXIT_FAILURE; | 
|  | 650 | } | 
|  | 651 |  | 
|  | 652 | /* First get list of symbols which are defined by the compiler.  */ | 
|  | 653 | ignore_list = get_null_defines (); | 
|  | 654 |  | 
|  | 655 | fputs ("Tested files:\n", stdout); | 
|  | 656 |  | 
|  | 657 | for (h = 0; h < NUMBER_OF_HEADERS; ++h) | 
|  | 658 | result |= check_header (&headers[h], ignore_list); | 
|  | 659 |  | 
|  | 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; | 
|  | 663 | } | 
|  | 664 |  | 
|  | 665 |  | 
|  | 666 | static char * | 
|  | 667 | xstrndup (const char *s, size_t n) | 
|  | 668 | { | 
|  | 669 | size_t len = n; | 
|  | 670 | char *new = malloc (len + 1); | 
|  | 671 |  | 
|  | 672 | if (new == NULL) | 
|  | 673 | return NULL; | 
|  | 674 |  | 
|  | 675 | new[len] = '\0'; | 
|  | 676 | return memcpy (new, s, len); | 
|  | 677 | } | 
|  | 678 |  | 
|  | 679 |  | 
|  | 680 | /* Like system but propagate interrupt and quit signals.  */ | 
|  | 681 | int | 
|  | 682 | xsystem (const char *cmd) | 
|  | 683 | { | 
|  | 684 | int status; | 
|  | 685 |  | 
|  | 686 | status = system (cmd); | 
|  | 687 | if (status != -1) | 
|  | 688 | { | 
|  | 689 | if (WIFSIGNALED (status)) | 
|  | 690 | { | 
|  | 691 | if (WTERMSIG (status) == SIGINT || WTERMSIG (status) == SIGQUIT) | 
|  | 692 | raise (WTERMSIG (status)); | 
|  | 693 | } | 
|  | 694 | else if (WIFEXITED (status)) | 
|  | 695 | { | 
|  | 696 | if (WEXITSTATUS (status) == SIGINT + 128 | 
|  | 697 | || WEXITSTATUS (status) == SIGQUIT + 128) | 
|  | 698 | raise (WEXITSTATUS (status) - 128); | 
|  | 699 | } | 
|  | 700 | } | 
|  | 701 | return status; | 
|  | 702 | } | 
|  | 703 |  | 
|  | 704 |  | 
|  | 705 | static const char ** | 
|  | 706 | get_null_defines (void) | 
|  | 707 | { | 
|  | 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; | 
|  | 714 |  | 
|  | 715 | macrofile = tmpnam (NULL); | 
|  | 716 |  | 
|  | 717 | command = malloc (sizeof fmt + sizeof "/dev/null" + 2 * strlen (CC) | 
|  | 718 | + strlen (INC) + strlen (macrofile)); | 
|  | 719 |  | 
|  | 720 | if (command == NULL) | 
|  | 721 | { | 
|  | 722 | puts ("No more memory."); | 
|  | 723 | exit (1); | 
|  | 724 | } | 
|  | 725 |  | 
|  | 726 | sprintf (command, fmt, "/dev/null", CC, INC, CC, macrofile); | 
|  | 727 |  | 
|  | 728 | if (xsystem (command)) | 
|  | 729 | { | 
|  | 730 | puts ("system() returned nonzero"); | 
|  | 731 | return NULL; | 
|  | 732 | } | 
|  | 733 | free (command); | 
|  | 734 | input = fopen (macrofile, "r"); | 
|  | 735 |  | 
|  | 736 | if (input == NULL) | 
|  | 737 | { | 
|  | 738 | printf ("Could not read %s: ", macrofile); | 
|  | 739 | perror (NULL); | 
|  | 740 | return NULL; | 
|  | 741 | } | 
|  | 742 |  | 
|  | 743 | while (fgets (line, sizeof line, input) != NULL) | 
|  | 744 | { | 
|  | 745 | char *start; | 
|  | 746 | if (strlen (line) < 9 || line[7] != ' ') | 
|  | 747 | { /* "#define A" */ | 
|  | 748 | printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n", | 
|  | 749 | line); | 
|  | 750 | continue; | 
|  | 751 | } | 
|  | 752 | if (line[8] == '_') | 
|  | 753 | /* It's a safe identifier.  */ | 
|  | 754 | continue; | 
|  | 755 | if (result_len == result_max) | 
|  | 756 | { | 
|  | 757 | result_max += 10; | 
|  | 758 | result = realloc (result, result_max * sizeof (char **)); | 
|  | 759 | if (result == NULL) | 
|  | 760 | { | 
|  | 761 | puts ("No more memory."); | 
|  | 762 | exit (1); | 
|  | 763 | } | 
|  | 764 | } | 
|  | 765 | start = &line[8]; | 
|  | 766 | result[result_len++] = xstrndup (start, strcspn (start, " (")); | 
|  | 767 |  | 
|  | 768 | if (first) | 
|  | 769 | { | 
|  | 770 | fputs ("The following identifiers will be ignored since the compiler defines them\nby default:\n", stdout); | 
|  | 771 | first = 0; | 
|  | 772 | } | 
|  | 773 | puts (result[result_len - 1]); | 
|  | 774 | } | 
|  | 775 | if (result_len == result_max) | 
|  | 776 | { | 
|  | 777 | result_max += 1; | 
|  | 778 | result = realloc (result, result_max * sizeof (char **)); | 
|  | 779 | if (result == NULL) | 
|  | 780 | { | 
|  | 781 | puts ("No more memory."); | 
|  | 782 | exit (1); | 
|  | 783 | } | 
|  | 784 | } | 
|  | 785 | result[result_len] = NULL; | 
|  | 786 | fclose (input); | 
|  | 787 | remove (macrofile); | 
|  | 788 |  | 
|  | 789 | return (const char **) result; | 
|  | 790 | } | 
|  | 791 |  | 
|  | 792 |  | 
|  | 793 | static int | 
|  | 794 | check_header (const struct header *header, const char **except) | 
|  | 795 | { | 
|  | 796 | char line[BUFSIZ], command[sizeof fmt + strlen (header->name) | 
|  | 797 | + 2 * strlen (CC) | 
|  | 798 | + strlen (INC) + strlen (macrofile)]; | 
|  | 799 | FILE *input; | 
|  | 800 | int result = 0; | 
|  | 801 | int found[header->nsyms]; | 
|  | 802 | int i; | 
|  | 803 |  | 
|  | 804 | memset (found, '\0', header->nsyms * sizeof (int)); | 
|  | 805 |  | 
|  | 806 | printf ("=== %s ===\n", header->name); | 
|  | 807 | sprintf (command, fmt, header->name, CC, INC, CC, macrofile); | 
|  | 808 |  | 
|  | 809 | /* First see whether this subset is supported at all.  */ | 
|  | 810 | if (header->subset != NULL) | 
|  | 811 | { | 
|  | 812 | sprintf (line, testfmt, header->subset, header->subset, CC, INC, CC, | 
|  | 813 | macrofile); | 
|  | 814 | if (xsystem (line)) | 
|  | 815 | { | 
|  | 816 | printf ("!! not available\n"); | 
|  | 817 | return 0; | 
|  | 818 | } | 
|  | 819 | } | 
|  | 820 |  | 
|  | 821 | if (xsystem (command)) | 
|  | 822 | { | 
|  | 823 | puts ("system() returned nonzero"); | 
|  | 824 | result = 1; | 
|  | 825 | } | 
|  | 826 | input = fopen (macrofile, "r"); | 
|  | 827 |  | 
|  | 828 | if (input == NULL) | 
|  | 829 | { | 
|  | 830 | printf ("Could not read %s: ", macrofile); | 
|  | 831 | perror (NULL); | 
|  | 832 | return 1; | 
|  | 833 | } | 
|  | 834 |  | 
|  | 835 | while (fgets (line, sizeof line, input) != NULL) | 
|  | 836 | { | 
|  | 837 | const char **ignore; | 
|  | 838 | if (strlen (line) < 9 || line[7] != ' ') | 
|  | 839 | { /* "#define A" */ | 
|  | 840 | printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n", | 
|  | 841 | line); | 
|  | 842 | result = 1; | 
|  | 843 | continue; | 
|  | 844 | } | 
|  | 845 |  | 
|  | 846 | /* Find next char after the macro identifier; this can be either | 
|  | 847 | a space or an open parenthesis.  */ | 
|  | 848 | line[8 + strcspn (&line[8], " (")] = '\0'; | 
|  | 849 |  | 
|  | 850 | /* Now check whether it's one of the required macros.  */ | 
|  | 851 | for (i = 0; i < header->nsyms; ++i) | 
|  | 852 | if (!strcmp (&line[8], header->syms[i])) | 
|  | 853 | break; | 
|  | 854 | if (i < header->nsyms) | 
|  | 855 | { | 
|  | 856 | found[i] = 1; | 
|  | 857 | continue; | 
|  | 858 | } | 
|  | 859 |  | 
|  | 860 | /* Symbols starting with "_" are ok.  */ | 
|  | 861 | if (line[8] == '_') | 
|  | 862 | continue; | 
|  | 863 |  | 
|  | 864 | /* Maybe one of the symbols which are always defined.  */ | 
|  | 865 | for (ignore = except; *ignore != NULL; ++ignore) | 
|  | 866 | if (! strcmp (&line[8], *ignore)) | 
|  | 867 | break; | 
|  | 868 | if (*ignore != NULL) | 
|  | 869 | continue; | 
|  | 870 |  | 
|  | 871 | /* Otherwise the symbol better should match one of the following.  */ | 
|  | 872 | for (i = 0; i < header->nmaybe; ++i) | 
|  | 873 | if (fnmatch (header->maybe[i], &line[8], 0) == 0) | 
|  | 874 | break; | 
|  | 875 | if (i < header->nmaybe) | 
|  | 876 | continue; | 
|  | 877 |  | 
|  | 878 | printf ("*  invalid macro `%s'\n", &line[8]); | 
|  | 879 | result |= 1; | 
|  | 880 | } | 
|  | 881 | fclose (input); | 
|  | 882 | remove (macrofile); | 
|  | 883 |  | 
|  | 884 | for (i = 0; i < header->nsyms; ++i) | 
|  | 885 | if (found[i] == 0) | 
|  | 886 | printf ("** macro `%s' not defined\n", header->syms[i]); | 
|  | 887 |  | 
|  | 888 | return result; | 
|  | 889 | } |