Commit | Line | Data |
---|---|---|
c7927a3c NC |
1 | #!/usr/bin/perl |
2 | # -*- perl -*- | |
3 | ||
4 | # Copyright (C) 2006 Red Hat Inc. | |
5 | # | |
6 | # This file is part of GAS, the GNU Assembler. | |
7 | # | |
8 | # GAS is free software; you can redistribute it and/or modify | |
9 | # it under the terms of the GNU General Public License as published by | |
10 | # the Free Software Foundation; either version 2, or (at your option) | |
11 | # any later version. | |
12 | # | |
13 | # GAS is distributed in the hope that it will be useful, | |
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | # GNU General Public License for more details. | |
17 | # | |
18 | # You should have received a copy of the GNU General Public License | |
19 | # along with GAS; see the file COPYING. If not, write to | |
20 | # the Free Software Foundation, 59 Temple Place - Suite 330, | |
21 | # Boston, MA 02111-1307, USA. */ | |
22 | ||
23 | %myfiles = (); | |
24 | ||
25 | $incdir = "."; | |
26 | ||
27 | while ($ARGV[0] =~ /^-/) { | |
28 | $opt = shift; | |
29 | if ($opt eq "-I") { | |
30 | $incdir = shift; | |
31 | } | |
32 | } | |
33 | ||
34 | $infile = shift; | |
35 | $outfile = shift; | |
36 | ||
37 | $inbase = $infile; | |
38 | $inbase =~ s@.*/@@; | |
39 | $inbase =~ s@[^a-zA-Z0-9].*@@; | |
40 | ||
41 | $t = 0; | |
42 | $errors = 0; | |
43 | ||
44 | if ($outfile) { | |
45 | open(OUT, ">$outfile"); | |
46 | } else { | |
47 | open(OUT, ">&STDOUT"); | |
48 | } | |
49 | ||
50 | open(I, "$incdir/macros.inc") || die("$incdir/macros.inc: $!"); | |
51 | &read_file(); | |
52 | close I; | |
53 | open(I, $infile) || die("$infile: $!"); | |
54 | &read_file(); | |
55 | close I; | |
56 | ||
57 | sub read_file { | |
58 | while (<I>) { | |
59 | $line ++; | |
60 | next if /^;/; | |
61 | s/[\r\n]+$//; | |
62 | if (/^macro\s+(\S+)\s+(.*)/) { | |
63 | ($name, $val) = ($1,$2); | |
64 | print "set macro \"$name\" to \"$val\"\n" if $t; | |
65 | $macro{$name} = $val; | |
66 | } elsif (/\S/) { | |
67 | &explode($_); | |
68 | } | |
69 | } | |
70 | } | |
71 | ||
72 | exit ($errors); | |
73 | ||
74 | # There's no way to quote braces so you can output them :-P | |
75 | ||
76 | sub explode { | |
77 | my ($s) = @_; | |
78 | my ($a, $b, $p, $e, @params); | |
79 | ||
80 | print "explode($s)\n" if $t; | |
81 | ||
82 | ($b, $a, @params) = &split_braces($s); | |
83 | @params = explode_params (@params); | |
84 | if (! $a && ! @params) { | |
85 | if ($t) { | |
86 | print "\033[33m$s\033[0m\n"; | |
87 | } else { | |
88 | print OUT "$s\n"; | |
89 | } | |
90 | return; | |
91 | } | |
92 | if (@params == 1 && defined $macro{$params[0]}) { | |
93 | $p = $macro{$params[0]}; | |
94 | &explode ("$b$p$a"); | |
95 | } else { | |
96 | for $p (@params) { | |
97 | &explode ("$b$p$a"); | |
98 | } | |
99 | } | |
100 | } | |
101 | ||
102 | sub explode_params { | |
103 | my (@p) = @_; | |
104 | my ($p,@r); | |
105 | ||
106 | @r = (); | |
107 | while (@p) { | |
108 | $p = shift @p; | |
109 | ($b,$a,@e) = split_braces ($p); | |
110 | if (defined $a) { | |
111 | for $e (reverse @e) { | |
112 | unshift (@p, "$b$e$a"); | |
113 | } | |
114 | } else { | |
115 | push (@r, $p); | |
116 | } | |
117 | } | |
118 | return @r; | |
119 | } | |
120 | ||
121 | sub getmacro { | |
122 | my ($v) = $macro{$_[0]}; | |
123 | if (! defined $v) { | |
124 | print STDERR "$line: Error: macro $_[0] not defined\n"; | |
125 | $errors ++; | |
126 | } | |
127 | return $v; | |
128 | } | |
129 | ||
130 | sub expand_macros { | |
131 | my ($l) = @_; | |
132 | 0 while $l =~ s/{([^{};]+)}/&getmacro($1)/ge; | |
133 | return $l; | |
134 | } | |
135 | ||
136 | # returns (before, after, list of variances) | |
137 | sub split_braces { | |
138 | my ($l) = @_; | |
139 | my (@l, $i, $a, @parms, $b, $n,$p); | |
140 | ||
141 | print "split_braces($l) = (" if $t; | |
142 | ||
143 | $l = &expand_macros ($l); | |
144 | ||
145 | if ($l !~ /\{.*\}/) { | |
146 | print "nothing)\n" if $t; | |
147 | return ($l); | |
148 | } | |
149 | if ($l =~ /^{([^{};]+)}/) { | |
150 | print "macro:", $macro{$1}, ")\n" if $t; | |
151 | return (&getmacro($1), ""); | |
152 | } | |
153 | ||
154 | $n = 0; | |
155 | @parms = (''); | |
156 | $p = 0; | |
157 | ||
158 | ($a, $l) = $l =~ m@^([^\{]*)\{(.*)@; | |
159 | @l = split(//, $l); | |
160 | ||
161 | while (defined ($i = shift @l)) { | |
162 | if ($n == 0) { | |
163 | print "\033[32m$i" if $t; | |
164 | if ($i eq '}') { | |
165 | print "\033[0m$a, ", join('', @l), ", (", join("\033[31m;\033[0m", @parms), ")\n" if $t; | |
166 | return ($a, join('',@l), @parms); | |
167 | } elsif ($i eq ';') { | |
168 | $p ++; | |
169 | $parms[$p] = ''; | |
170 | } else { | |
171 | $parms[$p] .= $i; | |
172 | $n ++ if $i eq '{'; | |
173 | } | |
174 | } else { | |
175 | print "\033[34m$i" if $t; | |
176 | $n ++ if $i eq '{'; | |
177 | $n -- if $i eq '}'; | |
178 | $parms[$p] .= $i; | |
179 | } | |
180 | } | |
181 | print "$a, <null>, (", join(';', @parms), ")\n" if $t; | |
182 | return ($a, "", @parms); | |
183 | } | |
184 | ||
185 | __END__; | |
186 | ||
187 | macro rest c,d | |
188 | foo {a;b},{{rest};e;} | |
189 | ||
190 | expands to: | |
191 | ||
192 | foo a,c | |
193 | foo a,d | |
194 | foo a,e | |
195 | foo a, | |
196 | foo b,c | |
197 | foo b,d | |
198 | foo b,e | |
199 | foo b, |