new tool to strip comments from headers
[rofl0r-c-split.git] / c-split.pl
blobf8cc3748557cf16f45818f798386f1f6fed97eef
1 #!/usr/bin/env perl
2 use strict;
3 use warnings;
4 use File::Basename;
6 sub name_wo_ext {
7 my $x = shift;
8 my $l = length($x);
9 $l-- while($l && substr($x, $l, 1) ne ".");
10 return substr($x, 0, $l) if($l);
11 return "";
14 sub syntax {
15 print "expected syntax: " . basename($0) . " myfile.c myoutputdirectory/\n";
16 exit 1;
19 my $file = $ARGV[0] or syntax;
20 my $outdir = $ARGV[1] or syntax;
21 die("error accessing outdir") if(!-d $outdir && !mkdir($outdir));
22 my $internal_header = name_wo_ext(basename($file)) . "_internal.h";
23 my $f;
24 open($f, "<", $file);
25 my $openbraces = 0;
26 my @includes;
27 my $incomment = 0;
28 my $line = "";
29 my @statics;
30 my @typedefs_macros;
31 my @extern;
33 sub scanbraces {
34 my $shit = shift;
35 my @chars = split //, $shit;
36 for my $c(@chars) {
37 if ($c eq "{") {
38 $openbraces++;
39 } elsif($c eq "}") {
40 $openbraces--;
45 sub writefunc {
46 my ($funcname, $code) = @_;
47 my $fd;
48 open($fd, ">", "$outdir/$funcname.c");
49 print {$fd} '#include "' . $internal_header . "\"\n\n";
50 print {$fd} $code, "\n";
51 close $fd;
54 sub handlesub {
55 my $_ = shift;
56 my $name = "";
57 my $wasstatic = 0;
58 while(!$name) {
59 my $x = 0;
60 $x++ while(substr($_, $x, 1) !~ /\s/);
61 my $word = substr($_, 0, $x);
62 if($word eq "static" || $word eq "inline") {
63 $_ = substr($_, $x);
64 s/^\s+//;
65 $wasstatic = 1;
66 next;
67 } else {
68 if(/(.*?)([\w_]+)\s*\((.*?)\)\s*\{/) {
69 $name = $2;
70 my $decl = $1 . $name . "(" . $3 . ");";
71 push @statics, $decl if($wasstatic);
72 #print $name , "\n" if $wasstatic;
73 writefunc($name, $_);
74 #print "function $name\n$_";
75 } else {
76 print "ERROR\n";
77 return;
83 sub parseline {
84 $_ = shift;
85 #print "PL: length line: ". length($line) . "\n";
86 return unless defined $_;
87 return if $_ eq "";
88 if($line eq "" && /^\s*#/) {
89 push @typedefs_macros, $_;
90 return;
92 $line .= $_ . "\n" if(!$openbraces || $line ne "");
93 scanbraces $_;
95 if($line ne "" && !$openbraces) {
96 if($line =~ /([;\}]{1})\s*\n*$/) {
97 if($1 eq ";") {
98 #print $line;
99 if ($line =~ /=/ || $line =~ /^\s*static[\s\n]+/) {
100 #print "extern!\n";
101 $line =~ s/^\s*static\s*//;
102 push @extern, $line;
103 } else {
104 push @typedefs_macros, $line;
106 $line = "";
107 return;
109 handlesub($line);
110 $line = "";
115 while(<$f>) {
117 # print;
118 chomp;
119 # print "$openbraces, $incomment\n";
120 if (/^\s*#\s*include\s+[<\"]{1}[\w_\-\/\.]+[>\"]{1}/) {
121 push @includes, $_;
122 } else {
123 next if(/^\s*$/); #skip empty lines
124 next if(/^\s*\/\//); #skip one line comments.
125 # normal source code line.
126 if (!$incomment && /(.*?)\/\*(.*?)$/) {
127 parseline($1);
128 my $rest = $2;
129 $incomment = 1 unless $rest =~ /\*\//;
130 } elsif($incomment) {
131 if(/\*\/(.*?)$/) {
132 parseline($2);
133 $incomment = 0;
135 } else {
136 parseline($_);
140 close $f;
142 my $extfd;
143 if(@extern) {
144 open($extfd, ">", $outdir . "/" . name_wo_ext(basename($file)) . "_variables.c");
145 print {$extfd} "#include \"$internal_header\"\n\n";
148 my $destname = "$outdir" . "/" . $internal_header;
149 my $fd;
150 open($fd, '>', $destname);
151 for(@includes) {
152 s/\s+\"/ \"\.\.\//;
153 print {$fd} $_, "\n";
155 print {$fd} "\n";
156 for(@typedefs_macros) {
157 print {$fd} $_, "\n";
159 print {$fd} "\n";
161 print {$fd} "\n";
162 for(@extern) {
163 my ($k, $v) = split /=/, $_;
164 print {$fd} "extern $k;\n";
165 print {$extfd} $_, "\n";
168 for(@statics) {
169 print {$fd} $_, "\n";
171 print {$fd} "\n";
172 print {$fd} "//RcB: DEP \"*.c\"\n\n";
173 close $fd;
174 close $extfd if(@extern);