hconst.ph 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #!/usr/bin/perl
  2. #
  3. # Routine to read define'd constants from a Verilog or C header
  4. # If expressions are used, they need to be defined with care to
  5. # be able to evaluate them. Conditionals are NOT processed.
  6. #
  7. use strict;
  8. use Math::BigInt;
  9. sub header_const($) {
  10. my($file) = @_;
  11. my %bases = ('d' => 10, 'b' => 2, 'o' => 8, 'q' => 8, 'h' => 16,
  12. 'x' => 16, '0' => 8, '0x' => 16, '' => 10);
  13. my %syms = ();
  14. open(my $f, '<', $file)
  15. or die "$0: $file: $!\n";
  16. while (defined(my $l = <$f>)) {
  17. chomp $l;
  18. while ($l =~ /\/$/) {
  19. my $ll = <$f>;
  20. last unless (defined($ll));
  21. chomp $ll;
  22. $l = substr($l,0,-1) . $ll;
  23. }
  24. $l =~ s/\/\/.*$//;
  25. $l =~ s/\/\*.*?\*\///g;
  26. if ($l =~ /^\s*[\`\#]\s*define\s+\`?([[:alpha:]_]\w*)\s+(.*?)\s*$/) {
  27. $syms{$1} = $2;
  28. } elsif ($l =~ /^\s*[\`\#]\s*undef\s+\`?([[:alpha:]_]\w*)/) {
  29. delete $syms{$1};
  30. }
  31. }
  32. close($f);
  33. foreach my $s (keys %syms) {
  34. my $e = $syms{$s};
  35. my $o = '';
  36. # Don't try to evaluate if...
  37. next if ($e =~ /[\"\$\@\[\{\\]/);
  38. $e =~ s/\`//g;
  39. while ($e =~ /^(.*?)\b[0-9]*\'([bhod])([0-9a-f_]+)\b(.*)$/i ||
  40. $e =~ /^(.*?)\b()(0[0-7_]+|0b[0-1_]+|0x[0-9a-f_]+)\b(.*)$/i) {
  41. $e = $4;
  42. $o .= $1;
  43. my $base = lc($2);
  44. my $dig = $3;
  45. $dig =~ s/_//g;
  46. if ($base ne '') {
  47. $base = $bases{$base};
  48. } elsif ($dig =~ /^0x/i) {
  49. $base = 16;
  50. } elsif ($dig =~ /^0b/i) {
  51. $base = 2;
  52. } elsif ($dig =~ /^0/) {
  53. $base = 8;
  54. }
  55. $o .= Math::BigInt::from_base($dig, $base)->bstr();
  56. }
  57. $syms{$s} = $o.$e;
  58. }
  59. foreach my $s (keys %syms) {
  60. my $e = $syms{$s};
  61. my $o = '';
  62. while ($e =~ /^(.*?)\b\`?([[:alpha:]_]\w*)\b(.*)$/) {
  63. $e = $3;
  64. $o .= $1;
  65. if (defined($syms{$2})) {
  66. $e = $syms{$2} . $e;
  67. } else {
  68. $o .= $2;
  69. }
  70. }
  71. $syms{$s} = eval("{ use bigint; return Math::BigInt->new($o$e)->numify(); }");
  72. }
  73. return %syms;
  74. }
  75. 1;