Package: autoheaders
Version 0.3.5autoheaders automatically generates header files from C source code.InstallationFrom PyPIInstall withpip:sudo pip3 install autoheadersTo install locally, run withoutsudoand add the--useroption.From the Git repositoryClone the repository (you’ll need to haveGitinstalled):git clone https://git.taylor.fish/taylor.fish/autoheaders
cd autoheadersThen install withpip:sudo pip3 install .Alternatively, you can run:[1]sudo ./setup.py installWith either command, to install locally, run withoutsudoand add the--useroption.[2]Run without installingRun the first set of commands in the previous section to clone the repository.
Then install the required dependencies:sudo pip3 install -r requirements.txtTo install the dependencies locally, run withoutsudoand add the--useroption.UsageIf you installed autoheaders, you can simply runautoheaders.[3]Otherwise, run./autoheaders.py. This will display usage information
similar to the following:autoheaders [options] [--] <c-file>
autoheaders -h | --help | --versionArguments:<c-file>:
The C source code file from which to generate the header. If-is passed,
standard input is read (unless the argument is preceded by--).Options:-p--private:
Generate a private header file containing static declarations.-o<file>Write the header file to the specified file. If given after-p, a private
header is written. This option may be given twice: once before-p, and
once after. If not given, the header is written to standard output.-c<cpp-arg>:
Pass arguments to the C preprocessor. Separate arguments with commas, or
provide multiple-coptions. Use\to escape characters.[4]Note that when the preprocessor is run, the current working directory is the
parent directory of the C file.It is therefore recommended to convert paths
in-carguments to absolute paths.--debug:
Run the program in debug mode. Exception tracebacks are shown.The generated header file is written to standard output.The C preprocessor command that is used is determined by trying the
following options in the order listed:The value of theAUTOHEADERS_CPPenvironment variable. This is parsed and
interpreted as a shell command. For example:AUTOHEADERS_CPP="gcc-E"gcc-Eclang-EThe C preprocessor must be compatible withGCC’s preprocessor (gcc-E).See the next section for how to structure your C code so that headers can be
generated properly.Header generationautoheaders parses the given C file and looks for all function definitions,
global variable definitions, and non-externglobal variable declarations
(which are essentially zero-initialized definitions).Definitions and declarations markedstaticare ignored. The remaining
function definitions are transformed into function declarations and are added
to the header file. The remaining variable definitions and declarations are
transformed intoexternvariable declarations and are added to the header
file.Additionally, you can explicitly specify code to be added to the header—this is
necessary if you define structs or need certain files to be to be included in
the header. All code between#ifdef HEADERand#endifis copied to the
header file, intermixed with the generated declarations (depending on where the#ifdef HEADERblocks occur in the source file).Include guards can also be generated. If a comment of the form@guard <name>is present, an include guard will be generated using the
macro<name>. The comment must appear at the top level, outside of any
blocks or preprocessor conditionals.Files that are included (with#include) by the C file do not need to exist
and are not processed by autoheaders,exceptfor files inside#ifdef HEADERblocks.[5]Sometimes, however, certain#includestatements do need to be processed for
autoheaders to parse the file properly, especially if the included files define
macros that are used at the top level (i.e., not inside functions) by the
original C file. In this case, a comment of the form@includecan be placed
after the#include<...>,on the same line. For example:#include<assert.h>/* @include */#include<stdio.h>will cause autoheaders to includeassert.hduring its processing, butstdio.hwill not be included (unless these#includestatements appear
in an#ifdef HEADERblock[5]).Private headersIn addition to the public header files normally generated by autoheaders,
private header files can be generated as well. These header files are designed
to be included only by the corresponding C file and remove the need for
forward declarations of static functions.To generate a private header file, provide the option-p.#ifdef HEADERblocks will not be included in the private header. To include
code in the private header (for things like private structures), use#ifdef PRIVATE_HEADERblocks (also closed with#endif, of course).Finally, the macroANY_HEADERwill be defined for both public and private
headers, which allows you to use#ifdef ANY_HEADERblocks to include code
in both headers. You shouldn’t usually need to do this, however.ExampleAlso see theexample/directory for a more complete example.If the following code is intest.c:// @guard TEST_H#include"test.h"#include"test.priv.h"#include<stdio.h>#ifdef HEADER#include<stdint.h>typedefstruct{int32_tfirst;int32_tsecond}IntPair;#endifconstIntPairzero_pair={0,0};// Adds a pair of integers.int32_tadd_pair(IntPairpair){returnadd(pair.first,pair.second);}// Adds two integers.staticint32_tadd(int32_tfirst,int32_tsecond){printf("Adding %"PRId32" and %"PRId32"\n",first,second);returnfirst+second;}then you can runautoheaders test.c-otest.hto generate the public header
file.test.hwill then contain the following code:#ifndef TEST_H
#define TEST_H#include<stdint.h>typedefstruct{int32_tfirst;int32_tsecond;}IntPair;externconstIntPairzero_pair;// Adds a pair of integers.int32_tadd_pair(IntPairpair);#endifSimilarly, you can runautoheaders test.c-p-otest.priv.hto generate the
private header file.test.priv.hwill then contain the following code:// Adds two integers.staticint32_tadd(int32_tfirst,int32_tsecond);You can also generate both the public and private headers at the same time,
which is faster than generating each individually, by running:autoheaders test.c -o test.h -p -o test.priv.hSee theexample/directory for a more complete example.Fake headersIf an included header contains a large about of code, it can cause autoheaders
to run slowly. Certain non-standard headers may not even be able to parse. In
these cases, you can create fake headers that override the real ones when
autoheaders runs.Fake headers simply need to declare the types and macros from the real header
that your code uses. The types do not need to match the real ones; they just
need to be declared. The recommended way to do this is with typedefs. For
example,typedef int div_t;is a suitable definition ofdiv_t,
regardless of whether or notdiv_tis actually an integer.Macros used by your code must be defined in the fake header as well. While, as
with types, the fake header macros don’t need to match the real ones, a little
more care must be taken to ensure that the fake macros produce syntactically
valid code.For example, a fake header forpthread.hcould contain the following:typedefintpthread_t;typedefintpthread_mutex_t;#define PTHREAD_MUTEX_INITIALIZER 0Put your fake headers in a directory with a structure that matches that of the
real headers. For example, using the directoryfake/, if your code
contained#include <pthread.h>, the fake header would be stored infake/pthread.h. If your code contained#include <pthread/pthread.h>,
the fake header would be stored infake/pthread/pthread.h.After creating your fake headers, you can run autoheaders as follows:autoheaders <c-file> -c -I<fake-header-dir>where<fake-header-dir>is the directory containing the fake headers.
Following the examples above, autoheaders might be invoked as:autoheaders file.c -c -Ifake/Additionally, you can include your fake header directory automatically by
giving it a special name. When running, autoheaders will look for a directory
named.fake-headers/in the directory containing the C file or in any parent
directory. If such a directory is found, it will be included with-I.Seethis article about pycparserfor more information about fake headers.TroubleshootingThe most likely error to be encountered is when code contains non-standard C
extensions; for example,__attribute__in GCC. C code is parsed after
preprocessing, so the use of non-standard features in any included files causes
problems for the parser.These issues can be easily mitigated by modifyingshim.h.
(__attribute__and some other extensions are currently handled and do not
cause errors.)shim.hcontains typedefs and macro definitions that
transform the code into standards-compliant C (at least enough to be parsed).
For more information, seethis article about pycparser.If you find that something is missing fromshim.h, please file an issue or
open a pull request.DependenciesPython≥ 3.5 withpipinstalledAGCC-compatible compiler (specifically, a compatible C preprocessor);
see theUsagesection.The following Python packages:pycparsersetuptools[6]The installation instructions above handle installing the Python packages.
Alternatively, runningpip3 install-rrequirements.freeze.txtwill install
specific versions of the dependencies that have been confirmed to work.What’s newVersion 0.3.3:autoheaders can now be installed from PyPI.Version 0.3.2:Array declarations without explicit sizes (appearing as part of a definition)
are no longer copied to header files, as this causes compilation errors.Version 0.3.1:Fixed issue where array declarations would be ignored.Version 0.3.0:Public and private headers can now be generated at the same time.Version 0.2.1:Clarified how the current working directory changes when the preprocessor is
run.Version 0.2.0:The order of#ifdef HEADERblocks and definitions is now preserved.
If an#ifdef HEADERblock appears after a function definition, it will
now appear after the generated declaration in the header file.Licenseautoheaders is licensed under the GNU General Public License, version 3 or any
later version. SeeLICENSE.[7]This README file has been released to the public domain usingCC0.[1]setuptoolsmust be installed before runningsetup.py. Ifpipis installed,setuptoolslikely is as well; otherwise, runsudo pip3 install setuptoolsorpip3 install--usersetuptools.[2]If usingsetup.py, add the--useroption afterinstall(rather than before it).[3]If Python package binary directories are not in your$PATH, you may
have to runpython3-mautoheadersinstead.[4]Backslashes can be used to include commas in the passed arguments: for
example,-c'arg\,with\,commas'will pass the single argumentarg,with,commasto the preprocessor. Other backslash escapes are simply
interpreted as the second character:-c'a\bc\\d'becomesabc\d.[5](1,2)Including#ifdef PRIVATE_HEADERand#ifdef ANY_HEADERblocks.[6]Specifically,pkg_resourcesmust be installed. Some package managers
distributepkg_resourcesseparately fromsetuptools. For example,
in Debian GNU/Linux and many derivatives,pkg_resourcesis available
viaaptinpython3-pkg-resources.[7]This does not apply to generated header files; the copyright and license
status of such files is unaffected by autoheaders.