根据《IEEE Std 1003.1-2008》生成VIM使用的TAGS文件的过程

     由于工作原因在Linux使用vim,tags必不可少,如何制作Linux函数的tags呢?
现在Linix和各种Unix都兼容Posix,根据Posix接口制作tags文件可以用于Linix和
各种Unix。下面简要根据《The Open Group Base Specifications Issue 7》也就
是《IEEE Std 1003.1-2008》制作Posix函数的tags的过程。

1.  这个过程需要一个文档转换工具html2text-1.3.2, 如果您的系统没有安装可
    以到下面的地址下载
    http://userpage.fu-berlin.de/~mbayer/tools/html2text.html
2.  从The Open Group的网站下载文档: T101.ZIP
    https://www2.opengroup.org/ogsys/catalog/T101
3.  解压文档:
    mkdir susv4
    unzip T101.ZIP
4.  制作文档的过程可以用下面的Makefile和两个Perl脚本完成, 只需要把下面的
    有了Makefile, head.pl, func.pl三个文件,并增加两个head.pl和func.pl的
    的执行权限,然后用make命令就可以生成susv4.tags,可以在VIM下使用。


#
# Makefile
#
# Copyright mymtom 2012-12-12.
#
# 根据《IEEE Std 1003.1-2008》生成用于VIM的TAGS
#

all: susv4.tags

