根据《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 () {
    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 (\w+)<\/b> structure/  ||
        /shall.* declare the (\w+)<\/b> structure/ ||
        /shall.* define the structure (\w+)<\/b>/  ||
        /shall define the struct (\w+)<\/b>/  ||
        /The (\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 (/
/) {
            $state = "struct_begin";
            next;
        }
    }

    if ($state eq "struct_begin") {
        if (/<\/pre>/) {
            $state = "struct_end";
            print "};\n\n";
        } else {
            if (/(.+)<\/tt>(.+)/) {
                print "\t$1; /*$2*/\n";
                next;
            }
            if (/(.+)<\/tt>(.+)/) {
                print "\t$1; /*$2*/\n";
                next;
            }
            if ($file_name eq "ftw.h" && (/^int\s+(\w+)$/ || /^int\s+(\w+)/)) {
                print "\tint\t$1;\n";
                next;
            }
            if ($file_name eq "locale.h" && (/^(\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" && (/^(.+posix_\w+)$/ || /^(.+posix_\w+)$/)) {
                print "\t$1;\n";
                next;
            }
            if (/(\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 (/
/) { $state = "const_begin"; next; } if (/<\/dl>/) { $state = "const_end"; $macro_count = 0; print "\n"; next; } if (/
[\[\{]?(\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 (/

(C_I\w+)<\/p>/) { $macro_name = $1; next; } if (/

(\d+)<\/p>/) { $macro_value = $1; printf "#define %-8s %s /* %s */\n", $macro_name, $macro_value, $macro_desc; next; } if (/

(.+)<\/p>/) { $macro_desc = $1; next; } if (/MAGIC/) { s///; printf "\n#define %s\n", $_; } } if ($file_name eq "sys/stat.h") { if (/

(S_I\w+)<\/p>/) { $macro_name = $1; next; } if (/

(\d+)<\/p>/) { $macro_value = $1; next; } if (/

(.+)<\/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 (/

(T\w+)<\/p>/ || /

(\w+TYPE)<\/p>/) { $macro_name = $1; next; } if (/

(\d+|"00"|"ustar"|'\\?\d'|)<\/p>/) { $macro_value = $1; next; } if (/

(.+)<\/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 (/

(V\w+)<\/p>/) { $macro_name = $1; next; } if (/

(\w+ character.)<\/p>/ || /

(\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 (/

/) { $state = "types_begin"; next; } if (/<\/dl>/) { $state = "types_end"; print "\n"; next; } if (/
(.+)<\/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 (/
/) {
            $state = "func_begin";
            print "\n";
            next;
        }
    }

    if ($state eq "func_begin") {
        if (/<\/pre>|<\/tt>/) {
            $state = "func_end";
        } else {
            next if (//);
            next if (//);
            s/| \[restrict\]//;
            s/]+>//;
            #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 && /\);$/);
}



你可能感兴趣的:(html2text,POSIX,posix,susv4,tags,vim,VIM,Vim)