aboutsummaryrefslogtreecommitdiff
path: root/dist
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-01-04 22:33:11 +0000
committerrsc <devnull@localhost>2005-01-04 22:33:11 +0000
commit02f38ca68ce484b2aad15fad4d59c4d43ef7eb1b (patch)
treeccd5694767b3939b5752f39597b2226b72f6993b /dist
parent3e1c71811965930d52db3df4d57acb9d9020f8df (diff)
downloadplan9port-02f38ca68ce484b2aad15fad4d59c4d43ef7eb1b.tar.gz
plan9port-02f38ca68ce484b2aad15fad4d59c4d43ef7eb1b.tar.bz2
plan9port-02f38ca68ce484b2aad15fad4d59c4d43ef7eb1b.zip
man page checking
Diffstat (limited to 'dist')
-rw-r--r--dist/checkman.awk453
-rw-r--r--dist/mkfile5
2 files changed, 458 insertions, 0 deletions
diff --git a/dist/checkman.awk b/dist/checkman.awk
new file mode 100644
index 00000000..4d682cab
--- /dev/null
+++ b/dist/checkman.awk
@@ -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]
+}
diff --git a/dist/mkfile b/dist/mkfile
new file mode 100644
index 00000000..5e679d52
--- /dev/null
+++ b/dist/mkfile
@@ -0,0 +1,5 @@
+check.out:V:
+ cd ../man; mk indices
+ cd ..
+ awk -f dist/checkman.awk man/man*/*.* >dist/check.out
+