Merge pull request #2216 from jwillemsen/jwi-cxxversionchecks
[ACE_TAO.git] / ACE / bin / doxygen-convert-h.pl
blob253e351e1a2fbc8dcf1fe8f618894004de33ba45
1 eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
2 & eval 'exec perl -S $0 $argv:q'
3 if 0;
5 # doxygen-convert-h.pl is a script that would be used to convert old
6 # documented style ACE/TAO header files to doxygen style.
8 # TODO List:
9 # (Search for @todo in this script)
11 use File::Copy;
12 use FileHandle;
13 use Getopt::Std;
15 ##############################################################################
16 # Parse the options
18 if (!getopts ('dDhsu') || $opt_h) {
19 print "doxygen-convert-h.pl [-dDhsu] filenames or directories\n";
20 print "\n";
21 print " -d debug script\n";
22 print " -D really verbose debug\n";
23 print " -h display this help\n";
24 print " -s print result to stdout\n";
25 print " -u turn off file verification\n";
26 exit (1);
29 ## if verbose debug, also regular debug
30 $opt_d = 1 if (defined $opt_D);
32 ##############################################################################
33 # Find the files
35 @files = ();
37 sub recursive_find {
38 my($file) = shift;
39 my(@rfiles) = ();
40 my($fh) = new FileHandle();
42 if (opendir($fh, $file)) {
43 foreach my $f (grep(!/^\.\.?$/, readdir($fh))) {
44 my($full) = "$file/$f";
45 if (-d $full) {
46 push(@rfiles, recursive_find($full));
48 else {
49 push(@rfiles, $full)
50 if ($f =~ /\.(h|hxx|hpp|hh|inl|idl|cpp|cxx|cc|c|C)$/)
54 closedir($fh);
57 return @rfiles;
60 foreach $arg (@ARGV) {
61 my @results = glob $arg;
62 if ($#results < 0) {
63 print STDERR "File not Found: $arg\n"
65 else {
66 foreach my $result (@results) {
67 if (-d $result) {
68 push(@files, recursive_find($result));
70 else {
71 push(@files, $result);
77 ##############################################################################
78 # Subroutines used to change the file.
80 $fail = 0;
82 sub verify (@)
84 my (@contents) = @_;
86 print "Verification\n" if (defined $opt_d);
88 my $found_id = 0;
89 my $found_filename = 0;
91 foreach $line (@contents) {
92 $found_id = 1 if ($line =~ /\$Id\:/);
93 $found_filename = 1 if ($line =~ /\= FILENAME/);
96 return 0 if ($found_id == 1 && $found_filename == 1);
98 # failed
99 return 1;
102 sub format_description (@)
104 my (@description) = @_;
105 my @after = ();
107 my $line;
109 if ($#description < 1) {
110 foreach $line (@description) {
111 $line =~ s/\/\// \* \@brief /;
112 push @after, $line;
115 else {
116 foreach $line (@description) {
117 $line =~ s/\/\// \*/;
118 $line =~ s/\* /\* /;
119 push @after, $line;
123 return @after;
126 sub fix_file_header (@)
128 my (@before) = @_;
129 my @after = ();
130 my @description = ();
131 my $id = "\$Id\$\n";
132 my $authors = "";
134 my $state = 'before';
135 ## state = before, filename, description, author, after, done
137 print "Fixing File Header\n" if (defined $opt_d);
139 LOOP: foreach $line (@before) {
140 printf ("%10s %s", $state, $line) if (defined $opt_D);
142 if ($state eq 'done') {
143 push @after, $line;
144 next LOOP;
147 if ($state eq 'before') {
148 if ($line =~ /\-\*\- C\+\+ \-\*\-/) {
149 push @after, $line;
151 elsif ($line =~ /\$Id\:(.*)\n/) {
152 $id = "\$Id\:$1";
154 elsif ($line =~ /===================/) {
155 push @after, "//========================================".
156 "=====================================\n";
157 push @after, "/**\n";
159 elsif ($line =~ /\= FILENAME/) {
160 $state = 'filename';
161 next LOOP;
163 elsif ($line !~ /^\s*\/\//) {
164 push @after, $line;
168 if ($state eq 'filename') {
169 if ($line =~ /\/\/ (.+)/) {
170 push @after, " * \@file $1\n";
171 push @after, " *\n";
172 push @after, " * $id\n";
173 push @after, " *\n";
175 elsif ($line =~ /\= DESCRIPTION/) {
176 $state = 'description';
177 next LOOP;
179 elsif ($line =~ /\= AUTHOR/) {
180 $state = 'author';
181 next LOOP;
183 elsif ($line =~ /===================/) {
184 $state = 'after';
185 ### Fall through so the after can put the ending in
189 if ($state eq 'description') {
190 if ($line =~ /\= AUTHOR/) {
191 push @after, format_description (@description);
192 @description = ();
193 push @after, " *\n";
194 $state = 'author';
195 next LOOP;
197 elsif ($line =~ /===================/) {
198 push @after, format_description (@description);
199 @description = ();
200 push @after, " *\n";
201 $state = 'after';
202 ### Fall through
204 push @description, $line;
206 if ($state eq 'author') {
207 if ($line =~ /\/\/ (.+)\n/) {
208 $authors .= $1;
210 elsif ($line =~ /===================/
211 || $line =~ /\= DESCRIPTION/) {
212 ## print the authors
214 if ($authors ne "") {
215 @authors = split /\,/, $authors;
217 foreach $author (@authors) {
218 if ($author =~ /^ (.*)/) {
219 $author = $1;
221 push @after, " * \@author $author\n";
225 if ($line =~ /\= DESCRIPTION/) {
226 push @after, " *\n";
227 $state = 'description';
228 next LOOP;
230 else {
231 $state = 'after';
232 ## Fall through
237 if ($state eq 'after') {
238 if ($line =~ /===================/) {
239 ## print the rest
240 push @after, " */\n";
241 push @after, "//========================================".
242 "=====================================\n";
243 push @after, "\n";
244 $state = 'done';
247 next LOOP;
251 return @after;
255 sub fix_class_headers (@)
257 my (@before) = @_;
258 my @after = ();
259 my @store = ();
260 my $classname = "";
262 my $state = 'outside';
263 ## state =
264 ## outside = not in class
265 ## template = stored template line
266 ## class = started collecting lines, in case of a class
267 ## header = after a class foo, but before any methods
269 print "Fixing class headers\n" if (defined $opt_d);
271 LOOP: foreach $line (@before) {
272 printf ("%10s %s", $state, $line) if (defined $opt_D);
274 if ($state eq 'outside') {
275 if ($line =~ /^\s*template/) {
276 push @store, $line;
277 $state = 'template';
278 next LOOP;
280 elsif ($line =~ /^\s*class/) {
281 $state = 'class';
282 ## Fall through
284 else {
285 push @after, $line;
290 if ($state eq 'template') {
291 if ($line =~ /^\s*class/) {
292 $state = 'class';
293 ## Fall through
295 else {
296 push @after, @store;
297 @store = ();
298 push @after, $line;
299 $state = 'outside';
300 next LOOP;
304 if ($state eq 'class') {
305 if ($line =~ /^\s*class(.*)\n/) {
306 push @store, $line;
307 my @s = split / /, $1;
308 if ($s[1] =~ /export$/i) {
309 $classname = $s[2];
311 else {
312 $classname = $s[1];
315 elsif ($line =~ /^\s*\{/) {
316 push @store, $line;
318 elsif ($line =~ /^\s*\/\//) {
319 $state = 'header';
320 ### Fall through
322 else {
323 push @after, @store;
324 @store = ();
325 push @after, $line;
326 $state = 'outside';
327 next LOOP;
331 if ($state eq 'header') {
332 if ($line =~ /^\s*\/\//) {
333 push @headers, $line;
335 else {
336 my $prefix = '';
338 $line =~ /^(\s*)[\w\/]/; ### used to get indent
339 my $indent = $1;
340 push @after, "$indent/**\n";
341 push @after, "$indent * \@class $classname\n";
343 foreach $header (@headers) {
344 if ($header =~ /\= TITLE/) {
345 push @after, "$indent *\n";
346 $prefix = "$indent * \@brief";
348 elsif ($header =~ /\= DESCRIPTION/) {
349 push @after, "$indent *\n";
350 $prefix = "$indent *";
352 elsif ($header !~ /\/\/\s*\n/) {
353 my $myline = $header;
354 $myline =~ s/\s*\/\/\s*/$prefix /;
355 push @after, $myline;
356 $prefix = "$indent *";
360 push @after, "$indent */\n";
361 @headers = ();
363 push @after, @store;
364 push @after, $line;
365 @store = ();
366 $state = 'outside';
367 next LOOP;
372 return @after;
376 sub format_comment (@)
378 my (@comments) = @_;
379 my @after = ();
381 my $line;
383 if ($#comments < 2) {
384 foreach $line (@comments) {
385 $line =~ s/\/\//\/\/\//;
386 push @after, $line;
389 else {
390 my $line = $comments[0];
391 $line =~ /^(\s*)\//;
392 my $indent = $1;
394 push @after, "$indent/**\n";
395 foreach $line (@comments) {
396 $line =~ s/\/\// */;
397 push @after, $line;
399 push @after, "$indent */\n";
402 return @after;
405 sub fix_class_members (@)
407 my (@before) = @_;
408 my @after = ();
409 my @method = ();
410 my @comment = ();
412 my $classfound = 0;
413 my $classlevel = 0;
414 my $level = 0;
416 print "Fixing class methods\n" if (defined $opt_d);
418 LOOP: foreach $line (@before) {
419 if ($line =~ /\{/ && $line !~ /^\s*\/\//) {
420 $level++;
423 if ($line =~ /^\s*class/
424 && $line !~ /\;/
425 && $level == $classlevel)
427 $classlevel++;
430 if ($line =~ /\}/ && $line !~ /^\s*\/\//) {
431 if ($classlevel == $level) {
432 $classlevel--;
434 $level--;
437 printf ("%2d%2d", $level, $classlevel) if (defined $opt_D);
439 if ($level == $classlevel && $level > 0) {
440 if ($line =~ /^\s*public/
441 || $line =~ /^\s*private/
442 || $line =~ /\s*protected/
443 || $line =~ /^\s*\n$/
444 || $line =~ /^\s*\{/
445 || $line =~ /^\s*\}/
446 || $line =~ /^\s*\#/)
448 push @after, format_comment (@comment);
449 push @after, @method;
450 @comment = ();
451 @method = ();
453 print " $line" if (defined $opt_D);
454 push @after, $line;
456 elsif ($line =~ /^\s*\/\//) {
457 print "C $line" if (defined $opt_D);
459 if ($#method >= 0) {
460 push @comment, $line;
462 else {
463 push @after, $line;
466 else {
467 print "M $line" if (defined $opt_D);
468 push @method, $line;
472 else {
473 push @after, format_comment (@comment);
474 push @after, @method;
475 @comment = ();
476 @method = ();
478 print " $line" if (defined $opt_D);
479 push @after, $line;
483 if ($level > 0 || $classlevel > 0) {
484 $fail = 1;
485 $failmessage = "Brace level recognition failed"
488 return @after;
491 ##############################################################################
492 # Read in the files.
494 FILELOOP: foreach $file (@files) {
495 print "\n" if (defined $opt_d);
496 print "$file\n";
497 print "\n" if (defined $opt_d);
499 $fail = 0;
501 my @contents = ();
503 ### Read file into @contents
504 print "Reading\n" if (defined $opt_d);
506 unless (open (FILE, "<$file")) {
507 print STDERR "$file: $!\n";
508 next FILELOOP;
511 @contents = <FILE>;
513 close (FILE);
515 ### Verify file
516 print "Verifying file\n" if (defined $opt_d);
518 if (!defined $opt_u) {
519 if (verify (@contents) == 1) {
520 print "$file did not pass verification\n";
521 next FILELOOP;
523 elsif (defined $opt_d) {
524 print "Passed verification\n";
528 ### Fix up parts of it
529 print "Fixing file\n" if (defined $opt_d);
531 @contents = fix_file_header (@contents);
532 @contents = fix_class_headers (@contents);
533 @contents = fix_class_members (@contents);
535 if ($fail != 0) {
536 print "$file: $failmessage\n";
538 else {
539 if (defined $opt_s) {
540 print @contents;
542 elsif (!defined $opt_D) {
543 ### Save @contents back to the file
544 print "Saving\n" if (defined $opt_d);
546 unless (open (FILE, ">$file")) {
547 print STDERR "$file: $!\n";
548 next FILELOOP;
551 foreach $line (@contents) {
552 print FILE $line;
555 close (FILE);