IPP(1)
π IPP(1) β like, the Include Pre-Processor bestie π
EN Tools Β· section 1, the manual pages
okay so. you know how you have a million little files and you want them to become, like, one big file? that's this. it's the Include Pre-Processor and it's genuinely iconic. let's get into it π
β¨ NAME β¨
ipp β Include Pre-Processor. yeah that's it. that's the whole name. short king energy π
β¨ SYNOPSIS β¨
ipp [-D name=value] [-S includedir] [-I includedir] [-s includefile] [-i
includefile] [-M options] [-P path] [-m mapfile] [-N nosynclines] [-o
outputfile] [-v] inputfile ...
β¨ DESCRIPTION β¨
so ipp reads all your *inputfile*s and recursively expands every single one of these directives:
#include 'file'
#include "file"
#include <file>
basically it swaps the directive out for the actual contents of the file. the output goes to stdout or to outputfile, whichever you picked. and the way it hunts down those files? here's the scheme, no cap:
#include 'file'β the file is searched in the current working directory only. use this when you want to force the loading of a local file. no wandering off, periodt.#include "file"β the file is searched in all directories given by the-Ioption, in the right-to-left order they are specified on the command line. and heads up: a-I .implicit option is automatically appended to command-line options, so files get searched in the current directory first.#include <file>β first the file is searched in the system wide"ipp"include directory specified with the-Soption. second, if it was not not found there (yes, the double negative is in the original, i'm just the messenger π), it is searched for in all directories given by the-Ioption.
and it provides eight additional features. eight!! an overachiever fr fr π
πΈ Using Wildcards πΈ
these characters have a special meaning in filenames, bestie:
*β matches any string, including the null string.?β matches any single character.[...]β like bracketed expressions in regexps, matches any of the enclosed characters.
if you want to include all your templates, you may write
#include "*.tmpl"
with the following parameters you can control the order and the number of included files using the #include 'pattern' directive:
IPP_SORT=schemeβ specify a sort criterion to include files. there are actually 3 different criteria:date(files are sorted according to their last modification time),name(this is the default) andnumeric(filenames are sorted numerically).IPP_REVERSE=schemeβ as above, but the resulting list of filenames is sorted in reverse order.IPP_MAX=nmaxβ only nmax files are included.
if you want to include the 5 newest include files of the news directory with file names like "20000131.inc", you may write:
#include 'news/*.inc' IPP_REVERSE IPP_MAX=5
in the files included with the #include 'pattern' directive, the following variables are set and can be read using $(name):
IPP_THISβ the full name of the included source file including path and extensionIPP_PREVβ the full name of the previous included file, unset in the first fileIPP_NEXTβ the full name of the next included file, unset in the last file
β οΈ keep in mind that a directive without wildcards does not set these variables. like, at all. don't come for me, it's just how it is π
π¦ Special Use Variant π¦
in analogon to Perl's use statement, ipp provides a special variant of #include:
#use type::category::file
this internally is equivalent to the directive
#include <category/file.type>
plus the special semantic that the include file is included (=used) only once, i.e. multiple inclusion is automatically avoided. in other words:
#include 'file'
#include 'file'
#use 'file'
#use 'file'
results in three inclusions of 'file'. two from the #include's and only once from the #use directives. the #use girlies are efficient like that π
π Special Depends Variant π
you can easily write fragments of Makefiles with the -M flag (see below) to keep tracks of which files the output file depends on. when "ipp" is invoked as a piece of "WML", the final output file may depend on other files. you can tell "ipp" about these hidden dependencies by using the #depends variant, e.g.
#depends 'foo.dat'
#depends "*/*.dat"
#depends <file>
the contents of the file is not inserted β only information about dependencies are updated. it's giving "i know her but i'm not inviting her to the party" π
β¨ Input Line Synchronization β¨
all include commands insert some special stuff to help "WML" keep track of input line numbers. this feature may be disabled by appending the string IPP_NOSYNCLINES to the #include (or its variants) command. see also the -N flag.
π Include Variables π
you can add
name[=value]
pairs at the end of #include (and #use) directives to let $(name) interpolate to "value" (or 1 if "=value" is missing) in this include file and all its recursively included files. it's giving inheritance, main character energy π
there are the following forms of the $(name) syntax, similar to the functionality any Bourne Shell provides:
$(name)βUse Only Value: the standard interpolation.
if (exists(name))
expandto(valueof(name))
else
expandto("")
$(name=string)βAssign Value: set a variable.
name := string
$(name:-string)βUse Default String: the standard interpolation with a default value.
if (exists(name))
expandto(valueof(name))
else
expandto(string)
$(name:=string)βUse Default String and Assign: the standard interpolation with a default value and additional assignment for later use.
if (exists(name))
expandto(valueof(name))
else
expandto(string)
name := string
$(name:+string)βUse Alternate String. the replacement interpolation.
if (exists(name))
expandto(string)
else
expandto("")
$(name:*string)βUse Negative Alternate String. the replacement interpolation with negated logic.
if (exists(name))
expandto("")
else
expandto(string)
$(name:?string)βIndicate Error If Unset. the error message interpolation. this can also be used in conjunction with the above variants.
if (exists(name))
expandto(valueof(name))
else
Error(string)
previous constructs may be nested when variable expansion contains no parenthesis. you may for instance need these forms:
Set a variable if unset.
$(var=$(var:-string))
Redefine a variable if it is already set.
$(var=$(var:+string))
π notice that nested expressions are not handled as shells do. in shells expressions are treated from left to right, whereas"ipp"treat inner expressions first. with this example below$(foo=bar) $(foo:-$(foo=quux))Bourne shells will show"bar"whereas"ipp"will print"quux". so like, don't assume. they're different girlies.
it is also possible to undefine a variable. to do so, assign an empty value to this variable, e.g.
$(foo=)
notice the possibility to do simple If-Then-Else constructs:
$(foo:+string_when_set)$(foo:*string_when_not_set)
this is equivalent to the following pseudo-code:
if (exists(foo))
expandto(string_when_set)
else
expandto(string_when_not_set)
π Implicit IPP Variables π
the strings __FILE__ and __LINE__ are always substituted by the currently processed include file and the current line number. free variables, no setup required, we love a no-effort win π«Ά
π Comments π
IPP provides support for up-to-end-of-line comments. this type of comment is like the one found in Bourne-Shell or Perl, i.e. any line which starts with a sharp symbol ("#") is entirely (i.e. including the newline at the end) removed from the input. additionally these lines can have whitespaces in front of the sharp symbol. when you really need a sharp symbol at the start of a line you can use \#, i.e. prefix it with an escaping backslash.
π§ End-Of-File Stopping π§
it stops processing the current include file when a line containing just
__END__
occurs. use this to append POD documents to include files for documentation purposes as in Perl. you can use __END__ in constructs like $(SHORTENING:+__END__), so that the processing is only stopped when the variable SHORTENING is set. conditional stopping, we stan a flexible queen β¨
β End-Of-Line Continuation β
it removes all occurrences of the pattern
\<whitespace>*<newline><whitespace>*
use this to let one or more lines to be concatenated. gluing lines together like it's nothing π
β¨ OPTIONS β¨
okay bestie, this is the part where we get to the good stuff π every single flag, no skips, no cap.
-D name=valueβ defines a variable for the initial inputfile, exactly the same way you'd define one with the#includefor include files. then you can interpolate it anywhere with$(name)in all the files π«Ά-S includedirβ adds a system-wide include directory. you can totally use this option more than once, and the files get searched in right-to-left order. noted. π-I includedirβ adds an entry to the include path, which is where include files get searched for. yes, you can use this more than once too. also searched in right-to-left order. and here's the little plot twist: the current working directory is always appended as the last directory to this list, so it ends up being searched first. iconic behavior tbh π-s includefileβ pre-loads a particular include file, aka it virtually adds
#include <includefile>
in front of inputfile. use this to automatically load default system include files. bonus: you can also use the syntax type::category::file, which leads to a virtually added
#include <category/file.type>
-i includefileβ pre-loads a particular include file, aka virtually adds
#include "includefile"
in front of inputfile. use this to automatically load default user include files. and yeah, same deal with the syntax: type::category::file leads to a virtually added
#include "category/file.type"
-M optionsβ outputs a rule suitable formakedescribing the dependencies of each output file, just likegccdoes. it only has sense when the-ooption is used, so don't skip that part bestie π
The D flag option writes the rule to a dependency file. the name of this file is obtained by replacing the suffix of the output file by .d.
The M flag option deletes the system files from the list of dependencies.
-P pathβ sets up one or more prolog program path, which get applied to each single input file just before real processing starts. use this to pre-process the data π§ each program receives the data to act on asSTDINand has to produce the filtered data onSTDOUT.-m mapfileβ adds an entry to the list of mapfiles, where a mapping between obsolete include file names and current ones can be found. you can use this option more than once. the mapfiles can contain the following lines:
# comment line
<blank line>
<oldname>[,<oldname>] <newname> \[S|W|E: <text>\]
Example:
<std/headfoot.wml>,wml::std::headfoot wml::OBSOLETE::std::headfoot [S]
-N nosynclinesβ by default, WML inserts some instructions to synchronize line numbers, which are then interpreted in passes 2 and 3. this option disables that whole feature. bye bestie π-o outputfileβ redirects the output to outputfile. usually the output will be sent tostdoutif no such option is specified, or if outputfile is"-". lowkey the most-used flag in the group chat fr fr π-vβ sets verbose mode, where some processing information will be given on the console. she's chatty and we love that for her π
π AUTHORS π
the legends who made this happen, show them some respect:
- Ralf S. Engelschall
rse@engelschall.comwww.engelschall.com - Denis Barbier
barbier@engelschall.com
and that's a wrap, bestie π¦ this page is from EN Tools, dated 2020-11-29, and lives at IPP(1). go forth and preprocess slayfully β¨π
π¦ where this page comes from
- debian bookworm: wml 2.32.0~ds1-1 Β· GPL-2.0-or-later
- debian trixie: wml 2.32.0~ds1-1 Β· GPL-2.0-or-later
- ubuntu jammy: wml 2.32.0~ds1-1 Β· GPL-2.0-or-later
- ubuntu noble: wml 2.32.0~ds1-1 Β· GPL-2.0-or-later
- ubuntu questing: wml 2.32.0~ds1-1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms