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
65 Clone this repository then
68 $ make PREFIX=/usr install
71 This will install the compiled binary under `PREFIX` (`/usr/bin`) in this case, if not specified `PREFIX` will default
72 to `/usr/local`. For staged installs, `DESTDIR` is also supported. As the binary does not have any dependency (other
73 than clang) it does not have to be installed before use.
76 Using **pp** is quite simple, you just specify the *source* file and *target* file
80 The source file however, can be omitted, in this case the program takes the input from the standard input until `EOF` or
85 this behavior can also be achieved by using ‘-’ as *source* file
91 In order to build on any Unix-like system, simply run `make`. Since the binary does not have any dependencies, it can
92 just be copied into your `PATH`.
95 The test suite consists of a POSIX shell script called `harness.sh` contained in the `test` folder. It's output is
96 similar to [googletest](https://github.com/google/googletest)'s and it can be invoked with `make test` which, if
97 everything is working should output something similar to
100 [----------] Test environment set-up.
101 [==========] Running 7 test cases.
104 [ RUN ] empty_destination
105 [ OK ] empty_destination
112 [ RUN ] filename_dash
116 [==========] 7 test cases ran.
119 [----------] Test environment teardown.
123 Static analysis on the code base is done by using clang's static analyzer run through `scan-build.sh` which wraps the
124 `scan-build` utility. The checkers used are part of the
125 [Experimental Checkers](https://releases.llvm.org/12.0.0/tools/clang/docs/analyzer/checkers.html#alpha-checkers)
126 (aka *alpha* checkers):
128 * `alpha.core.CastSize`
129 * `alpha.core.CastToStruct`
130 * `alpha.core.IdenticalExpr`
131 * `alpha.core.PointerArithm`
132 * `alpha.core.PointerSub`
133 * `alpha.core.SizeofPtr`
134 * `alpha.core.TestAfterDivZero`