.\" cppawk: C preprocessor wrapper around awk .\" Copyright 2022 Kaz Kylheku .\" .\" BSD-2 License .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are met: .\" .\" 1. Redistributions of source code must retain the above copyright notice, .\" this list of conditions and the following disclaimer. .\" .\" 2. Redistributions in binary form must reproduce the above copyright notice, .\" this list of conditions and the following disclaimer in the documentation .\" and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" .\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE .\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .TH CPPAWK-CASE 1 "19 April 2022" "cppawk Libraries" "Case Macro" .SH NAME case \- macro for portable switch statement .SH SYNOPSIS .ft B #include case (\fIexpr\fP) { of (\fI"abc"\fP) print "single key abc case" cbreak of (\fI1\fP, \fI2\fP, \fI3\fP) print \fI"multi-key 1, 2, 3 case"\fP cfall # fall through matching (\fI/regex1/\fP, \fI/regex2/\fP, \fI/regex3/\fP) print \fI"regex case"\fP cbreak mixed ((\fI"def"\fP, \fI"ghi"\fP), (\fI/regex4/\fP, \fI/regex5/\fP)) otherwise print \fI"default case"\fP } .ft R .SH DESCRIPTION The .B case macro provides syntax which .I cppawk translates very directly to the GNU Awk .B switch statement, or else to alternative code which works with other Awk implementations. The purpose of the macro is easy conversion of .B switch code; therefore, it has the same semantics with regard to fall through between cases, requiring an explicit break. The clauses of .B case are labeled with the identifiers .BR of , .BR matching , or .BR mixed , which take arguments, and are followed by one or more statements. The last one of those statements must always be a .BR cbreak , .B cfall or .B cret statement, described below. Regular expression keys must use the .B matching label; ordinary keys compared for equality must use the .B of label. The .B mixed label allows for both keys to be included in one case. The .B of and .B matching macros take variable arguments. Multiple matching keys or regular expressions are specified as multiple arguments, rather than by repetition of the construct: .ft B of (\fI3\fP) of (\fI4\fP) print \fI"3 or 4"\fP; cbreak // incorrect of (\fI3\fP, \fI4\fP) print \fI"3 or 4"\fP; cbreak // correct .ft R The .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: .ft B mixed ((\fI1\fP, \fI2\fP, \fI"a"\fP), (\fI/xyz$/\fP, \fI/^\et/\fP)) .ft R Each clause must specify how it terminates: whether it breaks out of the .B case statement, "falls through" to the next case, or returns from the surrounding function. The macros .BR cbreak , .B cfall and .B cret must be used for this purpose. The .B cret macro takes exactly one argument, the expression whose value is to be returned from the surrounding function: .ft B function f(\fIinput\fP, \fIcase_temps\fP) { case (\fIinput\fP) { match (\fI/abc/\fP) print \fI"match on regex /abc/"\fP cret(\fI1\fP) otherwise cbreak } // other logic return \fI0\fP } .ft R When .B case is transformed into portable code rather than .BR switch , that code depends on hidden state variables. If .B case is used in a top-level .BR BEGIN , .B END or Awk action, those variables will be global. They will also be global if .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 .B case_temps macro: .ft B #include function fun(\fIx\fP, \fIy\fP, \fIz\fP, # arguments \fIa\fP, \fIb\fP, # locals \fIcase_temps\fP) # locals for case { case (\fIx\fP) { of (\fI42\fP) { ... } ... } } .ft R .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, .B case_temps expands to an unspecified identifier in the .B __[a-z] reserved namespace. .SH "SEE ALSO" cppawk(1) .SH BUGS The .B case macro does not currently safely nest with itself. Forgetting to declare the temporary variables is a programmer pitfall. .SH AUTHOR Kaz Kylheku .SH COPYRIGHT Copyright 2022, BSD2 License.