diff options
-rw-r--r-- | cppawk-case.1 | 66 | ||||
-rw-r--r-- | cppawk-narg.1 | 105 | ||||
-rw-r--r-- | cppawk.1 | 146 |
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. @@ -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 |