URI: 
       tman page checking - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 02f38ca68ce484b2aad15fad4d59c4d43ef7eb1b
   DIR parent 3e1c71811965930d52db3df4d57acb9d9020f8df
  HTML Author: rsc <devnull@localhost>
       Date:   Tue,  4 Jan 2005 22:33:11 +0000
       
       man page checking
       
       Diffstat:
         A dist/checkman.awk                   |     453 +++++++++++++++++++++++++++++++
         A dist/mkfile                         |       5 +++++
       
       2 files changed, 458 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/dist/checkman.awk b/dist/checkman.awk
       t@@ -0,0 +1,453 @@
       +# Usage: cd $PLAN9; awk -f dist/checkman.awk man?/*.?
       +#
       +# Checks:
       +#        - .TH is first line, and has proper name section number
       +#        - sections are in order NAME, SYNOPSIS, DESCRIPTION, EXAMPLES,
       +#                FILES, SOURCE, SEE ALSO, DIAGNOSTICS, BUGS
       +#        - there's a manual page for each cross-referenced page
       +
       +BEGIN {
       +
       +#        .SH sections should come in the following order
       +
       +        Weight["NAME"] = 1
       +        Weight["SYNOPSIS"] = 2
       +        Weight["DESCRIPTION"] = 4
       +        Weight["EXAMPLE"] = 8
       +        Weight["EXAMPLES"] = 16
       +        Weight["FILES"] = 32
       +        Weight["SOURCE"] = 64
       +        Weight["SEE ALSO"] = 128
       +        Weight["DIAGNOSTICS"] = 256
       +        Weight["SYSTEM CALLS"] = 512
       +        Weight["BUGS"] = 1024
       +
       +        Skipdirs["CVS"] = 1
       +
       +        # allow references to pages provded
       +        # by the underlying Unix system
       +        Omitman["awk(1)"] = 1
       +        Omitman["bash(1)"] = 1
       +        Omitman["chmod(1)"] = 1
       +        Omitman["compress(1)"] = 1
       +        Omitman["cp(1)"] = 1
       +        Omitman["egrep(1)"] = 1
       +        Omitman["gs(1)"] = 1
       +        Omitman["gv(1)"] = 1
       +        Omitman["lex(1)"] = 1
       +        Omitman["lp(1)"] = 1
       +        Omitman["lpr(1)"] = 1
       +        Omitman["mail(1)"] = 1
       +        Omitman["nm(1)"] = 1
       +        Omitman["prof(1)"] = 1
       +        Omitman["pwd(1)"] = 1
       +        Omitman["sh(1)"] = 1
       +        Omitman["ssh(1)"] = 1
       +        Omitman["tar(1)"] = 1
       +        Omitman["tex(1)"] = 1
       +        Omitman["unutf(1)"] = 1
       +        Omitman["xterm(1)"] = 1
       +
       +        Omitman["access(2)"] = 1
       +        Omitman["brk(2)"] = 1
       +        Omitman["close(2)"] = 1
       +        Omitman["connect(2)"] = 1
       +        Omitman["fork(2)"] = 1
       +        Omitman["gethostname(2)"] = 1
       +        Omitman["getpid(2)"] = 1
       +        Omitman["getuid(2)"] = 1
       +        Omitman["open(2)"] = 1
       +        Omitman["pipe(2)"] = 1
       +        Omitman["ptrace(2)"] = 1
       +        Omitman["rmdir(2)"] = 1
       +        Omitman["send(2)"] = 1
       +        Omitman["signal(2)"] = 1
       +        Omitman["sigprocmask(2)"] = 1
       +        Omitman["socketpair(2)"] = 1
       +        Omitman["unlink(2)"] = 1
       +
       +        Omitman["abort(3)"] = 1
       +        Omitman["assert(3)"] = 1
       +        Omitman["fprintf(3)"] = 1
       +        Omitman["fscanf(3)"] = 1
       +        Omitman["fopen(3)"] = 1
       +        Omitman["isalpha(3)"] = 1
       +        Omitman["malloc(3)"] = 1
       +        Omitman["perror(3)"] = 1
       +        Omitman["remove(3)"] = 1
       +        Omitman["sin(3)"] = 1
       +        Omitman["strerror(3)"] = 1
       +
       +        Omitman["factotum(4)"] = 1        # for now leave undocumented
       +
       +        Omitman["core(5)"] = 1
       +        Omitman["passwd(5)"] = 1
       +
       +        Omitman["signal(7)"] = 1
       +
       +        Omitman["cron(8)"] = 1
       +
       +        # don't need documentation for these in bin
       +        Omitted[".cvsignore"] = 1
       +        Omitted["Getdir"] = 1
       +        Omitted["9grep"] = 1        # is in grep(1)
       +        Omitted["9sed"] = 1        # is in sed(1)
       +        Omitted["9lex"] = 1                # is in lex(1)
       +        Omitted["9yacc"] = 1        # is in yacc(1)
       +
       +        # not for users
       +        Omittedlib["creadimage"] = 1
       +        Omittedlib["pixelbits"] = 1
       +        Omittedlib["bouncemouse"] = 1
       +        Omittedlib["main"] = 1        # in libthread
       +
       +        # functions provided for -lthread_db
       +        Omittedlib["ps_get_thread_area"] = 1
       +        Omittedlib["ps_getpid"] = 1
       +        Omittedlib["ps_lcontinue"] = 1
       +        Omittedlib["ps_lgetfpregs"] = 1
       +        Omittedlib["ps_lgetregs"] = 1
       +        Omittedlib["ps_lsetfpregs"] = 1
       +        Omittedlib["ps_lsetregs"] = 1
       +        Omittedlib["ps_lstop"] = 1
       +        Omittedlib["ps_pcontinue"] = 1
       +        Omittedlib["ps_pdread"] = 1
       +        Omittedlib["ps_pdwrite"] = 1
       +        Omittedlib["ps_pglobal_lookup"] = 1
       +        Omittedlib["ps_pstop"] = 1
       +        Omittedlib["ps_ptread"] = 1
       +        Omittedlib["ps_ptwrite"] = 1
       +
       +        # libmach includes a small dwarf and elf library
       +        Omittedlib["corecmdfreebsd386"] = 1
       +        Omittedlib["corecmdlinux386"] = 1
       +        Omittedlib["coreregsfreebsd386"] = 1
       +        Omittedlib["coreregslinux386"] = 1
       +        Omittedlib["coreregsmachopower"] = 1
       +        Omittedlib["crackelf"] = 1
       +        Omittedlib["crackmacho"] = 1
       +        Omittedlib["dwarfaddrtounit"] = 1
       +        Omittedlib["dwarfclose"] = 1
       +        Omittedlib["dwarfenum"] = 1
       +        Omittedlib["dwarfenumunit"] = 1
       +        Omittedlib["dwarfget1"] = 1
       +        Omittedlib["dwarfget128"] = 1
       +        Omittedlib["dwarfget128s"] = 1
       +        Omittedlib["dwarfget2"] = 1
       +        Omittedlib["dwarfget4"] = 1
       +        Omittedlib["dwarfget8"] = 1
       +        Omittedlib["dwarfgetabbrev"] = 1
       +        Omittedlib["dwarfgetaddr"] = 1
       +        Omittedlib["dwarfgetn"] = 1
       +        Omittedlib["dwarfgetnref"] = 1
       +        Omittedlib["dwarfgetstring"] = 1
       +        Omittedlib["dwarflookupfn"] = 1
       +        Omittedlib["dwarflookupname"] = 1
       +        Omittedlib["dwarflookupnameinunit"] = 1
       +        Omittedlib["dwarflookupsubname"] = 1
       +        Omittedlib["dwarflookuptag"] = 1
       +        Omittedlib["dwarfnextsym"] = 1
       +        Omittedlib["dwarfnextsymat"] = 1
       +        Omittedlib["dwarfopen"] = 1
       +        Omittedlib["dwarfpctoline"] = 1
       +        Omittedlib["dwarfseeksym"] = 1
       +        Omittedlib["dwarfskip"] = 1
       +        Omittedlib["dwarfunwind"] = 1
       +        Omittedlib["elfclose"] = 1
       +        Omittedlib["elfdl386mapdl"] = 1
       +        Omittedlib["elfinit"] = 1
       +        Omittedlib["elfmachine"] = 1
       +        Omittedlib["elfmap"] = 1
       +        Omittedlib["elfopen"] = 1
       +        Omittedlib["elfsection"] = 1
       +        Omittedlib["elfsym"] = 1
       +        Omittedlib["elfsymlookup"] = 1
       +        Omittedlib["elftype"] = 1
       +        Omittedlib["machoclose"] = 1
       +        Omittedlib["machoinit"] = 1
       +        Omittedlib["machoopen"] = 1
       +        Omittedlib["stabsym"] = 1
       +        Omittedlib["symdwarf"] = 1
       +        Omittedlib["symelf"] = 1
       +        Omittedlib["symmacho"] = 1
       +        Omittedlib["symstabs"] = 1
       +
       +        Renamelib["chanalt"] = "alt"
       +        Renamelib["channbrecv"] = "nbrecv"
       +        Renamelib["channbrecvp"] = "nbrecvp"
       +        Renamelib["channbrecvul"] = "nbrecvul"
       +        Renamelib["channbsend"] = "nbsend"
       +        Renamelib["channbsendp"] = "nbsendp"
       +        Renamelib["channbsendul"] = "nbsendul"
       +        Renamelib["chanrecv"] = "recv"
       +        Renamelib["chanrecvp"] = "recvp"
       +        Renamelib["chanrecvul"] = "recvul"
       +        Renamelib["chansend"] = "send"
       +        Renamelib["chansendp"] = "sendp"
       +        Renamelib["chansendul"] = "sendul"
       +        Renamelib["threadyield"] = "yield"
       +
       +        Renamelib["fmtcharstod"] = "charstod"
       +        Renamelib["fmtstrtod"] = "strtod"
       +
       +        Renamelib["regcomp9"] = "regcomp"
       +        Renamelib["regcomplit9"] = "regcomplit"
       +        Renamelib["regcompnl9"] = "regcompnl"
       +        Renamelib["regerror9"] = "regerror"
       +        Renamelib["regexec9"] = "regexec"
       +        Renamelib["regsub9"] = "regsub"
       +        Renamelib["rregexec9"] = "rregexec"
       +        Renamelib["rregsub9"] = "rregsub"
       +}
       +
       +FNR==1        {
       +                n = length(FILENAME)
       +                nam = FILENAME
       +                if(nam ~ /\.html$/)
       +                        next
       +                if(nam !~ /^man\/man(.*)\/(.*)\.(.*)$/){
       +                        print "nam", nam, "not of form [0-9][0-9]?/*"
       +                        next
       +                }
       +                nam = substr(nam, 8)
       +                gsub("[/.]", " ", nam);
       +                n = split(nam, a)
       +                sec = a[1]
       +                name = a[2]
       +                section = a[3]
       +                if($1 != ".TH" || NF != 3)
       +                        print "First line of", FILENAME, "not a proper .TH"
       +                else if(($2 != toupper(name) || substr($3, 1, length(sec)) != sec || $3 != toupper(section)) \
       +                                && ($2!="INTRO" || name!="0intro") \
       +                                && (name !~ /^9/ || $2!=toupper(substr(name, 2)))){
       +                        print ".TH of", FILENAME, "doesn't match filename"
       +                }else
       +                        Pages[tolower($2) "(" tolower($3) ")"] = 1
       +                Sh = 0
       +}
       +
       +$1 == ".SH" {
       +                if(inex)
       +                        print "Unterminated .EX in", FILENAME, ":", $0
       +                inex = 0;
       +                if (substr($2, 1, 1) == "\"") {
       +                        if (NF == 2) {
       +                                print "Unneeded quote in", FILENAME, ":", $0
       +                                $2 = substr($2, 2, length($2)-2)
       +                        } else if (NF == 3) {
       +                                $2 = substr($2, 2) substr($3, 1, length($3)-1)
       +                                NF = 2
       +                        }
       +                }
       +                if(Sh == 0 && $2 != "NAME")
       +                        print FILENAME, "has no .SH NAME"
       +                w = Weight[$2]
       +                if (w) {
       +                        if (w < Sh)
       +                                print "Heading", $2, "out of order in", FILENAME
       +                        Sh += w
       +                }
       +                sh = $2
       +}
       +
       +$1 == ".EX" {
       +                if(inex)
       +                        print "Nested .EX in", FILENAME ":" FNR, ":", $0
       +                inex = 1
       +}
       +
       +$1 == ".EE" {
       +                if(!inex)
       +                        print "Bad .EE in", FILENAME ":" FNR ":", $0
       +                inex = 0;
       +}
       +
       +$1 == ".TF" {
       +                smallspace = 1
       +}
       +
       +$1 == ".PD" || $1 == ".SH" || $1 == ".SS" || $1 == ".TH" {
       +                smallspace = 0
       +}
       +
       +$1 == ".RE" {
       +                lastre = 1
       +}
       +
       +$1 == ".PP" {
       +                if(smallspace && !lastre)
       +                        print "Possible missing .PD at " FILENAME ":" FNR
       +                smallspace = 0
       +}
       +
       +$1 != ".RE" {
       +                lastre = 0
       +}
       +
       +sh == "SOURCE" && $1 ~ /^\// {
       +        Sources[$1] = 1
       +}
       +
       +sh == "SOURCE" && $2 ~ /^\// {
       +        Sources[$2] = 1
       +}
       +
       +$0 ~ /^\.[A-Z].*\([1-9]\)/ {
       +                if ($1 == ".IR" && $3 ~ /\([0-9]\)/) {
       +                        name = $2
       +                        section = $3
       +                }else if ($1 == ".RI" && $2 == "(" && $4 ~ /\([0-9]\)/) {
       +                        name = $3
       +                        section = $4
       +                }else if ($1 == ".IR" && $3 ~ /9.\([0-9]\)/) {
       +                        name = $2
       +                        section = "9"
       +                }else if ($1 == ".RI" && $2 == "(" && $4 ~ /9.\([0-9]\)/) {
       +                        name = $3
       +                        section = "9"
       +                } else {
       +                        print "Possible bad cross-reference format in", FILENAME ":" FNR
       +                        print $0
       +                        next
       +                }
       +                gsub(/[^0-9]/, "", section)
       +                Refs[toupper(name) "(" section ")"]++
       +}
       +
       +END {
       +        print "Checking Source References"
       +        cmd = "xargs -n 100 ls -d 2>&1 >/dev/null | sed 's/^ls: /        /; s/: .*//'"
       +        for (i in Sources) {
       +                print i |cmd
       +        }
       +        close(cmd)
       +        print ""
       +        print "Checking Cross-Referenced Pages"
       +        for (i in Refs) {
       +                if (!(tolower(i) in Pages) && !(tolower(i) in Omitman)){
       +                        b = tolower(i)
       +                        gsub("\\(", " \\(", b)
       +                        gsub("\\)", "\\)", b)
       +                        split(tolower(i), a, "/")
       +                        print "egrep -in '^\\.IR.*" b "' $PLAN9/man/man*/* # Need " tolower(i) |"sort"
       +                }
       +        }
       +        close("sort")
       +        print ""
       +        print "Checking commands"
       +        getindex("man/man1")
       +        getindex("man/man4")
       +        getindex("man/man7")
       +        getindex("man/man8")
       +        getbinlist("bin")
       +        for (i in List) {
       +                if (!(i in Index) && !(i in Omitted))
       +                        print "Need", i, "(in " List[i] ")" |"sort"
       +        }
       +        close("sort")
       +        print ""
       +        for (i in List) {
       +                if (!(i in Index) && (i in Omitted))
       +                        print "Omit", i, "(in " List[i] ")" |"sort"
       +        }
       +        close("sort")
       +        clearindex()
       +        clearlist()
       +        print ""
       +        print "Checking libraries"
       +        getindex("man/man3")
       +        getnmlist("lib/lib9.a")
       +        getnmlist("lib/lib9p.a")
       +        getnmlist("lib/lib9pclient.a")
       +        getnmlist("lib/libString.a")
       +        # getnmlist("lib/libauth.a")
       +        # getnmlist("lib/libauthsrv.a")
       +        getnmlist("lib/libbin.a")
       +        getnmlist("lib/libbio.a")
       +        getnmlist("lib/libcomplete.a")
       +        # getnmlist("lib/libcontrol.a")
       +        getnmlist("lib/libdisk.a")
       +        getnmlist("lib/libdraw.a")
       +        getnmlist("lib/libflate.a")
       +        getnmlist("lib/libframe.a")
       +        getnmlist("lib/libgeometry.a")
       +        getnmlist("lib/libhtml.a")
       +        # getnmlist("lib/libhttpd.a")
       +        getnmlist("lib/libip.a")
       +        getnmlist("lib/libmach.a")
       +        # getnmlist("lib/libmemdraw.a")
       +        # getnmlist("lib/libmemlayer.a")
       +        getnmlist("lib/libmp.a")
       +        getnmlist("lib/libmux.a")
       +        # getnmlist("lib/libndb.a")
       +        getnmlist("lib/libplumb.a")
       +        getnmlist("lib/libregexp9.a")
       +        getnmlist("lib/libsec.a")
       +        getnmlist("lib/libthread.a")
       +        # getnmlist("lib/libventi.a")
       +        for (i in List) {
       +                if (!(i in Index) && !(i in Omittedlib))
       +                        print "Need", List[i], i |"sort"
       +                        # print "Need", i, "(in " List[i] ")" |"sort"
       +        }
       +        close("sort")
       +        print ""
       +        for (i in List) {
       +                if (!(i in Index) && (i in Omittedlib))
       +                        print "Omit", List[i], i |"sort"
       +                        # print "Omit", i, "(in " List[i] ")" |"sort"
       +        }
       +        close("sort")
       +}
       +
       +func getindex(dir,    fname)
       +{
       +        fname = dir "/INDEX"
       +        while ((getline < fname) > 0)
       +                Index[$1] = dir
       +        close(fname)
       +}
       +
       +func getbinlist(dir,    cmd, subdirs, nsd)
       +{
       +        cmd = "ls -p -l " dir
       +        nsd = 0
       +        while (cmd | getline) {
       +                if ($1 ~ /^d/) {
       +                        if (!($10 in Skipdirs))
       +                                subdirs[++nsd] = $10
       +                } else if ($10 !~ "^_")
       +                        List[$10] = dir
       +        }
       +        for ( ; nsd > 0 ; nsd--)
       +                getbinlist(dir "/" subdirs[nsd])
       +        close(cmd)
       +}
       +
       +func getnmlist(lib,    cmd)
       +{
       +        cmd = "nm -g " lib
       +        while (cmd | getline) {
       +                if (($2 == "T" || $2 == "L") && $3 !~ "^_"){
       +                        sym = $3
       +                        sub("^p9", "", sym)
       +                        if(sym in Renamelib)
       +                                List[Renamelib[sym]] = lib " as " sym
       +                        else
       +                                List[sym] = lib
       +                }
       +        }
       +        close(cmd)
       +}
       +
       +func clearindex(    i)
       +{
       +        for (i in Index)
       +                delete Index[i]
       +}
       +
       +func clearlist(    i)
       +{
       +        for (i in List)
       +                delete List[i]
       +}
   DIR diff --git a/dist/mkfile b/dist/mkfile
       t@@ -0,0 +1,5 @@
       +check.out:V:
       +        cd ../man; mk indices
       +        cd ..
       +        awk -f dist/checkman.awk man/man*/*.* >dist/check.out
       +