## What is `cppawk`? `cppawk` is a tiny shell script that is used like `awk`. It invokes the C preprocessor (GNU `cpp`) on the Awk code and calls `gawk`. `cppawk` understands the basic Awk options like `-F` and `-v`, and also understand common `cpp` options like `-I` and `-Dmacro=value`. The `cppawk` `man` page has the invocation and usage details. For instance, if we define a file called `awkloop.h` which has these contents :::c #define awkloop(file) for (; getline < file || (close(file) && 0); ) #define nextrec continue #define rule(cond) if (cond) Then this sort of code is possible: ::c #include "awkloop.h" function main() { awkloop ("/proc/mounts") { rule ($3 != "ext4") { nextrec } rule ($2 == "/") { print $1 } } } BEGIN { main() } We have implemented a facsimile of an Awk input scanning loop inside a function with a bit of syntactic sugar. ## Roadmap `cppawk` is been carefully developed, and has a regression test suite. Nearly every feature and fix was developed by first writing one or more failing tests and getting them to pass. The script is stable and nearly feature-complete, since it is out of the project scope to modify Awk or the C preprocessor. The remaining work is likely solving portability issues, like using with different implementations of the C preprocessor. Among future directions for `cppawk` is the development of a small library of useful standard headers. The foundation has been laid for this because when `#include <...>` is used (angle bracket include), it looks in a subdirectory called `cppawk-include` which is in the same directory as itself. For instance if `cppawk` is `/usr/bin/cppawk`, it looks in `/usr/bin/cppawk-include`. This library directory is currently empty. ## Why? * Why not? * You know Awk. You know C preprocessing inside out. Now use two things that you know, together, in obvious ways. * Awks other than GNU Awk have poor support for making a program out of multiple files. No compile meta-programming, or conditional selection of code. * Other minor benefits: Awk has no comments other than from a `#` character to the end of the line. You get `/* ... */` comments with `cppawk`, and also `#if 0` ... `#endif` for temporarily disabling code. ## But GNU Awk has `@include`? * GNU Awk's `@include` isn't a full preprocessor. There are no conditional expressions, and no macros. * It is only implemented in GNU Awk. * It provides no way to capture all the included output. * The way `@include` searches for files is inferior to `cpp`. GNU Awk's include search is driven by the `AWKPATH` variable which brings in all the disadvantages shared by shared by `PATH`-like variables. In contrast `cpp` implements the familiar behavior that an `#include "..."` directive is resolved relative to the directory of the file which contains that `#include` directive. No configuration is required for a program to find all of its included pieces. ## I use `awk` on embedded systems with no `cpp`! Though packaged that way, `cppawk` doesn't have to be used as an interpreter which preprocesses and runs the code. Preprocessed code can be captured with the `--prepro-only` option, and then transferred to a target system for execution with its Awk. **Tip**: it may be a good idea to tweak `cppawk` so that it doesn't define the `__gawk__` symbol, if your target system's Awk isn't GNU Awk.