1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- #!/usr/bin/perl
- #
- # Routine to read define'd constants from a Verilog or C header
- # If expressions are used, they need to be defined with care to
- # be able to evaluate them. Conditionals are NOT processed.
- #
- use strict;
- use Math::BigInt;
- sub header_const($) {
- my($file) = @_;
- my %bases = ('d' => 10, 'b' => 2, 'o' => 8, 'q' => 8, 'h' => 16,
- 'x' => 16, '0' => 8, '0x' => 16, '' => 10);
- my %syms = ();
- open(my $f, '<', $file)
- or die "$0: $file: $!\n";
- while (defined(my $l = <$f>)) {
- chomp $l;
- while ($l =~ /\/$/) {
- my $ll = <$f>;
- last unless (defined($ll));
- chomp $ll;
- $l = substr($l,0,-1) . $ll;
- }
- $l =~ s/\/\/.*$//;
- $l =~ s/\/\*.*?\*\///g;
- if ($l =~ /^\s*[\`\#]\s*define\s+\`?([[:alpha:]_]\w*)\s+(.*?)\s*$/) {
- $syms{$1} = $2;
- } elsif ($l =~ /^\s*[\`\#]\s*undef\s+\`?([[:alpha:]_]\w*)/) {
- delete $syms{$1};
- }
- }
- close($f);
- foreach my $s (keys %syms) {
- my $e = $syms{$s};
- my $o = '';
- # Don't try to evaluate if...
- next if ($e =~ /[\"\$\@\[\{\\]/);
- $e =~ s/\`//g;
- while ($e =~ /^(.*?)\b[0-9]*\'([bhod])([0-9a-f_]+)\b(.*)$/i ||
- $e =~ /^(.*?)\b()(0[0-7_]+|0b[0-1_]+|0x[0-9a-f_]+)\b(.*)$/i) {
- $e = $4;
- $o .= $1;
- my $base = lc($2);
- my $dig = $3;
- $dig =~ s/_//g;
- if ($base ne '') {
- $base = $bases{$base};
- } elsif ($dig =~ /^0x/i) {
- $base = 16;
- } elsif ($dig =~ /^0b/i) {
- $base = 2;
- } elsif ($dig =~ /^0/) {
- $base = 8;
- }
- $o .= Math::BigInt::from_base($dig, $base)->bstr();
- }
- $syms{$s} = $o.$e;
- }
- foreach my $s (keys %syms) {
- my $e = $syms{$s};
- my $o = '';
- while ($e =~ /^(.*?)\b\`?([[:alpha:]_]\w*)\b(.*)$/) {
- $e = $3;
- $o .= $1;
- if (defined($syms{$2})) {
- $e = $syms{$2} . $e;
- } else {
- $o .= $2;
- }
- }
- $syms{$s} = eval("{ use bigint; return Math::BigInt->new($o$e)->numify(); }");
- }
- return %syms;
- }
- 1;
|