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 (needs clang >= 11.0) and uses POSIX make
35 The only dependency is the toolchain needed to build the program using the Makefile, which is `clang` >= 11.0. That's
36 because the security flags used to build the executable are specific to clang.
38 If you want to build it with GCC and have equivalent security flags you can change the `CFLAGS` and `LDFLAGS` to the
42 CFLAGS = -std=c99 -O2 -Wall -Wextra -Wpedantic \
43 -Wformat=2 -Wformat-overflow=2 -Wformat-truncation=2 -Wformat-security \
44 -Wnull-dereference -Wstack-protector -Wtrampolines -Walloca -Wvla \
45 -Warray-bounds=2 -Wimplicit-fallthrough=3 -Wtraditional-conversion \
46 -Wshift-overflow=2 -Wcast-qual -Wstringop-overflow=4 -Wconversion \
47 -Warith-conversion -Wlogical-op -Wduplicated-cond -Wduplicated-branches \
48 -Wformat-signedness -Wshadow -Wstrict-overflow=4 -Wundef \
49 -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wstack-usage=1000000 \
52 -fstack-protector-strong -fstack-clash-protection -fPIE
54 LDFLAGS = -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack \
58 Otherwise you can just remove the security flags and compile it with
60 CFLAGS = -std=c99 -O2 -Wall -Wextra -Wpedantic
64 or pass your own flags to make
66 make CC=gcc CFLAGS=... LDFLAGS=...
70 Clone this repository then
73 $ make PREFIX=/usr install
76 This will install the compiled binary under `PREFIX` (`/usr/bin`) in this case, if not specified `PREFIX` will default
77 to `/usr/local`. For staged installs, `DESTDIR` is also supported. As the binary does not have any dependency (other
78 than clang) it does not have to be installed before use.
81 Using **pp** is quite simple, you just specify the *source* file and *target* file
85 The source file however, can be omitted, in this case the program takes the input from the standard input until `EOF` or
90 this behavior can also be achieved by using ‘-’ as *source* file
96 In order to build on any Unix-like system, simply run `make`. Since the binary does not have any dependencies, it can
97 just be copied into your `PATH`.
100 The test suite consists of a POSIX shell script called `harness.sh` contained in the `test` folder. It's output is
101 similar to [googletest](https://github.com/google/googletest)'s and it can be invoked with `make test` which, if
102 everything is working should output something similar to
105 [----------] Test environment set-up.
106 [==========] Running 7 test cases.
109 [ RUN ] empty_destination
110 [ OK ] empty_destination
117 [ RUN ] filename_dash
121 [==========] 7 test cases ran.
124 [----------] Test environment teardown.
128 Static analysis on the code base is done by using clang's static analyzer run through `scan-build.sh` which wraps the
129 `scan-build` utility. The checkers used are part of the
130 [Experimental Checkers](https://releases.llvm.org/12.0.0/tools/clang/docs/analyzer/checkers.html#alpha-checkers)
131 (aka *alpha* checkers):
134 * `alpha.core.CastSize`
135 * `alpha.core.CastToStruct`
136 * `alpha.core.IdenticalExpr`
137 * `alpha.core.PointerArithm`
138 * `alpha.core.PointerSub`
139 * `alpha.core.SizeofPtr`
140 * `alpha.core.TestAfterDivZero`