forsyth20121205-174063a80cc13 years agoHistory
187 lines · 3.8 KB · Text
RawDownload
# Usage: awk -f 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} FNR==1	{		n = length(FILENAME)		seclen = 0		if (substr(FILENAME, 2, 1) == "/")			seclen = 1		else if (substr(FILENAME, 3, 1) == "/")			seclen = 2		if(seclen == 0)			print "FILENAME", FILENAME, "not of form [0-9][0-9]?/*"		else if(!(substr(FILENAME, seclen+2, n-seclen-1) ~ /^[A-Z]+$/)){			section = substr(FILENAME, 1, seclen)			name = substr(FILENAME, seclen+2, n-seclen-1)			if($1 != ".TH" || NF != 3)				print "First line of", FILENAME, "not a proper .TH"			else if($2 != toupper(name) || substr($3, 1, seclen) != section){				if($2!="INTRO" || name!="0intro")					print ".TH of", FILENAME, "doesn't match filename"			}else				Pages[section "/" $2] = 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			}		}		w = Weight[$2]		if (w) {			if (w < Sh)				print "Heading", $2, "out of order in", FILENAME			Sh += w		}} $1 == ".EX" {		if(inex)			print "Nested .EX in", FILENAME, ":", $0		inex = 1} $1 == ".EE" {		if(!inex)			print "Bad .EE in", FILENAME, ":", $0		inex = 0;} $0 ~ /^\..*\([0-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			print $0			next		}		gsub(/[^0-9]/, "", section)		Refs[section "/" toupper(name)]++} END {	print "Checking Cross-Referenced Pages"	for (i in Refs) {		if (!(i in Pages))			print "Need", tolower(i)	}	print ""	print "Checking commands"	getindex("/usr/inferno/doc/man/1")	getindex("/usr/inferno/doc/man/8")	Skipdirs["lib"] = 1	getbinlist("/usr/inferno/dis")	for (i in List) {		if (!(i in Index))			print "Need", i, "(in " List[i] ")"	}	clearindex()	clearlist()	print ""	print "Checking libraries"	getindex("/usr/inferno/doc/man/2")	getbinlist("/usr/inferno/dis/lib")	for (i in List) {		if (!(i in Index))			print "Need", i, "(in " List[i] ")"	}} func getindex(dir,    fname){	fname = dir "/INDEX"	while ((getline < fname) > 0)		Index[$1] = dir	close(fname)} func getindex9(dir,    fname){	fname = dir "/INDEX"	while ((getline < fname) > 0)		if($2 ~ "(getflags|picopen|getcmap)")			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 {			sub(".dis", "", $10)			List[$10] = dir		}	}	for ( ; nsd > 0 ; nsd--)		getbinlist(dir "/" subdirs[nsd])	close(cmd)} func getnmlist(lib,    cmd){	cmd = "nm -g -h " lib	while (cmd | getline) {		if (($1 == "T" || $1 == "L") && $2 !~ "^_")			List[$2] = lib	}	close(cmd)} func clearindex(    i){	for (i in Index)		delete Index[i]} func clearlist(    i){	for (i in List)		delete List[i]}