#!/usr/bin/perl # follow javadoc # @see http://java.sun.com/j2se/javadoc/writingdoccomments/ use strict; =cut 這個程式可以從 C 的程式碼中,列出所有 statis/non-static 的 functions。 每個 function 前面可以有 javadoc-style 的註解。範例如下: /** * Function of the function func. * @param x variable, if there are more than one @-style description, it * will end with the next @-style description. * @return void */ void func(int x) { ... } 如果有註解之後沒有接 function 的話,會原封不動丟出來。 =cut my $content; foreach my $f (@ARGV) { makedoc($f); } sub grep_desc { my @buffer = (); my $name = '\b\w+\b'; my $type = '\b (?: (?:struct|unsigned) \s+)? \w+\b (?: \s*\*\s* | \s+)'; my $sentence = '.*'; my $one_desc = "$name\\s+$sentence"; my $desc_head = "\\/ \\* \\* \n"; my $desc_tail = "\\s* \\* \\/ \n"; my $desc_line = "\\s* \\* .* \n"; my $paramdesc = "\@param\\s+ $one_desc (?:\n$desc_line)*"; my $returndesc = "\@return\\s+ $sentence (?:\n$desc_line)*"; my $seedesc = "\@see\\s+ $sentence (?:\n$desc_line)*"; my $desc = "$desc_head(?:$desc_line)*$desc_tail"; my $modifier = '(?: static | inline)\s+'; my $one_param = "$type \\s* $name"; my $more_param = ",\\s* $one_param"; my $param = "(?: $one_param(?:$more_param)* | void )?"; my $func_proto = "(?:$modifier)* $type \\s* $name\\($param\\)"; my $pattern = "(?: ($desc)|($func_proto)[\n\\s]*{ )"; my $out; if ($content =~ s/^([.\n]*)$pattern//mox) { $1 and push @buffer, {type => 'garbage', data => undef}; if ($2) { $out = $2; $out =~ s#^/\*\*##; $out =~ s#\s*\*/$##; $out =~ s/^\s*\* ?/ /mg; push @buffer, { type => 'comment', data => $out }; } elsif ($3) { $out = $3; $out =~ s/\n/ /g; $out =~ s/\s+/ /g; $out .= ";\n"; push @buffer, { type => 'function', data => $out }; } else { die; } } return @buffer; } sub makedoc { my $file = shift @_; open SRC, "<$file"; $content = join "",; close SRC; # just to break them up to avoid vim's misunderstanding print "// vim".":ft=c\n\n"; $content =~ s#/\*[^*].*?\*/##sg; my @buffer = (); while (my @b = grep_desc()) { push @buffer, @b; shift @buffer while ($buffer[0]->{type} eq 'garbage'); last unless @buffer; if (@buffer == 3) { if ($buffer[1]->{type} eq 'garbage') { $_ = shift @buffer; shift @buffer; unshift @buffer, $_; } } if (@buffer == 2) { if ($buffer[0]->{type} eq 'function') { $_ = shift @buffer; print $/, $_->{data}; } elsif ($buffer[0]->{type} eq 'comment') { if ($buffer[1]->{type} eq 'comment') { $_ = shift @buffer; print $_->{data}, $/; } else { print $/, $buffer[1]->{data}, $buffer[0]->{data}, $/; undef @buffer; } } } if (@buffer == 1) { if ($buffer[0]->{type} eq 'function') { $_ = shift @buffer; print $/, $_->{data}; } } } }