| 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;
 |