summaryrefslogblamecommitdiffstats
path: root/docs/proto/cdoc
blob: 60f29a50d938e333f9d08de72531d53168b3e807 (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                      
 











                                                                        


                                                      










                       
                    
                         
                                                                            


                                        





                                                                

                                                     














                                                                   
                                     











                                                               
     
                   



           

                        

                             


                                                           
 




































                                                                         
 
     
 
#!/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 "",<SRC>;
    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};
        }
    }

    }
}