aboutsummaryrefslogtreecommitdiffstats
path: root/cppawk-case.1
blob: ff1ed686d9a18f10e38b4bb7ca1c79da1bb3c9c7 (plain)
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
CPPAWK-CASE(1)                              Case Macro                             CPPAWK-CASE(1)

NAME
       case - macro for portable switch statement

SYNOPSIS
         #include <case.h>

         case (expr) {
           of ("abc")
             print "single key abc case"
             cbreak

           of (1, 2, 3)
             print "multi-key 1, 2, 3 case"
             cfall   # fall through

           matching (/regex1/, /regex2/, /regex3/)
             print "regex case"
             cbreak

           mixed (("def", "ghi"), (/regex4/, /regex5/))

           otherwise
             print "default case"
         }

DESCRIPTION
       The case macro provides syntax which cppawk translates very directly to the GNU Awk switch
       statement, or else to alternative code which works with other Awk implementations.

       The purpose of the macro is easy conversion of switch code; therefore, it has the same se-
       mantics with regard to fall through between cases, requiring an explicit break.

       The  clauses  of  case are labeled with the identifiers of, matching, or mixed, which take
       arguments, and are followed by one or more statements. The last one  of  those  statements
       must always be a cbreak, cfall or cret statement, described below.

       Regular  expression  keys must use the matching label; ordinary keys compared for equality
       must use the of label. The mixed label allows for both keys to be included in one case.

       The of and matching macros take variable arguments. Multiple matching keys or regular  ex-
       pressions are specified as multiple arguments, rather than by repetition of the construct:

         of (3) of (4) print "3 or 4"; cbreak    // incorrect

         of (3, 4) print "3 or 4"; cbreak        // correct

       The  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 lit-
       erals:

         mixed ((1, 2, "a"), (/xyz$/, /^\t/))

       Each  clause  must specify how it terminates: whether it breaks out of the case statement,
       "falls through" to the next case, or returns from the surrounding  function.   The  macros
       cbreak, cfall and cret must be used for this purpose. The cret macro takes exactly one ar-
       gument, the expression whose value is to be returned from the surrounding function:

         function f(input,
                    case_temps)
         {
           case (input) {
             match (/abc/)
               print "match on regex /abc/"
               cret(1)

             otherwise
               cbreak
           }

           // other logic
           return 0
         }

       When case is transformed into portable code rather than switch, that code depends on  hid-
       den state variables.  If case is used in a top-level BEGIN, END or Awk action, those vari-
       ables will be global.  They will also be global if case is used in a function, unless  de-
       fined as local variables in the parameter list.

       Defining the temporary variables as local is done using the provided case_temps macro:

         #include <case.h>

         function fun(x, y, z,    # arguments
                      a, b,       # locals
                      case_temps) # locals for case
         {
           case (x) {
             of (42) {
                ...
             }
             ...
           }
         }

       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, case_temps expands to an unspecified identifier in the __[a-z] re-
       served namespace.

SEE ALSO
       cppawk(1)

BUGS
       The case macro does not currently safely nest with itself.

       Forgetting to declare the temporary variables is a programmer pitfall.

AUTHOR
       Kaz Kylheku <kaz@kylheku.com>

COPYRIGHT
       Copyright 2022, BSD2 License.

cppawk Libraries                          19 April 2022                            CPPAWK-CASE(1)