"Fossies" - the Fresh Open Source Software Archive

Member "deheader-1.10/deheader" (17 Feb 2023, 72250 Bytes) of package /linux/privat/deheader-1.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "deheader": 1.8_vs_1.10.

    1 #!/usr/bin/env python3
    2 """\
    3 deheader -- find (optionally remove) unneeded includes in C or C++ sourcefiles.
    4 
    5 Usage: deheader [-h] [-i pattern] [-m cmd] [-b dir] [-q] [-r] [-x pattern] [-v] [file...]
    6     -h, --help     Emit this help message and quit.
    7     -m, --maker    Set the build command (by default 'make %s')
    8     -b, --builddir Set a build directory relative to where deheader is run
    9     -i, --ignore   Ignore (don't remove) headers matching the argument regexp
   10     -q, --quiet    Suppress statistical summary
   11     -r, --remove   Remove the final set of unneeded headers
   12     -v, --verbose  Be chatty about what you're doing.
   13     -x, --exclude  Exclude files matching regexp
   14     -V, --version  Emit version and exit.
   15 
   16 This tool takes a list of C or C++ sourcefiles and generates a report
   17 on which #includes can be omitted from them -- the test, for each foo.c
   18 or foo.cc or foo.cpp, is simply whether 'rm foo.o; make foo.o' returns a
   19 zero status. Optionally, with the -r option, the unneeded headers are removed.
   20 The tool also reports on headers required for strict portability.
   21 
   22 If a sourcefile argument is a directory, the report is generated on all source
   23 files beneath it.  Subdirectories beginning with a dot are ignored.  If no
   24 arguments are given, the program runs as if the name of the current directory
   25 had been passed to it.
   26 
   27 The original sourcefile is moved to a name with an .orig suffix and restored
   28 on interrupt or after processing with its original timestamp, unless the
   29 -r option was given and headers removed.
   30 
   31 The last line of the output is a statistical summary of operations.
   32 """
   33 # SPDX-License-Identifier: BSD-2-Clause
   34 
   35 # pylint: disable=line-too-long,invalid-name,redefined-outer-name,too-many-lines,missing-function-docstring,no-else-raise,no-else-return,consider-using-f-string,consider-using-dict-items,consider-using-with
   36 
   37 # pylint: disable=multiple-imports
   38 import sys, os, getopt, time, re, subprocess
   39 
   40 version = "1.10"
   41 
   42 try:
   43     from subprocess import getstatusoutput
   44 except ImportError:
   45     from commands import getstatusoutput
   46 
   47 BATON_DEBUG    = 1
   48 PROGRESS_DEBUG = 2
   49 COMMAND_DEBUG  = 3
   50 
   51 # Difference in various compiler implementations and OSes mean that for cross-
   52 # platform compatibility you sometimes want to leave "unneeded" headers alone
   53 # because they're required in order to satisfy dependencies on other platforms.
   54 requirements = (
   55     # Headers mandated by SuS Version 2 System Interfaces.
   56     # a64l, l64a - convert between a 32-bit integer and a radix-64 ASCII string
   57     (r"a64l()",          ["<stdlib.h>"]),
   58     (r"l64a()",          ["<stdlib.h>"]),
   59     # abort - generate an abnormal process abort
   60     (r"abort()",         ["<stdlib.h>"]),
   61     # abs - return an integer absolute value
   62     (r"abs()",           ["<stdlib.h>"]),
   63     # access - determine accessibility of a file
   64     (r"access()",        ["<unistd.h>"]),
   65     # acos - arc cosine function
   66     (r"acos()",          ["<math.h>"]),
   67     # acosh, asinh, atanh - inverse hyperbolic functions
   68     (r"acosh()",         ["<math.h>"]),
   69     (r"asinh()",         ["<math.h>"]),
   70     (r"atanh()",         ["<math.h>"]),
   71     # advance - pattern match given a compiled regular expression
   72     (r"advance()",       ["<regex.h>"]),
   73     # aio.h - asynchronous input and output
   74     (r"aio_cancel()",    ["<aio.h>"]),
   75     (r"aio_error()",     ["<aio.h>"]),
   76     (r"aio_fsync()",     ["<aio.h>"]),
   77     (r"aio_read()",      ["<aio.h>"]),
   78     (r"aio_return()",    ["<aio.h>"]),
   79     (r"aio_suspend()",   ["<aio.h>"]),
   80     (r"aio_write()",     ["<aio.h>"]),
   81     (r"lio_listio()",    ["<aio.h>"]),
   82     # alarm - schedule an alarm signal
   83     (r"alarm()",         ["<unistd.h>"]),
   84     # asctime, asctime_r - convert date and time to a string
   85     (r"asctime()",       ["<time.h>"]),
   86     (r"asctime_r()",     ["<time.h>"]),
   87     # asin - arc sine function
   88     (r"asin()",          ["<math.h>"]),
   89     # assert - verify program assertion
   90     (r"assert()",        ["<assert.h>"]),
   91     # atan - arc tangent function
   92     (r"atan()",          ["<math.h>"]),
   93     # atan2 - arc tangent function
   94     (r"atanh()",         ["<math.h>"]),
   95     # atanh - hyperbolic arc tangent
   96     (r"atan2()",         ["<math.h>"]),
   97     # atexit - register a function to run at process termination
   98     (r"atexit()",        ["<stdlib.h>"]),
   99     # atof - convert a string to double-precision number
  100     (r"atof()",          ["<stdlib.h>"]),
  101     # atoi - convert a string to integer
  102     (r"atoi()",          ["<stdlib.h>"]),
  103     # atol - convert a string to long integer
  104     (r"atol()",          ["<stdlib.h>"]),
  105     # basename - return the last component of a pathname
  106     (r"basename()",      ["<libgen.h>"]),
  107     # bcmp - memory operations
  108     (r"bcmp()",          ["<strings.h>"]),
  109     # bcopy - memory operations
  110     (r"bcopy()",         ["<strings.h>"]),
  111     # brk, sbrk - change space allocation (LEGACY)
  112     (r"brk()",           ["<unistd.h>"]),
  113     (r"sbrk()",          ["<unistd.h>"]),
  114     # bsearch - binary search a sorted table
  115     (r"bsort()",         ["<stdlib.h>"]),
  116     # btowc - single-byte to wide-character conversion
  117     (r"btowc()",         ["<stdio.h>", "<wchar.h>"]),
  118     # bzero - memory operations
  119     (r"bzero()",         ["<strings.h>"]),
  120     # calloc - a memory allocator
  121     (r"calloc()",        ["<stdlib.h>"]),
  122     # catclose - close a message catalogue descriptor
  123     (r"catclose()",      ["<nl_types.h>"]),
  124     # catgets - read a program message
  125     (r"catgets()",       ["<nl_types.h>"]),
  126     # catopen - open a message catalogue
  127     (r"catopen()",       ["<nl_types.h>"]),
  128     # cbrt - cube root function
  129     (r"cbrt()",          ["<math.h>"]),
  130     # ceil - ceiling value function
  131     (r"ceil()",          ["<math.h>"]),
  132     # chdir - change working directory
  133     (r"chdir()",         ["<unistd.h>"]),
  134     # chmod - change mode of a file
  135     (r"chmod()",         ["<sys/stat.h>", "<sys/types.h>"]),
  136     # chown - change owner and group of a file
  137     (r"chown()",         ["<sys/types.h>", "<unistd.h>"]),
  138     # chroot - change root directory (LEGACY)
  139     (r"chroot()",        ["<unistd.h>"]),
  140     # clearerr - clear indicators on a stream
  141     (r"clearerr()",      ["<stdio.h>"]),
  142     # clock - report CPU time used
  143     (r"clock()",         ["<time.h>"]),
  144     # clock_settime, clock_gettime, clock_getres - clock and timer functions
  145     (r"clock_settime()", ["<time.h>"]),
  146     (r"clock_gettime()", ["<time.h>"]),
  147     (r"clock_getres()",  ["<time.h>"]),
  148     # close - close a file descriptor
  149     (r"close()",         ["<unistd.h>"]),
  150     # closedir - close a directory stream
  151     (r"closedir()",      ["<sys/types.h>", "<dirent.h>"]),
  152     # closelog, openlog, setlogmask, syslog - control system log
  153     (r"closelog()",      ["<syslog.h>"]),
  154     (r"openlog()",       ["<syslog.h>"]),
  155     (r"setlogmask()",    ["<syslog.h>"]),
  156     (r"syslog()",        ["<syslog.h>"]),
  157     # compile - produce a compiled regular expression
  158     (r"compile()",       ["<regexp.h>"]),
  159     # confstr - get configurable variables
  160     (r"confstr()",       ["<unistd.h>"]),
  161     # cos - cosine function
  162     (r"cos()",           ["<math.h>"]),
  163     # cosh - hyperbolic cosine function
  164     (r"cosh()",          ["<math.h>"]),
  165     # creat - create a new file or rewrite an existing one
  166     (r"creat()",         ["<sys/types.h>", "<sys/stat.h>", "<fcntl.h>"]),
  167     # crypt - string encoding function
  168     (r"crypt()",         ["<unistd.h>"]),
  169     # ctermid - generate a pathname for controlling terminal
  170     (r"ctermid()",       ["<stdio.h>"]),
  171     # ctime, ctime_r - convert a time value to date and time string
  172     (r"ctime()",         ["<time.h>"]),
  173     (r"ctime_r()",       ["<time.h>"]),
  174     # ctype.h - character types
  175     (r"isalnum()",       ["<ctype.h>"]),
  176     (r"isalpha()",       ["<ctype.h>"]),
  177     (r"isascii()",       ["<ctype.h>"]),
  178     (r"iscntrl()",       ["<ctype.h>"]),
  179     (r"isdigit()",       ["<ctype.h>"]),
  180     (r"isgraph()",       ["<ctype.h>"]),
  181     (r"islower()",       ["<ctype.h>"]),
  182     (r"isprint()",       ["<ctype.h>"]),
  183     (r"ispunct()",       ["<ctype.h>"]),
  184     (r"isspace()",       ["<ctype.h>"]),
  185     (r"isupper()",       ["<ctype.h>"]),
  186     (r"isxdigit()",      ["<ctype.h>"]),
  187     (r"toascii()",       ["<ctype.h>"]),
  188     (r"tolower()",       ["<ctype.h>"]),
  189     (r"toupper()",       ["<ctype.h>"]),
  190     (r"_tolower()",      ["<ctype.h>"]),
  191     (r"_toupper()",      ["<ctype.h>"]),
  192     # cuserid - character login name of the user
  193     (r"cuserid()",       ["<stdio.h>"]),
  194     # daylight - daylight savings time flag
  195     (r"extern\s+int\s+daylight;", ["<time.h>"]),
  196     # dbm_clearerr, dbm_close, dbm_delete, dbm_error, dbm_fetch, dbm_firstkey, dbm_nextkey, dbm_open, dbm_store - database functions
  197     (r"dbm_clearerr()",  ["<ndbm.h>"]),
  198     (r"dbm_close()",     ["<ndbm.h>"]),
  199     (r"dbm_delete()",    ["<ndbm.h>"]),
  200     (r"dbm_error()",     ["<ndbm.h>"]),
  201     (r"dbm_fetch()",     ["<ndbm.h>"]),
  202     (r"dbm_firstkey()",  ["<ndbm.h>"]),
  203     (r"dbm_nextkey()",   ["<ndbm.h>"]),
  204     (r"dbm_open()",      ["<ndbm.h>"]),
  205     (r"dbm_store()",     ["<ndbm.h>"]),
  206     # difftime - compute the difference between two calendar time values
  207     (r"difftime()",      ["<time.h>"]),
  208     # dirname - report the parent directory name of a file pathname
  209     (r"dirname()",       ["<libgen.h>"]),
  210     # div - compute the quotient and remainder of an integer division
  211     (r"div()",           ["<stdio.h>"]),
  212     # dlclose - close a dlopen() object
  213     (r"dlclose()",       ["<dlfcn.h>"]),
  214     # dlerror - get diagnostic information
  215     (r"dlerror()",       ["<dlfcn.h>"]),
  216     # dlsym - obtain the address of a symbol from a dlopen() object
  217     (r"dlsym()",         ["<dlfcn.h>"]),
  218     # drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, seed48, srand48 - generate uniformly distributed pseudo-random numbers
  219     (r"drand48()",       ["<stdlib.h>"]),
  220     (r"erand48()",       ["<stdlib.h>"]),
  221     (r"jrand48()",       ["<stdlib.h>"]),
  222     (r"lcong48()",       ["<stdlib.h>"]),
  223     (r"lrand48()",       ["<stdlib.h>"]),
  224     (r"mrand48()",       ["<stdlib.h>"]),
  225     (r"nrand48()",       ["<stdlib.h>"]),
  226     (r"seed48()",        ["<stdlib.h>"]),
  227     (r"srand48()",       ["<stdlib.h>"]),
  228     # dup, dup2 - duplicate an open file descriptor
  229     (r"dup()",           ["<unistd.h>"]),
  230     (r"dup2()",          ["<unistd.h>"]),
  231     # exit, _exit - terminate a process
  232     (r"exit()",          ["<stdlib.h>"]),
  233     (r"_exit()",         ["<unistd.h>"]),
  234     # ecvt, fcvt, gcvt - convert a floating-point number to a string
  235     (r"ecvt()",          ["<stdlib.h>"]),
  236     (r"fcvt()",          ["<stdlib.h>"]),
  237     (r"gcvt()",          ["<stdlib.h>"]),
  238     # encrypt - encoding function
  239     (r"encrypt()",       ["<unistd.h>"]),
  240     # endgrent, getgrent, setgrent - group database entry functions
  241     (r"endgrent()",      ["<grp.h>"]),
  242     (r"getgrent()",      ["<grp.h>"]),
  243     (r"setgrent()",      ["<grp.h>"]),
  244     (r"getgrnam()",      ["<grp.h>"]),
  245     (r"getgrgid()",      ["<grp.h>"]),
  246     (r"getgrnam_r()",    ["<grp.h>"]),
  247     (r"getgrgid_r()",    ["<grp.h>"]),
  248     # endpwent, getpwent, setpwent - user database functions
  249     (r"endpwent()",      ["<pwd.h>"]),
  250     (r"getpwent()",      ["<pwd.h>"]),
  251     (r"setpwent()",      ["<pwd.h>"]),
  252     (r"getpwnam()",      ["<pwd.h>"]),
  253     (r"getpwuid()",      ["<pwd.h>"]),
  254     (r"getpwnam_r()",    ["<pwd.h>"]),
  255     (r"getpwuid_r()",    ["<pwd.h>"]),
  256     # endutxent, getutxent, getutxid, getutxline, pututxline, setutxent - user accounting database functions
  257     (r"endutxent()",     ["<utmpx.h>"]),
  258     (r"getutxent()",     ["<utmpx.h>"]),
  259     (r"getutxid()",      ["<utmpx.h>"]),
  260     (r"getutxline()",    ["<utmpx.h>"]),
  261     (r"pututxline()",    ["<utmpx.h>"]),
  262     (r"setutxent()",     ["<utmpx.h>"]),
  263     # erf, erfc - error and complementary error functions
  264     (r"erf()",           ["<math.h>"]),
  265     (r"erfc()",          ["<math.h>"]),
  266     # environ, execl, execv, execle, execve, execlp, execvp - execute a file
  267     (r"extern\s+char\s+\*\*environ;",         ["<unistd.h>"]),
  268     (r"execl()",         ["<unistd.h>"]),
  269     (r"execv()",         ["<unistd.h>"]),
  270     (r"execle()",        ["<unistd.h>"]),
  271     (r"execve()",        ["<unistd.h>"]),
  272     (r"execlp()",        ["<unistd.h>"]),
  273     (r"execvp()",        ["<unistd.h>"]),
  274     # exp - exponential function
  275     (r"exp()",           ["<math.h>"]),
  276     #     expm1 - compute exponential functions
  277     (r"expm1()",         ["<math.h>"]),
  278     # FD_CLR - macros for synchronous I/O multiplexing
  279     (r"FD_CLR()",        ["<sys/time.h>"]),
  280     (r"FD_ISSET()",      ["<sys/time.h>"]),
  281     (r"FD_SET()",        ["<sys/time.h>"]),
  282     (r"FD_ZERO()",       ["<sys/time.h>"]),
  283     # fabs - absolute value function
  284     (r"fabs()",          ["<math.h>"]),
  285     # fattach - attach a STREAMS-based file descriptor to a file in the file system name space
  286     (r"fattach()",       ["<stropts.h>"]),
  287     # fchdir - change working directory
  288     (r"fchdir()",        ["<unistd.h>"]),
  289     # fchmod - change mode of a file
  290     (r"fchmod()",        ["<sys/stat.h>"]),
  291     # fchown - change owner and group of a file
  292     (r"fchown()",        ["<unistd.h>"]),
  293     # fdopen - associate a stream with a file descriptor
  294     (r"fdopen()",        ["<stdio.h>"]),
  295     # fclose - close a stream
  296     (r"fclose()",        ["<stdio.h>"]),
  297     # fdatasync - synchronise the data of a file
  298     (r"fdatasync()",     ["<unistd.h>"]),
  299     # fdetach - detach a name from a STREAMS-based file descriptor
  300     (r"fdetach()",       ["<stropts.h>"]),
  301     # fdopen - associate a stream with a file descriptor
  302     (r"fdopen()",        ["<stdio.h>"]),
  303     # ferror - test error indicator on a stream
  304     (r"ferror()",        ["<stdio.h>"]),
  305     # feof - test end-of-file indicator on a stream
  306     (r"feof()",          ["<stdio.h>"]),
  307     # fflush - flush a stream
  308     (r"fflush()",        ["<stdio.h>"]),
  309     # ffs - find first set bit
  310     (r"ffs()",           ["<strings.h>"]),
  311     # fgetc - get a byte from a stream
  312     (r"fgetc()",         ["<stdio.h>"]),
  313     # fgetpos - get current file position information
  314     (r"fgetpos()",       ["<stdio.h>"]),
  315     # fgets - get a string from a stream
  316     (r"fgets()",         ["<stdio.h>"]),
  317     # fgetwc - get a wide-character code from a stream
  318     (r"fgetwc()",        ["<stdio.h>", "<wchar.h>"]),
  319     # fgetws - get a wide-character string from a stream
  320     (r"fgetws()",        ["<stdio.h>", "<wchar.h>"]),
  321     # fileno - map a stream pointer to a file descriptor
  322     (r"fileno()",        ["<stdio.h>"]),
  323     # flockfile, ftrylockfile, funlockfile - stdio locking functions
  324     (r"flockfile()",     ["<stdio.h>"]),
  325     (r"ftrylockfile()",  ["<stdio.h>"]),
  326     (r"funlockfile()",   ["<stdio.h>"]),
  327     # fmod - floating-point remainder value function
  328     (r"fmod()",          ["<math.h>"]),
  329     # fmtmsg.h - message display structures
  330     (r"fmtmsg()",        ["<fmtmsg.h>"]),
  331     # fnmatch.h - filename-matching types
  332     (r"fnmatch()",       ["<fnmatch.h>"]),
  333     # fopen - open a stream
  334     (r"fopen()",         ["<stdio.h>"]),
  335     # fork - create a new process
  336     (r"fork()",          ["<sys/types.h>", "<unistd.h>"]),
  337     # fpathconf, pathconf - get configurable pathname variables
  338     (r"fpathconf()",     ["<unistd.h>"]),
  339     (r"pathconf()",      ["<unistd.h>"]),
  340     # fputc - put a byte on a stream
  341     (r"fputc()",         ["<stdio.h>"]),
  342     # fputs - put a string on a stream
  343     (r"fputs()",         ["<stdio.h>"]),
  344     # fputwc - put a wide-character code on a stream
  345     (r"fputwc()",        ["<stdio.h>"]),
  346     # fputws - put a wide-character string on a stream
  347     (r"fputws()",        ["<stdio.h>"]),
  348     # fread - binary input
  349     (r"fread()",         ["<stdio.h>"]),
  350     # free - free allocated memory
  351     (r"free()",          ["<stdlib.h>"]),
  352     # freopen - open a stream
  353     (r"freopen()",       ["<stdio.h>"]),
  354     # frexp - extract mantissa and exponent from a double precision number
  355     (r"frexp()",         ["<math.h>"]),
  356     # fscanf, scanf, sscanf - convert formatted input
  357     (r"fscanf()",        ["<stdio.h>"]),
  358     (r"scanf()",         ["<stdio.h>"]),
  359     (r"sscanf()",        ["<stdio.h>"]),
  360     # fseek, fseeko - reposition a file-position indicator in a stream
  361     (r"fseek()",         ["<stdio.h>"]),
  362     (r"fseeko()",        ["<stdio.h>"]),
  363     # fsetpos - set current file position
  364     (r"fsetpos()",       ["<stdio.h>"]),
  365     # fstat - get file status
  366     (r"fstat()",         ["<sys/types.h>", "<sys/stat.h>"]),
  367     # fstatvfs, statvfs - get file system information
  368     (r"fstatvfs()",      ["<sys/statvfs.h>"]),
  369     (r"statvfs()",       ["<sys/statvfs.h>"]),
  370     # fsync - synchronise changes to a file
  371     (r"fsync()",         ["<unistd.h>"]),
  372     # ftell, ftello - return a file offset in a stream
  373     (r"ftell()",         ["<stdio.h>"]),
  374     (r"ftello()",        ["<stdio.h>"]),
  375     # ftime - get date and time
  376     (r"ftime()",         ["<sys/timeb.h>"]),
  377     # ftok - generate an IPC key
  378     (r"ftok()",          ["<sys/ipc.h>"]),
  379     # ftruncate, truncate - truncate a file to a specified length
  380     (r"truncate()",      ["<unistd.h>"]),
  381     (r"ftruncate()",     ["<unistd.h>"]),
  382     # ftw - traverse (walk) a file tree
  383     (r"ftw()",           ["<ftw.h>"]),
  384     (r"nftw()",          ["<ftw.h>"]),
  385     # fwide - set stream orientation
  386     (r"fwide()",         ["<stdio.h>", "<wchar.h>"]),
  387     # fwprintf, wprintf, swprintf - print formatted wide-character output
  388     (r"fwprintf()",      ["<stdio.h>", "<wchar.h>"]),
  389     (r"wprintf()",       ["<stdio.h>", "<wchar.h>"]),
  390     (r"swprintf()",      ["<stdio.h>", "<wchar.h>"]),
  391     # fwrite - binary output
  392     (r"fwrite()",        ["<stdio.h>"]),
  393     # fwscanf, wscanf, swscanf - convert formatted wide-character input
  394     (r"fwscanf()",       ["<stdio.h>", "<wchar.h>"]),
  395     (r"wscanf()",        ["<stdio.h>", "<wchar.h>"]),
  396     (r"swscanf()",       ["<stdio.h>", "<wchar.h>"]),
  397     # gamma, signgam - log gamma function
  398     (r"gamma()",         ["<math.h>"]),
  399     # getc - get a byte from a stream
  400     (r"getc()",          ["<stdio.h>"]),
  401     # getc_unlocked, getchar_unlocked, putc_unlocked, putchar_unlocked - stdio with explicit client locking
  402     (r"getc_unlocked()", ["<stdio.h>"]),
  403     (r"getchar_unlocked()", ["<stdio.h>"]),
  404     (r"putc_unlocked()",    ["<stdio.h>"]),
  405     (r"putchar_unlocked()", ["<stdio.h>"]),
  406     # getchar - get a byte from a stdin stream
  407     (r"getchar()",          ["<stdio.h>"]),
  408     # getcontext, setcontext - get and set current user context
  409     (r"getcontext()",       ["<ucontext.h>"]),
  410     (r"setcontext()",       ["<ucontext.h>"]),
  411     # getcwd - get the pathname of the current working directory
  412     (r"getcwd()",        ["<unistd.h>"]),
  413     # getdate - convert user format date and time
  414     (r"getdate()",       ["<time.h>"]),
  415     # getdtablesize - get the file descriptor table size
  416     (r"getdtablesize()", ["<unistd.h>"]),
  417     # getegid - get the effective group ID
  418     (r"getegid()",       ["<unistd.h>", "<sys/types.h>"]),
  419     # getenv - get value of an environment variable
  420     (r"getenv()",        ["<stdlib.h>"]),
  421     # geteuid - get the effective user ID
  422     (r"geteuid()",       ["<unistd.h>", "<sys/types.h>"]),
  423     # getgid - get the real group ID
  424     (r"getgid()",        ["<unistd.h>", "<sys/types.h>"]),
  425     # getgrgid, getgrgid_r - get group database entry for a group ID
  426     (r"getgrgid()",      ["<sys/types.h>", "<grp.h>"]),
  427     (r"getgrgid_r()",    ["<sys/types.h>", "<grp.h>"]),
  428     # getgrnam, getgrnam_r - search group database for a name
  429     (r"getgrnam()",      ["<sys/types.h>", "<pwd.h>"]),
  430     (r"getgrnam_r()",    ["<sys/types.h>", "<pwd.h>"]),
  431     # getgroups - get supplementary group IDs
  432     (r"getgroups()",     ["<unistd.h>", "<sys/types.h>"]),
  433     # gethostid - get an identifier for the current host
  434     (r"gethostid()",     ["<unistd.h>"]),
  435     # getitimer, setitimer - get or set value of interval timer
  436     (r"getitimer()",     ["<sys/time.h>"]),
  437     (r"setitimer()",     ["<sys/time.h>"]),
  438     # getlogin, getlogin_r - get login name
  439     (r"getlogin()",      ["<unistd.h>"]),
  440     (r"getlogin_r()",    ["<unistd.h>"]),
  441     # getmsg, getpmsg - receive next message from a STREAMS file
  442     (r"getmsg()",        ["<stropts.h>"]),
  443     (r"getpmsg()",       ["<stropts.h>"]),
  444     # getopt, optarg, optind, opterr, optopt - command option parsing
  445     (r"getopt()",        ["<unistd.h>"]),
  446     (r"extern\s+char\s+\*\*optarg;",  ["<unistd.h>"]),
  447     # getpagesize - get the current page size
  448     (r"getpagesize()",   ["<unistd.h>"]),
  449     # getpass - read a string of characters without echo
  450     (r"getpass()",       ["<unistd.h>"]),
  451     # getpgid - get the process group ID for a process
  452     (r"getpgid()",       ["<unistd.h>"]),
  453     # getpgrp - get the process group ID of the calling process
  454     (r"getpgrp()",       ["<sys/types.h>", "<unistd.h>"]),
  455     # getpid - get the process ID
  456     (r"getpid()",        ["<sys/types.h>", "<unistd.h>"]),
  457     # getppid - get the parent process ID
  458     (r"getppid()",       ["<sys/types.h>", "<unistd.h>"]),
  459     # getpriority, setpriority - get or set the nice value
  460     (r"getpriority()",   ["<sys/resource.h>"]),
  461     (r"setpriority()",   ["<sys/resource.h>"]),
  462     # getpwnam, getpwnam_r - search user database for a name
  463     (r"getpwnam()",      ["<sys/types.h>", "<pwd.h>"]),
  464     (r"getpwnam_r()",    ["<sys/types.h>", "<pwd.h>"]),
  465     # getpwuid, getpwuid_r - search user database for a user ID
  466     (r"getpwuid()",      ["<sys/types.h>", "<pwd.h>"]),
  467     (r"getpwuid_r()",    ["<sys/types.h>", "<pwd.h>"]),
  468     # getrlimit, setrlimit - control maximum resource consumption
  469     (r"getrlimit()",     ["<sys/resource.h>"]),
  470     (r"setrlimit()",     ["<sys/resource.h>"]),
  471     # getrusage - get information about resource utilisation
  472     (r"getrusage()",     ["<sys/resource.h>"]),
  473     # gets - get a string from a stdin stream
  474     (r"gets()",          ["<stdio.h>"]),
  475     # getsid - get the process group ID of session leader
  476     (r"getsid()",        ["<unistd.h>"]),
  477     # getsubopt - parse suboption arguments from a string
  478     (r"getsubopt()",     ["<stdlib.h>"]),
  479     # gettimeofday - get the date and time
  480     (r"gettimeofday()",  ["<sys/time.h>"]),
  481     # getuid - get a real user ID
  482     (r"getuid()",        ["<sys/types.h>", "<unistd.h>"]),
  483     # getw - get a word from a stream
  484     (r"getw()",          ["<stdio.h>"]),
  485     # getwc - get a wide-character code from a stream
  486     (r"getwc()",         ["<stdio.h>", "<wchar.h>"]),
  487     # getws - get a wide-character string from a stream
  488     (r"getws()",         ["<stdio.h>", "<wchar.h>"]),
  489     # getwchar - get a wide character from a stdin stream
  490     (r"getwchar()",      ["<wchar.h>"]),
  491     # getwd - get the current working directory pathname
  492     (r"getwd()",         ["<unistd.h>"]),
  493     # glob.h - pathname pattern-matching types
  494     (r"glob()",          ["<glob.h>"]),
  495     (r"globfree()",      ["<glob.h>"]),
  496     # gmtime, gmtime_r - convert a time value to a broken-down UTC time
  497     (r"gmtime()",        ["<time.h>"]),
  498     (r"gmtime_r()",      ["<time.h>"]),
  499     # grantpt - grant access to the slave pseudo-terminal device
  500     (r"grantpt()",       ["<stdlib.h>"]),
  501     # hcreate, hdestroy, hsearch - manage hash search table
  502     (r"hcreate()",       ["<search.h>"]),
  503     (r"hdestroy()",      ["<search.h>"]),
  504     (r"hsearch ()",      ["<search.h>"]),
  505     # hypot - Euclidean distance function
  506     (r"hypot()",         ["<math.h>"]),
  507     # iconv.h - codeset conversion facility
  508     (r"iconv_open()",    ["<iconv.h>"]),
  509     (r"iconv()",         ["<iconv.h>"]),
  510     (r"iconv_close()",   ["<iconv.h>"]),
  511     # ilogb - return an unbiased exponent
  512     (r"ilogb()",         ["<math.h>"]),
  513     # index - character string operations
  514     (r"index()",         ["<strings.h>"]),
  515     # initstate, random, setstate, srandom - pseudorandom number functions
  516     (r"initstate()",     ["<stdlib.h>"]),
  517     (r"random()",        ["<stdlib.h>"]),
  518     (r"setstate()",      ["<stdlib.h>"]),
  519     (r"srandom()",       ["<stdlib.h>"]),
  520     # insque, remque - insert or remove an element in a queue
  521     (r"insque()",        ["<search.h>"]),
  522     (r"remque()",        ["<search.h>"]),
  523     # SuS ioctl specifies <stropts.h>, but that's just wrong
  524     # isastream - test a file descriptor
  525     (r"isastream()",     ["<stropts.h>"]),
  526     # isnan - test for a NaN
  527     (r"isnan()",         ["<math.h>"]),
  528     # j0, j1, jn - Bessel functions of the first kind
  529     (r"j0()",            ["<math.h>"]),
  530     (r"j1()",            ["<math.h>"]),
  531     (r"jn()",            ["<math.h>"]),
  532     # labs - return a long integer absolute value
  533     (r"labs()",          ["<stdlib.h>"]),
  534     # lchown - change the owner and group of a symbolic link
  535     (r"lchown()",        ["<unistd.h>"]),
  536     # ldexp - load exponent of a floating point number
  537     (r"ldexp()",         ["<math.h>"]),
  538     # ldiv - compute quotient and remainder of a long division
  539     (r"ldiv()",          ["<stdlib.h>"]),
  540     # lgamma - log gamma function
  541     (r"lgamma()",        ["<math.h>"]),
  542     # libgen.h - definitions for pattern matching functions
  543     (r"regcmp()",        ["<libgen.h>"]),
  544     (r"regex()",         ["<libgen.h>"]),
  545     # link - link to a file
  546     (r"link()",          ["<unistd.h>"]),
  547     # localeconv - determine the program locale
  548     (r"localeconv()",    ["<locale.h>"]),
  549     # localtime, localtime_r - convert a time value to a broken-down local time
  550     (r"localtime()",     ["<time.h>"]),
  551     (r"localtime_r()",   ["<time.h>"]),
  552     # lockf - record locking on files
  553     (r"lockf()",         ["<unistd.h>"]),
  554     # log - natural logarithm function
  555     (r"log()",           ["<math.h>"]),
  556     # log10 - base 10 logarithm function
  557     (r"log10()",         ["<math.h>"]),
  558     # log1p - compute a natural logarithm
  559     (r"log1p()",         ["<math.h>"]),
  560     # logb - radix-independent exponent
  561     (r"logb()",          ["<math.h>"]),
  562     # lsearch, lfind - linear search and update
  563     (r"lfind()",         ["<search.h>"]),
  564     (r"lsearch()",       ["<search.h>"]),
  565     # lseek - move the read/write file offset
  566     (r"lseek()",         ["<sys/types.h>", "<unistd.h>"]),
  567     # lstat - get symbolic link status
  568     (r"lstat()",         ["<sys/stat.h>"]),
  569     # makecontext, swapcontext - manipulate user contexts
  570     (r"makecontext()",   ["<ucontext.h>"]),
  571     (r"swapcontext()",   ["<ucontext.h>"]),
  572     # malloc - a memory allocator
  573     (r"malloc()",        ["<stdlib.h>"]),
  574     # mblen - get number of bytes in a character
  575     (r"mblen()",         ["<stdlib.h>"]),
  576     # mbrlen - get number of bytes in a character (restartable)
  577     (r"mblren()",        ["<wchar.h>"]),
  578     # mbrtowc - convert a character to a wide-character code (restartable)
  579     (r"mbrtowc()",       ["<wchar.h>"]),
  580     # mbsinit - determine conversion object status
  581     (r"mbsinit()",       ["<wchar.h>"]),
  582     # mbsrtowcs - convert a character string to a wide-character string (restartable)
  583     (r"mbsrtowcs()",     ["<wchar.h>"]),
  584     # mbstowcs - convert a character string to a wide-character string
  585     (r"mbstowcs()",      ["<wchar.h>"]),
  586     # mbtowc - convert a character to a wide-character code
  587     (r"mbtowcs()",       ["<stdlib.h>"]),
  588     # mkdir - make a directory
  589     (r"mkdir()",         ["<sys/types.h>", "<sys/stat.h>"]),
  590     # mkfifo - make a FIFO special file
  591     (r"mkfifo()",        ["<sys/types.h>", "<sys/stat.h>"]),
  592     # mknod - make a directory, a special or regular file
  593     (r"mknod()",         ["<sys/stat.h>"]),
  594     # mkstemp - make a unique file name
  595     (r"mkstemp()",       ["<stdlib.h>"]),
  596     # mktemp - make a unique filename
  597     (r"mktemp()",        ["<stdlib.h>"]),
  598     # convert broken-down time into time since the Epoch
  599     (r"mktime()",        ["<time.h>"]),
  600     # sys/mman.h - memory management declarations
  601     (r"mlock()",         ["<sys/mman.h>"]),
  602     (r"mlockall()",      ["<sys/mman.h>"]),
  603     (r"mmap()",          ["<sys/mman.h>"]),
  604     (r"mprotect()",      ["<sys/mman.h>"]),
  605     (r"msync()",         ["<sys/mman.h>"]),
  606     (r"munlock()",       ["<sys/mman.h>"]),
  607     (r"munlockall()",    ["<sys/mman.h>"]),
  608     (r"munmap()",        ["<sys/mman.h>"]),
  609     (r"shm_open()",      ["<sys/mman.h>"]),
  610     (r"shm_unlink()",    ["<sys/mman.h>"]),
  611     # modf - decompose a floating-point number
  612     (r"modf()",          ["<math.h>"]),
  613     # monetary.h - monetary types
  614     (r"strfmon()",       ["<monetary.h>"]),
  615     # mqueue.h - message queues
  616     (r"mq_close()",      ["<mqueue.h>"]),
  617     (r"mq_getattr()",    ["<mqueue.h>"]),
  618     (r"mq_notify()",     ["<mqueue.h>"]),
  619     (r"mq_open()",       ["<mqueue.h>"]),
  620     (r"mq_receive()",    ["<mqueue.h>"]),
  621     (r"mq_send()",       ["<mqueue.h>"]),
  622     (r"mq_setattr()",    ["<mqueue.h>"]),
  623     (r"mq_unlink()",     ["<mqueue.h>"]),
  624     # sys/msg.h - message queue structures
  625     (r"msgctl()",        ["<sys/msg.h>"]),
  626     (r"msgget()",        ["<sys/msg.h>"]),
  627     (r"msgrcv()",        ["<sys/msg.h>"]),
  628     (r"msgsnd()",        ["<sys/msg.h>"]),
  629     # nanosleep - high resolution sleep
  630     (r"nanosleep()",     ["<time.h>"]),
  631     # nextafter - next representable double-precision floating-point number
  632     (r"nextafter()",     ["<math.h>"]),
  633     # change nice value of a process
  634     (r"nice()",          ["<unistd.h>"]),
  635     # nl_langinfo - language information
  636     (r"nl_langinfo()",   ["<langinfo.h>"]),
  637     # open - open a file
  638     (r"open()",          ["<sys/types.h>", "<sys/stat.h>", "<fcntl.h>"]),
  639     # opendir - open a directory
  640     (r"opendir()",       ["<sys/types.h>", "<dirent.h>"]),
  641     # pause - suspend the thread until signal is received
  642     (r"pause()",         ["<unistd.h>"]),
  643     # pclose - close a pipe stream to or from a process
  644     (r"pclose()",        ["<stdio.h>"]),
  645     # perror - write error messages to standard error
  646     (r"perror()",        ["<stdio.h>"]),
  647     # pipe - create an interprocess channel
  648     (r"pipe()",          ["<unistd.h>"]),
  649     # poll - input/output multiplexing
  650     (r"poll()",          ["<poll.h>"]),
  651     # popen - initiate pipe streams to or from a process
  652     (r"popen()",         ["<stdio.h>"]),
  653     # pow - power function
  654     (r"pow()",           ["<math.h>"]),
  655     # pread - read from a file
  656     ("pread()",          ["<unistd.h>"]),
  657     # pthread.h - threads
  658     (r"pthread_attr_destroy()",            ["<pthread.h>"]),
  659     (r"pthread_attr_getdetachstate()",     ["<pthread.h>"]),
  660     (r"pthread_attr_getguardsize()",       ["<pthread.h>"]),
  661     (r"pthread_attr_getinheritsched()",    ["<pthread.h>"]),
  662     (r"pthread_attr_getschedparam()",      ["<pthread.h>"]),
  663     (r"pthread_attr_getschedpolicy()",     ["<pthread.h>"]),
  664     (r"pthread_attr_getscope()",           ["<pthread.h>"]),
  665     (r"pthread_attr_getstackaddr()",       ["<pthread.h>"]),
  666     (r"pthread_attr_getstacksize()",       ["<pthread.h>"]),
  667     (r"pthread_attr_init()",               ["<pthread.h>"]),
  668     (r"pthread_attr_setdetachstate()",     ["<pthread.h>"]),
  669     (r"pthread_attr_setguardsize()",       ["<pthread.h>"]),
  670     (r"pthread_attr_setinheritsched()",    ["<pthread.h>"]),
  671     (r"pthread_attr_setschedparam()",      ["<pthread.h>"]),
  672     (r"pthread_attr_setschedpolicy()",     ["<pthread.h>"]),
  673     (r"pthread_attr_setscope()",           ["<pthread.h>"]),
  674     (r"pthread_attr_setstackaddr()",       ["<pthread.h>"]),
  675     (r"pthread_attr_setstacksize()",       ["<pthread.h>"]),
  676     (r"pthread_cancel()",                  ["<pthread.h>"]),
  677     (r"pthread_cleanup_push()",            ["<pthread.h>"]),
  678     (r"pthread_cleanup_pop()",             ["<pthread.h>"]),
  679     (r"pthread_cond_broadcast()",          ["<pthread.h>"]),
  680     (r"pthread_cond_destroy()",            ["<pthread.h>"]),
  681     (r"pthread_cond_init()",               ["<pthread.h>"]),
  682     (r"pthread_cond_signal()",             ["<pthread.h>"]),
  683     (r"pthread_cond_timedwait()",          ["<pthread.h>"]),
  684     (r"pthread_cond_wait()",               ["<pthread.h>"]),
  685     (r"pthread_condattr_destroy()",        ["<pthread.h>"]),
  686     (r"pthread_condattr_getpshared()",     ["<pthread.h>"]),
  687     (r"pthread_condattr_init()",           ["<pthread.h>"]),
  688     (r"pthread_condattr_setpshared()",     ["<pthread.h>"]),
  689     (r"pthread_create()",                  ["<pthread.h>"]),
  690     (r"pthread_detach()",                  ["<pthread.h>"]),
  691     (r"pthread_equal()",                   ["<pthread.h>"]),
  692     (r"pthread_exit()",                    ["<pthread.h>"]),
  693     (r"pthread_getconcurrency()",          ["<pthread.h>"]),
  694     (r"pthread_getschedparam()",           ["<pthread.h>"]),
  695     (r"pthread_getspecific()",             ["<pthread.h>"]),
  696     (r"pthread_join()",                    ["<pthread.h>"]),
  697     (r"pthread_key_create()",              ["<pthread.h>"]),
  698     (r"pthread_key_delete()",              ["<pthread.h>"]),
  699     (r"pthread_mutex_destroy()",           ["<pthread.h>"]),
  700     (r"pthread_mutex_getprioceiling()",    ["<pthread.h>"]),
  701     (r"pthread_mutex_init()",              ["<pthread.h>"]),
  702     (r"pthread_mutex_lock()",              ["<pthread.h>"]),
  703     (r"pthread_mutex_setprioceiling()",    ["<pthread.h>"]),
  704     (r"pthread_mutex_trylock()",           ["<pthread.h>"]),
  705     (r"pthread_mutex_unlock()",            ["<pthread.h>"]),
  706     (r"pthread_mutexattr_destroy()",       ["<pthread.h>"]),
  707     (r"pthread_mutexattr_getprioceiling()",["<pthread.h>"]),
  708     (r"pthread_mutexattr_getprotocol()",   ["<pthread.h>"]),
  709     (r"pthread_mutexattr_getpshared()",    ["<pthread.h>"]),
  710     (r"pthread_mutexattr_gettype()",       ["<pthread.h>"]),
  711     (r"pthread_mutexattr_init()",          ["<pthread.h>"]),
  712     (r"pthread_mutexattr_setprioceiling()",["<pthread.h>"]),
  713     (r"pthread_mutexattr_setprotocol()",   ["<pthread.h>"]),
  714     (r"pthread_mutexattr_setpshared()",    ["<pthread.h>"]),
  715     (r"pthread_mutexattr_settype()",       ["<pthread.h>"]),
  716     (r"pthread_once()",                    ["<pthread.h>"]),
  717     (r"pthread_rwlock_destroy()",          ["<pthread.h>"]),
  718     (r"pthread_rwlock_init()",             ["<pthread.h>"]),
  719     (r"pthread_rwlock_rdlock()",           ["<pthread.h>"]),
  720     (r"pthread_rwlock_tryrdlock()",        ["<pthread.h>"]),
  721     (r"pthread_rwlock_trywrlock()",        ["<pthread.h>"]),
  722     (r"pthread_rwlock_unlock()",           ["<pthread.h>"]),
  723     (r"pthread_rwlock_wrlock()",           ["<pthread.h>"]),
  724     (r"pthread_rwlockattr_destroy()",      ["<pthread.h>"]),
  725     (r"pthread_rwlockattr_getpshared()",   ["<pthread.h>"]),
  726     (r"pthread_rwlockattr_init()",         ["<pthread.h>"]),
  727     (r"pthread_rwlockattr_setpshared()",   ["<pthread.h>"]),
  728     (r"pthread_self()",                    ["<pthread.h>"]),
  729     (r"pthread_setcancelstate()",          ["<pthread.h>"]),
  730     (r"pthread_setcanceltype()",           ["<pthread.h>"]),
  731     (r"pthread_setconcurrency()",          ["<pthread.h>"]),
  732     (r"pthread_setschedparam()",           ["<pthread.h>"]),
  733     (r"pthread_setspecific()",             ["<pthread.h>"]),
  734     (r"pthread_testcancel()",              ["<pthread.h>"]),
  735     # ptsname - get name of the slave pseudo-terminal device
  736     (r"ptsname()",       ["<stdlib.h>"]),
  737     # putc - put a byte on a stream
  738     (r"putc()",          ["<stdio.h>"]),
  739     # putc_unlocked - stdio with explicit client locking
  740     (r"putc_unlocked()", ["<stdio.h>"]),
  741     # putchar - put byte on stdout stream
  742     (r"putchar()",       ["<stdio.h>"]),
  743     # putchar_unlocked - stdio with explicit client locking
  744     (r"putchar_unlocked()",                ["<stdio.h>"]),
  745     # putenv - change or add a value to environment
  746     (r"putenv()",        ["<stdlib.h>"]),
  747     # putmsg, putpmsg - send a message on a STREAM
  748     (r"putmsg()",        ["<stropts.h>"]),
  749     (r"putpmsg()",       ["<stropts.h>"]),
  750     # puts - put a string on standard output
  751     (r"puts()",          ["<stdio.h>"]),
  752     # putw - put a word on a stream
  753     (r"putw()",          ["<stdio.h>"]),
  754     # putwc - put a wide-character on a stream
  755     (r"putwc()",         ["<stdio.h>", "<wchar.h>"]),
  756     # putwchar - put a wide character from a stdin stream
  757     (r"putwchar()",      ["<wchar.h>"]),
  758     # qsort - sort a table of data
  759     (r"qsort()",         ["<stdlib.h>"]),
  760     # raise - send a signal to the executing process
  761     (r"raise()",         ["<signal.h>"]),
  762     # rand, rand_r - pseudo-random number generator
  763     (r"rand()",          ["<stdlib.h>"]),
  764     (r"srand()",         ["<stdlib.h>"]),
  765     (r"rand_r()",        ["<stdlib.h>"]),
  766     # random - generate pseudorandom number
  767     (r"random()",        ["<stdlib.h>"]),
  768     # re_comp.h - regular-expression-matching functions for re_comp()
  769     (r"re_comp()",       ["<re_comp.h>"]),
  770     (r"re_exec()",       ["<re_comp.h>"]),
  771     # read, readv, pread - read from a file
  772     ("read()",           ["<unistd.h>"]),
  773     ("readv()",          ["<sys/uio.h>"]),
  774     # readdir, readdir_r - read directory
  775     (r"readdir()",       ["<sys/types.h>", "<dirent.h>"]),
  776     (r"readdir_r()",     ["<sys/types.h>", "<dirent.h>"]),
  777     # readlink - read the contents of a symbolic link
  778     ("readlink()",       ["<unistd.h>"]),
  779     # realloc - memory reallocator
  780     ("realloc()",        ["<unistd.h>"]),
  781     # realpath - resolve a pathname
  782     ("realpath()",       ["<stdlib.h>"]),
  783     # regcomp, regexec, regerror, regfree - regular expression matching
  784     (r"regcomp()",       ["<sys/types.h>", "<regex.h>"]),
  785     (r"regexec()",       ["<sys/types.h>", "<regex.h>"]),
  786     (r"regerror()",      ["<sys/types.h>", "<regex.h>"]),
  787     (r"regfree()",       ["<sys/types.h>", "<regex.h>"]),
  788     # remainder - remainder function
  789     (r"remainder()",     ["<math.h>"]),
  790     # remove - remove files
  791     (r"remove()",        ["<stdio.h>"]),
  792     # rename - rename a file
  793     (r"rename()",        ["<stdio.h>"]),
  794     # rewind - reset file position indicator in a stream
  795     (r"rewind()",        ["<stdio.h>"]),
  796     # rewinddir - reset position of directory stream to the beginning of a directory
  797     (r"rewinddir()",     ["<sys/types.h>", "<dirent.h>"]),
  798     # rindex - character string operations
  799     (r"rindex()",        ["<strings.h>"]),
  800     # rint - round-to-nearest integral value
  801     (r"rint()",          ["<math.h>"]),
  802     # rmdir - remove a directory
  803     ("rmdir()",          ["<unistd.h>"]),
  804     # scalb - load exponent of a radix-independent floating-point number
  805     (r"scalb()",         ["<math.h>"]),
  806     # scanf - convert formatted input
  807     (r"scanf()",        ["<stdio.h>"]),
  808     # sched.h - execution scheduling
  809     (r"sched_get_priority_max()",      ["<sched.h>"]),
  810     (r"sched_get_priority_min()",      ["<sched.h>"]),
  811     (r"sched_getparam()",              ["<sched.h>"]),
  812     (r"sched_getscheduler()",          ["<sched.h>"]),
  813     (r"sched_rr_get_interval()",       ["<sched.h>"]),
  814     (r"sched_setparam()",              ["<sched.h>"]),
  815     (r"sched_setscheduler()",          ["<sched.h>"]),
  816     (r"sched_yield()",                 ["<sched.h>"]),
  817     # seekdir - set position of directory stream
  818     (r"seekdir()",       ["<sys/types.h>", "<dirent.h>"]),
  819     # select - synchronous I/O multiplexing
  820     (r"select()",        ["<sys/time.h>"]),
  821     # semaphore.h - semaphores
  822     (r"sem_close()",     ["<semaphore.h>"]),
  823     (r"sem_destroy()",   ["<semaphore.h>"]),
  824     (r"sem_getvalue()",  ["<semaphore.h>"]),
  825     (r"sem_init()",      ["<semaphore.h>"]),
  826     (r"sem_open()",      ["<semaphore.h>"]),
  827     (r"sem_post()",      ["<semaphore.h>"]),
  828     (r"sem_trywait()",   ["<semaphore.h>"]),
  829     (r"sem_unlink()",    ["<semaphore.h>"]),
  830     (r"sem_wait()",      ["<semaphore.h>"]),
  831     # sys/sem.h - semaphore facility
  832     (r"semctl()",        ["<sys/sem.h>"]),
  833     (r"semget()",        ["<sys/sem.h>"]),
  834     (r"semop()",         ["<sys/sem.h>"]),
  835     # setbuf - assign buffering to a stream
  836     (r"setbuf()",        ["<stdio.h>"]),
  837     # setgid - set-group-ID
  838     (r"setgid()",        ["<sys/types.h>", "<unistd.h>"]),
  839     # setgrent - reset group database to first entry
  840     (r"setgrent()",      ["<grp.h>"]),
  841     # setkey - set encoding key
  842     (r"setkey()",        ["<stdlib.h>"]),
  843     # setpgid - set process group ID for job control
  844     (r"setpgid()",       ["<sys/types.h>", "<unistd.h>"]),
  845     # setpgrp - set process group ID
  846     (r"setpgrp()",       ["<unistd.h>"]),
  847     # setregid - set real and effective group IDs
  848     (r"setregid()",      ["<unistd.h>"]),
  849     # setreuid - set real and effective user IDs
  850     (r"setreuid()",      ["<unistd.h>"]),
  851     # setsid - create session and set process group ID
  852     (r"setsid()",        ["<sys/types.h>", "<unistd.h>"]),
  853     # setuid - set-user-ID
  854     (r"setuid()",        ["<sys/types.h>", "<unistd.h>"]),
  855     # setvbuf - assign buffering to a stream
  856     (r"setvbuf()",       ["<stdio.h>"]),
  857     # sys/shm.h - shared memory facility
  858     (r"shmat()",         ["<sys/shm.h>"]),
  859     (r"shmctl()",        ["<sys/shm.h>"]),
  860     (r"shmdt()",         ["<sys/shm.h>"]),
  861     (r"shmget()",        ["<sys/shm.h>"]),
  862     # setjmp.h - stack environment declarations
  863     (r"longjmp()",       ["<setjmp.h>"]),
  864     (r"siglongjmp()",    ["<setjmp.h>"]),
  865     (r"_longjmp()",      ["<setjmp.h>"]),
  866     (r"setjmp()",        ["<setjmp.h>"]),
  867     (r"sigsetjmp()",     ["<setjmp.h>"]),
  868     (r"_setjmp()",       ["<setjmp.h>"]),
  869     # signal.h - signals
  870     (r"bsd_signal()",    ["<signal.h>"]),
  871     (r"kill()",          ["<signal.h>"]),
  872     (r"killpg()",        ["<signal.h>"]),
  873     (r"pthread_kill()",  ["<signal.h>"]),
  874     (r"pthread_sigmask()",    ["<signal.h>"]),
  875     (r"raise()",         ["<signal.h>"]),
  876     (r"sigaction()",     ["<signal.h>"]),
  877     (r"sigaddset()",     ["<signal.h>"]),
  878     (r"sigaltstack()",   ["<signal.h>"]),
  879     (r"sigdelset()",     ["<signal.h>"]),
  880     (r"sigemptyset()",   ["<signal.h>"]),
  881     (r"sigfillset()",    ["<signal.h>"]),
  882     (r"sighold()",       ["<signal.h>"]),
  883     (r"sigignore()",     ["<signal.h>"]),
  884     (r"siginterrupt()",  ["<signal.h>"]),
  885     (r"sigismember()",   ["<signal.h>"]),
  886     (r"signal()",        ["<signal.h>"]),
  887     (r"sigpause()",      ["<signal.h>"]),
  888     (r"sigpending()",    ["<signal.h>"]),
  889     (r"sigprocmask()",   ["<signal.h>"]),
  890     (r"sigqueue()",      ["<signal.h>"]),
  891     (r"sigrelse()",      ["<signal.h>"]),
  892     (r"sigset()",        ["<signal.h>"]),
  893     (r"sigstack()",      ["<signal.h>"]),
  894     (r"sigsuspend()",    ["<signal.h>"]),
  895     (r"sigtimedwait()",  ["<signal.h>"]),
  896     (r"sigwait()",       ["<signal.h>"]),
  897     (r"sigwaitinfo()",   ["<signal.h>"]),
  898     # sin - sine function
  899     (r"sin()",           ["<math.h>"]),
  900     # sinh - hyperbolic sine function
  901     (r"sinh()",          ["<math.h>"]),
  902     # sleep - suspend execution for an interval of time
  903     (r"sleep()",         ["<unistd.h>"]),
  904     # fprintf, printf, snprintf, sprintf - print formatted output
  905     (r"fprintf()",       ["<stdio.h>"]),
  906     (r"printf()",        ["<stdio.h>"]),
  907     (r"snprintf()",      ["<stdio.h>"]),
  908     (r"sprintf()",       ["<stdio.h>"]),
  909     # sqrt - square root function
  910     (r"sqrt()",          ["<math.h>"]),
  911     # stat - get file status
  912     (r"stat()",          ["<sys/types.h>", "<sys/stat.h>"]),
  913     # stdarg.h - handle variable argument list
  914     (r"va_start()",      ["<stdarg.h>"]),
  915     (r"va_arg()",        ["<stdarg.h>"]),
  916     (r"va_end()",        ["<stdarg.h>"]),
  917     # stddef.h - standard type definitions
  918     (r"offsetof()",      ["<stddef.h>"]),
  919     # step - pattern match with regular expressions
  920     (r"step()",          ["<regexp.h>"]),
  921     # strcasecmp, strncasecmp - case-insensitive string comparisons
  922     (r"strcasecmp()",    ["<strings.h>"]),
  923     (r"strncasecmp()",   ["<strings.h>"]),
  924     # string.h - string operations
  925     (r"memccpy()",       ["<string.h>"]),
  926     (r"memchr()",        ["<string.h>"]),
  927     (r"memcmp()",        ["<string.h>"]),
  928     (r"memcpy()",        ["<string.h>"]),
  929     (r"memmove()",       ["<string.h>"]),
  930     (r"memset()",        ["<string.h>"]),
  931     (r"strcat()",        ["<string.h>"]),
  932     (r"strchr()",        ["<string.h>"]),
  933     (r"strcmp()",        ["<string.h>"]),
  934     (r"strcoll()",       ["<string.h>"]),
  935     (r"strcpy()",        ["<string.h>"]),
  936     (r"strcspn()",       ["<string.h>"]),
  937     (r"strdup()",        ["<string.h>"]),
  938     (r"strerror()",      ["<string.h>"]),
  939     (r"strlen()",        ["<string.h>"]),
  940     (r"strncat()",       ["<string.h>"]),
  941     (r"strncmp()",       ["<string.h>"]),
  942     (r"strncpy()",       ["<string.h>"]),
  943     (r"strpbrk()",       ["<string.h>"]),
  944     (r"strrchr()",       ["<string.h>"]),
  945     (r"strspn()",        ["<string.h>"]),
  946     (r"strstr()",        ["<string.h>"]),
  947     (r"strtok()",        ["<string.h>"]),
  948     (r"strtok_r()",      ["<string.h>"]),
  949     (r"strxfrm()",       ["<string.h>"]),
  950     # wctype.h - wide-character classification and mapping utilities
  951     (r"iswalnum()",      ["<wctype.h>"]),
  952     (r"iswalpha()",      ["<wctype.h>"]),
  953     (r"iswascii()",      ["<wctype.h>"]),
  954     (r"iswcntrl()",      ["<wctype.h>"]),
  955     (r"iswdigit()",      ["<wctype.h>"]),
  956     (r"iswgraph()",      ["<wctype.h>"]),
  957     (r"iswlower()",      ["<wctype.h>"]),
  958     (r"iswprint()",      ["<wctype.h>"]),
  959     (r"iswpunct()",      ["<wctype.h>"]),
  960     (r"iswspace()",      ["<wctype.h>"]),
  961     (r"iswupper()",      ["<wctype.h>"]),
  962     (r"iswxdigit()",     ["<wctype.h>"]),
  963     (r"iswctype()",      ["<wctype.h>"]),
  964     (r"towctrans()",     ["<wctype.h>"]),
  965     (r"towlower()",      ["<wctype.h>"]),
  966     (r"towupper()",      ["<wctype.h>"]),
  967     (r"wctrans()",       ["<wctype.h>"]),
  968     (r"wctype()",        ["<wctype.h>"]),
  969     # strftime - convert date and time to a string
  970     (r"strftime()",      ["<time.h>"]),
  971     # strptime - date and time conversion
  972     (r"strptime()",      ["<time.h>"]),
  973     # strtod - convert string to a double-precision number
  974     (r"strtod()",        ["<stdlib.h>"]),
  975     # strtol - convert string to a long integer
  976     (r"strtol()",        ["<stdlib.h>"]),
  977     # strtoul - convert string to an unsigned long
  978     (r"strtoul()",       ["<stdlib.h>"]),
  979     # strtoull - convert string to an unsigned long qlong
  980     (r"strtoull()",       ["<stdlib.h>"]),
  981     # swab - swap bytes
  982     (r"swab()",          ["<stdlib.h>"]),
  983     # symlink - make symbolic link to a file
  984     (r"symlink()",       ["<stdlib.h>"]),
  985     # sync - schedule filesystem updates
  986     (r"sync()",          ["<stdlib.h>"]),
  987     # sysconf - get configurable system variables
  988     (r"sysconf()",       ["<unistd.h>"]),
  989     # system - issue a command
  990     (r"system()",        ["<stdlib.h>"]),
  991     # sys/wait.h - declarations for waiting
  992     (r"wait()",          ["<sys/types.h>", "<sys/wait.h>"]),
  993     (r"wait3()",         ["<sys/types.h>", "<sys/wait.h>"]),
  994     (r"waitid()",        ["<sys/types.h>", "<sys/wait.h>"]),
  995     (r"waitpid()",       ["<sys/types.h>", "<sys/wait.h>"]),
  996     (r"WEXITSTATUS()",   ["<sys/types.h>", "<sys/wait.h>"]),
  997     (r"WIFCONTINUED()",  ["<sys/types.h>", "<sys/wait.h>"]),
  998     (r"WIFEXITED()",     ["<sys/types.h>", "<sys/wait.h>"]),
  999     (r"WIFSIGNALED()",   ["<sys/types.h>", "<sys/wait.h>"]),
 1000     (r"WIFSTOPPED()",    ["<sys/types.h>", "<sys/wait.h>"]),
 1001     (r"WSTOPSIG()",      ["<sys/types.h>", "<sys/wait.h>"]),
 1002     (r"WTERMSIG()",      ["<sys/types.h>", "<sys/wait.h>"]),
 1003     # tan - tangent function
 1004     (r"tan()",           ["<math.h>"]),
 1005     # tanh - hyperbolic tangent function
 1006     (r"tanh()",          ["<math.h>"]),
 1007     # tcgetpgrp - get the foreground process group ID
 1008     (r"tcgetpgrp()",     ["<sys/types.h>", "<unistd.h>"]),
 1009     # tcsetpgrp - set the foreground process group ID
 1010     (r"tcsetpgrp()",     ["<sys/types.h>", "<unistd.h>"]),
 1011     # tdelete - delete node from binary search tree
 1012     (r"tdelete()",       ["<search.h>"]),
 1013     # telldir - current location of a named directory stream
 1014     (r"telldir()",       ["<dirent.h>"]),
 1015     # tempnam - create a name for a temporary file
 1016     (r"tempnam()",       ["<stdio.h>"]),
 1017     # termios.h - define values for termios
 1018     (r"cfgetispeed()",   ["<termios.h>"]),
 1019     (r"cfgetospeed()",   ["<termios.h>"]),
 1020     (r"cfsetispeed()",   ["<termios.h>"]),
 1021     (r"cfsetospeed()",   ["<termios.h>"]),
 1022     (r"tcdrain()",       ["<termios.h>"]),
 1023     (r"tcflow()",        ["<termios.h>"]),
 1024     (r"tcflush()",       ["<termios.h>"]),
 1025     (r"tcgetattr()",     ["<termios.h>"]),
 1026     (r"tcgetsid()",      ["<termios.h>"]),
 1027     (r"tcsendbreak()",   ["<termios.h>"]),
 1028     (r"tcsetattr()",     ["<termios.h>"]),
 1029     # tdelete, tfind, tsearch, twalk - manage a binary search tree
 1030     (r"tsearch()",       ["<termios.h>"]),
 1031     (r"tfind()",         ["<termios.h>"]),
 1032     (r"tdelete()",       ["<termios.h>"]),
 1033     (r"twalk()",         ["<termios.h>"]),
 1034     # time - get time
 1035     (r"time()",          ["<time.h>"]),
 1036     # timer_create - create a per-process timer
 1037     (r"timer_create()",  ["<time.h>", "<signal.h>"]),
 1038     # timer_delete - delete a per-process timer
 1039     (r"timer_delete()",  ["<time.h>", "<signal.h>"]),
 1040     # timer_settime, timer_gettime, timer_getoverrun - per-process timers
 1041     (r"timer_settime()",      ["<time.h>"]),
 1042     (r"timer_gettime()",      ["<time.h>"]),
 1043     (r"timer_getoverrun()",   ["<time.h>"]),
 1044     # times - get process and waited-for child process times
 1045     (r"times()",         ["<sys/time.h>"]),
 1046     # tmpfile - create a temporary file
 1047     (r"tmpfile()",       ["<stdio.h>"]),
 1048     # tmpnam - create a name for a temporary file
 1049     (r"tmpnam()",        ["<stdio.h>"]),
 1050     # truncate - truncate a file to a specified length
 1051     (r"truncate()",      ["<stdio.h>"]),
 1052     # ttyname, ttyname_r - find pathname of a terminal
 1053     ("ttyname()",        ["<unistd.h>"]),
 1054     ("ttyname_r()",      ["<unistd.h>"]),
 1055     # ttyslot - find the slot of the current user in the user accounting database
 1056     ("ttyslot()",        ["<unistd.h>"]),
 1057     # tzset - set time zone conversion information
 1058     ("tzset()",          ["<time.h>"]),
 1059     # ualarm - set the interval timer
 1060     ("ualarm()",         ["<unistd.h>"]),
 1061     # ulimit - get and set process limits
 1062     ("ulimit()",         ["<ulimit.h>"]),
 1063     # umask - set and get file mode creation mask
 1064     (r"umask()",         ["<sys/stat.h>", "<sys/types.h>"]),
 1065     # uname - get name of current system
 1066     ("uname()",          ["<sys/utsname.h>"]),
 1067     # ungetc - push byte back into input stream
 1068     (r"ungetc()",        ["<stdio.h>"]),
 1069     # ungetwc - push wide-character code back into input stream
 1070     (r"ungetwc()",       ["<stdio.h>", "<wchar.h>"]),
 1071     # unlink - remove a directory entry
 1072     ("unlink()",         ["<unistd.h>"]),
 1073     # unlockpt - unlock a pseudo-terminal master/slave pair
 1074     (r"unlockpt()",      ["<stdlib.h>"]),
 1075     # usleep - suspend execution for an interval
 1076     ("usleep()",         ["<unistd.h>"]),
 1077     # utime - set file access and modification times
 1078     (r"utime()",         ["<sys/types.h>", "<utime.h>"]),
 1079     # utimes - set file access and modification times
 1080     (r"utimes()",        ["<sys/time.h>"]),
 1081     # valloc - page-aligned memory allocator
 1082     (r"valloc()",        ["<stdlib.h>"]),
 1083     # vfork - create new process; share virtual memory
 1084     ("vfork()",          ["<unistd.h>"]),
 1085     # vfprintf, vprintf, vsnprintf, vsprintf - format output of a stdarg argument list
 1086     (r"vfprintf()",      ["<stdarg.h>", "<stdio.h>"]),
 1087     (r"vprintf()",       ["<stdarg.h>", "<stdio.h>"]),
 1088     (r"vsnprintf()",     ["<stdarg.h>", "<stdio.h>"]),
 1089     (r"vsprintf()",      ["<stdarg.h>", "<stdio.h>"]),
 1090     # vfwprintf, vwprintf, vswprintf - wide-character formatted output of a stdarg argument list
 1091     (r"vwprintf()",      ["<stdarg.h>", "<stdio.h>", "<wchar.h>"]),
 1092     (r"vfwprintf()",     ["<stdarg.h>", "<stdio.h>", "<wchar.h>"]),
 1093     (r"vswprintf()",     ["<stdarg.h>", "<stdio.h>", "<wchar.h>"]),
 1094     # wchar.h - wide-character types
 1095     (r"wcrtomb()",       ["<wchar.h>"]),   # SuSv2 erroneously says <stdio.h>
 1096     (r"wcscat()",        ["<wchar.h>"]),
 1097     (r"wcschr()",        ["<wchar.h>"]),
 1098     (r"wcscmp()",        ["<wchar.h>"]),
 1099     (r"wcscoll()",       ["<wchar.h>"]),
 1100     (r"wcscpy()",        ["<wchar.h>"]),
 1101     (r"wcscpy()",        ["<wchar.h>"]),
 1102     (r"wcsftime()",      ["<wchar.h>"]),
 1103     (r"wcslen()",        ["<wchar.h>"]),
 1104     (r"wcsncat()",       ["<wchar.h>"]),
 1105     (r"wcsncmp()",       ["<wchar.h>"]),
 1106     (r"wcsncpy()",       ["<wchar.h>"]),
 1107     (r"wcspbrk()",       ["<wchar.h>"]),
 1108     (r"wcsrchr()",       ["<wchar.h>"]),
 1109     (r"wcsrtombs()",     ["<wchar.h>"]),
 1110     (r"wcsspn()",        ["<wchar.h>"]),
 1111     (r"wcsstr()",        ["<wchar.h>"]),
 1112     (r"wcstod()",        ["<wchar.h>"]),
 1113     (r"wcstok()",        ["<wchar.h>"]),
 1114     (r"wcstol()",        ["<wchar.h>"]),
 1115     (r"wcstoul()",       ["<wchar.h>"]),
 1116     (r"wcswcs()",        ["<wchar.h>"]),
 1117     (r"wcswidth()",      ["<wchar.h>"]),
 1118     (r"wcsxfrm()",       ["<wchar.h>"]),
 1119     (r"wctob()",         ["<wchar.h>"]),
 1120     (r"wctype()",        ["<wchar.h>"]),
 1121     (r"wcwidth()",       ["<wchar.h>"]),
 1122     (r"wmemchr()",       ["<wchar.h>"]),
 1123     (r"wmemcmp()",       ["<wchar.h>"]),
 1124     (r"wmemcpy()",       ["<wchar.h>"]),
 1125     (r"wmemmove()",      ["<wchar.h>"]),
 1126     (r"wmemset()",       ["<wchar.h>"]),
 1127     (r"wprintf()",       ["<wchar.h>"]),
 1128     (r"wscanf()",        ["<wchar.h>"]),
 1129     # wordexp.h - word-expansion types
 1130     (r"wordexp()",       ["<wordexp.h>"]),
 1131     (r"wordfree()",      ["<wordexp.h>"]),
 1132     # write, writev, pwrite - write on a file
 1133     (r"write()",         ["<unistd.h>"]),
 1134     (r"pwrite()",        ["<unistd.h>"]),
 1135     (r"writev()",        ["<sys/uio.h>"]),
 1136     # y0, y1, yn - Bessel functions of the second kind
 1137     (r"y0()",            ["<math.h>"]),
 1138     (r"y1()",            ["<math.h>"]),
 1139     (r"yn()",            ["<math.h>"]),
 1140     # stdbool.h - standard boolean type
 1141     (r"=\s*true",          ["<stdbool.h>"]),
 1142     (r"=\s*false",         ["<stdbool.h>"]),
 1143 
 1144     # Headers mandated by SuS Version 2 Network Services.
 1145     # sys/socket.h - Internet Protocol family
 1146     (r"accept()",        ["<sys/socket.h>"]),
 1147     (r"bind()",          ["<sys/socket.h>"]),
 1148     (r"connect()",       ["<sys/socket.h>"]),
 1149     (r"getpeername()",   ["<sys/socket.h>"]),
 1150     (r"getsockname()",   ["<sys/socket.h>"]),
 1151     (r"getsockopt()",    ["<sys/socket.h>"]),
 1152     (r"listen()",        ["<sys/socket.h>"]),
 1153     (r"recv()",          ["<sys/socket.h>"]),
 1154     (r"recvfrom()",      ["<sys/socket.h>"]),
 1155     (r"recvmsg()",       ["<sys/socket.h>"]),
 1156     (r"send()",          ["<sys/socket.h>"]),
 1157     (r"sendmsg()",       ["<sys/socket.h>"]),
 1158     (r"sendto()",        ["<sys/socket.h>"]),
 1159     (r"setsockopt()",    ["<sys/socket.h>"]),
 1160     (r"shutdown()",      ["<sys/socket.h>"]),
 1161     (r"socket()",        ["<sys/socket.h>"]),
 1162     (r"socketpair()",    ["<sys/socket.h>"]),
 1163     # arpa/inet.h - definitions for internet operations
 1164     (r"inet_addr()",     ["<arpa/inet.h>"]),
 1165     (r"inet_lnaof()",    ["<arpa/inet.h>"]),
 1166     (r"inet_makeaddr()", ["<arpa/inet.h>"]),
 1167     (r"inet_netof()",    ["<arpa/inet.h>"]),
 1168     (r"inet_network()",  ["<arpa/inet.h>"]),
 1169     (r"inet_ntoa()",     ["<arpa/inet.h>"]),
 1170     (r"htonl()",         ["<arpa/inet.h>"]),
 1171     (r"htons()",         ["<arpa/inet.h>"]),
 1172     (r"ntohl()",         ["<arpa/inet.h>"]),
 1173     (r"ntohs()",         ["<arpa/inet.h>"]),
 1174     # netdb.h - definitions for network database operations
 1175     (r"endhostent()",      ["<netdb.h>"]),
 1176     (r"endnetent()",       ["<netdb.h>"]),
 1177     (r"endprotoent()",     ["<netdb.h>"]),
 1178     (r"endservent()",      ["<netdb.h>"]),
 1179     (r"gethostbyaddr()",   ["<netdb.h>"]),
 1180     (r"gethostbyname()",   ["<netdb.h>"]),
 1181     (r"gethostent()",      ["<netdb.h>"]),
 1182     (r"getnetbyaddr()",    ["<netdb.h>"]),
 1183     (r"getnetbyname()",    ["<netdb.h>"]),
 1184     (r"getnetent()",       ["<netdb.h>"]),
 1185     (r"getprotobyname()",  ["<netdb.h>"]),
 1186     (r"getprotobynumber()",["<netdb.h>"]),
 1187     (r"getprotoent()",     ["<netdb.h>"]),
 1188     (r"getservbyname()",   ["<netdb.h>"]),
 1189     (r"getservbyport()",   ["<netdb.h>"]),
 1190     (r"getservent()",      ["<netdb.h>"]),
 1191     (r"sethostent()",      ["<netdb.h>"]),
 1192     (r"setnetent()",       ["<netdb.h>"]),
 1193     (r"setprotoent()",     ["<netdb.h>"]),
 1194     (r"setservent()",      ["<netdb.h>"]),
 1195     # net/if.h  - mappings between network interface names and indexes
 1196     (r"if_nametoindex()",  ["net/if.h"]),
 1197     (r"if_indextoname()",  ["net/if.h"]),
 1198     (r"if_nameindex()",    ["net/if.h"]),
 1199     (r"if_freenameindex()",["net/if.h"]),
 1200     # unistd.h - standard symbolic constants and types
 1201     (r"gethostname()",     ["<unistd.h>"]),
 1202 
 1203     # Linux only
 1204     (r"syscall()",         ["<unistd.h>", "<sys/syscall.h>"]),  # Originally from 4BSD
 1205 
 1206     # Dependencies observed on systems other than the Linux this was
 1207     # developed under.
 1208     (r"<sys/socket.h>",    ["<sys/stat.h>", "<sys/types.h>"]),
 1209     (r"<arpa/inet.h>",     ["<netinet/in.h>"]),
 1210     )
 1211 
 1212 class Baton:
 1213     "Ship progress indications to stderr."
 1214     def __init__(self, prompt, endmsg=None):
 1215         self.stream = sys.stderr
 1216         self.stream.write(prompt + "...")
 1217         if os.isatty(self.stream.fileno()):
 1218             self.stream.write(" \b")
 1219         self.stream.flush()
 1220         self.count = 0
 1221         self.endmsg = endmsg
 1222         self.time = time.time()
 1223 
 1224     def twirl(self, ch=None):
 1225         if self.stream is None:
 1226             return
 1227         if os.isatty(self.stream.fileno()):
 1228             if ch:
 1229                 self.stream.write(ch)
 1230             else:
 1231                 self.stream.write("-/|\\"[self.count % 4])
 1232                 self.stream.write("\b")
 1233             self.stream.flush()
 1234         self.count = self.count + 1
 1235 
 1236     def end(self, msg=None):
 1237         if msg is None:
 1238             msg = self.endmsg
 1239         if self.stream:
 1240             self.stream.write("...(%2.2f sec) %s.\n" % (time.time() - self.time, msg))
 1241 
 1242 class InclusionMap:
 1243     "Map the inclusion dependencies of a set of files and directories."
 1244     @staticmethod
 1245     def c_source(filename):
 1246         "Predicate: return true if the filename appears to be C or C++ source."
 1247         return filename.endswith(".c") or filename.endswith(".cpp") or filename.endswith(".cc")
 1248     # pylint: disable=too-many-locals,too-many-branches,too-many-statements
 1249     def __init__(self, roots, ignore, excludes, verbosity):
 1250         "Build the initial inclusion map."
 1251         self.verbosity = verbosity
 1252         self.files = []
 1253         compiled = []
 1254         for (r, h) in requirements:
 1255             if r.endswith("()"):
 1256                 # The prefix is intended to exclude false suffix matches:
 1257                 # also, excluding : prevents matching on C++ method names.
 1258                 c = re.compile(r"[^a-zA-Z0-9:_]" + r.replace("()", r"\s*\("))
 1259             else:
 1260                 c = re.compile(r)
 1261             compiled.append((r, c, h))
 1262         # pylint: disable=too-many-nested-blocks
 1263         for root in roots:
 1264             if not os.path.isdir(root):
 1265                 if excludes and excludes.search(root):
 1266                     if verbose > 1:
 1267                         print("deheader: %s excluded" % root)
 1268                 elif InclusionMap.c_source(root):
 1269                     self.files.append(root)
 1270                 else:
 1271                     sys.stderr.write("deheader: can't analyze %s\n" % root)
 1272             else:
 1273                 sublist = []
 1274                 for root, dirs, files in os.walk(root):
 1275                     dirs = [x for x in dirs if not x.startswith(".")]
 1276                     for name in files:
 1277                         path = os.path.join(root, name)
 1278                         if excludes and excludes.search(path):
 1279                             if verbose > 1:
 1280                                 print("deheader: %s excluded" % root)
 1281                         elif InclusionMap.c_source(path):
 1282                             sublist.append(path)
 1283                 self.files += sublist
 1284             self.files.sort()
 1285         self.depends_on = {}
 1286         self.requires = {}
 1287         # pylint: disable=too-many-nested-blocks
 1288         for sourcefile in self.files:
 1289             includes = []
 1290             requires = []
 1291             seen = []
 1292             conditions = []
 1293             with open(sourcefile, encoding='ascii', errors='surrogateescape') as rfp:
 1294                 for (i, line) in enumerate(rfp):
 1295                     c = match_preproc(["ifndef", "ifdef", "if"], line)
 1296                     if c is not False:
 1297                         conditions.append(c)
 1298                     elif match_preproc("endif", line) is not False:
 1299                         try:
 1300                             conditions.pop()
 1301                         except IndexError:
 1302                             sys.stderr.write('%s:%d: unbalanced #endif\n' % (sourcefile, i+1))
 1303                             sys.exit(1)
 1304                     else:
 1305                         f = match_preproc("include", line)
 1306                         if f is not False:
 1307                             if verbosity >= PROGRESS_DEBUG:
 1308                                 name = trim(f)
 1309                                 print("deheader: %s includes %s" % (sourcefile, name))
 1310                             if ignore and ignore.search(line):
 1311                                 if verbosity >= PROGRESS_DEBUG:
 1312                                     print("deheader: ignoring %s (exclusion match with %s)." % (name, ignore.pattern))
 1313                                 continue
 1314                             if not conditions or conditions == ["S_SPLINT_S"]:
 1315                                 includes.append(line)
 1316                             elif verbose > 1:
 1317                                 print("deheader: ignoring %s (conditional inclusion)" % name)
 1318                     for (r, c, h) in compiled:
 1319                         if c.search(line):
 1320                             if not set(h).issubset(set(seen)):
 1321                                 requires.append((h, r))
 1322                                 seen += h
 1323             self.depends_on[sourcefile] = includes
 1324             self.requires[sourcefile] = requires
 1325             # Duplicate-header detection
 1326             trimmedcount = {}
 1327             for ref in map(trim, includes):
 1328                 trimmedcount[ref] = trimmedcount.get(ref, 0) + 1
 1329             for ref in trimmedcount:
 1330                 if trimmedcount[ref] > 1:
 1331                     print("deheader: %s has more than one inclusion of %s" % (sourcefile, ref))
 1332             trimmedcount = {}
 1333             for ref in map(supertrim, includes):
 1334                 trimmedcount[ref] = trimmedcount.get(ref, 0) + 1
 1335             for ref in trimmedcount:
 1336                 if trimmedcount[ref] > 1:
 1337                     print("deheader: %s has duplicates or colliding inclusions of %s" % (sourcefile, ref))
 1338     def forget(self, sourcefile, header):
 1339         "Forget a header dependency."
 1340         self.depends_on[sourcefile].remove(header)
 1341     def remember(self, sourcefile, header):
 1342         "Undo forgetting of a dependency."
 1343         self.depends_on[sourcefile].append(header)
 1344 
 1345 class SaveForModification:
 1346     "Prepare a file to be temporarily modified, with guaranteed reversion."
 1347     def __init__(self, filename):
 1348         self.filename = filename
 1349         self.original = filename + "-orig"
 1350         os.rename(self.filename, self.original)
 1351     def remove_headers(self, removables):
 1352         "Prepare a version with specified headers deleted."
 1353         ofp = open(self.filename, "w", encoding='ascii', errors='surrogateescape')
 1354         for line in open(self.original, encoding='ascii', errors='surrogateescape'):
 1355             if line not in removables:
 1356                 ofp.write(line)
 1357         ofp.close()
 1358     def forget(self):
 1359         "Disable reversion."
 1360         os.remove(self.original)
 1361     def revert(self):
 1362         "Revert modifications on the file at the end of this object's lifetime."
 1363         if os.path.exists(self.original):
 1364             try:
 1365                 os.remove(self.filename)
 1366             except OSError:
 1367                 pass
 1368             os.rename(self.original, self.filename)
 1369 
 1370 def match_preproc(directives, line):
 1371     if not isinstance(directives, list):
 1372         directives = [directives]
 1373     regexp = "|".join([r"#\s*" + d for d in directives])
 1374     m = re.match(regexp, line)
 1375     if m:
 1376         return line[m.span()[1]:].strip()
 1377     return False
 1378 
 1379 def trim(line):
 1380     "Get file reference from an #include, retaining <> if a system header."
 1381     trimmed = re.sub(r"^#\s*include", "", line).strip()
 1382     if trimmed[0] in '"':
 1383         return '"' + trimmed.split('"')[1] + '"'
 1384     elif trimmed[0] == '<':
 1385         return trimmed.split('>')[0] + ">"
 1386     else:
 1387         return repr(line)
 1388 
 1389 def supertrim(line):
 1390     "Get file bare reference from an #include - used fr detecting duplicates/collisions."
 1391     trimmed = re.sub(r"^#\s*include", "", line).strip()
 1392     if trimmed[0] in '"':
 1393         return trimmed.split('"')[1]
 1394     elif trimmed[0] == '<':
 1395         return trimmed.split('<')[1]
 1396     else:
 1397         return repr(line)
 1398 
 1399 def clean(derived):
 1400     "Clean a derived object file preparatory to test-compiling it"
 1401     if os.path.exists(os.path.join(builddir, derived)):
 1402         os.remove(os.path.join(builddir, derived))
 1403     elif os.path.exists("CMakeList.txt"):
 1404         subprocess.call(["make","clean"])
 1405 
 1406 # pylint: disable=too-many-arguments,too-many-statements,too-many-locals
 1407 def testcompile(source, maker, msg="", verbosity=0, showerrs=False, subdir=""):
 1408     "Test-compile a sourcefile.  Return the status and the compilation time"
 1409     (stem, _suffix) = os.path.splitext(source)
 1410     derived = stem + ".o"
 1411     clean(os.path.join(subdir, derived))
 1412     command = maker % derived
 1413     olddir = os.getcwd()
 1414     if len(subdir) > 0:
 1415         os.chdir(subdir)
 1416     start = time.time()
 1417     (status, output) = getstatusoutput(command)
 1418     end = time.time()
 1419     os.chdir(olddir)
 1420     if verbosity >= COMMAND_DEBUG or (showerrs and os.WIFEXITED(status) and os.WEXITSTATUS(status) != 0):
 1421         sys.stdout.write(output + "\n")
 1422     if status:
 1423         explain = "failed"
 1424         if verbosity >= PROGRESS_DEBUG:
 1425             explain += " (%d)" % status
 1426     else:
 1427         explain = "succeeded"
 1428     if verbosity >= PROGRESS_DEBUG:
 1429         print("deheader: %s%s %s." % (source, msg, explain))
 1430     clean(os.path.join(subdir, derived))
 1431     return (status, end - start)
 1432 
 1433 # pylint: disable=too-many-locals,too-many-nested-blocks,too-many-branches
 1434 def c_analyze(sourcefile, maker, includes, requires, verbosity, subdir=""):
 1435     "Given a C file and a list of includes, return those that can be omitted."
 1436     # We'll remove headers in reverse order, because later unnecessary
 1437     # headers might depend on earlier ones
 1438     includes.reverse()
 1439     unneeded = []
 1440     if verbosity == BATON_DEBUG:
 1441         baton = Baton(sourcefile + ": ", "Done")
 1442     try:
 1443         saveit = SaveForModification(os.path.join(subdir, sourcefile))
 1444         while True:
 1445             keepgoing = False
 1446             for header in includes[:]:
 1447                 if verbosity == BATON_DEBUG:
 1448                     baton.twirl()
 1449                 retain = 0
 1450                 for (requirements, trigger) in requires:
 1451                     for required in requirements:
 1452                         if required in header:
 1453                             if verbosity >= PROGRESS_DEBUG:
 1454                                 print("deheader: in %s, %s prevents uninclusion of %s" % (os.path.join(subdir, sourcefile), trigger, trim(header)))
 1455                             retain += 1
 1456                 if not retain:
 1457                     saveit.remove_headers(unneeded + [header])
 1458                     (st, _t) = testcompile(sourcefile, maker, " without %s" % trim(header), verbosity, showerrs=False, subdir=subdir)
 1459                     if st == 0:
 1460                         unneeded.append(header)
 1461                         includes.remove(header)
 1462                         keepgoing = True
 1463             if not keepgoing:
 1464                 break
 1465     finally:
 1466         saveit.revert()
 1467         if verbosity == BATON_DEBUG:
 1468             baton.end()
 1469     # Missing-require detection.  Can't be merged with duplicate-header
 1470     # detection because this has to be done after unneeded headers are removed.
 1471     stillhere = list(map(trim, includes))
 1472     for (requirement, trigger) in requires:
 1473         if not set(requirement).issubset(stillhere):
 1474             print("deheader: in %s, %s portability requires %s." % (os.path.join(subdir, sourcefile), trigger, ",".join(requirement)))
 1475     return unneeded
 1476 
 1477 def deheader(sourcefile, maker, includes, requires, remove, verbose):
 1478     # Sanity check against broken sourcefiles; we want this to
 1479     # complain visibly if the sourcefile won't build at all.
 1480     subdir = ""
 1481     (st, _t) = testcompile(sourcefile, maker, verbosity=max(1, verbose), showerrs=False)
 1482     if st != 0:
 1483         subdir = os.path.dirname(sourcefile)
 1484         sourcefile = os.path.basename(sourcefile)
 1485         (st, _t) = testcompile(sourcefile, maker, verbosity=max(1, verbose), showerrs=True, subdir=subdir)
 1486     if st == 0:
 1487         # Now do the analysis
 1488         if sourcefile.endswith(".c") or sourcefile.endswith(".cpp") or sourcefile.endswith(".cc"):
 1489             unneeded = c_analyze(sourcefile, maker,
 1490                                  includes[:], requires, verbose, subdir=subdir)
 1491         if unneeded:
 1492             for line in unneeded:
 1493                 print("deheader: remove %s from %s" % (trim(line), os.path.join(subdir, sourcefile)))
 1494             if remove:
 1495                 remove_it = SaveForModification(os.path.join(subdir, sourcefile))
 1496                 remove_it.remove_headers(unneeded)
 1497                 remove_it.forget()
 1498                 del remove_it
 1499         return Summary([sourcefile], includes, unneeded)
 1500     else:
 1501         sys.stderr.write("deheader: basic compilation failed on %s\n" % (sourcefile,))
 1502         return Summary([sourcefile], includes, [])
 1503 
 1504 # After-action analysis starts here
 1505 
 1506 class Summary:
 1507     "Summarize results from a deheading."
 1508     def __init__(self, filenames=None, includes=None, unneeded=None):
 1509         self.filenames = filenames or []
 1510         self.includes = includes or []
 1511         self.unneeded = unneeded or []
 1512     def __add__(self, other):
 1513         result = Summary()
 1514         result.filenames = self.filenames + other.filenames
 1515         result.includes = self.includes + other.includes
 1516         result.unneeded = self.unneeded + other.unneeded
 1517         return result
 1518     def has_unneeded_includes(self):
 1519         return len(self.unneeded) > 0
 1520     def __repr__(self):
 1521         return "%d files, %d includes, %d removable" % \
 1522                (len(self.filenames), len(self.includes), len(self.unneeded))
 1523 
 1524 if __name__ == "__main__":
 1525     (options, arguments) = getopt.getopt(sys.argv[1:], "bhi:m:qrvx:V",
 1526                                          ["builddir", "help", "ignore",
 1527                                           "maker", "quiet", "remove",
 1528                                           "verbose", "exclude", "version"])
 1529     maker = "make %s"
 1530     builddir = '.'
 1531     verbose = 0
 1532     quiet = False
 1533     remove = False
 1534     ignores = []
 1535     exclusions = []
 1536     for (switch, val) in options:
 1537         if switch in ('-h', '--help'):
 1538             sys.stderr.write(__doc__)
 1539             sys.exit(0)
 1540         elif switch in ('-i', '--ignore'):
 1541             ignores.append(val)
 1542         elif switch in ('-m', '--maker'):
 1543             maker = val
 1544         elif switch in ('-b', '--builddir'):
 1545             builddir = os.path.abspath(val)
 1546         elif switch in ('-q', '--quiet'):
 1547             quiet = True
 1548         elif switch in ('-r', '--remove'):
 1549             remove = True
 1550         elif switch in ('-v', '--verbose'):
 1551             verbose += 1
 1552         elif switch in ('-V', '--version'):
 1553             print("deheader", version)
 1554             raise SystemExit(0)
 1555         elif switch in ('-x', '--exclude'):
 1556             exclusions.append(val)
 1557     if not ignores:
 1558         ignore = None
 1559     else:
 1560         ignore = re.compile("|".join(ignores))
 1561     if not exclusions:
 1562         exclusions = None
 1563     else:
 1564         exclusions = re.compile("|".join(exclusions))
 1565     if not arguments:
 1566         arguments = ["."]
 1567 
 1568     summaries = []
 1569     inclusion_map = InclusionMap(arguments, ignore, exclusions, verbose)
 1570     for sourcefile in sorted(inclusion_map.depends_on.keys()):
 1571         summaries.append(deheader(sourcefile, maker,
 1572                                   inclusion_map.depends_on[sourcefile],
 1573                                   inclusion_map.requires[sourcefile],
 1574                                   remove, verbose))
 1575     stats = Summary()
 1576     for summary in summaries:
 1577         stats = stats + summary
 1578     if not quiet:
 1579         print("deheader: saw %s" % stats)
 1580     if stats.has_unneeded_includes():
 1581         print("deheader: has unneeded includes %s" % " ".join(stats.unneeded))
 1582     raise SystemExit(0)
 1583 
 1584 # End