diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-03-22 15:07:03 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-03-22 15:07:03 -0700 |
commit | 127fd1981aa50beac05b1e2348c70d690e4e4070 (patch) | |
tree | 64b1c07aa6e34d10e7767e79e3871bcbe5eee639 | |
parent | 86a3448b554e2c9963eed87a43b2db2a8156f842 (diff) | |
download | cppawk-127fd1981aa50beac05b1e2348c70d690e4e4070.tar.gz cppawk-127fd1981aa50beac05b1e2348c70d690e4e4070.tar.bz2 cppawk-127fd1981aa50beac05b1e2348c70d690e4e4070.zip |
Add markdown README.
-rw-r--r-- | README.md | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..571ff7b --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +## 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`. + +There is a `man` page with all the 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. + +If you know C and the C preprocessor, and if you know Awk, the utility +and applications for this should be obvious; you may skip the next section +and go get it! + +## Why or who might use `cppawk`? + +0. Why not? It's just a tiny shell script. + +1. You know how to use the C preprocessor, and are doing work on a system or + situation where you can count on it being installed, such as build + scripts or continuous integration. Make use of what you know. + +2. It makes some things easy, like making a program out of multiple + files, which easily find each other in the same directory or relative + path. Or macros, for some syntactic sugars. + +3. Though GNU Awk has `@include`, that feature provides no preprocessor + features and works with GNU Awk only. `cppawk` calls `gawk`, but can + easily be tweaked to target any Awk; any Awk can have file inclusion. + There is the possibility of using `#ifdef` to make code + work on different Awks from one file. (The default cppawk installation uses + gawk, and also defines `__gawk__` as 1, which you can test for.) + +4. Comments. Awk has no comments that don't end at the end of + the line; `cppawk` gives you `/*...*/`. + +5. Temporarily disabling code with `#if 0` ... `#endif` rather than + fiddling with hash marks. + +6. Exploration: Awk is syntactically C like, but not C: what + implications does that have for writing macros? You can discover some + new-ish techniques, though it won't be earth-shattering. + +7. Weird access to some host attributes intended for C: + + $ cppawk '#include <limits.h> + BEGIN { print PATH_MAX, ULONG_MAX }' + 4096 214748364701 + + this sort of thing can be useful in devops land. + +## How about systems that have `awk` but no `cpp`? + +`cppawk` is used directly on systems that have `cpp`, as if +it were an Awk implementation. + +`cppawk --prepro-only` will generate the preprocessed Awk code, +which can be captured and transferred to a system that has no +preprocessor installed, such as an embedded board that has +BusyBox Awk. + +Of course, capturing the preprocessed output has other uses. +It's possible to generate different versions of an Awk program +by using `cppawk --prepro-only` in conjunction with conditional +preprocessing which reacts to different values of a macro defined +on the command line via `-D`. |