blob: f4d26feff071a307cd8d992df8d8f77826865a65 [file] [log] [blame]
#!/usr/bin/perl
# -*- perl -*-
# Copyright (C) 2006 Red Hat Inc.
#
# This file is part of GAS, the GNU Assembler.
#
# GAS is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# GAS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GAS; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA. */
%myfiles = ();
$incdir = ".";
while ($ARGV[0] =~ /^-/) {
$opt = shift;
if ($opt eq "-I") {
$incdir = shift;
}
}
$infile = shift;
$outfile = shift;
$inbase = $infile;
$inbase =~ s@.*/@@;
$inbase =~ s@[^a-zA-Z0-9].*@@;
$t = 0;
$errors = 0;
if ($outfile) {
open(OUT, ">$outfile");
} else {
open(OUT, ">&STDOUT");
}
open(I, "$incdir/macros.inc") || die("$incdir/macros.inc: $!");
&read_file();
close I;
open(I, $infile) || die("$infile: $!");
&read_file();
close I;
sub read_file {
while (<I>) {
$line ++;
next if /^;/;
s/[\r\n]+$//;
if (/^macro\s+(\S+)\s+(.*)/) {
($name, $val) = ($1,$2);
print "set macro \"$name\" to \"$val\"\n" if $t;
$macro{$name} = $val;
} elsif (/\S/) {
&explode($_);
}
}
}
exit ($errors);
# There's no way to quote braces so you can output them :-P
sub explode {
my ($s) = @_;
my ($a, $b, $p, $e, @params);
print "explode($s)\n" if $t;
($b, $a, @params) = &split_braces($s);
@params = explode_params (@params);
if (! $a && ! @params) {
if ($t) {
print "\033[33m$s\033[0m\n";
} else {
print OUT "$s\n";
}
return;
}
if (@params == 1 && defined $macro{$params[0]}) {
$p = $macro{$params[0]};
&explode ("$b$p$a");
} else {
for $p (@params) {
&explode ("$b$p$a");
}
}
}
sub explode_params {
my (@p) = @_;
my ($p,@r);
@r = ();
while (@p) {
$p = shift @p;
($b,$a,@e) = split_braces ($p);
if (defined $a) {
for $e (reverse @e) {
unshift (@p, "$b$e$a");
}
} else {
push (@r, $p);
}
}
return @r;
}
sub getmacro {
my ($v) = $macro{$_[0]};
if (! defined $v) {
print STDERR "$line: Error: macro $_[0] not defined\n";
$errors ++;
}
return $v;
}
sub expand_macros {
my ($l) = @_;
0 while $l =~ s/{([^{};]+)}/&getmacro($1)/ge;
return $l;
}
# returns (before, after, list of variances)
sub split_braces {
my ($l) = @_;
my (@l, $i, $a, @parms, $b, $n,$p);
print "split_braces($l) = (" if $t;
$l = &expand_macros ($l);
if ($l !~ /\{.*\}/) {
print "nothing)\n" if $t;
return ($l);
}
if ($l =~ /^{([^{};]+)}/) {
print "macro:", $macro{$1}, ")\n" if $t;
return (&getmacro($1), "");
}
$n = 0;
@parms = ('');
$p = 0;
($a, $l) = $l =~ m@^([^\{]*)\{(.*)@;
@l = split(//, $l);
while (defined ($i = shift @l)) {
if ($n == 0) {
print "\033[32m$i" if $t;
if ($i eq '}') {
print "\033[0m$a, ", join('', @l), ", (", join("\033[31m;\033[0m", @parms), ")\n" if $t;
return ($a, join('',@l), @parms);
} elsif ($i eq ';') {
$p ++;
$parms[$p] = '';
} else {
$parms[$p] .= $i;
$n ++ if $i eq '{';
}
} else {
print "\033[34m$i" if $t;
$n ++ if $i eq '{';
$n -- if $i eq '}';
$parms[$p] .= $i;
}
}
print "$a, <null>, (", join(';', @parms), ")\n" if $t;
return ($a, "", @parms);
}
__END__;
macro rest c,d
foo {a;b},{{rest};e;}
expands to:
foo a,c
foo a,d
foo a,e
foo a,
foo b,c
foo b,d
foo b,e
foo b,