home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / contrib / edb / add-line-directive next >
Encoding:
Text File  |  1999-06-05  |  8.9 KB  |  421 lines

  1. #!/usr/local/bin/perl
  2. #----------------------------------------------------------------------------- 
  3. #  add-line-directive
  4. #
  5. #     add c line directive 
  6. #          to 
  7. #     Small Eiffel generated C-code 
  8. #     (For 0.79)
  9. #----------------------------------------------------------------------------- 
  10. #    History
  11. #     Vers     Date        Coder        Description
  12. #     00-00    May 15,1997    Masato Mogaki    first version
  13. #     00-01    Aug 28,1997    Masato Mogaki    for -0.85
  14. #     00-02    Jul 09,1998    Masato Mogaki    for -0.80
  15. #     00-03    Sep 08,1998    Masato Mogaki    for -0.79
  16. #----------------------------------------------------------------------------- 
  17. @c = ();
  18. @h = ();
  19. $with_line_directive = 1;
  20.  
  21.  
  22. # collect source file names and options.
  23.  
  24. for ($i=0; $i<=$#ARGV;$i++) {
  25.     $s = $ARGV[$i];
  26.     if($s =~ /\.c$/) {
  27.     push(@c,$s);
  28.     } elsif($s =~ /\.h$/) {
  29.     push(@h,$s);
  30.     } elsif($s =~ /^-n$/) {
  31.     $with_line_directive = 0;
  32.     } elsif($s =~ /^c$/) {
  33.     $with_gc = 1;
  34.     }
  35. }
  36.  
  37.  
  38. #find eiffel souce file name from the lines like  p[123]="./test.e";
  39.  
  40. foreach $s (@c) {
  41.     open(IN,$s);
  42.     $se_init = 0;
  43.     while(<IN>) {
  44.     if($se_init) {
  45.         if(/^p\[(\d+)\]="(.*)";/) {
  46.         $src_name[$1] = $2;
  47.         }elsif(/^p\[(\d+)\]=p\[(\d+)\];/) {
  48.         $src_name[$1] = $src_name[$2];
  49.         }elsif(/^g\[(\d+)\]="(.*)";/) {
  50.         $se_init = -1;
  51.         }
  52.     } elsif(/^void initialize_eiffel_runtime/) {
  53.         $se_init = 1;
  54.     }
  55.     if($se_init<0) { last;  }
  56.     }
  57.     close(IN);
  58.     if($se_init<0) { last; }
  59. }
  60.  
  61. # convert header file.
  62. #   + change prototype of routines
  63. #   + change macro
  64.  
  65. foreach $s (@h) {
  66.     $o = "B/$s";
  67.     $t = "C/$s";
  68.     if(system("cmp -s $s $o")) { # $s is changed 
  69.     print STDERR "$s is changed\n";
  70.     rename($s,$o);
  71.     open(IN,$o);
  72.     open(OUT,">$t");
  73.     &convert_h;
  74.     } else {
  75.     unlink($s);
  76.     }
  77. }
  78.  
  79. # convert c source.
  80. #  remove runtime trace code
  81. #  rename routine arguments
  82. #  add line directive #line NN "source.e"
  83.  
  84. foreach $s (@c) {
  85.     $o = "B/$s";
  86.     $t = "C/$s";
  87.     if(system("cmp -s $s $o")) { # $s is changed 
  88.     print STDERR "$s is changed\n";
  89.     rename($s,$o);
  90.     open(IN,$o);
  91.     open(OUT,">$t");
  92.     &convert_c;
  93.     } else {
  94.     unlink($s);
  95.     }
  96. }
  97.  
  98. #---------------------------------------------------------------
  99. sub convert_h {
  100.     while(<IN>) {
  101.       s/(r\d+\w+\()se_dump_stack\*caller,?/$1/;
  102.       s/(X\d+\w+\()se_dump_stack\*caller,int l,int c,int f, /$1/;
  103.       print OUT $_;
  104.     }
  105.     close IN;
  106.  
  107.     print OUT "#define ci(_d,_o,_l,_c,_f) (_o)\n";
  108.     print OUT "#define error0(_m) fprintf(stderr,\"%s\\n\",_m),abort()\n";
  109.     print OUT "#define error1(_m,_l,_c,_f) error0(_m)\n";
  110.     if ($with_gc) {
  111.       print OUT "#include <gc.h>\n";
  112.       print OUT "#define malloc(n) GC_malloc(n)\n";
  113.       print OUT "#define calloc(m,n) GC_malloc((m)*(n))\n";
  114.       print OUT "#define realloc(p,n) GC_realloc((p),(n))\n";
  115.       print OUT "#define free(p) GC_free(p)\n";
  116.       print OUT "#define gc_is_off GC_dont_gc\n";
  117.       print OUT "#define gc_start() GC_gcollect()\n";
  118.     }
  119.     close OUT;
  120. }
  121.  
  122.  
  123. sub convert_c {
  124.     my($in_routine);
  125.     $in_routine = 0;
  126.     $o_count = 0;
  127.     while(<IN>) {
  128.     chomp;
  129.     if($in_routine == 0) {
  130.         if(/^(T0\*|T\d+|int|char|void|void\*) r(\d+)(\w+)\(.*\)\{$/) {
  131.         s/se_dump_stack\*caller,?//;
  132.         @body = ($_);
  133.         @lvars = ();
  134.         $in_routine = 1;
  135.         $e_fno = 0;
  136.         $e_lno = 0;
  137.         $e_local = "";
  138.         } elsif (/^(T0\*|T\d+|int|char|void|void\*) (X\d+\w+\()se_dump_stack\*caller,int l,int c,int f, /) {
  139.         s//$1 $2/;
  140.         print OUT "$_\n";
  141.         $o_count++;
  142.         $in_routine = 10;
  143.         } elsif(/^void error[01]/) {
  144.         while(<IN>) {
  145.             if(/^}/) {
  146.             last;
  147.             }
  148.         }
  149.         } elsif(/^T0\* ci/) {
  150.         while(<IN>) {
  151.             if(/^}/) {
  152.             last;
  153.             }
  154.         }
  155.         } else {
  156.             if(!/^ms\d+/) {
  157.             s/exit\([^0()]*\)/abort()/g;
  158.             s/\(&ds,?/\(/g;
  159.             s/se_trace\(\d+,\d+,\d+\);//;
  160.         }
  161.         print OUT "$_\n";
  162.         $o_count++;
  163.         }
  164.     } elsif ($in_routine == 1) {
  165.         if(/^se_dump_stack ds;/) {
  166.         if($e_local) {
  167.             $e_local .= "\n";
  168.             push(@body,$e_local);
  169.         }
  170.         $in_routine = 2;
  171.         } elsif(/^void\*\*locals\[(\d+)\];/) {
  172.         $n_local = $1;
  173.         } else {
  174.         $e_local .= $_;
  175.         }
  176.     } elsif ($in_routine == 2) {
  177.         if(/^ds\.(\w+)=(.*);/) {
  178.         my($attr,$val);
  179.         $attr = $1;
  180.         $val  = $2;
  181.         if ($attr eq "l") {
  182.             $e_lno = $val;
  183.         } elsif($attr eq "f") {
  184.             $e_fno = $val;
  185.             if($with_line_directive) {
  186.             $r_post = "<$e_fno,$e_lno>\n";
  187.             }
  188.             unshift(@body,$r_post);
  189.         }
  190.         } elsif(/^locals\[(\d+)\]=\(void\*\*\)\&(\w+);/) {
  191.         $lvars[$1] = $2;
  192.         } elsif(/^se_dst=\&ds;/) {
  193.         $in_routine = 3;
  194.         }
  195.     } elsif ($in_routine < 10) {
  196.         if(/^if\(!se_af_rlr\)\{se_af_rlr=1/) {
  197.         $in_routine++;
  198.         } elsif(/^\{static int se_af=1/) {
  199.         $in_routine++;
  200.         } elsif(/^if\(se_af\)\{/) {
  201.         $in_routine++;
  202.         } elsif($in_routine>3 && /^\}/) {
  203.         --$in_routine;
  204.         } elsif(/^se_frame_descriptor f\d+\w+=\{\"(.+ of .+)",(\d+),(\d+),\"(.*)\",\d+\};/) {
  205.         output_routine($1,$2,$3,$4);
  206.         print OUT "$_\n";
  207.                 if($with_line_directive){
  208.             print OUT "#line $o_count \"$t\"\n";
  209.             $o_count++;
  210.                 }
  211.         $in_routine = 0;
  212.         } elsif(/se_af/) {
  213.         $_ = "";
  214.         # Ignore
  215.         } else {
  216.         while(/se_trace\(\&ds,(\d+),(\d+),(\d+)\)[,;]/) {
  217.             s//<$3:$1>/;
  218.         }
  219.         while(/(X\d+\w+\()\&ds,(\d+),(\d+),(\d+),/) {
  220.             s//<$4:$2>$1/;
  221.         }
  222.         while(/ci\(\d+,([^,]+),(\d+),(\d+),(\d+)\)/) {
  223.             s//<$4:$2>$1/;
  224.         }
  225.         s/\/\*\w+\*\///g;
  226.         s/se_dst=caller;//;
  227.         s/\(&ds,?/\(/g;
  228.         if(/\S/) {
  229.             if($with_line_directive) {
  230.             s/(.+?)(<\d+:\d+>)/$2$1/;
  231.             $_ = &update_fl($_);
  232.             } else {
  233.             s/<\d+:\d+>//g;
  234.             }
  235.             push(@body,$_);
  236.         }
  237.         }
  238.     } elsif($in_routine == 10) {
  239.         if (/^se_dst=caller;$/) {
  240.         $in_routine = 0;
  241.         } elsif(/se_dump_stack ds=\*caller;/) {
  242.         # skip
  243.         } elsif(/^\{int id=vc\(C,l,c,f\)->id;/) {
  244.         print OUT "{int id=((T0*)C)->id;\n";
  245.         $o_count++;
  246.         } else {
  247.         s/\(&ds,?/\(/g;
  248.         print OUT "$_\n";
  249.         $o_count++;
  250.         }
  251.     }
  252.     }
  253.  
  254.     close(OUT);
  255.     close(IN);
  256. }
  257.  
  258. sub update_fl {
  259.     my($s) = @_;
  260.     my($fl);
  261.     while($s =~ /<(\d+):(\d+)>/) {
  262.     if($e_fno != $1 || $e_lno != $2) {
  263.         $fl = "\n<$1,$2>\n";
  264.         $e_fno = $1;
  265.         $e_lno = $2;
  266.     } else {
  267.         $fl = "";
  268.     }
  269.     $s =~ s//$fl/;
  270.     }
  271.     return $s;
  272. }
  273.  
  274. # print out
  275.  
  276. sub output_routine {
  277.     my($rout, $use_current, $nlocal, $l_desc) = @_;
  278.     %name_map = ();
  279.     if ($use_current) {
  280.       $l_desc =~ s/^%\w+%//;
  281.     }
  282.     $l_desc =~ s/%[A-Z]\d+//g;
  283.     my(@l_descs) = split(/%/,$l_desc);
  284.     $i = 0;
  285.     foreach $l (@l_descs) {
  286.       $name_map{$lvars[$i]} = "_".$l;
  287.       $i++;
  288.     }
  289.     @body = &split_lines(@body);
  290.     @body = &merge_lines(@body);
  291.     foreach $l (@body) {
  292.     $l =~ s/<\d+,\d+>//g;
  293.     $l = &replace_name($l);
  294.     print OUT $l,"\n";
  295.     $o_count++;
  296.     }
  297. }
  298.  
  299. # replace name of local variables.
  300. sub replace_name {
  301.     my ($line) = @_;
  302.     my($n,$v);
  303.  
  304.     if(!/^\#/) {
  305.     foreach $v (keys %name_map) {
  306.         $n = $name_map{$v};
  307.         $line =~ s/\b$v\b/$n/g;
  308.     }
  309.     } 
  310.     return $line;
  311. }
  312.  
  313. # split embedded line number
  314. sub split_lines {
  315.     my @lines = @_;
  316.     my (@new_lines,@ls,$l,$s);
  317.     @new_lines = ();
  318.     foreach $l (@lines) {
  319.     @ls = split(/\n/,$l);
  320.     foreach $s (@ls) {
  321.         if($s =~ /\S/) {
  322.         push(@new_lines,$s);
  323.         }
  324.     }
  325.     }
  326.     return (@new_lines);
  327. }
  328.  
  329. #-- Merge inline code to one line.
  330. sub merge_lines {
  331.     my @lines = @_;
  332.     my (@merged,@wl,$l,$ll,$last_lno,$lno);
  333.     @merged = ();
  334.     @wl = ();
  335.     $last_lno = 0;
  336.     $last_fno = -1;
  337.     while (@lines) {
  338.     $l = shift(@lines);
  339.     if($l =~ /<(\d+),(\d+)>/) {
  340.         @merged = (@merged,@wl);
  341.         $fno = $1;
  342.         $lno = $2;
  343.         $last_lno += $#wl+1;
  344.         @wl = ();
  345.  
  346.         if($fno != $last_fno || $lno < $last_lno) {
  347.         push(@merged,&source_line_directive($fno,$lno));
  348.         $last_fno = $fno;
  349.         $last_lno = $lno;
  350.         } elsif($lno > $last_lno) {
  351.         while($lno > $last_lno) {
  352.             push(@merged,"");
  353.             $last_lno++;
  354.         }
  355.         }
  356.     } elsif($l =~ /\S/) {
  357.         # Creation call (gc)
  358.         if($l =~ /^\{T\d+\*n=new\d+\(\);$/) {
  359.         $ll = '';
  360.         while($l && $l !~ /\}$/) {
  361.             $ll .= $l;
  362.             $l = shift(@lines);
  363.         }
  364.         $l = $ll . $l;
  365.  
  366.         # Creation call (-no_gc)
  367.         } elsif($l =~ /^\{T\d+\*n=malloc\(sizeof\(\*n\)\);$/) {
  368.         $ll = '';
  369.         while($l && $l !~ /\}$/) {
  370.             $ll .= $l;
  371.             $l = shift(@lines);
  372.         }
  373.         $l = $ll . $l;
  374.         
  375.         # Reverse assignment call to attribute
  376.         } elsif($l =~ /^if.NULL!=.C->_\w+..switch...T0..C->_\w+.->id. \{$/) {
  377.         $ll = pop(@wl);
  378.         do {
  379.             $ll .= $l;
  380.             $l = shift(@lines);
  381.         } until(!$l || ($l =~ /^\w+=NULL;$/));
  382.         $ll .= $l;
  383.         $l = $ll;
  384.  
  385.         # Reverse assignment call to local variable
  386.         } elsif($l =~ /^if.NULL!=.\w+..switch...T0\*.\w+.->id. \{$/) {
  387.         $ll = pop(@wl);
  388.         do {
  389.             $ll .= $l;
  390.             $l = shift(@lines);
  391.         } until(!$l || ($l =~ /^\w+=NULL;$/));
  392.         $ll .= $l;
  393.         $l = $ll;
  394.  
  395.         } elsif($l =~ /^ ?else/) {
  396.         $ll = pop(@wl);
  397.         $l = $ll.$l;
  398.  
  399.         } elsif($l =~ /^if \(fBC\d+\w+==0\)\{$/) {
  400.         do {
  401.             $ll = shift(@lines);
  402.             $l .= $ll;
  403.         } until(!$ll || ($ll =~ /^fBC\d+\w+=1;$/));
  404.  
  405.         }
  406.         push(@wl,$l);
  407.     }
  408.     }
  409.     return (@merged,@wl);
  410. }
  411.  
  412.  
  413. sub source_line_directive {
  414.     my($f,$l)= @_;
  415.     return "#line $l ".'"'.$src_name[$f].'"';
  416.     return "";
  417. }
  418. #-------- add_line_directive END 
  419.  
  420.