./PaxHeaders/deheader-1.130000644000000000000000000000013215235622021012333 xustar0030 mtime=1786192913.342012629 30 atime=1786192913.341012609 30 ctime=1786192913.342012629 deheader-1.13/0000755000175000017500000000000015235622021011401 5ustar00esresrdeheader-1.13/PaxHeaders/README.adoc0000644000000000000000000000013215235622021014040 xustar0030 mtime=1786192913.341012609 30 atime=1786192913.341012609 30 ctime=1786192913.341012609 deheader-1.13/README.adoc0000644000175000017500000000071415235622021013170 0ustar00esresr= deheader deheader analyzes C and C++ files to determine which header inclusions can be removed while still allowing them to compile. This may result in substantial improvements in compilation time, especially on large C++ projects; it also sometimes exposes dependencies and cohesions of which developers were unaware. This code is commonly packaged as "deheader". image:https://repology.org/badge/vertical-allrepos/deheader.svg[Repology package status] deheader-1.13/PaxHeaders/COPYING0000644000000000000000000000013215235622021013306 xustar0030 mtime=1786192913.341012609 30 atime=1786192913.341012609 30 ctime=1786192913.341012609 deheader-1.13/COPYING0000644000175000017500000000243615235622021012441 0ustar00esresr BSD LICENSE Copyright (c) 2015, Eric S. Raymond All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. deheader-1.13/PaxHeaders/NEWS.adoc0000644000000000000000000000013215235622021013657 xustar0030 mtime=1786192913.342012629 30 atime=1786192913.341012609 30 ctime=1786192913.342012629 deheader-1.13/NEWS.adoc0000644000175000017500000000543215235622021013011 0ustar00esresr deheader project news 1.13: 2026-08-08:: Fixed typo in hsearch() pattern. Added requirements for entire SUSv2 coverage. Spellchecked the documentation. Corrected an error in CMake build detection. Typo fixes and code hardening by ChatGPT 5.2. Don't over-remove duplicates when -r is specified. Restore meaningful exit statuses Correct and normalize portability requirements Restore the working directory when builds are interrupted Make source rewriting recoverable and metadata-safe Fix parsing of options that require values 1.12: 2026-02-20:: batchspell -> spellcheck Updated the requirements list with missing SUSv2/POSIX items Fixed the typoed hsearch pattern. Repair exclusion of dotfiles. Move documentation to asciidoc and spellchecked it 1.11: 2024-10-04:: Adjust test suite for GCC14 compatibility. Work around a zealous correctness check in Python 3.11. 1.10: 2023-02-17:: Fix error in Makefile iunstall production. Add two missing funtions from net.if.h Cleanup for modern pylint. 1.9: 2023-01-30:: Work on non-UTF inputs under Python 3. Make must now specify how to subsitute in a make target. 1.8: 2022-01-28:: Change shebang to Python 3, required by a recent Ubuntu action. 1.7: 2020-08-12:: Use modern GCC error format for failure messages. Fix filename of header for (f)statvfs. 1.6: 2016-09-30:: Fix bug that prevented the -b option from being interpreted. Acknowledge Debian bug #839179: keywords in comments not ignored. 1.5: 2016-09-27:: exit(1) if unneeded includes are detected (useful in Makefiles). 1.4: 2016-09-01:: Now runs polyglot under either Python 2 or Python 3 Added assert() to requirements. 1.3 @ 2016-01-12:: When compilation fails, also try it directly inside subdirectories. 1.2 @ 2015-07-18:: Notice preprocessor directives with whitespace after the hash-mark 1.1 @ 2015-01-26:: Allow --version on the command line. Fix up the regression tests. 1.0 @ 2014-06-03:: Added --quiet option. 0.8 @ 2013-09-14:: Minor documentation fixes. 0.7 @ 2013-01-22:: Accept .cc as an extension as well as .cpp. 0.6 @ 2011-02-10:: Add the return-status macros from sys/wait.h to the portability list. 0.5 @ 2010-12-22:: Source is now checked against all SuS portability requirements. There is an option to exclude files by pattern. 0.4 @ 2010-12-20:: Script now removes generated objects. Duplicate inclusions are now detected. Absence of some headers required for portability is now detected. 0.3 @ 2010-12-09:: Add a dependencies table to head off common cross-platform problems. 0.2 @ 2010-12-02:: Make the last line of output a statistical summary. Document some limitations. 0.1 @ 2010-12-01:: Initial release. deheader-1.13/PaxHeaders/deheader0000644000000000000000000000013215235622021013737 xustar0030 mtime=1786192913.342012629 30 atime=1786192913.342012629 30 ctime=1786192913.342012629 deheader-1.13/deheader0000755000175000017500000022737615235622021013111 0ustar00esresr#!/usr/bin/env python3 """\ deheader -- find (optionally remove) unneeded includes in C or C++ sourcefiles. Usage: deheader [-h] [-i pattern] [-m cmd] [-b dir] [-q] [-r] [-x pattern] [-v] [file...] -h, --help Emit this help message and quit. -m, --maker Set the build command (by default 'make %s') -b, --builddir Set a build directory relative to where deheader is run -i, --ignore Ignore (don't remove) headers matching the argument regexp -q, --quiet Suppress statistical summary -r, --remove Remove the final set of unneeded headers -v, --verbose Be chatty about what you're doing. -x, --exclude Exclude files matching regexp -V, --version Emit version and exit. This tool takes a list of C or C++ sourcefiles and generates a report on which #includes can be omitted from them -- the test, for each foo.c or foo.cc or foo.cpp, is simply whether 'rm foo.o; make foo.o' returns a zero status. Optionally, with the -r option, the unneeded headers are removed. The tool also reports on headers required for strict portability. If a sourcefile argument is a directory, the report is generated on all source files beneath it. Subdirectories beginning with a dot are ignored. If no arguments are given, the program runs as if the name of the current directory had been passed to it. The original sourcefile is backed up to a unique temporary file and restored on interrupt or after processing with its original timestamp, unless the -r option was given and headers removed. The last line of the output is a statistical summary of operations. """ # SPDX-License-Identifier: BSD-2-Clause # 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,too-many-positional-arguments # pylint: disable=multiple-imports import sys, os, getopt, time, re, subprocess, shutil, tempfile, shlex version = "1.13" builddir = "." try: from subprocess import getstatusoutput except ImportError: from commands import getstatusoutput BATON_DEBUG = 1 PROGRESS_DEBUG = 2 COMMAND_DEBUG = 3 # fmt: off # Difference in various compiler implementations and OSes mean that for cross- # platform compatibility you sometimes want to leave "unneeded" headers alone # because they're required in order to satisfy dependencies on other platforms. requirements = ( # Headers mandated by SuS Version 2 System Interfaces. # a64l, l64a - convert between a 32-bit integer and a radix-64 ASCII string (r"a64l()", [""]), (r"l64a()", [""]), # abort - generate an abnormal process abort (r"abort()", [""]), # abs - return an integer absolute value (r"abs()", [""]), # access - determine accessibility of a file (r"access()", [""]), # acos - arc cosine function (r"acos()", [""]), # acosh, asinh, atanh - inverse hyperbolic functions (r"acosh()", [""]), (r"asinh()", [""]), (r"atanh()", [""]), # aio.h - asynchronous input and output (r"aio_cancel()", [""]), (r"aio_error()", [""]), (r"aio_fsync()", [""]), (r"aio_read()", [""]), (r"aio_return()", [""]), (r"aio_suspend()", [""]), (r"aio_write()", [""]), (r"lio_listio()", [""]), # alarm - schedule an alarm signal (r"alarm()", [""]), # asctime, asctime_r - convert date and time to a string (r"asctime()", [""]), (r"asctime_r()", [""]), # asin - arc sine function (r"asin()", [""]), # assert - verify program assertion (r"assert()", [""]), # atan - arc tangent function (r"atan()", [""]), # atan2 - arc tangent function (r"atan2()", [""]), # atexit - register a function to run at process termination (r"atexit()", [""]), # atof - convert a string to double-precision number (r"atof()", [""]), # atoi - convert a string to integer (r"atoi()", [""]), # atol - convert a string to long integer (r"atol()", [""]), # basename - return the last component of a pathname (r"basename()", [""]), # bcmp - memory operations (r"bcmp()", [""]), # bcopy - memory operations (r"bcopy()", [""]), # brk, sbrk - change space allocation (LEGACY) (r"brk()", [""]), (r"sbrk()", [""]), # bsearch - binary search a sorted table (r"bsearch()", [""]), # btowc - single-byte to wide-character conversion (r"btowc()", ["", ""]), # bzero - memory operations (r"bzero()", [""]), # calloc - a memory allocator (r"calloc()", [""]), # catclose - close a message catalogue descriptor (r"catclose()", [""]), # catgets - read a program message (r"catgets()", [""]), # catopen - open a message catalogue (r"catopen()", [""]), # cbrt - cube root function (r"cbrt()", [""]), # ceil - ceiling value function (r"ceil()", [""]), # chdir - change working directory (r"chdir()", [""]), # chmod - change mode of a file (r"chmod()", ["", ""]), # chown - change owner and group of a file (r"chown()", ["", ""]), # chroot - change root directory (LEGACY) (r"chroot()", [""]), # clearerr - clear indicators on a stream (r"clearerr()", [""]), # clock - report CPU time used (r"clock()", [""]), # clock_settime, clock_gettime, clock_getres - clock and timer functions (r"clock_settime()", [""]), (r"clock_gettime()", [""]), (r"clock_getres()", [""]), # close - close a file descriptor (r"close()", [""]), # closedir - close a directory stream (r"closedir()", ["", ""]), # closelog, openlog, setlogmask, syslog - control system log (r"closelog()", [""]), (r"openlog()", [""]), (r"setlogmask()", [""]), (r"syslog()", [""]), # compile - produce a compiled regular expression (r"compile()", [""]), # confstr - get configurable variables (r"confstr()", [""]), # cos - cosine function (r"cos()", [""]), # cosh - hyperbolic cosine function (r"cosh()", [""]), # creat - create a new file or rewrite an existing one (r"creat()", ["", "", ""]), # crypt - string encoding function (r"crypt()", [""]), # ctermid - generate a pathname for controlling terminal (r"ctermid()", [""]), # ctime, ctime_r - convert a time value to date and time string (r"ctime()", [""]), (r"ctime_r()", [""]), # ctype.h - character types (r"isalnum()", [""]), (r"isalpha()", [""]), (r"isascii()", [""]), (r"iscntrl()", [""]), (r"isdigit()", [""]), (r"isgraph()", [""]), (r"islower()", [""]), (r"isprint()", [""]), (r"ispunct()", [""]), (r"isspace()", [""]), (r"isupper()", [""]), (r"isxdigit()", [""]), (r"toascii()", [""]), (r"tolower()", [""]), (r"toupper()", [""]), (r"_tolower()", [""]), (r"_toupper()", [""]), # cuserid - character login name of the user (r"cuserid()", [""]), # daylight - daylight savings time flag (r"extern\s+int\s+daylight;", [""]), # dbm_clearerr, dbm_close, dbm_delete, dbm_error, dbm_fetch, dbm_firstkey, dbm_nextkey, dbm_open, dbm_store - database functions (r"dbm_clearerr()", [""]), (r"dbm_close()", [""]), (r"dbm_delete()", [""]), (r"dbm_error()", [""]), (r"dbm_fetch()", [""]), (r"dbm_firstkey()", [""]), (r"dbm_nextkey()", [""]), (r"dbm_open()", [""]), (r"dbm_store()", [""]), # difftime - compute the difference between two calendar time values (r"difftime()", [""]), # dirname - report the parent directory name of a file pathname (r"dirname()", [""]), # div - compute the quotient and remainder of an integer division (r"div()", [""]), # dlclose - close a dlopen() object (r"dlclose()", [""]), # dlerror - get diagnostic information (r"dlerror()", [""]), # dlsym - obtain the address of a symbol from a dlopen() object (r"dlsym()", [""]), # drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, seed48, srand48 - generate uniformly distributed pseudo-random numbers (r"drand48()", [""]), (r"erand48()", [""]), (r"jrand48()", [""]), (r"lcong48()", [""]), (r"lrand48()", [""]), (r"mrand48()", [""]), (r"nrand48()", [""]), (r"seed48()", [""]), (r"srand48()", [""]), # dup, dup2 - duplicate an open file descriptor (r"dup()", [""]), (r"dup2()", [""]), # exit, _exit - terminate a process (r"exit()", [""]), (r"_exit()", [""]), # ecvt, fcvt, gcvt - convert a floating-point number to a string (r"ecvt()", [""]), (r"fcvt()", [""]), (r"gcvt()", [""]), # encrypt - encoding function (r"encrypt()", [""]), # endgrent, getgrent, setgrent - group database entry functions (r"endgrent()", [""]), (r"getgrent()", [""]), (r"setgrent()", [""]), # endpwent, getpwent, setpwent - user database functions (r"endpwent()", [""]), (r"getpwent()", [""]), (r"setpwent()", [""]), # endutxent, getutxent, getutxid, getutxline, pututxline, setutxent - user accounting database functions (r"endutxent()", [""]), (r"getutxent()", [""]), (r"getutxid()", [""]), (r"getutxline()", [""]), (r"pututxline()", [""]), (r"setutxent()", [""]), # erf, erfc - error and complementary error functions (r"erf()", [""]), (r"erfc()", [""]), # environ, execl, execv, execle, execve, execlp, execvp - execute a file (r"extern\s+char\s+\*\*environ;", [""]), (r"execl()", [""]), (r"execv()", [""]), (r"execle()", [""]), (r"execve()", [""]), (r"execlp()", [""]), (r"execvp()", [""]), # exp - exponential function (r"exp()", [""]), # expm1 - compute exponential functions (r"expm1()", [""]), # FD_CLR - macros for synchronous I/O multiplexing (r"FD_CLR()", [""]), (r"FD_ISSET()", [""]), (r"FD_SET()", [""]), (r"FD_ZERO()", [""]), # fabs - absolute value function (r"fabs()", [""]), # fattach - attach a STREAMS-based file descriptor to a file in the file system name space (r"fattach()", [""]), # fchdir - change working directory (r"fchdir()", [""]), # fchmod - change mode of a file (r"fchmod()", [""]), # fchown - change owner and group of a file (r"fchown()", [""]), # fclose - close a stream (r"fclose()", [""]), # fdatasync - synchronise the data of a file (r"fdatasync()", [""]), # fdetach - detach a name from a STREAMS-based file descriptor (r"fdetach()", [""]), # fdopen - associate a stream with a file descriptor (r"fdopen()", [""]), # ferror - test error indicator on a stream (r"ferror()", [""]), # feof - test end-of-file indicator on a stream (r"feof()", [""]), # fflush - flush a stream (r"fflush()", [""]), # ffs - find first set bit (r"ffs()", [""]), # fgetc - get a byte from a stream (r"fgetc()", [""]), # fgetpos - get current file position information (r"fgetpos()", [""]), # fgets - get a string from a stream (r"fgets()", [""]), # fgetwc - get a wide-character code from a stream (r"fgetwc()", ["", ""]), # fgetws - get a wide-character string from a stream (r"fgetws()", ["", ""]), # fileno - map a stream pointer to a file descriptor (r"fileno()", [""]), # flockfile, ftrylockfile, funlockfile - stdio locking functions (r"flockfile()", [""]), (r"ftrylockfile()", [""]), (r"funlockfile()", [""]), # fmod - floating-point remainder value function (r"fmod()", [""]), # fmtmsg.h - message display structures (r"fmtmsg()", [""]), # fnmatch.h - filename-matching types (r"fnmatch()", [""]), # fopen - open a stream (r"fopen()", [""]), # fork - create a new process (r"fork()", ["", ""]), # fpathconf, pathconf - get configurable pathname variables (r"fpathconf()", [""]), (r"pathconf()", [""]), # fputc - put a byte on a stream (r"fputc()", [""]), # fputs - put a string on a stream (r"fputs()", [""]), # fputwc - put a wide-character code on a stream (r"fputwc()", ["", ""]), # fputws - put a wide-character string on a stream (r"fputws()", ["", ""]), # fread - binary input (r"fread()", [""]), # free - free allocated memory (r"free()", [""]), # freopen - open a stream (r"freopen()", [""]), # frexp - extract mantissa and exponent from a double precision number (r"frexp()", [""]), # fscanf, scanf, sscanf - convert formatted input (r"fscanf()", [""]), (r"scanf()", [""]), (r"sscanf()", [""]), # fseek, fseeko - reposition a file-position indicator in a stream (r"fseek()", [""]), (r"fseeko()", [""]), # fsetpos - set current file position (r"fsetpos()", [""]), # fstat - get file status (r"fstat()", ["", ""]), # fstatvfs, statvfs - get file system information (r"fstatvfs()", [""]), (r"statvfs()", [""]), # fsync - synchronise changes to a file (r"fsync()", [""]), # ftell, ftello - return a file offset in a stream (r"ftell()", [""]), (r"ftello()", [""]), # ftime - get date and time (r"ftime()", [""]), # ftok - generate an IPC key (r"ftok()", [""]), # ftruncate, truncate - truncate a file to a specified length (r"truncate()", [""]), (r"ftruncate()", [""]), # ftw - traverse (walk) a file tree (r"ftw()", [""]), (r"nftw()", [""]), # fwide - set stream orientation (r"fwide()", ["", ""]), # fwprintf, wprintf, swprintf - print formatted wide-character output (r"fwprintf()", ["", ""]), (r"wprintf()", ["", ""]), (r"swprintf()", ["", ""]), # fwrite - binary output (r"fwrite()", [""]), # fwscanf, wscanf, swscanf - convert formatted wide-character input (r"fwscanf()", ["", ""]), (r"wscanf()", ["", ""]), (r"swscanf()", ["", ""]), # gamma, signgam - log gamma function (r"gamma()", [""]), # getc - get a byte from a stream (r"getc()", [""]), # getc_unlocked, getchar_unlocked, putc_unlocked, putchar_unlocked - stdio with explicit client locking (r"getc_unlocked()", [""]), (r"getchar_unlocked()", [""]), (r"putc_unlocked()", [""]), (r"putchar_unlocked()", [""]), # getchar - get a byte from a stdin stream (r"getchar()", [""]), # getcontext, setcontext - get and set current user context (r"getcontext()", [""]), (r"setcontext()", [""]), # getcwd - get the pathname of the current working directory (r"getcwd()", [""]), # getdate - convert user format date and time (r"getdate()", [""]), # getdtablesize - get the file descriptor table size (r"getdtablesize()", [""]), # getegid - get the effective group ID (r"getegid()", ["", ""]), # getenv - get value of an environment variable (r"getenv()", [""]), # geteuid - get the effective user ID (r"geteuid()", ["", ""]), # getgid - get the real group ID (r"getgid()", ["", ""]), # getgrgid, getgrgid_r - get group database entry for a group ID (r"getgrgid()", ["", ""]), (r"getgrgid_r()", ["", ""]), # getgrnam, getgrnam_r - search group database for a name (r"getgrnam()", ["", ""]), (r"getgrnam_r()", ["", ""]), # getgroups - get supplementary group IDs (r"getgroups()", ["", ""]), # gethostid - get an identifier for the current host (r"gethostid()", [""]), # getitimer, setitimer - get or set value of interval timer (r"getitimer()", [""]), (r"setitimer()", [""]), # getlogin, getlogin_r - get login name (r"getlogin()", [""]), (r"getlogin_r()", [""]), # getmsg, getpmsg - receive next message from a STREAMS file (r"getmsg()", [""]), (r"getpmsg()", [""]), # getopt, optarg, optind, opterr, optopt - command option parsing (r"getopt()", [""]), (r"extern\s+char\s+\*\*optarg;", [""]), (r"extern\s+int\s+optind;", [""]), (r"extern\s+int\s+opterr;", [""]), (r"extern\s+int\s+optopt;", [""]), # getpagesize - get the current page size (r"getpagesize()", [""]), # getpass - read a string of characters without echo (r"getpass()", [""]), # getpgid - get the process group ID for a process (r"getpgid()", [""]), # getpgrp - get the process group ID of the calling process (r"getpgrp()", ["", ""]), # getpid - get the process ID (r"getpid()", ["", ""]), # getppid - get the parent process ID (r"getppid()", ["", ""]), # getpriority, setpriority - get or set the nice value (r"getpriority()", [""]), (r"setpriority()", [""]), # getpwnam, getpwnam_r - search user database for a name (r"getpwnam()", ["", ""]), (r"getpwnam_r()", ["", ""]), # getpwuid, getpwuid_r - search user database for a user ID (r"getpwuid()", ["", ""]), (r"getpwuid_r()", ["", ""]), # getrlimit, setrlimit - control maximum resource consumption (r"getrlimit()", [""]), (r"setrlimit()", [""]), # getrusage - get information about resource utilisation (r"getrusage()", [""]), # gets - get a string from a stdin stream (r"gets()", [""]), # getsid - get the process group ID of session leader (r"getsid()", [""]), # getsubopt - parse suboption arguments from a string (r"getsubopt()", [""]), # gettimeofday - get the date and time (r"gettimeofday()", [""]), # getuid - get a real user ID (r"getuid()", ["", ""]), # getw - get a word from a stream (r"getw()", [""]), # getwc - get a wide-character code from a stream (r"getwc()", ["", ""]), # getws - get a wide-character string from a stream (r"getws()", ["", ""]), # getwchar - get a wide character from a stdin stream (r"getwchar()", [""]), # getwd - get the current working directory pathname (r"getwd()", [""]), # glob.h - pathname pattern-matching types (r"glob()", [""]), (r"globfree()", [""]), # gmtime, gmtime_r - convert a time value to a broken-down UTC time (r"gmtime()", [""]), (r"gmtime_r()", [""]), # grantpt - grant access to the slave pseudo-terminal device (r"grantpt()", [""]), # hcreate, hdestroy, hsearch - manage hash search table (r"hcreate()", [""]), (r"hdestroy()", [""]), (r"hsearch()", [""]), # hypot - Euclidean distance function (r"hypot()", [""]), # iconv.h - codeset conversion facility (r"iconv_open()", [""]), (r"iconv()", [""]), (r"iconv_close()", [""]), # ilogb - return an unbiased exponent (r"ilogb()", [""]), # index - character string operations (r"index()", [""]), # initstate, random, setstate, srandom - pseudorandom number functions (r"initstate()", [""]), (r"random()", [""]), (r"setstate()", [""]), (r"srandom()", [""]), # insque, remque - insert or remove an element in a queue (r"insque()", [""]), (r"remque()", [""]), # SuS ioctl specifies , but that's just wrong # isastream - test a file descriptor (r"isastream()", [""]), # isnan - test for a NaN (r"isnan()", [""]), # j0, j1, jn - Bessel functions of the first kind (r"j0()", [""]), (r"j1()", [""]), (r"jn()", [""]), # labs - return a long integer absolute value (r"labs()", [""]), # lchown - change the owner and group of a symbolic link (r"lchown()", [""]), # ldexp - load exponent of a floating point number (r"ldexp()", [""]), # ldiv - compute quotient and remainder of a long division (r"ldiv()", [""]), # lgamma - log gamma function (r"lgamma()", [""]), # libgen.h - definitions for pattern matching functions (r"regcmp()", [""]), (r"regex()", [""]), # link - link to a file (r"link()", [""]), # setlocale, localeconv - set or query program locale (r"setlocale()", [""]), (r"localeconv()", [""]), # localtime, localtime_r - convert a time value to a broken-down local time (r"localtime()", [""]), (r"localtime_r()", [""]), # lockf - record locking on files (r"lockf()", [""]), # log - natural logarithm function (r"log()", [""]), # log10 - base 10 logarithm function (r"log10()", [""]), # log1p - compute a natural logarithm (r"log1p()", [""]), # logb - radix-independent exponent (r"logb()", [""]), # lsearch, lfind - linear search and update (r"lfind()", [""]), (r"lsearch()", [""]), # lseek - move the read/write file offset (r"lseek()", ["", ""]), # lstat - get symbolic link status (r"lstat()", [""]), # makecontext, swapcontext - manipulate user contexts (r"makecontext()", [""]), (r"swapcontext()", [""]), # malloc - a memory allocator (r"malloc()", [""]), # mblen - get number of bytes in a character (r"mblen()", [""]), # mbrlen - get number of bytes in a character (restartable) (r"mbrlen()", [""]), # mbrtowc - convert a character to a wide-character code (restartable) (r"mbrtowc()", [""]), # mbsinit - determine conversion object status (r"mbsinit()", [""]), # mbsrtowcs - convert a character string to a wide-character string (restartable) (r"mbsrtowcs()", [""]), # mbstowcs - convert a character string to a wide-character string (r"mbstowcs()", [""]), # mbtowc - convert a character to a wide-character code (r"mbtowc()", [""]), # mkdir - make a directory (r"mkdir()", ["", ""]), # mkfifo - make a FIFO special file (r"mkfifo()", ["", ""]), # mknod - make a directory, a special or regular file (r"mknod()", [""]), # mkstemp - make a unique file name (r"mkstemp()", [""]), # mktemp - make a unique filename (r"mktemp()", [""]), # convert broken-down time into time since the Epoch (r"mktime()", [""]), # sys/mman.h - memory management declarations (r"mlock()", [""]), (r"mlockall()", [""]), (r"mmap()", [""]), (r"mprotect()", [""]), (r"msync()", [""]), (r"munlock()", [""]), (r"munlockall()", [""]), (r"munmap()", [""]), (r"shm_open()", [""]), (r"shm_unlink()", [""]), # modf - decompose a floating-point number (r"modf()", [""]), # monetary.h - monetary types (r"strfmon()", [""]), # mqueue.h - message queues (r"mq_close()", [""]), (r"mq_getattr()", [""]), (r"mq_notify()", [""]), (r"mq_open()", [""]), (r"mq_receive()", [""]), (r"mq_send()", [""]), (r"mq_setattr()", [""]), (r"mq_unlink()", [""]), # sys/msg.h - message queue structures (r"msgctl()", [""]), (r"msgget()", [""]), (r"msgrcv()", [""]), (r"msgsnd()", [""]), # nanosleep - high resolution sleep (r"nanosleep()", [""]), # nextafter - next representable double-precision floating-point number (r"nextafter()", [""]), # change nice value of a process (r"nice()", [""]), # nl_langinfo - language information (r"nl_langinfo()", [""]), # open - open a file (r"open()", ["", "", ""]), # opendir - open a directory (r"opendir()", ["", ""]), # pause - suspend the thread until signal is received (r"pause()", [""]), # pclose - close a pipe stream to or from a process (r"pclose()", [""]), # perror - write error messages to standard error (r"perror()", [""]), # pipe - create an interprocess channel (r"pipe()", [""]), # poll - input/output multiplexing (r"poll()", [""]), # popen - initiate pipe streams to or from a process (r"popen()", [""]), # pow - power function (r"pow()", [""]), # pread - read from a file ("pread()", [""]), # pthread.h - threads (r"pthread_attr_destroy()", [""]), (r"pthread_attr_getdetachstate()", [""]), (r"pthread_attr_getguardsize()", [""]), (r"pthread_attr_getinheritsched()", [""]), (r"pthread_attr_getschedparam()", [""]), (r"pthread_attr_getschedpolicy()", [""]), (r"pthread_attr_getscope()", [""]), (r"pthread_attr_getstackaddr()", [""]), (r"pthread_attr_getstacksize()", [""]), (r"pthread_attr_init()", [""]), (r"pthread_attr_setdetachstate()", [""]), (r"pthread_attr_setguardsize()", [""]), (r"pthread_attr_setinheritsched()", [""]), (r"pthread_attr_setschedparam()", [""]), (r"pthread_attr_setschedpolicy()", [""]), (r"pthread_attr_setscope()", [""]), (r"pthread_attr_setstackaddr()", [""]), (r"pthread_attr_setstacksize()", [""]), (r"pthread_cancel()", [""]), (r"pthread_cleanup_push()", [""]), (r"pthread_cleanup_pop()", [""]), (r"pthread_cond_broadcast()", [""]), (r"pthread_cond_destroy()", [""]), (r"pthread_cond_init()", [""]), (r"pthread_cond_signal()", [""]), (r"pthread_cond_timedwait()", [""]), (r"pthread_cond_wait()", [""]), (r"pthread_condattr_destroy()", [""]), (r"pthread_condattr_getpshared()", [""]), (r"pthread_condattr_init()", [""]), (r"pthread_condattr_setpshared()", [""]), (r"pthread_create()", [""]), (r"pthread_detach()", [""]), (r"pthread_equal()", [""]), (r"pthread_exit()", [""]), (r"pthread_getconcurrency()", [""]), (r"pthread_getschedparam()", [""]), (r"pthread_getspecific()", [""]), (r"pthread_join()", [""]), (r"pthread_key_create()", [""]), (r"pthread_key_delete()", [""]), (r"pthread_mutex_destroy()", [""]), (r"pthread_mutex_getprioceiling()", [""]), (r"pthread_mutex_init()", [""]), (r"pthread_mutex_lock()", [""]), (r"pthread_mutex_setprioceiling()", [""]), (r"pthread_mutex_trylock()", [""]), (r"pthread_mutex_unlock()", [""]), (r"pthread_mutexattr_destroy()", [""]), (r"pthread_mutexattr_getprioceiling()",[""]), (r"pthread_mutexattr_getprotocol()", [""]), (r"pthread_mutexattr_getpshared()", [""]), (r"pthread_mutexattr_gettype()", [""]), (r"pthread_mutexattr_init()", [""]), (r"pthread_mutexattr_setprioceiling()",[""]), (r"pthread_mutexattr_setprotocol()", [""]), (r"pthread_mutexattr_setpshared()", [""]), (r"pthread_mutexattr_settype()", [""]), (r"pthread_once()", [""]), (r"pthread_rwlock_destroy()", [""]), (r"pthread_rwlock_init()", [""]), (r"pthread_rwlock_rdlock()", [""]), (r"pthread_rwlock_tryrdlock()", [""]), (r"pthread_rwlock_trywrlock()", [""]), (r"pthread_rwlock_unlock()", [""]), (r"pthread_rwlock_wrlock()", [""]), (r"pthread_rwlockattr_destroy()", [""]), (r"pthread_rwlockattr_getpshared()", [""]), (r"pthread_rwlockattr_init()", [""]), (r"pthread_rwlockattr_setpshared()", [""]), (r"pthread_self()", [""]), (r"pthread_setcancelstate()", [""]), (r"pthread_setcanceltype()", [""]), (r"pthread_setconcurrency()", [""]), (r"pthread_setschedparam()", [""]), (r"pthread_setspecific()", [""]), (r"pthread_testcancel()", [""]), # ptsname - get name of the slave pseudo-terminal device (r"ptsname()", [""]), # putc - put a byte on a stream (r"putc()", [""]), # putchar - put byte on stdout stream (r"putchar()", [""]), # putenv - change or add a value to environment (r"putenv()", [""]), # putmsg, putpmsg - send a message on a STREAM (r"putmsg()", [""]), (r"putpmsg()", [""]), # puts - put a string on standard output (r"puts()", [""]), # putw - put a word on a stream (r"putw()", [""]), # putwc - put a wide-character on a stream (r"putwc()", ["", ""]), # putwchar - put a wide character from a stdin stream (r"putwchar()", [""]), # qsort - sort a table of data (r"qsort()", [""]), # raise - send a signal to the executing process (r"raise()", [""]), # rand, rand_r - pseudo-random number generator (r"rand()", [""]), (r"srand()", [""]), (r"rand_r()", [""]), # re_comp.h - regular-expression-matching functions for re_comp() (r"re_comp()", [""]), (r"re_exec()", [""]), # read, readv, pread - read from a file ("read()", [""]), ("readv()", [""]), # readdir, readdir_r - read directory (r"readdir()", ["", ""]), (r"readdir_r()", ["", ""]), # readlink - read the contents of a symbolic link ("readlink()", [""]), # realloc - memory reallocator ("realloc()", [""]), # realpath - resolve a pathname ("realpath()", [""]), # regcomp, regexec, regerror, regfree - regular expression matching (r"regcomp()", ["", ""]), (r"regexec()", ["", ""]), (r"regerror()", ["", ""]), (r"regfree()", ["", ""]), # remainder - remainder function (r"remainder()", [""]), # remove - remove files (r"remove()", [""]), # rename - rename a file (r"rename()", [""]), # rewind - reset file position indicator in a stream (r"rewind()", [""]), # rewinddir - reset position of directory stream to the beginning of a directory (r"rewinddir()", ["", ""]), # rindex - character string operations (r"rindex()", [""]), # rint - round-to-nearest integral value (r"rint()", [""]), # rmdir - remove a directory ("rmdir()", [""]), # scalb - load exponent of a radix-independent floating-point number (r"scalb()", [""]), # sched.h - execution scheduling (r"sched_get_priority_max()", [""]), (r"sched_get_priority_min()", [""]), (r"sched_getparam()", [""]), (r"sched_getscheduler()", [""]), (r"sched_rr_get_interval()", [""]), (r"sched_setparam()", [""]), (r"sched_setscheduler()", [""]), (r"sched_yield()", [""]), # seekdir - set position of directory stream (r"seekdir()", ["", ""]), # select - synchronous I/O multiplexing (r"select()", [""]), # semaphore.h - semaphores (r"sem_close()", [""]), (r"sem_destroy()", [""]), (r"sem_getvalue()", [""]), (r"sem_init()", [""]), (r"sem_open()", [""]), (r"sem_post()", [""]), (r"sem_trywait()", [""]), (r"sem_unlink()", [""]), (r"sem_wait()", [""]), # sys/sem.h - semaphore facility (r"semctl()", [""]), (r"semget()", [""]), (r"semop()", [""]), # setbuf - assign buffering to a stream (r"setbuf()", [""]), # setegid, seteuid - set effective group/user ID (r"setegid()", [""]), (r"seteuid()", [""]), # setgid - set-group-ID (r"setgid()", ["", ""]), # setgrent - reset group database to first entry # setkey - set encoding key (r"setkey()", [""]), # setpgid - set process group ID for job control (r"setpgid()", ["", ""]), # setpgrp - set process group ID (r"setpgrp()", [""]), # setregid - set real and effective group IDs (r"setregid()", [""]), # setreuid - set real and effective user IDs (r"setreuid()", [""]), # setsid - create session and set process group ID (r"setsid()", ["", ""]), # setuid - set-user-ID (r"setuid()", ["", ""]), # setvbuf - assign buffering to a stream (r"setvbuf()", [""]), # sys/shm.h - shared memory facility (r"shmat()", [""]), (r"shmctl()", [""]), (r"shmdt()", [""]), (r"shmget()", [""]), # setjmp.h - stack environment declarations (r"longjmp()", [""]), (r"siglongjmp()", [""]), (r"_longjmp()", [""]), (r"setjmp()", [""]), (r"sigsetjmp()", [""]), (r"_setjmp()", [""]), # signal.h - signals (r"bsd_signal()", [""]), (r"kill()", [""]), (r"killpg()", [""]), (r"pthread_kill()", [""]), (r"pthread_sigmask()", [""]), (r"sigaction()", [""]), (r"sigaddset()", [""]), (r"sigaltstack()", [""]), (r"sigdelset()", [""]), (r"sigemptyset()", [""]), (r"sigfillset()", [""]), (r"sighold()", [""]), (r"sigignore()", [""]), (r"siginterrupt()", [""]), (r"sigismember()", [""]), (r"signal()", [""]), (r"sigpause()", [""]), (r"sigpending()", [""]), (r"sigprocmask()", [""]), (r"sigqueue()", [""]), (r"sigrelse()", [""]), (r"sigset()", [""]), (r"sigstack()", [""]), (r"sigsuspend()", [""]), (r"sigtimedwait()", [""]), (r"sigwait()", [""]), (r"sigwaitinfo()", [""]), # sin - sine function (r"sin()", [""]), # sinh - hyperbolic sine function (r"sinh()", [""]), # sleep - suspend execution for an interval of time (r"sleep()", [""]), # fprintf, printf, snprintf, sprintf - print formatted output (r"fprintf()", [""]), (r"printf()", [""]), (r"snprintf()", [""]), (r"sprintf()", [""]), # sqrt - square root function (r"sqrt()", [""]), # stat - get file status (r"stat()", ["", ""]), # stdarg.h - handle variable argument list (r"va_start()", [""]), (r"va_arg()", [""]), (r"va_end()", [""]), # stddef.h - standard type definitions (r"offsetof()", [""]), # step - pattern match with regular expressions (r"step()", [""]), # strcasecmp, strncasecmp - case-insensitive string comparisons (r"strcasecmp()", [""]), (r"strncasecmp()", [""]), # string.h - string operations (r"memccpy()", [""]), (r"memchr()", [""]), (r"memcmp()", [""]), (r"memcpy()", [""]), (r"memmove()", [""]), (r"memset()", [""]), (r"strcat()", [""]), (r"strchr()", [""]), (r"strcmp()", [""]), (r"strcoll()", [""]), (r"strcpy()", [""]), (r"strcspn()", [""]), (r"strdup()", [""]), (r"strerror()", [""]), (r"strlen()", [""]), (r"strncat()", [""]), (r"strncmp()", [""]), (r"strncpy()", [""]), (r"strpbrk()", [""]), (r"strrchr()", [""]), (r"strspn()", [""]), (r"strstr()", [""]), (r"strtok()", [""]), (r"strtok_r()", [""]), (r"strxfrm()", [""]), # wctype.h - wide-character classification and mapping utilities (r"iswalnum()", [""]), (r"iswalpha()", [""]), (r"iswascii()", [""]), (r"iswcntrl()", [""]), (r"iswdigit()", [""]), (r"iswgraph()", [""]), (r"iswlower()", [""]), (r"iswprint()", [""]), (r"iswpunct()", [""]), (r"iswspace()", [""]), (r"iswupper()", [""]), (r"iswxdigit()", [""]), (r"iswctype()", [""]), (r"towctrans()", [""]), (r"towlower()", [""]), (r"towupper()", [""]), (r"wctrans()", [""]), (r"wctype()", [""]), # strftime - convert date and time to a string (r"strftime()", [""]), # strptime - date and time conversion (r"strptime()", [""]), # strtod - convert string to a double-precision number (r"strtod()", [""]), # strtol - convert string to a long integer (r"strtol()", [""]), # strtoul - convert string to an unsigned long (r"strtoul()", [""]), # strtoull - convert string to an unsigned long qlong (r"strtoull()", [""]), # swab - swap bytes (r"swab()", [""]), # symlink - make symbolic link to a file (r"symlink()", [""]), # sync - schedule filesystem updates (r"sync()", [""]), # sysconf - get configurable system variables (r"sysconf()", [""]), # system - issue a command (r"system()", [""]), # sys/wait.h - declarations for waiting (r"wait()", ["", ""]), (r"wait3()", ["", ""]), (r"waitid()", ["", ""]), (r"waitpid()", ["", ""]), (r"WEXITSTATUS()", ["", ""]), (r"WIFCONTINUED()", ["", ""]), (r"WIFEXITED()", ["", ""]), (r"WIFSIGNALED()", ["", ""]), (r"WIFSTOPPED()", ["", ""]), (r"WSTOPSIG()", ["", ""]), (r"WTERMSIG()", ["", ""]), # tan - tangent function (r"tan()", [""]), # tanh - hyperbolic tangent function (r"tanh()", [""]), # tcgetpgrp - get the foreground process group ID (r"tcgetpgrp()", ["", ""]), # tcsetpgrp - set the foreground process group ID (r"tcsetpgrp()", ["", ""]), # telldir - current location of a named directory stream (r"telldir()", [""]), # tempnam - create a name for a temporary file (r"tempnam()", [""]), # termios.h - define values for termios (r"cfgetispeed()", [""]), (r"cfgetospeed()", [""]), (r"cfsetispeed()", [""]), (r"cfsetospeed()", [""]), (r"tcdrain()", [""]), (r"tcflow()", [""]), (r"tcflush()", [""]), (r"tcgetattr()", [""]), (r"tcgetsid()", [""]), (r"tcsendbreak()", [""]), (r"tcsetattr()", [""]), # tdelete, tfind, tsearch, twalk - manage a binary search tree (r"tsearch()", [""]), (r"tfind()", [""]), (r"tdelete()", [""]), (r"twalk()", [""]), # time - get time (r"time()", [""]), # timer_create - create a per-process timer (r"timer_create()", ["", ""]), # timer_delete - delete a per-process timer (r"timer_delete()", ["", ""]), # timer_settime, timer_gettime, timer_getoverrun - per-process timers (r"timer_settime()", [""]), (r"timer_gettime()", [""]), (r"timer_getoverrun()", [""]), # times - get process and waited-for child process times (r"times()", [""]), # tmpfile - create a temporary file (r"tmpfile()", [""]), # tmpnam - create a name for a temporary file (r"tmpnam()", [""]), # ttyname, ttyname_r - find pathname of a terminal ("ttyname()", [""]), ("ttyname_r()", [""]), # ttyslot - find the slot of the current user in the user accounting database ("ttyslot()", [""]), # tzset - set time zone conversion information ("tzset()", [""]), # ualarm - set the interval timer ("ualarm()", [""]), # ulimit - get and set process limits ("ulimit()", [""]), # umask - set and get file mode creation mask (r"umask()", ["", ""]), # uname - get name of current system ("uname()", [""]), # ungetc - push byte back into input stream (r"ungetc()", [""]), # ungetwc - push wide-character code back into input stream (r"ungetwc()", ["", ""]), # unlink - remove a directory entry ("unlink()", [""]), # unlockpt - unlock a pseudo-terminal master/slave pair (r"unlockpt()", [""]), # usleep - suspend execution for an interval ("usleep()", [""]), # utime - set file access and modification times (r"utime()", ["", ""]), # utimes - set file access and modification times (r"utimes()", [""]), # valloc - page-aligned memory allocator (r"valloc()", [""]), # vfork - create new process; share virtual memory ("vfork()", [""]), # vfprintf, vprintf, vsnprintf, vsprintf - format output of a stdarg argument list (r"vfprintf()", ["", ""]), (r"vprintf()", ["", ""]), (r"vsnprintf()", ["", ""]), (r"vsprintf()", ["", ""]), # vfwprintf, vwprintf, vswprintf - wide-character formatted output of a stdarg argument list (r"vwprintf()", ["", "", ""]), (r"vfwprintf()", ["", "", ""]), (r"vswprintf()", ["", "", ""]), # wchar.h - wide-character types (r"wcrtomb()", [""]), # SuSv2 erroneously says (r"wcscat()", [""]), (r"wcschr()", [""]), (r"wcscmp()", [""]), (r"wcscoll()", [""]), (r"wcscpy()", [""]), (r"wcsftime()", [""]), (r"wcslen()", [""]), (r"wcsncat()", [""]), (r"wcsncmp()", [""]), (r"wcsncpy()", [""]), (r"wcspbrk()", [""]), (r"wcsrchr()", [""]), (r"wcsrtombs()", [""]), (r"wcsspn()", [""]), (r"wcsstr()", [""]), (r"wcstod()", [""]), (r"wcstok()", [""]), (r"wcstol()", [""]), (r"wcstoul()", [""]), (r"wcswcs()", [""]), (r"wcswidth()", [""]), (r"wcsxfrm()", [""]), (r"wctob()", [""]), (r"wcwidth()", [""]), (r"wmemchr()", [""]), (r"wmemcmp()", [""]), (r"wmemcpy()", [""]), (r"wmemmove()", [""]), (r"wmemset()", [""]), # wordexp.h - word-expansion types (r"wordexp()", [""]), (r"wordfree()", [""]), # write, writev, pwrite - write on a file (r"write()", [""]), (r"pwrite()", [""]), (r"writev()", [""]), # y0, y1, yn - Bessel functions of the second kind (r"y0()", [""]), (r"y1()", [""]), (r"yn()", [""]), # stdbool.h - standard boolean type (r"=\s*true", [""]), (r"=\s*false", [""]), # Headers mandated by SuS Version 2 Network Services. # sys/socket.h - Internet Protocol family (r"accept()", [""]), (r"bind()", [""]), (r"connect()", [""]), (r"getpeername()", [""]), (r"getsockname()", [""]), (r"getsockopt()", [""]), (r"listen()", [""]), (r"recv()", [""]), (r"recvfrom()", [""]), (r"recvmsg()", [""]), (r"send()", [""]), (r"sendmsg()", [""]), (r"sendto()", [""]), (r"setsockopt()", [""]), (r"shutdown()", [""]), (r"socket()", [""]), (r"socketpair()", [""]), # arpa/inet.h - definitions for internet operations (r"inet_addr()", [""]), (r"inet_lnaof()", [""]), (r"inet_makeaddr()", [""]), (r"inet_netof()", [""]), (r"inet_network()", [""]), (r"inet_ntoa()", [""]), (r"htonl()", [""]), (r"htons()", [""]), (r"ntohl()", [""]), (r"ntohs()", [""]), # netdb.h - definitions for network database operations (r"endhostent()", [""]), (r"endnetent()", [""]), (r"endprotoent()", [""]), (r"endservent()", [""]), (r"gethostbyaddr()", [""]), (r"gethostbyname()", [""]), (r"gethostent()", [""]), (r"getnetbyaddr()", [""]), (r"getnetbyname()", [""]), (r"getnetent()", [""]), (r"getprotobyname()", [""]), (r"getprotobynumber()",[""]), (r"getprotoent()", [""]), (r"getservbyname()", [""]), (r"getservbyport()", [""]), (r"getservent()", [""]), (r"sethostent()", [""]), (r"setnetent()", [""]), (r"setprotoent()", [""]), (r"setservent()", [""]), # net/if.h - mappings between network interface names and indexes (r"if_nametoindex()", [""]), (r"if_indextoname()", [""]), (r"if_nameindex()", [""]), (r"if_freenameindex()",[""]), # unistd.h - standard symbolic constants and types (r"gethostname()", [""]), # Linux only (r"syscall()", ["", ""]), # Originally from 4BSD # Dependencies observed on systems other than the Linux this was # developed under. (r"", ["", ""]), (r"", [""]) ) # fmt: on class Baton: "Ship progress indications to stderr." def __init__(self, prompt, endmsg=None): self.stream = sys.stderr self.stream.write(prompt + "...") if os.isatty(self.stream.fileno()): self.stream.write(" \b") self.stream.flush() self.count = 0 self.endmsg = endmsg self.time = time.time() def twirl(self, ch=None): if self.stream is None: return if os.isatty(self.stream.fileno()): if ch: self.stream.write(ch) else: self.stream.write("-/|\\"[self.count % 4]) self.stream.write("\b") self.stream.flush() self.count = self.count + 1 def end(self, msg=None): if msg is None: msg = self.endmsg if self.stream: self.stream.write("...(%2.2f sec) %s.\n" % (time.time() - self.time, msg)) class CSourceCleaner: "Remove comments and literals while preserving lines and token positions." def __init__(self): self.in_block_comment = False self.quote = None @staticmethod def blank(ch): if ch in "\r\n": return ch return " " def clean(self, line): "Return versions suitable for directive parsing and code scanning." directive = [] code = [] i = 0 while i < len(line): ch = line[i] if self.in_block_comment: if line.startswith("*/", i): directive.extend((" ", " ")) code.extend((" ", " ")) self.in_block_comment = False i += 2 else: directive.append(self.blank(ch)) code.append(self.blank(ch)) i += 1 elif self.quote is not None: directive.append(ch) code.append(self.blank(ch)) if ch == "\\" and i + 1 < len(line): directive.append(line[i + 1]) code.append(self.blank(line[i + 1])) i += 2 else: if ch in (self.quote, "\n"): self.quote = None i += 1 elif line.startswith("//", i): directive.extend(self.blank(rest) for rest in line[i:]) code.extend(self.blank(rest) for rest in line[i:]) break elif line.startswith("/*", i): directive.extend((" ", " ")) code.extend((" ", " ")) self.in_block_comment = True i += 2 elif ch in "\"'": self.quote = ch directive.append(ch) code.append(" ") i += 1 else: directive.append(ch) code.append(ch) i += 1 return ("".join(directive), "".join(code)) class InclusionMap: "Map the inclusion dependencies of a set of files and directories." @staticmethod def c_source(filename): "Predicate: return true if the filename appears to be C or C++ source." return ( filename.endswith(".c") or filename.endswith(".cpp") or filename.endswith(".cc") ) # pylint: disable=too-many-locals,too-many-branches,too-many-statements def __init__(self, roots, ignore, excludes, verbosity): "Build the initial inclusion map." self.verbosity = verbosity self.files = [] compiled = [] for r, h in requirements: if r.endswith("()"): # The lookbehinds exclude suffix and C++ method-name matches # without preventing a call at the beginning of a line. c = re.compile( r"(?)" + r.replace("()", r"\s*\(") ) else: c = re.compile(r) compiled.append((r, c, h)) # pylint: disable=too-many-nested-blocks for root in roots: if not os.path.isdir(root): if excludes and excludes.search(root): if verbosity > 1: print("deheader: %s excluded" % root) elif InclusionMap.c_source(root): self.files.append(root) else: sys.stderr.write("deheader: can't analyze %s\n" % root) else: sublist = [] for root, dirs, files in os.walk(root): dirs[:] = [x for x in dirs if not x.startswith(".")] for name in files: path = os.path.join(root, name) if excludes and excludes.search(path): if verbosity > 1: print("deheader: %s excluded" % root) elif InclusionMap.c_source(path): sublist.append(path) self.files += sublist self.files.sort() self.depends_on = {} self.requires = {} # pylint: disable=too-many-nested-blocks for sourcefile in self.files: includes = [] requires = [] seen = [] conditions = [] cleaner = CSourceCleaner() with open( sourcefile, encoding="ascii", errors="surrogateescape", newline="", ) as rfp: for i, line in enumerate(rfp): (directive_line, code_line) = cleaner.clean(line) c = match_preproc(["ifndef", "ifdef", "if"], directive_line) if c is not False: conditions.append(c) elif match_preproc("endif", directive_line) is not False: try: conditions.pop() except IndexError: sys.stderr.write( "%s:%d: unbalanced #endif\n" % (sourcefile, i + 1) ) sys.exit(1) else: f = match_preproc("include", directive_line) if f is not False: if verbosity >= PROGRESS_DEBUG: name = trim(f) print("deheader: %s includes %s" % (sourcefile, name)) if ignore and ignore.search(line): if verbosity >= PROGRESS_DEBUG: print( "deheader: ignoring %s (exclusion match with %s)." % (name, ignore.pattern) ) continue if not conditions or conditions == ["S_SPLINT_S"]: includes.append(line) elif verbosity > 1: print( "deheader: ignoring %s (conditional inclusion)" % name ) for r, c, h in compiled: if c.search(code_line): if not set(h).issubset(set(seen)): requires.append((h, r)) seen += h self.depends_on[sourcefile] = includes self.requires[sourcefile] = requires # Duplicate-header detection trimmedcount = {} for ref in map(trim, includes): trimmedcount[ref] = trimmedcount.get(ref, 0) + 1 for ref in trimmedcount: if trimmedcount[ref] > 1: print( "deheader: %s has more than one inclusion of %s" % (sourcefile, ref) ) trimmedcount = {} for ref in map(supertrim, includes): trimmedcount[ref] = trimmedcount.get(ref, 0) + 1 for ref in trimmedcount: if trimmedcount[ref] > 1: print( "deheader: %s has duplicates or colliding inclusions of %s" % (sourcefile, ref) ) def forget(self, sourcefile, header): "Forget a header dependency." self.depends_on[sourcefile].remove(header) def remember(self, sourcefile, header): "Undo forgetting of a dependency." self.depends_on[sourcefile].append(header) class SaveForModification: "Prepare a file to be modified, with rollback unless it is committed." def __init__(self, filename): self.filename = os.path.abspath(filename) self.stat = os.stat(self.filename) directory = os.path.dirname(self.filename) basename = os.path.basename(self.filename) (backup_fd, self.original) = tempfile.mkstemp( prefix=".%s.deheader-" % basename, suffix=".bak", dir=directory, ) try: with open(self.filename, "rb") as rfp, os.fdopen(backup_fd, "wb") as ofp: backup_fd = None shutil.copyfileobj(rfp, ofp) ofp.flush() os.fsync(ofp.fileno()) except BaseException: if backup_fd is not None: os.close(backup_fd) os.remove(self.original) self.original = None raise def __enter__(self): return self def __exit__(self, _exc_type, _exc_value, _traceback): if self.original is not None: self.revert() return False def remove_headers(self, removables): "Prepare a version with specified headers deleted." remove_counts = {} for line in removables: encoded = line.encode("ascii", errors="surrogateescape") remove_counts[encoded] = remove_counts.get(encoded, 0) + 1 with open(self.original, "rb") as rfp, open(self.filename, "r+b") as ofp: ofp.seek(0) ofp.truncate() for line in rfp: if remove_counts.get(line, 0): remove_counts[line] -= 1 continue ofp.write(line) ofp.flush() os.fsync(ofp.fileno()) def forget(self): "Commit the current contents and disable reversion." os.remove(self.original) self.original = None def revert(self): "Restore the original contents, timestamps, and inode metadata." if self.original is None: return with open(self.original, "rb") as rfp, open(self.filename, "r+b") as ofp: ofp.seek(0) ofp.truncate() shutil.copyfileobj(rfp, ofp) ofp.flush() os.fsync(ofp.fileno()) os.utime( self.filename, ns=(self.stat.st_atime_ns, self.stat.st_mtime_ns), follow_symlinks=True, ) os.remove(self.original) self.original = None def match_preproc(directives, line): if not isinstance(directives, list): directives = [directives] regexp = ( r"^[ \t\v\f]*#[ \t\v\f]*(?:" + "|".join(map(re.escape, directives)) + r")\b" ) m = re.match(regexp, line) if m: return line[m.span()[1] :].strip() return False def trim(line): "Get file reference from an #include, retaining <> if a system header." trimmed = re.sub( r"^[ \t\v\f]*#[ \t\v\f]*include\b", "", line, count=1 ).strip() if not trimmed: sys.stderr.write("deheader: malformed #include with no filename: %s\n" % line) sys.exit(1) if trimmed[0] in '"': return '"' + trimmed.split('"')[1] + '"' elif trimmed[0] == "<": return trimmed.split(">")[0] + ">" else: return repr(line) def supertrim(line): "Get file bare reference from an #include - used fr detecting duplicates/collisions." trimmed = re.sub( r"^[ \t\v\f]*#[ \t\v\f]*include\b", "", line, count=1 ).strip() if not trimmed: sys.stderr.write("deheader: malformed #include with no filename: %s\n" % line) sys.exit(1) if trimmed[0] in '"': return trimmed.split('"')[1] elif trimmed[0] == "<": return trimmed[1:].split(">", 1)[0] else: return repr(line) def clean(derived): "Clean a derived object file preparatory to test-compiling it" if os.path.exists(os.path.join(builddir, derived)): os.remove(os.path.join(builddir, derived)) elif os.path.exists("CMakeLists.txt"): subprocess.call(["make", "clean"]) # pylint: disable=too-many-arguments,too-many-statements,too-many-locals def build_command(maker, target): "Build a shell command, substituting a safely quoted target when requested." if "%s" not in maker: return maker return maker.replace("%s", shlex.quote(target)) def testcompile(source, maker, msg="", verbosity=0, showerrs=False, subdir=""): "Test-compile a sourcefile. Return the status and the compilation time" (stem, _suffix) = os.path.splitext(source) derived = stem + ".o" clean(os.path.join(subdir, derived)) command = build_command(maker, derived) olddir = os.getcwd() start = time.time() try: if len(subdir) > 0: os.chdir(subdir) (status, output) = getstatusoutput(command) finally: os.chdir(olddir) end = time.time() if verbosity >= COMMAND_DEBUG or (showerrs and status != 0): sys.stdout.write(output + "\n") if status: explain = "failed" if verbosity >= PROGRESS_DEBUG: explain += " (%d)" % status else: explain = "succeeded" if verbosity >= PROGRESS_DEBUG: print("deheader: %s%s %s." % (source, msg, explain)) clean(os.path.join(subdir, derived)) return (status, end - start) # pylint: disable=too-many-locals,too-many-nested-blocks,too-many-branches def c_analyze(sourcefile, maker, includes, requires, verbosity, subdir=""): "Given a C file and a list of includes, return those that can be omitted." # We'll remove headers in reverse order, because later unnecessary # headers might depend on earlier ones includes.reverse() unneeded = [] if verbosity == BATON_DEBUG: baton = Baton(sourcefile + ": ", "Done") saveit = SaveForModification(os.path.join(subdir, sourcefile)) try: while True: keepgoing = False for header in includes[:]: if verbosity == BATON_DEBUG: baton.twirl() retain = 0 for requirements, trigger in requires: for required in requirements: if required in header: if verbosity >= PROGRESS_DEBUG: print( "deheader: in %s, %s prevents uninclusion of %s" % ( os.path.join(subdir, sourcefile), trigger, trim(header), ) ) retain += 1 if not retain: saveit.remove_headers(unneeded + [header]) (st, _t) = testcompile( sourcefile, maker, " without %s" % trim(header), verbosity, showerrs=False, subdir=subdir, ) if st == 0: unneeded.append(header) includes.remove(header) keepgoing = True if not keepgoing: break finally: saveit.revert() if verbosity == BATON_DEBUG: baton.end() # Missing-require detection. Can't be merged with duplicate-header # detection because this has to be done after unneeded headers are removed. stillhere = list(map(trim, includes)) for requirement, trigger in requires: if not set(requirement).issubset(stillhere): print( "deheader: in %s, %s portability requires %s." % (os.path.join(subdir, sourcefile), trigger, ",".join(requirement)) ) return unneeded def deheader(sourcefile, maker, includes, requires, remove, verbose): # Sanity check against broken sourcefiles; we want this to # complain visibly if the sourcefile won't build at all. subdir = "" (st, _t) = testcompile(sourcefile, maker, verbosity=max(1, verbose), showerrs=False) if st != 0: subdir = os.path.dirname(sourcefile) sourcefile = os.path.basename(sourcefile) (st, _t) = testcompile( sourcefile, maker, verbosity=max(1, verbose), showerrs=True, subdir=subdir ) if st == 0: # Now do the analysis unneeded = [] if ( sourcefile.endswith(".c") or sourcefile.endswith(".cpp") or sourcefile.endswith(".cc") ): unneeded = c_analyze( sourcefile, maker, includes[:], requires, verbose, subdir=subdir ) if unneeded: for line in unneeded: print( "deheader: remove %s from %s" % (trim(line), os.path.join(subdir, sourcefile)) ) if remove: with SaveForModification(os.path.join(subdir, sourcefile)) as remove_it: remove_it.remove_headers(unneeded) remove_it.forget() return Summary([sourcefile], includes, unneeded) else: failed_source = os.path.join(subdir, sourcefile) sys.stderr.write( "deheader: basic compilation failed on %s\n" % (failed_source,) ) return Summary([sourcefile], includes, [], [failed_source]) # After-action analysis starts here class Summary: "Summarize results from a deheading." def __init__(self, filenames=None, includes=None, unneeded=None, failures=None): self.filenames = filenames or [] self.includes = includes or [] self.unneeded = unneeded or [] self.failures = failures or [] def __add__(self, other): result = Summary() result.filenames = self.filenames + other.filenames result.includes = self.includes + other.includes result.unneeded = self.unneeded + other.unneeded result.failures = self.failures + other.failures return result def has_unneeded_includes(self): return len(self.unneeded) > 0 def has_failures(self): return len(self.failures) > 0 def __repr__(self): summary = "%d files, %d includes, %d removable" % ( len(self.filenames), len(self.includes), len(self.unneeded), ) if self.failures: summary += ", %d failed" % len(self.failures) return summary if __name__ == "__main__": (options, arguments) = getopt.getopt( sys.argv[1:], "b:hi:m:qrvx:V", [ "builddir=", "help", "ignore=", "maker=", "quiet", "remove", "verbose", "exclude=", "version", ], ) maker = "make %s" builddir = "." verbose = 0 quiet = False remove = False ignores = [] exclusions = [] for switch, val in options: if switch in ("-h", "--help"): sys.stderr.write(__doc__) sys.exit(0) elif switch in ("-i", "--ignore"): ignores.append(val) elif switch in ("-m", "--maker"): maker = val elif switch in ("-b", "--builddir"): builddir = os.path.abspath(val) elif switch in ("-q", "--quiet"): quiet = True elif switch in ("-r", "--remove"): remove = True elif switch in ("-v", "--verbose"): verbose += 1 elif switch in ("-V", "--version"): print("deheader", version) raise SystemExit(0) elif switch in ("-x", "--exclude"): exclusions.append(val) if not ignores: ignore = None else: ignore = re.compile("|".join(ignores)) if not exclusions: exclusions = None else: exclusions = re.compile("|".join(exclusions)) if not arguments: arguments = ["."] summaries = [] inclusion_map = InclusionMap(arguments, ignore, exclusions, verbose) for sourcefile in sorted(inclusion_map.depends_on.keys()): summaries.append( deheader( sourcefile, maker, inclusion_map.depends_on[sourcefile], inclusion_map.requires[sourcefile], remove, verbose, ) ) stats = Summary() for summary in summaries: stats = stats + summary if not quiet: print("deheader: saw %s" % stats) if stats.has_unneeded_includes(): print("deheader: has unneeded includes %s" % " ".join(stats.unneeded)) if stats.has_failures(): raise SystemExit(2) if stats.has_unneeded_includes(): raise SystemExit(1) raise SystemExit(0) # End deheader-1.13/PaxHeaders/deheader.adoc0000644000000000000000000000013215235622021014644 xustar0030 mtime=1786192913.342012629 30 atime=1786192913.342012629 30 ctime=1786192913.342012629 deheader-1.13/deheader.adoc0000644000175000017500000001454215235622021014000 0ustar00esresr= deheader(1) :doctype: manpage :manmanual: Development Tools :mansource: deheader // spellcheck: add sourcefile sourcefiles sys builddir cmake gcc // spellcheck: add ifdef endif Werror Wfatal-errors makefile CFLAGS // spellcheck: add targetless pre-release deheadered POSIX // spellcheck: add subdirectory Subdirectories file-or-dir == Name deheader - report which includes in C or C++ compiles can be removed == Synopsis *deheader* [-h] [-m _command_] [-b _builddir_] [-i _pattern_] [-q] [-r] [-v] [-x _pattern_] [-V] [_file-or-dir_] == Description This tool takes a list of C or C++ sourcefiles and generates a report on which #includes can be omitted from them; also, what standard inclusions may be required for portability. The test, for each foo.c or foo.cc or foo.cpp, is simply whether "rm foo.o; make foo.o" returns a zero status (but the build command may be overridden). Exception: Under cmake, foo.o is a phony target. Therefore, when a "CMakeList.txt" is detected, "make clean" is done rather than "rm foo.o". Optionally, with the *-r* switch, the unneeded headers are removed from the sourcefiles. Don't use this option unless you have your sourcefiles safely under version control and can revert! If a sourcefile argument is a directory, the report is generated on all source files beneath it. Subdirectories beginning with a dot are assumed to be repository directories for version-control systems and ignored. If no arguments are given, the program runs as if the name of the current directory had been passed to it. Inclusions within the scope of #if/#ifdef/#else/#endif directives are left alone, because trying to reason about potential combinations of -D and U options would be too complicated and prone to weird errors. One exception: headers protected only by S_SPLINT_S, the conditional for blocking scanning by the static analysis tool splint(1), are scanned normally. The tool will also emit warnings about duplicate inclusions, and inclusions required for portability but not present. It is recommended that you arrange to compile with options that will stop the compiler on warnings when using this tool; otherwise it will report headers that only declare prototypes and return types (and thus throw only warnings) as being not required. Under gcc the compiler options to accomplish this are -Werror -Wfatal-errors. If your makefile follows normal conventions, running with *-m "make CFLAGS='-Werror -Wfatal-errors' %s"* may do the right thing; you can check this by running with -v -v -v to see what compilation commands are actually emitted. On each test compile, the original sourcefile is copied to a unique temporary backup and restored on interrupt or after processing with its original timestamp, unless the *-r* option was given and headers removed. If the -b option is given, it tells the program that generated .o files live in a file tree parallel to the source tree but rooted at the specified argument. If the argument is a relative path, it is interpreted relative to the directory in which *deheader* is run. If the first test compilation from the top-level directory fails, *deheader* descends into the subdirectory of the source file and retries compiling inside there. At verbosity level 0, only messages indicating removable headers are issued. At verbosity 1, test compilations are timed and progress indicated with a twirling-baton prompt. At verbosity level 2, you get verbose progress messages on the analysis. At verbosity level 3, you see the output from the make and compilation commands. If the -q (--quiet) option flag was not set, the last line of the output will be a statistical summary. Running *deheader* will leave a lot of binaries in your directory that were compiled in ways possibly not invoked by your normal build process. Running "make clean" afterwards (or the equivalent under whatever build system you are using) is strongly recommended. == Options *-h*:: Display some help and exit. *-m* _command_:: Set the build command used for test compiles. Defaults to 'make %s'. A %s in the build command is replaced with the shell-quoted make target. If there is no %s, the command is run unchanged; targetless builders such as meson can therefore be supported with, e.g. "-m 'ninja -C build'". *-b* _builddir_:: Set the build directory for object files. *-i* _pattern_:: Set a pattern for includes to be ignored. Takes a Python regular expression. *-q*:: Suppress statistical summary. *-r*:: Remove header inclusions from sourcefiles where they are not required. *-v*:: Set verbosity. *-x* _pattern_:: Exclude files with names matching the specified Python regexp. *-V*:: Show version of program and exit. == Return Values Returns 1 if unneeded includes were found, 2 if one or more files could not be compiled and analyzed, and 0 otherwise. Thus, you can use it for pre-release sanity checking in Makefile. == Bugs Very rarely, test-compiling after running with *-r* may show that this tool removed some headers that are actually required for your build. This can happen because *deheader* doesn't know about all the strange things your build system gets up to, and the problem of analyzing your build to understand them would be Turing-complete. Simply revert the altered files and continue. Due to minor variations in system headers, it is possible your program may not port correctly in older Unix variants after being deheadered. This is normally not a problem with the portion of the API specified by POSIX and ANSI C, but may be for headers that are not standardized or only weakly standardized. The sockets API (; (home page at http://www.catb.org/~esr/). deheader-1.13/PaxHeaders/Makefile0000644000000000000000000000013215235622021013713 xustar0030 mtime=1786192913.342012629 30 atime=1786192913.342012629 30 ctime=1786192913.342012629 deheader-1.13/Makefile0000644000175000017500000000416115235622021013043 0ustar00esresr# # makefile for `deheader' # # SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause PREFIX ?= /usr/local BINDIR ?= $(PREFIX)/bin DATADIR ?= $(PREFIX)/share MANDIR ?= $(DATADIR)/man VERSION=$(shell sed /tmp/regress @diff -u regress.chk /tmp/regress @./setpython python3 @-../deheader -v -v . >/tmp/regress @diff -u regress.chk /tmp/regress @python3 test_deheader.py @./setpython python @rm /tmp/regress checkfile: @-../deheader -v -v . >regress.chk refine: for x in $(SOURCES); do echo "$$x"; ../deheader $$x || exit 1; done # Verify that the test sources build correctly when unaltered verify: for x in $(SOURCES:.c=.o); do make CFLAGS='-Werror -Wfatal-errors' $$x; done clean: rm -f *.o *~ deheader-1.13/tests/PaxHeaders/README0000644000000000000000000000013215235622021014275 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/README0000644000175000017500000000016115235622021013421 0ustar00esresrThis directory contains C sourcfiles intended to test deheader, and a check against which to compare the output. deheader-1.13/tests/PaxHeaders/regress.chk0000644000000000000000000000013215235622021015556 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/regress.chk0000644000175000017500000002240315235622021014705 0ustar00esresrdeheader: ./a64l.c includes deheader: ./abort.c includes deheader: ./abs.c includes deheader: ./access.c includes deheader: ./acos.c includes deheader: ./acosh.c includes deheader: ./alarm.c includes deheader: ./asin.c includes deheader: ./asinh.c includes deheader: ./atan.c includes deheader: ./atan2.c includes deheader: ./atanh.c includes deheader: ./atexit.c includes deheader: ./atof.c includes deheader: ./atoi.c includes deheader: ./atol.c includes deheader: ./basename.c includes deheader: ./bcmp.c includes deheader: ./bcopy.c includes deheader: ./brk.c includes deheader: ./bsd_signal.c includes deheader: ./bsort.c includes deheader: ignoring (conditional inclusion) deheader: ./bsort.c includes deheader: ignoring (conditional inclusion) deheader: ./bsort.c includes deheader: ./btowc.c includes deheader: ./btowc.c includes deheader: ./bzero.c includes deheader: ./calloc.c includes deheader: ./catclose.c includes deheader: ./catgets.c includes deheader: ./catopen.c includes deheader: ./cbrt.c includes deheader: ./ceil.c includes deheader: ./cfgetispeed.c includes deheader: ./cfgetospeed.c includes deheader: ./cfsetispeed.c includes deheader: ./cfsetospeed.c includes deheader: ./chdir.c includes deheader: ./chmod.c includes deheader: ./chmod.c includes deheader: ./chown.c includes deheader: ./chown.c includes deheader: ./chroot.c includes deheader: ./clearerr.c includes deheader: ./clock.c includes deheader: ./clock_getres.c includes deheader: ./clock_gettime.c includes deheader: ./clock_settime.c includes deheader: ./close.c includes deheader: ./closedir.c includes deheader: ./closedir.c includes deheader: ./crypt.c includes deheader: ./ctime.c includes deheader: ./duplicate.c includes deheader: ./duplicate.c includes deheader: ./duplicate.c has more than one inclusion of deheader: ./duplicate.c has duplicates or colliding inclusions of stdio.h deheader: ./fchmod.c includes deheader: ./fchown.c includes deheader: ./fclose.c includes deheader: ./fstat.c includes deheader: ./fstat.c includes deheader: ./nonutf.c includes deheader: ./sbrk.c includes deheader: ./string.c includes deheader: ./umask.c includes deheader: ./umask.c includes deheader: ./a64l.c succeeded. deheader: in ./a64l.c, a64l() prevents uninclusion of deheader: ./abort.c succeeded. deheader: in ./abort.c, abort() prevents uninclusion of deheader: ./abs.c succeeded. deheader: in ./abs.c, abs() prevents uninclusion of deheader: ./access.c succeeded. deheader: in ./access.c, access() prevents uninclusion of deheader: ./acos.c succeeded. deheader: in ./acos.c, acos() prevents uninclusion of deheader: ./acosh.c succeeded. deheader: in ./acosh.c, acosh() prevents uninclusion of deheader: ./alarm.c succeeded. deheader: in ./alarm.c, alarm() prevents uninclusion of deheader: ./asin.c succeeded. deheader: in ./asin.c, asin() prevents uninclusion of deheader: ./asinh.c succeeded. deheader: in ./asinh.c, asinh() prevents uninclusion of deheader: ./atan.c succeeded. deheader: in ./atan.c, atan() prevents uninclusion of deheader: ./atan2.c succeeded. deheader: in ./atan2.c, atan2() prevents uninclusion of deheader: ./atanh.c succeeded. deheader: in ./atanh.c, atanh() prevents uninclusion of deheader: ./atexit.c succeeded. deheader: in ./atexit.c, atexit() prevents uninclusion of deheader: ./atof.c succeeded. deheader: in ./atof.c, atof() prevents uninclusion of deheader: ./atoi.c succeeded. deheader: in ./atoi.c, atoi() prevents uninclusion of deheader: ./atol.c succeeded. deheader: in ./atol.c, atol() prevents uninclusion of deheader: ./basename.c succeeded. deheader: in ./basename.c, basename() prevents uninclusion of deheader: ./bcmp.c succeeded. deheader: in ./bcmp.c, bcmp() prevents uninclusion of deheader: ./bcopy.c succeeded. deheader: in ./bcopy.c, bcopy() prevents uninclusion of deheader: ./brk.c succeeded. deheader: in ./brk.c, brk() prevents uninclusion of deheader: ./bsd_signal.c succeeded. deheader: in ./bsd_signal.c, bsd_signal() prevents uninclusion of deheader: ./bsort.c succeeded. deheader: in ./bsort.c, bsearch() prevents uninclusion of deheader: in ./bsort.c, strcoll() portability requires . deheader: in ./bsort.c, scanf() portability requires . deheader: ./btowc.c succeeded. deheader: in ./btowc.c, btowc() prevents uninclusion of deheader: in ./btowc.c, btowc() prevents uninclusion of deheader: ./bzero.c succeeded. deheader: in ./bzero.c, bzero() prevents uninclusion of deheader: ./calloc.c succeeded. deheader: in ./calloc.c, calloc() prevents uninclusion of deheader: ./catclose.c succeeded. deheader: in ./catclose.c, catclose() prevents uninclusion of deheader: ./catgets.c succeeded. deheader: in ./catgets.c, catgets() prevents uninclusion of deheader: ./catopen.c succeeded. deheader: in ./catopen.c, catopen() prevents uninclusion of deheader: ./cbrt.c succeeded. deheader: in ./cbrt.c, cbrt() prevents uninclusion of deheader: ./ceil.c succeeded. deheader: in ./ceil.c, ceil() prevents uninclusion of deheader: ./cfgetispeed.c succeeded. deheader: in ./cfgetispeed.c, cfgetispeed() prevents uninclusion of deheader: ./cfgetospeed.c succeeded. deheader: in ./cfgetospeed.c, cfgetospeed() prevents uninclusion of deheader: ./cfsetispeed.c succeeded. deheader: in ./cfsetispeed.c, cfsetispeed() prevents uninclusion of deheader: ./cfsetospeed.c succeeded. deheader: in ./cfsetospeed.c, cfsetospeed() prevents uninclusion of deheader: ./chdir.c succeeded. deheader: in ./chdir.c, chdir() prevents uninclusion of deheader: ./chmod.c succeeded. deheader: in ./chmod.c, chmod() prevents uninclusion of deheader: in ./chmod.c, chmod() prevents uninclusion of deheader: ./chown.c succeeded. deheader: in ./chown.c, chown() prevents uninclusion of deheader: in ./chown.c, chown() prevents uninclusion of deheader: ./chroot.c succeeded. deheader: in ./chroot.c, chroot() prevents uninclusion of deheader: ./clearerr.c succeeded. deheader: in ./clearerr.c, clearerr() prevents uninclusion of deheader: ./clock.c succeeded. deheader: in ./clock.c, clock() prevents uninclusion of deheader: ./clock_getres.c succeeded. deheader: in ./clock_getres.c, clock_getres() prevents uninclusion of deheader: ./clock_gettime.c succeeded. deheader: in ./clock_gettime.c, clock_gettime() prevents uninclusion of deheader: ./clock_settime.c succeeded. deheader: in ./clock_settime.c, clock_settime() prevents uninclusion of deheader: ./close.c succeeded. deheader: in ./close.c, close() prevents uninclusion of deheader: ./closedir.c succeeded. deheader: in ./closedir.c, closedir() prevents uninclusion of deheader: in ./closedir.c, closedir() prevents uninclusion of deheader: ./crypt.c succeeded. deheader: in ./crypt.c, crypt() prevents uninclusion of deheader: ./ctime.c succeeded. deheader: in ./ctime.c, ctime() prevents uninclusion of deheader: ./duplicate.c succeeded. deheader: ./duplicate.c without succeeded. deheader: ./duplicate.c without succeeded. deheader: remove from ./duplicate.c deheader: remove from ./duplicate.c deheader: ./fchmod.c succeeded. deheader: in ./fchmod.c, fchmod() prevents uninclusion of deheader: ./fchown.c succeeded. deheader: in ./fchown.c, fchown() prevents uninclusion of deheader: ./fclose.c succeeded. deheader: in ./fclose.c, fclose() prevents uninclusion of deheader: ./fstat.c succeeded. deheader: in ./fstat.c, fstat() prevents uninclusion of deheader: in ./fstat.c, fstat() prevents uninclusion of deheader: ./noheaders.c succeeded. deheader: ./nonutf.c succeeded. deheader: in ./nonutf.c, printf() prevents uninclusion of deheader: ./sbrk.c succeeded. deheader: in ./sbrk.c, sbrk() prevents uninclusion of deheader: ./string.c succeeded. deheader: ./string.c without succeeded. deheader: remove from ./string.c deheader: ./umask.c succeeded. deheader: in ./umask.c, umask() prevents uninclusion of deheader: in ./umask.c, umask() prevents uninclusion of deheader: saw 57 files, 63 includes, 3 removable deheader: has unneeded includes #include #include #include deheader-1.13/tests/PaxHeaders/setpython0000644000000000000000000000013215235622021015375 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/setpython0000755000175000017500000000104715235622021014530 0ustar00esresr#!/bin/sh # # setpython - create a local link from 'python' to a specified version # # This script is used to to redirect the 'python' in a shebang line to # a specified version when running regression tests. if [ "$1" = python ] || [ "$1" = python2 ] || [ "$1" = python3 ] then p=$(command -v "$1") case $p in */bin/*) # shellcheck disable=SC2086 ln -sf "$p" ./python; echo "python -> $p" ;; *) #saved=`readlink ./python 2>/dev/null` rm -f ./python ;; esac else echo "setpython: unrecognized python version" >&2 exit 1 fi deheader-1.13/tests/PaxHeaders/a64l.c0000644000000000000000000000013215235622021014327 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/a64l.c0000644000175000017500000000030615235622021013454 0ustar00esresr/* * Items: a64l(, l64a( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void) a64l("2317"); (void) l64a(2317); } deheader-1.13/tests/PaxHeaders/abort.c0000644000000000000000000000013215235622021014670 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/abort.c0000644000175000017500000000023415235622021014015 0ustar00esresr/* * Items: abort( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { abort(); } deheader-1.13/tests/PaxHeaders/abs.c0000644000000000000000000000013215235622021014326 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/abs.c0000644000175000017500000000023315235622021013452 0ustar00esresr/* * Items: abs( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { abs(-23); } deheader-1.13/tests/PaxHeaders/access.c0000644000000000000000000000013215235622021015022 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/access.c0000644000175000017500000000052615235622021014153 0ustar00esresr/* * Items: access( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { /* * Note: use of a symbolic constant like F_OK *will* * cause the compile to fail and the requrement * for to be tetected. */ (void)access("/dev/null", 0); } deheader-1.13/tests/PaxHeaders/acos.c0000644000000000000000000000013215235622021014506 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/acos.c0000644000175000017500000000023515235622021013634 0ustar00esresr/* * Items: acos( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { acos(-23.0); } deheader-1.13/tests/PaxHeaders/acosh.c0000644000000000000000000000013215235622021014656 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/acosh.c0000644000175000017500000000023715235622021014006 0ustar00esresr/* * Items: acosh( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { acosh(-23.0); } deheader-1.13/tests/PaxHeaders/alarm.c0000644000000000000000000000013215235622021014655 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/alarm.c0000644000175000017500000000023615235622021014004 0ustar00esresr/* * Items: alarm( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { alarm(23); } deheader-1.13/tests/PaxHeaders/asin.c0000644000000000000000000000013215235622021014513 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/asin.c0000644000175000017500000000023515235622021013641 0ustar00esresr/* * Items: asin( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { asin(-23.0); } deheader-1.13/tests/PaxHeaders/asinh.c0000644000000000000000000000013215235622021014663 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/asinh.c0000644000175000017500000000023715235622021014013 0ustar00esresr/* * Items: asinh( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { asinh(-23.0); } deheader-1.13/tests/PaxHeaders/atan.c0000644000000000000000000000013215235622021014504 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/atan.c0000644000175000017500000000023515235622021013632 0ustar00esresr/* * Items: atan( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { atan(-23.0); } deheader-1.13/tests/PaxHeaders/atan2.c0000644000000000000000000000013215235622021014566 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/atan2.c0000644000175000017500000000024515235622021013715 0ustar00esresr/* * Items: atan2( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { atan2(-23.0, 17.0); } deheader-1.13/tests/PaxHeaders/atanh.c0000644000000000000000000000013215235622021014654 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/atanh.c0000644000175000017500000000023715235622021014004 0ustar00esresr/* * Items: atanh( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { atanh(-23.0); } deheader-1.13/tests/PaxHeaders/atexit.c0000644000000000000000000000013215235622021015057 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/atexit.c0000644000175000017500000000023615235622021014206 0ustar00esresr/* * Items: atexit( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { atexit(NULL); } deheader-1.13/tests/PaxHeaders/atof.c0000644000000000000000000000013215235622021014512 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/atof.c0000644000175000017500000000026015235622021013636 0ustar00esresr/* * Items: atofl(, l64a( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void) atof("2317"); } deheader-1.13/tests/PaxHeaders/atoi.c0000644000000000000000000000013215235622021014515 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/atoi.c0000644000175000017500000000026015235622021013641 0ustar00esresr/* * Items: atoil(, l64a( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void) atoi("2317"); } deheader-1.13/tests/PaxHeaders/atol.c0000644000000000000000000000013215235622021014520 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/atol.c0000644000175000017500000000026015235622021013644 0ustar00esresr/* * Items: atoll(, l64a( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void) atol("2317"); } deheader-1.13/tests/PaxHeaders/basename.c0000644000000000000000000000013215235622021015334 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/basename.c0000644000175000017500000000026315235622021014463 0ustar00esresr/* * Items: basename( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void)basename("/dev/null"); } deheader-1.13/tests/PaxHeaders/bcmp.c0000644000000000000000000000013215235622021014502 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/bcmp.c0000644000175000017500000000026115235622021013627 0ustar00esresr/* * Items: bcmp( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void) bcmp("aaa", "bbb", 3); } deheader-1.13/tests/PaxHeaders/bcopy.c0000644000000000000000000000013215235622021014675 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/bcopy.c0000644000175000017500000000024715235622021014026 0ustar00esresr/* * Items: bcopy( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void) bcopy(0, 0, 0); } deheader-1.13/tests/PaxHeaders/brk.c0000644000000000000000000000013215235622021014337 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/brk.c0000644000175000017500000000023015235622021013460 0ustar00esresr/* * Items: brk( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { brk(NULL); } deheader-1.13/tests/PaxHeaders/bsd_signal.c0000644000000000000000000000013215235622021015666 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/bsd_signal.c0000644000175000017500000000035315235622021015015 0ustar00esresr/* * Items: bsd_signal( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #define _XOPEN_SOURCE 500 #include void handler(int sig) { } int main(int arg, char **argv) { (void) bsd_signal(0, handler); } deheader-1.13/tests/PaxHeaders/bsort.c0000644000000000000000000000013215235622021014712 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/bsort.c0000644000175000017500000000221515235622021014040 0ustar00esresr/* * Items: bsort( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ /* example taken pretty much directly from SuS */ #ifndef __DEHEADER__ #include #include #endif #include #define TABSIZE 1000 struct node { /* these are stored in the table */ char *string; int length; }; struct node table[TABSIZE]; /* table to be searched */ int node_compare(const void *node1, const void *node2) { return strcoll(((const struct node *)node1)->string, ((const struct node *)node2)->string); } int main(int argc, char **argv) { struct node *node_ptr, node; char str_space[20]; /* space to read string into */ node.string = str_space; while (scanf("%s", node.string) != EOF) { node_ptr = (struct node *)bsearch((void *)(&node), (void *)table, TABSIZE, sizeof(struct node), node_compare); if (node_ptr != NULL) { (void)printf("string = %20s, length = %d\n", node_ptr->string, node_ptr->length); } else { (void)printf("not found: %s\n", node.string); } } } deheader-1.13/tests/PaxHeaders/btowc.c0000644000000000000000000000013215235622021014677 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/btowc.c0000644000175000017500000000026715235622021014032 0ustar00esresr/* * Items: btowc( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include #include int main(int arg, char **argv) { (void)btowc('a'); } deheader-1.13/tests/PaxHeaders/bzero.c0000644000000000000000000000013215235622021014702 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/bzero.c0000644000175000017500000000025015235622021014025 0ustar00esresr/* * Items: bzero( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void) bzero(0, 0); } deheader-1.13/tests/PaxHeaders/calloc.c0000644000000000000000000000013215235622021015016 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/calloc.c0000644000175000017500000000076415235622021014153 0ustar00esresr/* * Items: calloc( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include // Required to shut up gcc #define IGNORE(r) \ do { \ if (r) { \ } \ } while (0) int main(int arg, char **argv) { IGNORE(calloc(0, 0)); } deheader-1.13/tests/PaxHeaders/catclose.c0000644000000000000000000000013215235622021015356 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/catclose.c0000644000175000017500000000025415235622021014505 0ustar00esresr/* * Items: catclose( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void) catclose(0); } deheader-1.13/tests/PaxHeaders/catgets.c0000644000000000000000000000013215235622021015213 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/catgets.c0000644000175000017500000000027215235622021014342 0ustar00esresr/* * Items: catgets( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void) catgets(0, 0, 0, "foobar"); } deheader-1.13/tests/PaxHeaders/catopen.c0000644000000000000000000000013215235622021015212 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/catopen.c0000644000175000017500000000026415235622021014342 0ustar00esresr/* * Items: catopen( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void) catopen("foobar", 0); } deheader-1.13/tests/PaxHeaders/cbrt.c0000644000000000000000000000013215235622021014513 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/cbrt.c0000644000175000017500000000023415235622021013640 0ustar00esresr/* * Items: cbrt( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { cbrt(23.0); } deheader-1.13/tests/PaxHeaders/ceil.c0000644000000000000000000000013215235622021014475 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/ceil.c0000644000175000017500000000023415235622021013622 0ustar00esresr/* * Items: ceil( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { ceil(23.0); } deheader-1.13/tests/PaxHeaders/cfgetispeed.c0000644000000000000000000000013215235622021016043 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/cfgetispeed.c0000644000175000017500000000030115235622021015163 0ustar00esresr/* * Items: cfgetispeed( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { struct termios t; cfgetispeed(&t); } deheader-1.13/tests/PaxHeaders/cfgetospeed.c0000644000000000000000000000013215235622021016051 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/cfgetospeed.c0000644000175000017500000000030115235622021015171 0ustar00esresr/* * Items: cfgetospeed( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { struct termios t; cfgetospeed(&t); } deheader-1.13/tests/PaxHeaders/cfsetispeed.c0000644000000000000000000000013215235622021016057 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/cfsetispeed.c0000644000175000017500000000030415235622021015202 0ustar00esresr/* * Items: cfsetispeed( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { struct termios t; cfsetispeed(&t, 0); } deheader-1.13/tests/PaxHeaders/cfsetospeed.c0000644000000000000000000000013215235622021016065 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/cfsetospeed.c0000644000175000017500000000030415235622021015210 0ustar00esresr/* * Items: cfsetospeed( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { struct termios t; cfsetospeed(&t, 0); } deheader-1.13/tests/PaxHeaders/chdir.c0000644000000000000000000000013215235622021014652 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/chdir.c0000644000175000017500000000024515235622021014001 0ustar00esresr/* * Items: chdir( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void)chdir("/"); } deheader-1.13/tests/PaxHeaders/chmod.c0000644000000000000000000000013215235622021014653 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/chmod.c0000644000175000017500000000030115235622021013773 0ustar00esresr/* * Items: chmod( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include #include int main(int arg, char **argv) { (void)chmod("/", 0); } deheader-1.13/tests/PaxHeaders/chown.c0000644000000000000000000000013215235622021014677 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/chown.c0000644000175000017500000000030215235622021014020 0ustar00esresr/* * Items: chown( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include #include int main(int arg, char **argv) { (void)chown("/", 0, 0); } deheader-1.13/tests/PaxHeaders/chroot.c0000644000000000000000000000013215235622021015057 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/chroot.c0000644000175000017500000000024715235622021014210 0ustar00esresr/* * Items: chroot( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void)chroot("/"); } deheader-1.13/tests/PaxHeaders/clearerr.c0000644000000000000000000000013215235622021015360 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/clearerr.c0000644000175000017500000000025015235622021014503 0ustar00esresr/* * Items: clearerr( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void)clearerr(stdin); } deheader-1.13/tests/PaxHeaders/clock.c0000644000000000000000000000013215235622021014654 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/clock.c0000644000175000017500000000023415235622021014001 0ustar00esresr/* * Items: clock( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void)clock(); } deheader-1.13/tests/PaxHeaders/clock_getres.c0000644000000000000000000000013215235622021016225 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/clock_getres.c0000644000175000017500000000031015235622021015345 0ustar00esresr/* * Items: clock_getres( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { struct timespec ts; (void)clock_getres(0, &ts); } deheader-1.13/tests/PaxHeaders/clock_gettime.c0000644000000000000000000000013215235622021016372 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/clock_gettime.c0000644000175000017500000000031215235622021015514 0ustar00esresr/* * Items: clock_gettime( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { struct timespec ts; (void)clock_gettime(0, &ts); } deheader-1.13/tests/PaxHeaders/clock_settime.c0000644000000000000000000000013215235622021016406 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/clock_settime.c0000644000175000017500000000031215235622021015530 0ustar00esresr/* * Items: clock_settime( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { struct timespec ts; (void)clock_settime(0, &ts); } deheader-1.13/tests/PaxHeaders/close.c0000644000000000000000000000013215235622021014666 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/close.c0000644000175000017500000000024315235622021014013 0ustar00esresr/* * Items: close( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void)close(0); } deheader-1.13/tests/PaxHeaders/closedir.c0000644000000000000000000000013215235622021015365 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/closedir.c0000644000175000017500000000027415235622021014516 0ustar00esresr/* * Items: closedir( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux */ #include #include int main(int arg, char **argv) { (void)closedir(0); } deheader-1.13/tests/PaxHeaders/crypt.c0000644000000000000000000000013215235622021014722 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/crypt.c0000644000175000017500000000025715235622021014054 0ustar00esresr/* * Items: crypt( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void)crypt("foo", "salt"); } deheader-1.13/tests/PaxHeaders/ctime.c0000644000000000000000000000013215235622021014662 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/ctime.c0000644000175000017500000000024015235622021014004 0ustar00esresr/* * Items: ctime( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void)ctime(NULL); } deheader-1.13/tests/PaxHeaders/duplicate.c0000644000000000000000000000013215235622021015533 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/duplicate.c0000644000175000017500000000020015235622021014651 0ustar00esresr/* this file tests detection of duplicate heafers */ #include #include int main(int arg, char **argv) { } deheader-1.13/tests/PaxHeaders/fchmod.c0000644000000000000000000000013215235622021015021 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/fchmod.c0000644000175000017500000000025215235622021014146 0ustar00esresr/* * Items: fchmod( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void)fchmod(0, 0); } deheader-1.13/tests/PaxHeaders/fchown.c0000644000000000000000000000013215235622021015045 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/fchown.c0000644000175000017500000000025315235622021014173 0ustar00esresr/* * Items: fchown( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void)fchown(0, 0, 0); } deheader-1.13/tests/PaxHeaders/fclose.c0000644000000000000000000000013215235622021015034 xustar0030 mtime=1786192913.342780282 30 atime=1786192913.342780282 30 ctime=1786192913.342780282 deheader-1.13/tests/fclose.c0000644000175000017500000000024415235622021014162 0ustar00esresr/* * Items: fclose( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { (void)fclose(stdin); } deheader-1.13/tests/PaxHeaders/fstat.c0000644000000000000000000000013215235622021014702 xustar0030 mtime=1786192913.343012648 30 atime=1786192913.343012648 30 ctime=1786192913.343012648 deheader-1.13/tests/fstat.c0000644000175000017500000000027115235622021014030 0ustar00esresr/* * Items: fstat( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include #include int main(int arg, char **argv) { fstat(0, 0); } deheader-1.13/tests/PaxHeaders/noheaders.c0000644000000000000000000000013215235622021015531 xustar0030 mtime=1786192913.343012648 30 atime=1786192913.343012648 30 ctime=1786192913.343012648 deheader-1.13/tests/noheaders.c0000644000175000017500000000012215235622021014652 0ustar00esresr/* this file has no headers and needs none */ int main(int arg, char **argv) { } deheader-1.13/tests/PaxHeaders/nonutf.c0000644000000000000000000000013215235622021015072 xustar0030 mtime=1786192913.343012648 30 atime=1786192913.343012648 30 ctime=1786192913.343012648 deheader-1.13/tests/nonutf.c0000644000175000017500000000027215235622021014221 0ustar00esresr/* * Test that deheader doesn't choke * on the non-UTF-8 characters in the next line. * * ’ ’ */ #include int mail() { printf("ABC\n"); return 0; } deheader-1.13/tests/PaxHeaders/sbrk.c0000644000000000000000000000013215235622021014522 xustar0030 mtime=1786192913.343012648 30 atime=1786192913.343012648 30 ctime=1786192913.343012648 deheader-1.13/tests/sbrk.c0000644000175000017500000000023415235622021013647 0ustar00esresr/* * Items: sbrk( * Standardized-By: SuS * Not-Detected-by: gcc-4.4.3 + Linux */ #include int main(int arg, char **argv) { sbrk(23); } deheader-1.13/tests/PaxHeaders/string.c0000644000000000000000000000013215235622021015067 xustar0030 mtime=1786192913.343012648 30 atime=1786192913.343012648 30 ctime=1786192913.343012648 deheader-1.13/tests/string.c0000644000175000017500000000015215235622021014213 0ustar00esresr/* this file has string.h but doesn't need it */ #include int main(int arg, char **argv) { } deheader-1.13/tests/PaxHeaders/umask.c0000644000000000000000000000013215235622021014701 xustar0030 mtime=1786192913.343012648 30 atime=1786192913.343012648 30 ctime=1786192913.343012648 deheader-1.13/tests/umask.c0000644000175000017500000000031415235622021014025 0ustar00esresr/* * Items: umask( * Standardized-By: SuS * Detected-by: gcc-4.4.3 + Linux * Not-detected-by: BSD */ #include #include int main(int arg, char **argv) { umask(777); } deheader-1.13/tests/PaxHeaders/test_deheader.py0000644000000000000000000000013215235622021016567 xustar0030 mtime=1786192913.343012648 30 atime=1786192913.343012648 30 ctime=1786192913.343012648 deheader-1.13/tests/test_deheader.py0000644000175000017500000002651715235622021015730 0ustar00esresr#!/usr/bin/env python3 """Focused regression tests for the deheader command-line tool.""" import importlib.machinery import importlib.util import os import pathlib import stat import subprocess import sys import tempfile import unittest sys.dont_write_bytecode = True PROJECT_ROOT = pathlib.Path(__file__).resolve().parent.parent DEHEADER = PROJECT_ROOT / "deheader" def load_deheader_module(): """Load the extensionless executable without running its CLI.""" loader = importlib.machinery.SourceFileLoader("deheader_module", str(DEHEADER)) spec = importlib.util.spec_from_loader(loader.name, loader) module = importlib.util.module_from_spec(spec) loader.exec_module(module) return module DEHEADER_MODULE = load_deheader_module() def run_deheader(*arguments): """Run the CLI and capture its output without imposing an expected status.""" return subprocess.run( [sys.executable, str(DEHEADER), *arguments], cwd=PROJECT_ROOT, check=False, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) class SaveForModificationTests(unittest.TestCase): """Exercise rollback and commit behavior without invoking a compiler.""" ORIGINAL = b"#include \r\nint answer = 42;\r\n" MODIFIED = b"int answer = 42;\r\n" INCLUDE = "#include \r\n" def setUp(self): self.tempdir = tempfile.TemporaryDirectory() self.directory = pathlib.Path(self.tempdir.name) def tearDown(self): self.tempdir.cleanup() def make_source(self, name="sample.c"): source = self.directory / name source.write_bytes(self.ORIGINAL) source.chmod(0o640) timestamp = 1_600_000_000_123_456_789 os.utime(source, ns=(timestamp, timestamp)) return source def test_rollback_restores_contents_timestamp_and_inode(self): source = self.make_source() original_stat = source.stat() with DEHEADER_MODULE.SaveForModification(source) as saved: saved.remove_headers([self.INCLUDE]) self.assertEqual(source.read_bytes(), self.MODIFIED) self.assertEqual(source.stat().st_ino, original_stat.st_ino) self.assertEqual(stat.S_IMODE(source.stat().st_mode), 0o640) restored_stat = source.stat() self.assertEqual(source.read_bytes(), self.ORIGINAL) self.assertEqual(restored_stat.st_ino, original_stat.st_ino) self.assertEqual(restored_stat.st_mtime_ns, original_stat.st_mtime_ns) self.assertEqual(stat.S_IMODE(restored_stat.st_mode), 0o640) def test_commit_preserves_symlink_hardlink_and_mode(self): source = self.make_source() hardlink = self.directory / "hardlink.c" symlink = self.directory / "symlink.c" os.link(source, hardlink) symlink.symlink_to(source.name) original_inode = source.stat().st_ino with DEHEADER_MODULE.SaveForModification(symlink) as saved: saved.remove_headers([self.INCLUDE]) saved.forget() self.assertTrue(symlink.is_symlink()) self.assertEqual(source.read_bytes(), self.MODIFIED) self.assertEqual(hardlink.read_bytes(), self.MODIFIED) self.assertEqual(source.stat().st_ino, original_inode) self.assertEqual(stat.S_IMODE(source.stat().st_mode), 0o640) def test_exception_rolls_back_and_does_not_touch_legacy_backup(self): source = self.make_source() legacy_backup = pathlib.Path(str(source) + "-orig") legacy_backup.write_text("keep me", encoding="ascii") with self.assertRaisesRegex(RuntimeError, "probe"): with DEHEADER_MODULE.SaveForModification(source) as saved: saved.remove_headers([self.INCLUDE]) raise RuntimeError("probe") self.assertEqual(source.read_bytes(), self.ORIGINAL) self.assertEqual(legacy_backup.read_text(encoding="ascii"), "keep me") def test_dependency_scan_retains_crlf_for_exact_removal(self): source = self.make_source() inclusion_map = DEHEADER_MODULE.InclusionMap([str(source)], None, None, 0) self.assertEqual(inclusion_map.depends_on[str(source)], [self.INCLUDE]) class BuildExecutionTests(unittest.TestCase): """Check process state around build-command execution.""" def test_build_exception_restores_working_directory(self): original_runner = DEHEADER_MODULE.getstatusoutput original_directory = os.getcwd() def raise_probe(_command): raise RuntimeError("probe") with tempfile.TemporaryDirectory() as directory: DEHEADER_MODULE.builddir = "." DEHEADER_MODULE.getstatusoutput = raise_probe try: with self.assertRaisesRegex(RuntimeError, "probe"): DEHEADER_MODULE.testcompile( "sample.c", "make %s", subdir=directory ) self.assertEqual(os.getcwd(), original_directory) finally: DEHEADER_MODULE.getstatusoutput = original_runner os.chdir(original_directory) def test_target_substitution_is_shell_quoted(self): command = DEHEADER_MODULE.build_command( "make -- %s", "objects/a file;name.o" ) self.assertEqual(command, "make -- 'objects/a file;name.o'") def test_targetless_build_command_is_unchanged(self): command = "ninja -C build" self.assertEqual(DEHEADER_MODULE.build_command(command, "unused.o"), command) class PortabilityRequirementsTests(unittest.TestCase): """Keep the portability database normalized and internally consistent.""" def test_requirement_triggers_are_unique(self): triggers = [trigger for trigger, _headers in DEHEADER_MODULE.requirements] duplicates = sorted( trigger for trigger in set(triggers) if triggers.count(trigger) > 1 ) self.assertEqual(duplicates, []) def test_header_references_are_normalized(self): malformed = [] for trigger, headers in DEHEADER_MODULE.requirements: for header in headers: if not (header.startswith("<") and header.endswith(">")): malformed.append((trigger, header)) self.assertEqual(malformed, []) def test_corrected_function_header_mappings(self): requirements = dict(DEHEADER_MODULE.requirements) expected = { "div()": [""], "fputwc()": ["", ""], "fputws()": ["", ""], "getgrnam()": ["", ""], "getgrnam_r()": ["", ""], "mbrlen()": [""], "mbstowcs()": [""], "mbtowc()": [""], "realloc()": [""], "swab()": [""], "symlink()": [""], "sync()": [""], "tdelete()": [""], "tfind()": [""], "times()": [""], "tsearch()": [""], "truncate()": [""], "twalk()": [""], "wctype()": [""], } for trigger, headers in expected.items(): with self.subTest(trigger=trigger): self.assertEqual(requirements[trigger], headers) self.assertNotIn("mblren()", requirements) self.assertNotIn("mbtowcs()", requirements) class ScannerTests(unittest.TestCase): """Cover preprocessing boundaries and lexical false positives.""" def test_indented_include_directive_is_recognized(self): line = " \t# include \n" self.assertEqual( DEHEADER_MODULE.match_preproc("include", line), "" ) self.assertEqual(DEHEADER_MODULE.trim(line), "") def test_include_next_is_not_misclassified_as_include(self): line = "#include_next \n" self.assertIs(DEHEADER_MODULE.match_preproc("include", line), False) def test_angle_and_quote_headers_have_the_same_bare_name(self): angle = DEHEADER_MODULE.supertrim("#include // system\n") quote = DEHEADER_MODULE.supertrim('#include "example.h" // local\n') self.assertEqual(angle, "example.h") self.assertEqual(angle, quote) def test_scanner_ignores_comments_and_literals_but_matches_at_bol(self): source_text = ( "/* abort();\n" "#include \n" "*/\n" " # include \n" 'const char *text = "div();";\n' "abort();\n" ) with tempfile.TemporaryDirectory() as directory: source = pathlib.Path(directory) / "scanner.c" source.write_bytes(source_text.encode("ascii")) inclusion_map = DEHEADER_MODULE.InclusionMap( [str(source)], None, None, 0 ) self.assertEqual( inclusion_map.depends_on[str(source)], [" # include \n"] ) self.assertEqual( inclusion_map.requires[str(source)], [([""], "abort()")] ) class InstallationTests(unittest.TestCase): """Check staged install commands without changing the filesystem.""" def test_install_builds_and_installs_manpage_with_data_mode(self): result = subprocess.run( [ "make", "-n", "-B", "install", "DESTDIR=/tmp/deheader-install-test", "PREFIX=/usr", ], cwd=PROJECT_ROOT, check=False, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) self.assertEqual(result.returncode, 0, result.stderr) commands = result.stdout.splitlines() make_manpage = "asciidoctor -D. -a nofooter -b manpage deheader.adoc" make_mandir = "install -d /tmp/deheader-install-test/usr/share/man/man1" install_manpage = ( "install -m 644 deheader.1 " "/tmp/deheader-install-test/usr/share/man/man1/deheader.1" ) self.assertIn(make_manpage, commands) self.assertIn(make_mandir, commands) self.assertIn(install_manpage, commands) self.assertLess(commands.index(make_mandir), commands.index(install_manpage)) class ExitStatusTests(unittest.TestCase): """Keep command statuses useful to CI and pre-release checks.""" def test_clean_analysis_exits_zero(self): result = run_deheader("-q", "-m", "true %s", "tests/noheaders.c") self.assertEqual(result.returncode, 0, result.stderr) def test_removable_header_exits_one(self): result = run_deheader("-q", "-m", "true %s", "tests/string.c") self.assertEqual(result.returncode, 1, result.stderr) self.assertIn("remove ", result.stdout) def test_failed_basic_compilation_exits_two(self): result = run_deheader("-q", "-m", "false %s", "tests/noheaders.c") self.assertEqual(result.returncode, 2, result.stdout) self.assertIn("basic compilation failed", result.stderr) def test_targetless_builder_runs_without_formatting_error(self): result = run_deheader("-q", "-m", "true", "tests/noheaders.c") self.assertEqual(result.returncode, 0, result.stderr) if __name__ == "__main__": unittest.main()