3 The **pp** (prepend) utility takes the content of the file named by the *source* operand and inserts or prepends it
4 above the first line of the file named by the *target* operand. The file operands are processed in command-line order.
5 If the *source* file is a single dash (‘-’) or absent, **pp** reads from the standard input.
7 So, essentially, if I have a CSV file without a header and I want to quickly insert the header from a file, I
11 $ pp header.txt spreadsheet.csv
14 and it would be functionally equivalent to
17 $ cat header.txt spreadsheet.csv > temp
18 $ mv temp spreadsheet.csv
23 * Compiled with security hardening flags
24 * Static analysis integrated using clang's `scan-build` using checkers `alpha.security`, `alpha.core.CastSize`,
25 `alpha.core.CastToStruct`, `alpha.core.IdenticalExpr`, `alpha.core.PointerArithm`, `alpha.core.PointerSub`,
26 `alpha.core.SizeofPtr`, `alpha.core.TestAfterDivZero`, `alpha.unix`
28 * Follows [FreeBSD coding style](https://www.freebsd.org/cgi/man.cgi?query=style&sektion=9)
31 * Self-contained, no external dependencies
32 * Easy to compile and uses POSIX make
35 The only dependency is a toolchain supporting the following flags:
38 CFLAGS = -std=c99 -O2 -Wall -Wextra -Wpedantic \
39 -Walloca -Wcast-qual -Wconversion -Wformat=2 -Wformat-security \
40 -Wnull-dereference -Wstack-protector -Wvla -Warray-bounds \
41 -Wbad-function-cast -Wconversion -Wshadow -Wstrict-overflow=4 -Wundef \
42 -Wstrict-prototypes -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough \
43 -Wpointer-arith -Wswitch-enum \
45 -fstack-protector-strong -fPIE -fstack-clash-protection
47 LDFLAGS = -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wl,-z,separate-code
50 Otherwise you can just remove the security flags and compile it with
52 CFLAGS = -std=c99 -O2 -Wall -Wextra -Wpedantic
56 or pass your own flags to make
58 make CC=gcc CFLAGS=... LDFLAGS=...
62 Clone this repository then
65 $ make PREFIX=/usr install
68 This will install the compiled binary under `PREFIX` (`/usr/bin`) in this case, if not specified `PREFIX` will default
69 to `/usr/local`. For staged installs, `DESTDIR` is also supported. As the binary does not have any dependency it does
70 not have to be installed before use.
73 Using **pp** is quite simple, you just specify the *source* file and *target* file
77 The source file however, can be omitted, in this case the program takes the input from the standard input until `EOF` or
82 this behavior can also be achieved by using ‘-’ as *source* file
88 In order to build on any Unix-like system, simply run `make`. Since the binary does not have any dependencies, it can
89 just be copied into your `PATH`.
92 The test suite consists of a POSIX shell script called `harness.sh` contained in the `test` folder. It's output is
93 similar to [googletest](https://github.com/google/googletest)'s and it can be invoked with `make test` which, if
94 everything is working should output something similar to
97 [----------] Test environment set-up.
98 [==========] Running 7 test cases.
101 [ RUN ] empty_destination
102 [ OK ] empty_destination
109 [ RUN ] filename_dash
113 [==========] 7 test cases ran.
116 [----------] Test environment teardown.
120 Static analysis on the code base is done by using clang's static analyzer run through `scan-build.sh` which wraps the
121 `scan-build` utility. The checkers used are part of the
122 [Experimental Checkers](https://releases.llvm.org/12.0.0/tools/clang/docs/analyzer/checkers.html#alpha-checkers)
123 (aka *alpha* checkers):
126 * `alpha.core.CastSize`
127 * `alpha.core.CastToStruct`
128 * `alpha.core.IdenticalExpr`
129 * `alpha.core.PointerArithm`
130 * `alpha.core.PointerSub`
131 * `alpha.core.SizeofPtr`
132 * `alpha.core.TestAfterDivZero`