susv4.tags : clean headfiles
	ls usr/include/*.h > cscope.files
	exctags --c-kinds=+px --fields=+iaS --extra=+q --language-force=c  -L cscope.files
	sed \
		-e 's:usr/include/:/usr/include/:' \
		-e 's:/usr/include/arpa_inet.h:/usr/include/arpa/inet.h:' \
		-e 's:/usr/include/net_if.h:/usr/include/net/if.h:' \
		-e 's:/usr/include/netinet_in.h:/usr/include/netinet/in.h:' \
		-e 's:/usr/include/netinet_tcp.h:/usr/include/netinet/tcp.h:' \
		-e 's:/usr/include/sys_ipc.h:/usr/include/sys/ipc.h:' \
		-e 's:/usr/include/sys_mman.h:/usr/include/sys/mman.h:' \
		-e 's:/usr/include/sys_msg.h:/usr/include/sys/msg.h:' \
		-e 's:/usr/include/sys_resource.h:/usr/include/sys/resource.h:' \
		-e 's:/usr/include/sys_select.h:/usr/include/sys/select.h:' \
		-e 's:/usr/include/sys_sem.h:/usr/include/sys/sem.h:' \
		-e 's:/usr/include/sys_shm.h:/usr/include/sys/shm.h:' \
		-e 's:/usr/include/sys_socket.h:/usr/include/sys/socket.h:' \
		-e 's:/usr/include/sys_stat.h:/usr/include/sys/stat.h:' \
		-e 's:/usr/include/sys_statvfs.h:/usr/include/sys/statvfs.h:' \
		-e 's:/usr/include/sys_time.h:/usr/include/sys/time.h:' \
		-e 's:/usr/include/sys_times.h:/usr/include/sys/times.h:' \
		-e 's:/usr/include/sys_types.h:/usr/include/sys/types.h:' \
		-e 's:/usr/include/sys_uio.h:/usr/include/sys/uio.h:' \
		-e 's:/usr/include/sys_un.h:/usr/include/sys/un.h:' \
		-e 's:/usr/include/sys_utsname.h:/usr/include/sys/utsname.h:' \
		-e 's:/usr/include/sys_wait.h:/usr/include/sys/wait.h:' \
		tags > $@

textfiles:
	@if [ ! -d usr/text ];then \
		mkdir -p usr/text; \
		for html in susv4/functions/*.html; do \
			text=usr/text/`basename $${html} .html`.txt; \
			echo $${text}; \
			html2text -width 120 -nobs -o $${text} $${html}; \
		done; \
	fi

headfiles: textfiles
	@if [ ! -d usr/include ]; \
		then mkdir -p usr/include; \
		for html in susv4/basedefs/*.h.html; do \
			head=usr/include/`basename $${html} .html`; \
			echo "$${head}"; \
			./head.pl < $${html} > $${head}; \
		done; \
	fi

clean:
	rm -f cscope.files
	rm -f tags
	rm -f susv4.tags

cleanhead: clean
	rm -rf usr/include

cleantext: clean
	rm -rf usr/text

cleanall: clean
	rm -rf usr



#!/usr/bin/perl -w
#
# head.pl
#
# Copyright mymtom 2012
#
# 根据《IEEE Std 1003.1-2008》生成用于VIM的TAGS
#

use strict;
use warnings;

my $state = "";
my $func_name = "";
my $file_name = "";
my $struct_name = "";
my $type_name = "";
my $guard_name = "";

my $macro_name = "";
my $macro_value= "";
my $macro_desc = "";

my $line_count = 0;
my $macro_count = 0;

for (<STDIN>) {
    last if (/The following sections are informative/);

    $line_count++;

    #
    # file name
    #
    if (/#include <([0-9A-Za-z_\/]+\.h)>/) {
        if ($file_name eq "") {
            $file_name = $1;
            $guard_name = uc $1;
            $guard_name =~ s/\./_/;
            $guard_name =~ s/\//_/;
            print "/*\n";
            print " * $file_name\n";
            print " */\n\n";
            print "#ifndef $guard_name\n";
            print "#define $guard_name\n\n";
        }
        if ($file_name eq "stdarg.h") {
            print "typedef char * va_list;\n\n";
            print "void va_start(va_list ap, argN);\n";
            print "void va_copy(va_list dest, va_list src);\n";
            print "type va_arg(va_list ap, type);\n";
            print "void va_end(va_list ap);\n\n";
            print "\n#endif /* $guard_name */\n";
            exit 0;
        }
        if ($file_name eq "assert.h") {
            print "#define NDEBUG 0\n\n";
            print "void assert(int expression);\n\n";
            print "\n#endif /* $guard_name */\n";
            exit 0;
        }
        if ($file_name eq "errno.h") {
            print "extern int errno;\n";
        }
        if ($file_name eq "math.h") {
            print "extern int signgam;\n";
            print "\n";
        }
        if ($file_name eq "ndbm.h") {
            print "typedef struct {\n";
            print "\tvoid   *dptr; /* A pointer to the application's data. */\n";
            print "\tsize_t  dsize;/* The size of the object pointed to by dptr. */\n";
            print "} datum;\n\n";
            print "typedef struct {} DBM;\n";
        }
        if ($file_name eq "mqueue.h") {
            print "typedef int mqd_t;\n\n";
        }
        if ($file_name eq "semaphore.h") {
            print "typedef int sem_t;\n";
        }
        if ($file_name eq "search.h") {
            print "typedef struct entry { char *key; void *data; } ENTRY;\n";
            print "typedef enum { FIND, ENTER } ACTION;\n";
            print "typedef enum { preorder, postorder, endorder, leaf } VISIT;\n";
        }
        if ($file_name eq "setjmp.h") {
            print "typedef struct {} jum_buf;\n";
            print "typedef struct {} sigjum_buf;\n";
        }
        if ($file_name eq "sys/socket.h") {
            print "#define SCM_RIGHTS 0x01\n\n";
            print "struct cmsghdr;\n";
            print "struct msghdr;\n\n";
            print "unsigned char  *CMSG_DATA(struct cmsghdr *cmsg);\n";
            print "struct cmsghdr *CMSG_NXTHDR(struct msghdr *mhdr, struct cmsghdr *cmsg);\n";
            print "struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *mhdr);\n\n";
        }
        if ($file_name eq "syslog.h") {
            print "int LOG_MASK(int pri);\n\n";
        }
        if ($file_name eq "time.h") {
            print "extern int    daylight;\n";
            print "extern long   timezone;\n";
            print "extern char  *tzname[];\n";
            print "\n";
        }
        if ($file_name eq "unistd.h") {
            print "extern char *optarg;\n";
            print "extern int opterr, optind, optopt;\n";
            print "\n";
        }
        if ($file_name eq "float.h") {
            $state = "const";
        }
        next;
    }


    #
    # struct
    #
    if (0 ||
        /shall.* define the <b>(\w+)<\/b> structure/  ||
        /shall.* declare the <b>(\w+)<\/b> structure/ ||
        /shall.* define the structure <b>(\w+)<\/b>/  ||
        /shall define the <b>struct (\w+)<\/b>/  ||
        /The <b>(\w+)<\/b> structure defined in/  ||
        0) {
        next if (/as described/);
        next if ($file_name eq "ftw.h" && $1 eq "stat");

        $struct_name = $1;
        $state = "struct";
        print "struct $struct_name {\n";
        next;
    }

    if ($state eq "struct") {
        if (/<pre>/) {
            $state = "struct_begin";
            next;
        }
    }

    if ($state eq "struct_begin") {
        if (/<\/pre>/) {
            $state = "struct_end";
            print "};\n\n";
        } else {
            if (/<tt>(.+)<\/tt>(.+)<tt>/) {
                print "\t$1; /*$2*/\n";
                next;
            }
            if (/(.+)<\/tt>(.+)<tt>/) {
                print "\t$1; /*$2*/\n";
                next;
            }
            if ($file_name eq "ftw.h" && (/^<tt>int\s+(\w+)$/ || /^int\s+(\w+)/)) {
                print "\tint\t$1;\n";
                next;
            }
            if ($file_name eq "locale.h" && (/^<tt>(\w+\s+\**\w+)$/ || /^(\w+\s+\**\w+)$/)) {
                print "\t$1;\n";
                next;
            }
            if ( ($file_name eq "sys/msg.h" && /^(.+)<\/tt>(.+<\/i>)/) ||
                 ($file_name eq "sys/sem.h" && /^(.+)<\/tt>(.+<\/i>)/) ||
                 ($file_name eq "sys/shm.h" && /^(.+)<\/tt>(.+<\/i>)/) ) {
                print "\t$1; /*$2 */\n";
                next;
            }
            if ($file_name eq "trace.h" && (/^<tt>(.+posix_\w+)$/ || /^(.+posix_\w+)$/)) {
                print "\t$1;\n";
                next;
            }
            if (/<tt>(\w+\s+\**\w+)/) {
                print "\t$1;\n";
                next;
            }
            next;
        }
    }


    #
    # constants/macros
    #

    if (0 ||
       (/following symbolic constant/) ||
       (/header shall define at least the following symbolic constant/) ||
       (/following macros/) ||
       (/header shall define the following macros/) ||
       (/Symbolic constants:/ && $file_name eq "ulimit.h") ||
        0) {
        $state = "const";
        print "\n";
        next;
    }

    if ($state eq "const" || $state eq "const_end") {
        if (/<dl>/) {
            $state = "const_begin";
            next;
        }
        if (/<\/dl>/) {
            $state = "const_end";
            $macro_count = 0;
            print "\n";
            next;
        }
        if (/<dt>[\[\{]?(\w+)[\]\}]?<\/dt>/) {
            next if (length($1) == 1);
            printf "#define %-32s %3d\n", $1, $macro_count++;
            next;
        }
        if (/(_SC_\w+)/ ||
            /(_CS_\w+)/ ||
            /(_PC_\w+)/ ||
            /(FE_\w+)/ ||
            /(MM_NULL\w+)/ ||
            (/(PTHREAD_\w+)/ && $file_name eq "pthread.h" ) ||
            (/(POSIX_SPAWN_\w+)/ && $file_name eq "spawn.h" ) ||
            (/(POSIX_TRACE_\w+)/ && $file_name eq "trace.h" ) ||
            0) {
            printf "#define %-32s %3d\n", $1, $macro_count++;
            next;
        }
    }

    if ($file_name eq "cpio.h") {
        if (/<p class="tent">(C_I\w+)<\/p>/) {
            $macro_name = $1;
            next;
        }
        if (/<p class="tent">(\d+)<\/p>/) {
            $macro_value = $1;
            printf "#define %-8s %s /* %s */\n", $macro_name, $macro_value, $macro_desc;
            next;
        }
        if (/<p class="tent">(.+)<\/p>/) {
            $macro_desc = $1;
            next;
        }
        if (/MAGIC/) {
            s/<tt>//;
            printf "\n#define %s\n", $_;
        }
    }

    if ($file_name eq "sys/stat.h") {
        if (/<p class="tent">(S_I\w+)<\/p>/) {
            $macro_name = $1;
            next;
        }
        if (/<p class="tent">(\d+)<\/p>/) {
            $macro_value = $1;
            next;
        }
        if (/<p class="tent">(.+)<\/p>/) {
            $macro_desc = $1;
            next if (length($macro_name) == 0);
            printf "#define %-8s %07s /* %s */\n", $macro_name, $macro_value, $macro_desc;
            next;
        }
    }

    if ($file_name eq "tar.h") {
        if (/<p class="tent">(T\w+)<\/p>/ ||
            /<p class="tent">(\w+TYPE)<\/p>/) {
            $macro_name = $1;
            next;
        }
        if (/<p class="tent">(\d+|"00"|"ustar"|'\\?\d'|)<\/p>/) {
            $macro_value = $1;
            next;
        }
        if (/<p class="tent">(.+)<\/p>/) {
            $macro_desc = $1;
            next if (length($macro_name) == 0);
            printf "#define %-8s %-8s \/* %s */\n", $macro_name, $macro_value, $macro_desc;
            next;
        }
    }

    if ($file_name eq "termios.h") {
        if (/<p class="tent">(V\w+)<\/p>/) {
            $macro_name = $1;
            next;
        }
        if (/<p class="tent">(\w+ character.)<\/p>/ ||
            /<p class="tent">(\w+ value.)<\/p>/) {
            $macro_desc = $1;
            printf "#define %-8s %3d \/* %s */\n", $macro_name, $macro_count++, $macro_desc;
            next;
        }
    }



    #
    # types
    #

    if (/header shall define.* the following .*type/) {
        $state = "types";
        next;
    }
    if ($state eq "types") {
        if (/<dl>/) {
            $state = "types_begin";
            next;
        }
        if (/<\/dl>/) {
            $state = "types_end";
            print "\n";
            next;
        }
        if (/<dt><b>(.+)<\/b><\/dt>/) {
            $type_name = $1;
            if ($type_name =~ /pthread(.+)_t/) {
                print "typedef struct pthread$1_s {} $type_name;\n";
            } elsif ($type_name =~ /trace_(.+)_t/) {
                print "typedef struct trace_$1_s {} $type_name;\n";
            } elsif ($type_name =~ /FILE|DIR/) {
                print "typedef struct {} $type_name;\n";
            } elsif ($type_name =~ /va_list/) {
                print "typedef char * $type_name;\n";
            } elsif ($type_name =~ /(float|double)_t/) {
                print "typedef $1 $type_name;\n";
            } elsif ($type_name =~ /size_t/ && $file_name ne "sys/types.h") {
                next;
            } else {
                print "typedef int $type_name;\n"
            }
            next;
        }
    }
    

    #
    # function
    #
    if (/following shall be declared as functions/) {
        $state = "function";
    }
    if (/following shall be declared as a function/) {
        $state = "function";
    }

    if ($state eq "function") {
        if (/<pre>/) {
            $state = "func_begin";
            print "\n";
            next;
        }
    }

    if ($state eq "func_begin") {
        if (/<\/pre>|<\/tt>/) {
            $state = "func_end";
        } else {
            next if (/<img.+>/);
            next if (/<sup>/);
            s/<tt>| \[restrict\]//;
            s/<img src=[^>]+>//;
            #print;
            if (/(\w+\()/) {
                $func_name = $1;
                chop $func_name;
                next if ($func_name eq "void");
                next if ($func_name eq "int");
                system './func.pl', 'usr/text/' . $func_name . '.txt';
            }
        }
    }

}

print "\n#endif /* $guard_name */\n";




#!/usr/bin/perl -w
#
# func.pl
#
# Copyright mymtom 2012
#
# 根据《IEEE Std 1003.1-2008》生成用于VIM的TAGS
#

use strict;
use warnings;
use File::Basename;

my $file_name = "";
my $func_name = "";

if (scalar(@ARGV) != 1) {
    exit 1;
}

$file_name = basename($ARGV[0], ".txt");

for (<>) {
    exit 0 if (/DESCRIPTION/);
    next if (/^\s*$/);
    next if (/#include/);
    s/\s{5}//;
    s/\[.+\] \[\[Option Start\]\]\s?//;
    s/\s*\[\[Option End\]\]//;
    $func_name = $1 if (/(\w+)\(/);
    print if ($func_name eq $file_name);
    last if ($func_name eq $file_name && /\);$/);
}



  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值