1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
|
CPPAWK(1) Awk With C Preprocessing CPPAWK(1)
NAME
cppawk - wrapper for awk, with C preprocessing
SYNOPSIS
cppawk [cpp, awk and cppawk options] [awk arguments]
cppawk --prepro-only [cpp, awk and cppawk options]
DESCRIPTION
cppawk is a shell script which passes awk code through the standalone C preprocessor, and
then invokes awk on the preprocessed code. This allows Awk code to be written which uses C
preprocessor #define macros, #include C comments, trigraphs (though perish the thought)
and backslash continuation.
cppawk deliberately has an invocation syntax similar to Awk, and understands certain Awk
options such as -f and also understands cpp options, such as -Dfoo=bar for pre-defining a
macro.
Just like with awk, code is specified either directly as the first non-option argument, or
via the -f option which indicates a file. In either situation, cppawk preprocesses the
code and places the result in a temporary file which is then executed as awk code.
OPTIONS
Any option not described here is assumed to be an Awk option which takes no argument, and
is consequently passed through to the awk program.
-- End of options: any subsequent argument is the first non-option argument, even if
it looks like an option.
--prepro-only
Do not run the preprocessed Awk program; dump the preprocessed code to standard
output.
--awk=path
Specify alternative Awk implementation. If it contains no slashes, then PATH is
searched to find the program. If the base name of the program is gawk or mawk,
then, respectively, one of the preprocessor symbols __gawk__ or __mawk__ is prede-
fined, with a value of 1. This happens immediately when this option is processed,
so can be counter-acted by a subsequent -U option.
--prepro=path
Specify alternative preprocessor. If it contains no slashes, then PATH is searched
to find the program.
-f filename
Read the awk program from filename rather than processing awk code from the first
non-option command-line argument. The program is preprocessed to a temporary file,
and awk is then invoked on this file. The file is deleted when awk terminates.
--nobash
Pretend that the shell which executes cppawk isn't GNU Bash, even if it is. This
has the effect of disabling the use of process substitution in favor of the use of
a temporary file.
--dump-macros
Instruct the preprocessor to dump all of the #define directives instead of the pre-
processed output. Since this is only useful with --prepro-only that option is im-
plied.
-M, --bignum
These two equivalent GNU Awk options are passed through to awk, which will under-
stand them if it is GNU Awk. Using either of them causes the preprocessor symbol
__bignum__ to be defined with the value 1.
-P, --posix
These two equivalent GNU Awk options are passed through to awk, which will under-
stand them if it is GNU Awk. Using either of them causes the preprocessor symbol
__posix__ to be defined with the value 1.
-M... Any optional argument beginning with -M and followed by one or more characters re-
sults in a diagnostic message and failed termination. The intent is that the -M
family of options that are supported by GNU cpp are not supported by cppawk.
-F, -v, -E, -i, -l, -L
These standard and GNU Awk options are recognizes by cppawk as requiring an argu-
ment. They are validated for the presence of the required argument, and passed to
awk.
-U..., -D..., -I..., -iquote...
Options which match these patterns are passed to the cpp program instead of awk.
PREDEFINED SYMBOLS
__gawk__
When cppawk installation is configured to use GNU Awk, which is the default, the
preprocessor symbol __gawk__ is predefined with a value of 1. See the --awk option.
__cppawk_ver
This preprocessor symbol gives the version of cppawk. Its value is a is an eight
digit decimal integer the form YYYYMMDD, such as 20220321.
NOT PREDEFINED, SIGNIFICANT SYMBOLS
__gawk_ver
Certain cppawk header files may have functionality that depends on GNU Awk.
By default, those cppawk headers which require GNU Awk may assume the latest ver-
sion released by the GNU Awk project, with all of its features and bugfixes.
Consequently, the generate code may not work on older versions of GNU Awk.
The user application, prior to including any cppawk header, may define the macro
__gawk_ver to indicate which version of GNU Awk the generated code is required to
work with.
In reaction to this variable, those header files may be able to generate alterna-
tive code suitable for the indicated version of GNU Awk.
The variable should be a decimal integer, whose last four digits encode the minor
and build numbers. For instance 4.1.3 is encoded as 40103:
#define __gawk_ver 40103 // Please support GNU Awk 4.1.3
#include <...> // inclusion of headers follows
Naturally, __gawk_ver may be specified on the command line with the -D option.
STANDARD HEADERS
cppawk points the preprocessor to look for #include <...> files in its own directory.
There are currently no files in this directory.
EXAMPLES
Print the larger of field 1 or 2:
cppawk '// C comment
#define max(a, b) ((a) > (b) ? (a) : (b))
{ print max($1, $2) /* C comment */ } #awk comment'
Implement awk-like processing loop within function, to process /proc/mounts:
#include "awkloop.h"
function main()
{
awkloop ("/proc/mounts") {
rule ($3 != "ext4") { nextrec }
rule ($2 == "/") { print $1 }
}
}
BEGIN {
main()
}
Where awkloop.h contains:
#define awkloop(file) for (; getline < file || (close(file) && 0); )
#define nextrec continue
#define rule(cond) if (cond)
SEE ALSO
awk(1), cpp(6)
BUGS
The -f option can be given only once, whereas awk accepts multiple -f options, and exe-
cutes each of the indicated files.
Awk error messages are reported against the preprocessed text.
Awk # comments cannot be used at the start of a line because # begins a preprocessing di-
rective. They also cannot be used inside a preprocessing directive, such as a macro defi-
nition, because # is an operator in the preprocessor language. It may be a good idea to
avoid # comments entirely in cppawk source, and use only C comments.
The cpp program tokenizes text using C preprocessor rules. Because Awk is "C-like", there
is a lot of compatibility between that and Awk syntax, which is why cppawk works at all;
however, there may be corner cases where some issue arises because of this.
The default choices of gawk and cpp are fixed in the source code; users must edit cppawk
to select alternative implementations or locations of these tools, if they don't wish to
use the --awk and --prepro command line options.
The C preprocessor's #include "..." directive is expected to search in the same directory
as the file in which it is located, which is critically important feature. However, cppawk
feeds the Awk code to cpp via a pipe, even in the case when source is specified via the -f
option. The reason is that the Awk source is filtered to remove the #! ("hash bang")
line, which cpp doesn't like. To make sure #include works as expected, cppawk inserts a
preprocessor option to add the original directory into the include file search path: the
current working directory in the case of Awk code specified in the command line, or else
the directory of the file specified via the -f option. In the default configuration, which
assumes the GNU C Preprocessor, the -iquote option is used for this; but in a configura-
tion using some preprocessor which does not have that option, it may have to be done via
the more heavy-handed -I option. These options are inserted before any preprocessor op-
tions that come from the cppawk command line.
AUTHOR
Kaz Kylheku <kaz@kylheku.com>
COPYRIGHT
Copyright 2022, BSD2 License.
Utility Commands 25 March 2022 CPPAWK(1)
|