IEEE 802.15.4 subsystem
Sign in or create your account | Project List | Help
IEEE 802.15.4 subsystem Git Source Tree
Root/
Source at commit 873f80cb4dac00800826958f9869ec55dbd9e91c created 10 years 7 months ago. By Werner Almesberger, tools/atrf-txrx/atrf-txrx.c: option -q becomes "quick" and uses aggressive polling | |
---|---|
1 | #!/usr/bin/perl |
2 | # |
3 | # hmac.pl - Simple macro pre-processor for HTML |
4 | # |
5 | # Written 2001, 2011 by Werner Almesberger |
6 | # Copyright 2001 EPFL DSC-ICA, Network Robots |
7 | # Copyright 2001, 2011 Werner Almesberger |
8 | # |
9 | # This program is free software; you can redistribute it and/or modify |
10 | # it under the terms of the GNU General Public License as published by |
11 | # the Free Software Foundation; either version 2 of the License, or |
12 | # (at your option) any later version. |
13 | # |
14 | |
15 | #------------------------------------------------------------------------------ |
16 | # |
17 | # hmac processes macro definitions of the following type: |
18 | # |
19 | # <MACRO NAME=name param[=default] ...> ... </MACRO> |
20 | # |
21 | # The macro is invoked with <name param=value ...> or with |
22 | # <name param=value ...> ... </name> |
23 | # |
24 | # HTML tags corresponding to the parameters (e.g. <param>) are expanded in |
25 | # the macro body. Parameters for which no default value was given must be |
26 | # specified. |
27 | # |
28 | # In the block-style invocation, the content of the block is assigned to |
29 | # the parameter BODY. Block-style invocations cannot be nested. |
30 | # |
31 | # Macros and macro definitions are processed in the order in which they appear |
32 | # in the input file. Macro definitions inside macros are processed when the |
33 | # outer macro is expanded. |
34 | # |
35 | # Files can be included with the <INCLUDE FILE=name> tag. File inclusions |
36 | # are made as we go. |
37 | # |
38 | # hmac is not case-sensitive. |
39 | # |
40 | #------------------------------------------------------------------------------ |
41 | |
42 | # |
43 | # Marker |
44 | # |
45 | $BM = "\001"; |
46 | $EM = "\002"; |
47 | |
48 | # |
49 | # Collect -Dmacro=value options |
50 | # |
51 | while ($ARGV[0] =~ /^-D([^=]+)=/) { |
52 | $mac{$1} = $'; |
53 | shift(@ARGV); |
54 | } |
55 | |
56 | # |
57 | # Complain about unrecognized options |
58 | # |
59 | if ($ARGV[0] =~ /^-/) { |
60 | print STDERR "usage: $0 [-Dmacro=value ...] file ...\n"; |
61 | exit(1); |
62 | } |
63 | |
64 | # |
65 | # Read input and put warning |
66 | # |
67 | $in = join("",<>); |
68 | $in =~ s/\n/\n\n<!-- MACHINE-GENERATED FILE, DO NOT EDIT ! -->\n\n/; |
69 | |
70 | # |
71 | # Scan text for macros or includes |
72 | # |
73 | while (1) { |
74 | $first_macdef = &find_macdef($in); |
75 | $first_macro = &find_macro($in); |
76 | $first_include = &find_include($in); |
77 | last if $first_macdef == -1 && $first_macro == -1 && $first_include == -1; |
78 | if ($first_include != -1 && |
79 | ($first_include < $first_macro || $first_macro == -1) && |
80 | ($first_include < $first_macdef || $first_macdef == -1)) { |
81 | $in = &include_file($in); |
82 | } |
83 | else { |
84 | if (($first_macdef < $first_macro && $first_macdef != -1) || |
85 | $first_macro == -1) { |
86 | $in = &define_macro($in); |
87 | } |
88 | else { |
89 | $in = &expand_macro($in); |
90 | } |
91 | } |
92 | } |
93 | print $in; |
94 | |
95 | |
96 | # |
97 | # Find includes, and macros and their definitions |
98 | # |
99 | |
100 | sub find_include |
101 | { |
102 | local ($in) = @_; |
103 | return -1 unless $in =~ /<INCLUDE\s+file="[^"]*"/i; |
104 | return length($`)+length($&); |
105 | } |
106 | |
107 | |
108 | sub find_macdef |
109 | { |
110 | local ($in) = @_; |
111 | return -1 unless $in =~ /<MACRO\b/i; |
112 | return length $`; |
113 | } |
114 | |
115 | |
116 | sub find_macro |
117 | { |
118 | local ($in) = @_; |
119 | local ($first) = -1; |
120 | |
121 | for $mac (keys %mac) { |
122 | if ($in =~ /<$mac\b/i) { |
123 | $first = length $` if $first == -1 || length $` < $first; |
124 | } |
125 | } |
126 | return $first; |
127 | } |
128 | |
129 | |
130 | # |
131 | # Include a file |
132 | # |
133 | |
134 | sub include_file |
135 | { |
136 | local ($in) = @_; |
137 | local ($name,$f); |
138 | |
139 | $in =~ /<INCLUDE\s+FILE=("([^"]*)"|\S+)\s*>\s*/i; |
140 | $name = defined $2 ? $2 : $1; |
141 | undef $f; |
142 | open(FILE,$name) || die "open $name: $!"; |
143 | $f = $`.join("",<FILE>).$'; |
144 | close FILE; |
145 | return $f; |
146 | } |
147 | |
148 | |
149 | # |
150 | # Extract first macro definition |
151 | # |
152 | |
153 | sub define_macro |
154 | { |
155 | local ($in) = @_; |
156 | local ($a,$b,$c,$d); |
157 | local ($name, $need, $prm, %arg); |
158 | |
159 | $in =~ s/<MACRO\b/$BM/gi; |
160 | $in =~ s|</MACRO>|$EM|gi; |
161 | if ($in =~ /$BM(("[^"]*"|[^>])*)>/is) { |
162 | ($a,$b,$c) = ($`,$1,$'); |
163 | $d = ""; |
164 | $need = 1; |
165 | while ($need) { |
166 | $bm = index($c,$BM); |
167 | $em = index($c,$EM); |
168 | die "<MACRO> without </MACRO>" if $em == -1; |
169 | if ($bm < $em && $bm != -1) { |
170 | $d .= substr($c,0,$bm+1,""); |
171 | $need++; |
172 | } |
173 | else { |
174 | $d .= substr($c,0,$em+1,""); |
175 | $need--; |
176 | } |
177 | } |
178 | $c =~ s/^\s*//s; |
179 | $in = $a.$c; |
180 | chop($d); # remove last $EM |
181 | undef $name; |
182 | undef %arg; |
183 | $b =~ s/^\s*//; |
184 | while ($b =~ /^([a-z_][a-z0-9_]*)(=("([^"]*)"|\S+))?\s*/is) { |
185 | $b = $'; |
186 | ($prm = $1) =~ tr/a-z/A-Z/; |
187 | if ($prm eq "NAME") { |
188 | die "duplicate NAME" if defined $name; |
189 | die "NAME without value" unless defined $2; |
190 | ($name = defined $4 ? $4 : $3) =~ tr/a-z/A-Z/; |
191 | next; |
192 | } |
193 | die "reserved parameter name BODY" if $prm eq "BODY"; |
194 | die "duplicate parameter \"$prm\"" if exists $arg{$prm}; |
195 | $arg{$prm} = defined $2 ? defined $4 ? $4 : $3 : undef; |
196 | } |
197 | die "syntax error" unless $b eq ""; |
198 | die "NAME parameter is missing" unless defined $name; |
199 | $d =~ s/$BM/<MACRO/gi; |
200 | $d =~ s|$EM|</MACRO>|gi; |
201 | # $mac{$name} = $d; |
202 | $mac{$name} = &expand_macro_list($d, $name); |
203 | $args{$name} = { %arg }; |
204 | } |
205 | else { |
206 | die "</MACRO> without <MACRO>" if $in =~ m|$EM|; |
207 | } |
208 | $in =~ s/$BM/<MACRO/gi; |
209 | $in =~ s|$EM|</MACRO>|gi; |
210 | return $in; |
211 | } |
212 | |
213 | |
214 | # |
215 | # Expand first macro |
216 | # |
217 | |
218 | sub expand_macro_list |
219 | { |
220 | local ($in, @mac) = @_; |
221 | local ($a,$b,$c); |
222 | local ($mac, $done, $prm, %arg); |
223 | |
224 | undef $a; |
225 | for $mac (@mac) { |
226 | if ($in =~ /<$mac\b(("[^"]*"|[^>])*)>/is) { |
227 | ($a,$b,$c) = ($`,$1,$') if length $` < length $a || !defined $a; |
228 | } |
229 | next unless defined $a; |
230 | undef %arg; |
231 | %arg = %{ $args{$mac} }; |
232 | if ($c =~ m|</$mac>|i) { |
233 | $arg{"BODY"} = $`; |
234 | $c = $'; |
235 | } |
236 | else { |
237 | $arg{"BODY"} = undef; |
238 | } |
239 | $b =~ s/^\s*//; |
240 | while ($b =~ /^([a-z_][a-z0-9_]*)(=("([^"]*)"|\S+))\s*/is) { |
241 | $b = $'; |
242 | ($prm = $1) =~ tr/a-z/A-Z/; |
243 | die "unrecognized parameter \"$prm\"" unless exists $arg{$prm}; |
244 | $arg{$prm} = defined $2 ? defined $4 ? $4 : $3 : undef; |
245 | } |
246 | $b = $mac{$mac}; |
247 | while (1) { |
248 | $done = 1; |
249 | for (keys %arg) { |
250 | while ($b =~ /<$_>/i) { |
251 | $done = 0; |
252 | die "required parameter $_ is missing in macro $mac" |
253 | unless defined $arg{$_}; |
254 | $b = $`.$arg{$_}.$'; |
255 | } |
256 | } |
257 | last if $done; |
258 | } |
259 | return $a.$b.$c; |
260 | } |
261 | return $in; |
262 | } |
263 | |
264 | |
265 | sub expand_macro |
266 | { |
267 | local ($in) = @_; |
268 | |
269 | return &expand_macro_list($in, keys %mac); |
270 | } |
271 |