如何提取源码中的注释?

如何提取源码中的注释?

有个问题请perl大牛们指点一下

注释的匹配如何写好?

现在想提取linux内核源码中的所有注释,以便进一步处理。要求把一个函数的注释搜索出来,搞成一块(搞成一行,不要和其他函数的注释混到一起。)
内核代码可从下面网站下载。
http://www.cn.kernel.org/pub/linux/kernel/v2.6/

注释的格式如下
/**
* bus_find_device - device iterator for locating a particular device.//可能没有该行
* @bus: bus type
* @start: Device to begin with
* @data: Data to pass to match function
* @match: Callback function to check device
*
* This is similar to the bus_for_each_dev() function above, but it//下面这些说明也可能没有
* returns a reference to a device that is 'found' for later use, as
* determined by the @match callback.
*
* The callback should return 0 if the device doesn't match and non-zero
* if it does.  If the callback returns non-zero, this function will
* return to the caller and not iterate over any more devices.
*/
struct device *bus_find_device(struct bus_type *bus,
                   struct device *start, void *data,
                   int (*match)(struct device *dev, void *data))
{
...
省略

我学perl没几天。写了下面这些代码,意思意思,功能完全没达到。主要是匹配不会写。
$kernel_dir=shift || die "Need a directory argument (kernel sources).\n";

@ARGV=split(/\0/, `find "$kernel_dir" -type f -iname "*.[ch]" -print0`);

foreach $file (@ARGV) {

        $line = " ";

        if (open(FILE, $file)) {

                while (<FILE>) {
                        $_ =~ s/\n/ /;
                        $line .= $_;
                }   

                if ($line =~ m{(
                                (?:\/\*\*\s+)
                                (?:\s\*\s\@\:\s (\w{0,10}\,\s)+ )+
                                )}xg) {
                        $tmp = $1;
                        print $tmp."\n"."$file\n\n";
                }
   

                close(FILE);

        } else {
                print "Cannot open $file: $!.secondly\n";
        }

#we will check the next file in the following iteration.
}
修改了匹配条件。搜出2340个函数注释,条件放得很松,但好像还跑得不错。但不知是不是会漏掉很多情况。不知 各位有什么意见?
              if ($line =~ m{(
                                (?:\/\*\*\s+)
                                (?:.{0,80})
                                (?:.{0,10}\@.{0,10}\:.{0,80})+
                                (?:\*\/\s+)
                                )}xg) {
                        $tmp = $1;
                        print $tmp."\n"."$file\n\n";
                }


/**  * vm_unmap_ram - unmap linear kernel address space set up by vm_map_ram  * @mem: the pointer returned by vm_map_ram  * @count: the count passed to that vm_map_ram call (cannot unmap partial)  */
/storage/linus-git/linux-2.6/mm/vmalloc.c

/**  * __page_set_anon_rmap - setup new anonymous rmap  * @page:        the page to add the mapping to  * @vma: the vm area in which the mapping is added  * @address:  the user virtual address mapped  */
/storage/linus-git/linux-2.6/mm/rmap.c

/**  * lru_cache_add_lru - add a page to a page list  * @page: the page to be added to the LRU.  * @lru: the LRU list to which the page is added.  */  
/storage/linus-git/linux-2.6/mm/swap.c

/**  * shmem_free_swp - free some swap entries in a directory  * @dir:        pointer to the directory  * @edir:       pointer after last entry of the directory  * @punch_lock: pointer to spinlock when needed for the holepunch case  */
/storage/linus-git/linux-2.6/mm/shmem.c
....
...