aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cppawk-case.166
-rw-r--r--cppawk-narg.1105
-rw-r--r--cppawk.1146
3 files changed, 160 insertions, 157 deletions
diff --git a/cppawk-case.1 b/cppawk-case.1
index 9fd33f3..f3496b0 100644
--- a/cppawk-case.1
+++ b/cppawk-case.1
@@ -27,45 +27,45 @@ case \- macro for portable switch statement
.SH DESCRIPTION
The
-.BI case
+.B case
macro provides syntax which
-.B cppawk
+.I cppawk
translates very directly to the GNU Awk
-.BI switch
+.B switch
statement, or else to alternative code which works with other Awk implementations.
The purpose of the macro is easy conversion of
-.BI switch
+.B switch
code; therefore, it has the same semantics with regard to fall through between
cases, requiring an explicit break.
The clauses of
-.BI case
+.B case
are labeled with the identifiers
-.BI of,
-.BI matching,
+.BR of ,
+.BR matching ,
or
-.BI mixed
+.BR mixed ,
which take arguments, and are followed by one or more statements. The last one
of those statements must always be a
-.BI cbreak,
-.BI cfall
+.BR cbreak ,
+.B cfall
or
-.BI cret
+.B cret
statement, described below.
Regular expression keys must use the
-.BI matching
+.B matching
label; ordinary keys compared for equality must use the
-.BI of
+.B of
label. The
-.BI mixed
+.B mixed
label allows for both keys to be included in one case.
The
-.BI of
+.B of
and
-.BI matching
+.B matching
macros take variable arguments. Multiple matching keys or regular expressions
are specified as multiple arguments, rather than by repetition of the
construct:
@@ -75,7 +75,7 @@ construct:
of (3, 4) print "3 or 4"; cbreak // correct
The
-.BI mixed
+.B mixed
macro takes exactly two arguments, which are parenthesized lists of
keys. The left list must be a list of ordinary value keys, and the
second of regular expression literals:
@@ -83,15 +83,15 @@ second of regular expression literals:
mixed ((1, 2, "a"), (/xyz$/, /^\et/))
Each clause must specify how it terminates: whether it breaks out of the
-.BI case
+.B case
statement, "falls through" to the next case, or returns from the surrounding
function. The macros
-.BI cbreak,
-.BI cfall
+.BR cbreak ,
+.B cfall
and
-.BI cret
+.B cret
must be used for this purpose. The
-.BI cret
+.B cret
macro takes exactly one argument, the expression whose value is to be
returned from the surrounding function:
@@ -112,22 +112,22 @@ returned from the surrounding function:
}
When
-.BI case
+.B case
is transformed into portable code rather than
-.BI switch,
+.BR switch ,
that code depends on hidden state variables.
If
-.BI case
+.B case
is used in a top-level
-.BI BEGIN,
-.BI END
+.BR BEGIN ,
+.B END
or Awk action, those variables will be global.
They will also be global if
-.BI case
+.B case
is used in a function, unless defined as local variables in the parameter list.
Defining the temporary variables as local is done using the provided
-.BI case_temps
+.B case_temps
macro:
#include <case.h>
@@ -144,13 +144,13 @@ macro:
}
}
-.BI case_temps
+.B case_temps
does not have to be in the last argument position. It is guaranteed to expand to one or
more identifiers separated by commas, with no leading or trailing comma. When the target
is GNU Awk,
-.BI case_temps
+.B case_temps
expands to an unspecified identifier in the
-.BI __[a-z]
+.B __[a-z]
reserved namespace.
.SH "SEE ALSO"
@@ -159,7 +159,7 @@ cppawk(1)
.SH BUGS
The
-.BI cond
+.B cond
macro does not currently safely nest with itself.
Forgetting to declare the temporary variables is a programmer pitfall.
diff --git a/cppawk-narg.1 b/cppawk-narg.1
index f802f39..409a602 100644
--- a/cppawk-narg.1
+++ b/cppawk-narg.1
@@ -1,32 +1,35 @@
.TH CPPAWK-NARG 1 "29 March 2022" "cppawk Libraries" "Case Macro"
.SH NAME
-narg \- macros for writing variable argument macros
+.I narg
+\- macros for writing variable argument macros
.SH SYNOPSIS
+.ft B
#include <narg.h>
#define narg(...)
#define splice(args)
#define varexpand(first_mac, rest_mac, ...)
#define revarg(...)
+.ft R
.SH DESCRIPTION
The
-.B <narg.h>
+.I <narg.h>
header provides several macros which are useful to macro writers.
In particular, these macros make it easy to develop variable argument
macros which take one or more argument, and have complex expansions.
In this manual, the
-.BI ->
+.B ->
(arrow) notation means "expands to". For instance
foo(bar) -> 42 // the macro call foo(bar) expands to 42
A description of each macro follows:
-.IP narg
+.IP \fBnarg\fR
This macro takes one or more arguments, and expands to a decimal integer which
indicates how many arguments there are.
@@ -35,20 +38,20 @@ indicates how many arguments there are.
narg(x, y, z) -> 3
The
-.BI narg
+.B narg
macro can be called with up to 32 (thirty-two) arguments. If it is called
with between 33 to 48 arguments, it expands to an unspecified token
sequence which generates a syntax error in Awk. The token sequence begins
with an identifier and therefore may appear as the right operand of the
token-pasting
-.BI ##
+.B ##
operator, opposite to an identifier token.
If more than 48 arguments are given, the behavior is unspecified.
-.IP splice
+.IP \fBsplice\fR
The
-.BI splice
+.B splice
macro provides a shim for inserting a parenthesized argument into
a macro expansion, such that the argument turns into individual
arguments. Suppose we have a macro like this:
@@ -60,19 +63,19 @@ For some reason, we need to write fixed a macro like this:
#define fmac(x, y, args) vmac(x, y, ???)
where the
-.BI args
+.B args
argument is a parenthesized list of arguments that must become the
-.BI ...
+.I ...
argument of the
-.BI vmac
+.B vmac
macro. That is to say,
-.BI fmac
+.B fmac
is to be invoked like this, with the indicated expansion:
fmac(1, 2, (3, 4, 5)) -> vmac(1, 2, 3, 4, 5)
The
-.BI splice
+.B splice
macro solves the question of what to write into the position
indicated by the ??? question marks to achieve this:
@@ -84,17 +87,17 @@ Example: produce the following macro:
sqrt(sumsq(x, y)))
This is a trick example:
-.BI splice
+.B splice
is not required at all:
#define csum(left, right) (sqrt(sumsq left) + \e
sqrt(sumsq right))
The
-.BI splice
+.B splice
macro is not required because the parenthesized arguments constitute
the entire argument list of
-.BI sumsq.
+.BR sumsq .
However, suppose the requirement is this, requiring the parenthesized
arguments to be inserted into an argument list containing other arguments:
@@ -108,7 +111,7 @@ Now we need:
sumsq(parm, \e
splice(right))))
-.IP revarg
+.IP \fBrevarg\fR
This macro expands to a comma-separated list of its arguments, which
appear in reverse.
@@ -117,31 +120,31 @@ appear in reverse.
revarg(1, 2, 3) -> 3, 2, 1
Like
-.BI narg,
+.BR narg ,
the
-.BI revarg
+.B revarg
macro can be called with up to 32 arguments, beyond which there is
some overflow detection up to 48 arguments, followed by unspecified behavior
for 49 or more arguments.
-.IP varexpand
+.IP \fBvarexpand\fR
The most complex macro in the
-.B <narg.h>
+.I <narg.h>
header is
-.BI varexpand.
+.BR varexpand .
This macro is used for writing variadic macros with complex expansions,
using a compact specification.
The
-.BI varexpand
+.B varexpand
macro uses "higher order macro" programming: it has arguments which are
themselves macros. To understand
-.BI varexpand
+.B varexpand
it helps to understand the Lisp
-.BI reduce
+.B reduce
function, or the similar
-.BI fold
+.B fold
function found in functional languages. Recall that the prototype of the
.BI varexpand
macro is this:
@@ -149,27 +152,27 @@ macro is this:
#define varexpand(first_mac, rest_mac, ...)
To use
-.BI varexpand
+.B varexpand
you must first write two macros: a one-argument macro whose name is passed
as the
-.BI first_mac
+.B first_mac
argument, and two argument macro to be used as the
-.BI rest_mac
+.B rest_mac
argument.
Most variadic macros written with
-.BI varexpand
+.B varexpand
will pass through their
-.BI __VA_ARGS__
+.B __VA_ARGS__
list as the
-.BI ...
+.I ...
parameter; however, the
-.BI splice
+.B splice
macro can also be used to place parenthesized argument lists
into that position
Up to 32 variadic arguments are accepted by
-.BI varexpand
+.B varexpand
beyond which there is overflow detection up to 48 arguments,
followed by unspecified behavior for 49 or more arguments.
@@ -192,15 +195,15 @@ argument. The right argument is the next argument to be added to the expansion.
For instance, if the arguments 1, 2 have already been expanded to 1 + 2
and the next argument is 3, then
-.BI acc
+.B acc
takes on the tokens 1 + 2, and
-.BI x
+.B x
takes on 3. Thus the expansion is:
add_next(1 + 2, 3) -> 1 + 2 + 3
With these two macros, we can then write
-.BI add
+.B add
like this:
#define add(...) varexpand(add_first, add_next, __VA_ARGS__)
@@ -219,9 +222,9 @@ the products. We write the helper macros like this:
#define sumsq_next(a, x) a + sumsq_first(x)
Note that
-.BI sumsq_next
+.B sumsq_next
reuses
-.BI sumsq_first
+.B sumsq_first
to avoid repeating the (x)*(x) term. Then we complete the implementation:
#define sumsq(...) (varexpand(sumsq_first, \e
@@ -229,9 +232,9 @@ to avoid repeating the (x)*(x) term. Then we complete the implementation:
__VA_ARGS__))
The outer parentheses are written around the
-.BI varexpand
+.B varexpand
call. In general,
-.BI varexpand
+.B varexpand
can be just a small component of a larger macro expansion, and
can be used more than one time in a macro expansion.
@@ -257,34 +260,34 @@ association, rather than in reverse? So that is to say:
list(1, 2, 3) -> cons(1, cons(2, cons(3, nil)))
Here we simply take advantage of the
-.BI revarg
+.B revarg
macro to reverse the arguments:
#define list(...) rlist(revarg(__VA_ARG__))
.SH BUGS
As noted in the DESCRIPTION, the
-.BI narg,
-.BI revarg,
+.BR narg ,
+.B revarg
and
-.BI varexpand
+.B varexpand
macros are limited to handling 32 variadic arguments, beyond
which there is a 16 argument safety margin with error detection,
followed by unspecified behavior.
The C preprocessor doesn't support macro recursion, which forbids
some complex uses of
-.BI varexpand
+.B varexpand
whereby the
-.BI first_mac
+.B first_mac
and
-.BI next_mac
+.B next_mac
macros themselves make use of
-.BI varexpand.
+.BR varexpand .
A possible workaround is to clone the implementation of
-.BI varexpand
+.B varexpand
to produce an identical macro called
-.BI varexpand2.
+.BR varexpand2 .
This then allows for two "recursion" levels, whereby each one uses
the macro under a different name.
diff --git a/cppawk.1 b/cppawk.1
index 2b7d0c3..f39cff9 100644
--- a/cppawk.1
+++ b/cppawk.1
@@ -9,69 +9,69 @@ cppawk [cpp, awk and cppawk options] [awk arguments]
cppawk --prepro-only [cpp, awk and cppawk options]
.SH DESCRIPTION
-.B cppawk
+.I 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
-.BI #define
+.B #define
macros,
-.BI #include
+.B #include
C comments, trigraphs (though perish the thought) and backslash continuation.
-.B cppawk
+.I cppawk
deliberately has an invocation syntax similar to Awk, and understands certain
Awk options such as
-.BI -f
+.B -f
and also understands
-.B cpp
+.I cpp
options, such as
-.BI -Dfoo=bar
+.BI -Dfoo= bar
for pre-defining a macro.
Just like with
-.BR awk ,
+.IR awk ,
code is specified either directly as the first non-option argument, or via the
-.BI -f
+.B -f
option which indicates a file. In either situation,
-.B cppawk
+.I cppawk
preprocesses the code and places the result in a temporary file which is then
executed as
-.B awk
+.I awk
code.
.SH OPTIONS
Any option not described here is assumed to be an Awk option which takes
no argument, and is consequently passed through to the
-.B awk
+.I awk
program.
-.IP "\fB\-\-\fR"
+.IP "\fB--\fR"
End of options: any subsequent argument is the first non-option argument, even
if it looks like an option.
-.IP "\fB\-\-prepro\-only\fR"
+.IP "\fB--prepro-only\fR"
Do not run the preprocessed Awk program; dump the preprocessed code to standard output.
-.IP "\fB\-\-awk=\fR\fIpath\fR"
+.IP "\fB--awk=\fR\fIpath\fR"
Specify alternative Awk implementation. If it contains no slashes, then
-.BI PATH
+.B PATH
is searched to find the program. If the base name of the program is
-.BI gawk
+.I gawk
or
-.BI mawk,
+.I mawk,
then, respectively, one of the preprocessor symbols
-.BI __gawk__
+.B __gawk__
or
-.BI __mawk__
+.B __mawk__
is predefined, with a value of 1. This happens immediately when this
option is processed, so can be counter-acted by a subsequent
-.BI -U
+.B -U
option.
.IP "\fB\-\-prepro=\fR\fIpath\fR"
Specify alternative preprocessor. If it contains no slashes, then
-.BI PATH
+.B PATH
is searched to find the program.
.IP "\fB\-f\fR \fIfilename\fR"
@@ -79,76 +79,76 @@ Read the awk program from
.I filename
rather than processing awk code from the first non-option command-line
argument. The program is preprocessed to a temporary file, and
-.B awk
+.I awk
is then invoked on this file. The file is deleted when
-.B awk
+.I awk
terminates.
-.IP "\fB\-\-nobash\fR"
+.IP "\fB--nobash\fR"
Pretend that the shell which executes
-.B cppawk
+.I 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.
-.IP "\fB\-\-dump-macros\fR"
+.IP "\fB-\dump-macros\fR"
Instruct the preprocessor to dump all of the
-.BI #define
+.B #define
directives instead of the preprocessed output. Since this is only useful with
-.BI --prepro-only
+.B --prepro-only
that option is implied.
.IP "\fB\-M\fR, \fB\--bignum\fR"
These two equivalent GNU Awk options are passed through to
-.BR awk ,
+.I awk ,
which will understand them if it is GNU Awk. Using either of them causes
the preprocessor symbol
-.BI __bignum__
+.B __bignum__
to be defined with the value 1.
.IP "\fB\-P\fR, \fB\--posix\fR"
These two equivalent GNU Awk options are passed through to
-.BR awk ,
+.I awk ,
which will understand them if it is GNU Awk. Using either of them causes
the preprocessor symbol
-.BI __posix__
+.B __posix__
to be defined with the value 1.
.IP "\fB\-M...\fR
Any optional argument beginning with
-.BI -M
+.B -M
and followed by one or more characters results in a diagnostic
message and failed termination. The intent is that the
-.BI -M
+.B -M
family of options that are supported by GNU cpp are not supported by
-.BR cppawk .
+.IR cppawk .
.IP "\fB-F\fR, \fB-v\fR, \fB-E\fR, \fB-i\fR, \fB-l\fR, \fB-L\fR"
-These standard and GNU Awk options are recognizes by
-.B cppawk
+These standard and GNU Awk options are recognized by
+.I cppawk
as requiring an argument. They are validated for the presence of the
required argument, and passed to
-.BR awk .
+.IR awk .
.IP "\fB-U...\fR, \fB-D...\fR, \fB-I...\fR, \fB-iquote...\fR"
Options which match these patterns are passed to the
-.B cpp
+.I cpp
program instead of
-.BR awk .
+.IR awk .
.SH PREDEFINED SYMBOLS
.IP \fB__gawk__\fR
When
-.B cppawk
+.I cppawk
installation is configured to use GNU Awk, which is the default, the
preprocessor symbol
-.BI __gawk__
+.I __gawk__
is predefined with a value of 1. See the
-.BI --awk
+.I --awk
option.
.IP \fB__cppawk_ver\fR
This preprocessor symbol gives the version of
-.BR cppawk .
+.IR cppawk .
Its value is a is an eight digit decimal integer the form
.IR YYYYMMDD ,
such as 20220321.
@@ -156,18 +156,18 @@ such as 20220321.
.SH CONFIGURATION SYMBOLS
.IP \fB__gawk_ver\fR
Certain
-.B cppawk
+.I cppawk
header files may have functionality that depends on GNU Awk.
The
-.BI __gawk_ver
+.B __gawk_ver
variable may be set by the application to indicate which version of GNU Awk
should be assumed by those library headers. The headers will avoid generating
code that doesn't work with later versions than this.
This variable should be set before including any header files, or
using the
-.BI -D
+.B -D
option on the command line.
The variable should be a decimal integer, whose last four digits encode the minor
@@ -184,27 +184,27 @@ Lower values than 40000 are not supported; code that requires GNU Awk
assumes at least version 4.0.
.SH STANDARD HEADERS
-.B cppawk
+.I cppawk
points the preprocessor to look for
-.BI "#include <...>"
+.B "#include <...>"
files in its own directory, which contains a library of header files that accompany
-.BR cppawk .
+.IR cppawk .
-.IR <narg.h>
+.IP \fB<narg.h>\fR
This header provides macros which make it easy to write variable-argument
macros with complex expansions. This is documented in the
-.B cppawk-narg
+.I cppawk-narg
manual page.
-.IR <case.h>
+.IP \fB<case.h>\fR
This header provides macros for writing a
-.BI case
+.B case
statement. The case statement
syntax is designed so that a GNU Awk switch statement is easily converted to it.
The preprocessor translates it back to a clean GNU Awk switch statement,
or to portable Awk code that runs on other Awks. The contents of this header
are documented by the
-.B cppawk-case
+.I cppawk-case
manual page.
.SH EXAMPLES
@@ -212,7 +212,7 @@ 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'
+ { print max($1, $2) /* C comment */ } #awk comment'
Implement awk-like processing loop within function, to process
/proc/mounts:
@@ -232,7 +232,7 @@ Implement awk-like processing loop within function, to process
}
Where
-.BI awkloop.h
+.B awkloop.h
contains:
#define awkloop(file) for (; getline < file || (close(file) && 0); )
@@ -244,35 +244,35 @@ awk(1), cpp(6)
.SH BUGS
The
-.BI -f
+.B -f
option can be given only once, whereas
-.B awk
+.I awk
accepts multiple
-.BI -f
+.B -f
options, and executes each of the indicated files.
Awk error messages are reported against the preprocessed text.
Awk
-.BI #
+.B #
comments cannot be used at the start of a line because
-.BI #
+.B #
begins a preprocessing directive. They also cannot be used inside
a preprocessing directive, such as a macro definition, because
-.BI #
+.B #
is an operator in the preprocessor language. It may be a good idea
to avoid
-.BI #
+.B #
comments entirely in
-.B cppawk
+.I cppawk
source, and use only C comments.
The
-.B cpp
+.I 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
-.B cppawk
+.I cppawk
works at all; however, there may be corner cases where some issue arises
because of this. One example is that double quote characters may be used
in Awk regular expressions such as
@@ -291,16 +291,16 @@ original file. Although the preprocessed output indicates source file and line
number information, Awks do not understand this.
The default choices of
-.B gawk
+.I gawk
and
-.B cpp
+.I cpp
are fixed in the source code; users must edit
-.B cppawk
+.I cppawk
to select alternative implementations or locations of these tools,
if they don't wish to use the
-.BI --awk
+.B --awk
and
-.BI --prepro
+.B --prepro
command line options.
.SH AUTHOR