1 # Usage: cd $PLAN9; awk -f dist/checkman.awk man?/*.?
4 # - .TH is first line, and has proper name section number
5 # - sections are in order NAME, SYNOPSIS, DESCRIPTION, EXAMPLES,
6 # FILES, SOURCE, SEE ALSO, DIAGNOSTICS, BUGS
7 # - there's a manual page for each cross-referenced page
11 # .SH sections should come in the following order
14 Weight["SYNOPSIS"] = 2
15 Weight["DESCRIPTION"] = 4
17 Weight["EXAMPLES"] = 16
20 Weight["SEE ALSO"] = 128
21 Weight["DIAGNOSTICS"] = 256
22 Weight["SYSTEM CALLS"] = 512
27 # allow references to pages provded
28 # by the underlying Unix system
30 Omitman["bash(1)"] = 1
31 Omitman["chmod(1)"] = 1
32 Omitman["compress(1)"] = 1
34 Omitman["egrep(1)"] = 1
40 Omitman["mail(1)"] = 1
42 Omitman["prof(1)"] = 1
48 Omitman["unutf(1)"] = 1
49 Omitman["xterm(1)"] = 1
51 Omitman["access(2)"] = 1
53 Omitman["close(2)"] = 1
54 Omitman["connect(2)"] = 1
55 Omitman["fork(2)"] = 1
56 Omitman["gethostname(2)"] = 1
57 Omitman["getpid(2)"] = 1
58 Omitman["getuid(2)"] = 1
59 Omitman["open(2)"] = 1
60 Omitman["pipe(2)"] = 1
61 Omitman["ptrace(2)"] = 1
62 Omitman["rmdir(2)"] = 1
63 Omitman["send(2)"] = 1
64 Omitman["signal(2)"] = 1
65 Omitman["sigprocmask(2)"] = 1
66 Omitman["socketpair(2)"] = 1
67 Omitman["unlink(2)"] = 1
69 Omitman["abort(3)"] = 1
70 Omitman["assert(3)"] = 1
71 Omitman["fprintf(3)"] = 1
72 Omitman["fscanf(3)"] = 1
73 Omitman["fopen(3)"] = 1
74 Omitman["isalpha(3)"] = 1
75 Omitman["malloc(3)"] = 1
76 Omitman["perror(3)"] = 1
77 Omitman["remove(3)"] = 1
79 Omitman["strerror(3)"] = 1
81 Omitman["factotum(4)"] = 1 # for now leave undocumented
83 Omitman["core(5)"] = 1
84 Omitman["passwd(5)"] = 1
86 Omitman["signal(7)"] = 1
88 Omitman["cron(8)"] = 1
90 # don't need documentation for these in bin
91 Omitted[".cvsignore"] = 1
93 Omitted["9grep"] = 1 # is in grep(1)
94 Omitted["9sed"] = 1 # is in sed(1)
95 Omitted["9lex"] = 1 # is in lex(1)
96 Omitted["9yacc"] = 1 # is in yacc(1)
99 Omittedlib["creadimage"] = 1
100 Omittedlib["pixelbits"] = 1
101 Omittedlib["bouncemouse"] = 1
102 Omittedlib["main"] = 1 # in libthread
104 # functions provided for -lthread_db
105 Omittedlib["ps_get_thread_area"] = 1
106 Omittedlib["ps_getpid"] = 1
107 Omittedlib["ps_lcontinue"] = 1
108 Omittedlib["ps_lgetfpregs"] = 1
109 Omittedlib["ps_lgetregs"] = 1
110 Omittedlib["ps_lsetfpregs"] = 1
111 Omittedlib["ps_lsetregs"] = 1
112 Omittedlib["ps_lstop"] = 1
113 Omittedlib["ps_pcontinue"] = 1
114 Omittedlib["ps_pdread"] = 1
115 Omittedlib["ps_pdwrite"] = 1
116 Omittedlib["ps_pglobal_lookup"] = 1
117 Omittedlib["ps_pstop"] = 1
118 Omittedlib["ps_ptread"] = 1
119 Omittedlib["ps_ptwrite"] = 1
121 # libmach includes a small dwarf and elf library
122 Omittedlib["corecmdfreebsd386"] = 1
123 Omittedlib["corecmdlinux386"] = 1
124 Omittedlib["coreregsfreebsd386"] = 1
125 Omittedlib["coreregslinux386"] = 1
126 Omittedlib["coreregsmachopower"] = 1
127 Omittedlib["crackelf"] = 1
128 Omittedlib["crackmacho"] = 1
129 Omittedlib["dwarfaddrtounit"] = 1
130 Omittedlib["dwarfclose"] = 1
131 Omittedlib["dwarfenum"] = 1
132 Omittedlib["dwarfenumunit"] = 1
133 Omittedlib["dwarfget1"] = 1
134 Omittedlib["dwarfget128"] = 1
135 Omittedlib["dwarfget128s"] = 1
136 Omittedlib["dwarfget2"] = 1
137 Omittedlib["dwarfget4"] = 1
138 Omittedlib["dwarfget8"] = 1
139 Omittedlib["dwarfgetabbrev"] = 1
140 Omittedlib["dwarfgetaddr"] = 1
141 Omittedlib["dwarfgetn"] = 1
142 Omittedlib["dwarfgetnref"] = 1
143 Omittedlib["dwarfgetstring"] = 1
144 Omittedlib["dwarflookupfn"] = 1
145 Omittedlib["dwarflookupname"] = 1
146 Omittedlib["dwarflookupnameinunit"] = 1
147 Omittedlib["dwarflookupsubname"] = 1
148 Omittedlib["dwarflookuptag"] = 1
149 Omittedlib["dwarfnextsym"] = 1
150 Omittedlib["dwarfnextsymat"] = 1
151 Omittedlib["dwarfopen"] = 1
152 Omittedlib["dwarfpctoline"] = 1
153 Omittedlib["dwarfseeksym"] = 1
154 Omittedlib["dwarfskip"] = 1
155 Omittedlib["dwarfunwind"] = 1
156 Omittedlib["elfclose"] = 1
157 Omittedlib["elfdl386mapdl"] = 1
158 Omittedlib["elfinit"] = 1
159 Omittedlib["elfmachine"] = 1
160 Omittedlib["elfmap"] = 1
161 Omittedlib["elfopen"] = 1
162 Omittedlib["elfsection"] = 1
163 Omittedlib["elfsym"] = 1
164 Omittedlib["elfsymlookup"] = 1
165 Omittedlib["elftype"] = 1
166 Omittedlib["machoclose"] = 1
167 Omittedlib["machoinit"] = 1
168 Omittedlib["machoopen"] = 1
169 Omittedlib["stabsym"] = 1
170 Omittedlib["symdwarf"] = 1
171 Omittedlib["symelf"] = 1
172 Omittedlib["symmacho"] = 1
173 Omittedlib["symstabs"] = 1
175 Renamelib["chanalt"] = "alt"
176 Renamelib["channbrecv"] = "nbrecv"
177 Renamelib["channbrecvp"] = "nbrecvp"
178 Renamelib["channbrecvul"] = "nbrecvul"
179 Renamelib["channbsend"] = "nbsend"
180 Renamelib["channbsendp"] = "nbsendp"
181 Renamelib["channbsendul"] = "nbsendul"
182 Renamelib["chanrecv"] = "recv"
183 Renamelib["chanrecvp"] = "recvp"
184 Renamelib["chanrecvul"] = "recvul"
185 Renamelib["chansend"] = "send"
186 Renamelib["chansendp"] = "sendp"
187 Renamelib["chansendul"] = "sendul"
188 Renamelib["threadyield"] = "yield"
190 Renamelib["fmtcharstod"] = "charstod"
191 Renamelib["fmtstrtod"] = "strtod"
193 Renamelib["regcomp9"] = "regcomp"
194 Renamelib["regcomplit9"] = "regcomplit"
195 Renamelib["regcompnl9"] = "regcompnl"
196 Renamelib["regerror9"] = "regerror"
197 Renamelib["regexec9"] = "regexec"
198 Renamelib["regsub9"] = "regsub"
199 Renamelib["rregexec9"] = "rregexec"
200 Renamelib["rregsub9"] = "rregsub"
208 if(nam !~ /^man\/man(.*)\/(.*)\.(.*)$/){
209 print "nam", nam, "not of form [0-9][0-9]?/*"
213 gsub("[/.]", " ", nam);
218 if($1 != ".TH" || NF != 3)
219 print "First line of", FILENAME, "not a proper .TH"
220 else if(($2 != toupper(name) || substr($3, 1, length(sec)) != sec || $3 != toupper(section)) \
221 && ($2!="INTRO" || name!="0intro") \
222 && (name !~ /^9/ || $2!=toupper(substr(name, 2)))){
223 print ".TH of", FILENAME, "doesn't match filename"
225 Pages[tolower($2) "(" tolower($3) ")"] = 1
231 print "Unterminated .EX in", FILENAME, ":", $0
233 if (substr($2, 1, 1) == "\"") {
235 print "Unneeded quote in", FILENAME, ":", $0
236 $2 = substr($2, 2, length($2)-2)
237 } else if (NF == 3) {
238 $2 = substr($2, 2) substr($3, 1, length($3)-1)
242 if(Sh == 0 && $2 != "NAME")
243 print FILENAME, "has no .SH NAME"
247 print "Heading", $2, "out of order in", FILENAME
255 print "Nested .EX in", FILENAME ":" FNR, ":", $0
261 print "Bad .EE in", FILENAME ":" FNR ":", $0
269 $1 == ".PD" || $1 == ".SH" || $1 == ".SS" || $1 == ".TH" {
278 if(smallspace && !lastre)
279 print "Possible missing .PD at " FILENAME ":" FNR
287 sh == "SOURCE" && $1 ~ /^\// {
291 sh == "SOURCE" && $2 ~ /^\// {
295 $0 ~ /^\.[A-Z].*\([1-9]\)/ {
296 if ($1 == ".IR" && $3 ~ /\([0-9]\)/) {
299 }else if ($1 == ".RI" && $2 == "(" && $4 ~ /\([0-9]\)/) {
302 }else if ($1 == ".IR" && $3 ~ /9.\([0-9]\)/) {
305 }else if ($1 == ".RI" && $2 == "(" && $4 ~ /9.\([0-9]\)/) {
309 print "Possible bad cross-reference format in", FILENAME ":" FNR
313 gsub(/[^0-9]/, "", section)
314 Refs[toupper(name) "(" section ")"]++
318 print "Checking Source References"
319 cmd = "xargs -n 100 ls -d 2>&1 >/dev/null | sed 's/^ls: / /; s/: .*//'"
325 print "Checking Cross-Referenced Pages"
327 if (!(tolower(i) in Pages) && !(tolower(i) in Omitman)){
329 gsub("\\(", " \\(", b)
330 gsub("\\)", "\\)", b)
331 split(tolower(i), a, "/")
332 print "egrep -in '^\\.IR.*" b "' $PLAN9/man/man*/* # Need " tolower(i) |"sort"
337 print "Checking commands"
344 if (!(i in Index) && !(i in Omitted))
345 print "Need", i, "(in " List[i] ")" |"sort"
350 if (!(i in Index) && (i in Omitted))
351 print "Omit", i, "(in " List[i] ")" |"sort"
357 print "Checking libraries"
359 getnmlist("lib/lib9.a")
360 getnmlist("lib/lib9p.a")
361 getnmlist("lib/lib9pclient.a")
362 getnmlist("lib/libString.a")
363 # getnmlist("lib/libauth.a")
364 # getnmlist("lib/libauthsrv.a")
365 getnmlist("lib/libbin.a")
366 getnmlist("lib/libbio.a")
367 getnmlist("lib/libcomplete.a")
368 # getnmlist("lib/libcontrol.a")
369 getnmlist("lib/libdisk.a")
370 getnmlist("lib/libdraw.a")
371 getnmlist("lib/libflate.a")
372 getnmlist("lib/libframe.a")
373 getnmlist("lib/libgeometry.a")
374 getnmlist("lib/libhtml.a")
375 # getnmlist("lib/libhttpd.a")
376 getnmlist("lib/libip.a")
377 getnmlist("lib/libmach.a")
378 # getnmlist("lib/libmemdraw.a")
379 # getnmlist("lib/libmemlayer.a")
380 getnmlist("lib/libmp.a")
381 getnmlist("lib/libmux.a")
382 # getnmlist("lib/libndb.a")
383 getnmlist("lib/libplumb.a")
384 getnmlist("lib/libregexp9.a")
385 getnmlist("lib/libsec.a")
386 getnmlist("lib/libthread.a")
387 # getnmlist("lib/libventi.a")
389 if (!(i in Index) && !(i in Omittedlib))
390 print "Need", List[i], i |"sort"
391 # print "Need", i, "(in " List[i] ")" |"sort"
396 if (!(i in Index) && (i in Omittedlib))
397 print "Omit", List[i], i |"sort"
398 # print "Omit", i, "(in " List[i] ")" |"sort"
403 func getindex(dir, fname)
406 while ((getline < fname) > 0)
411 func getbinlist(dir, cmd, subdirs, nsd)
413 cmd = "ls -p -l " dir
415 while (cmd | getline) {
417 if (!($10 in Skipdirs))
419 } else if ($10 !~ "^_")
422 for ( ; nsd > 0 ; nsd--)
423 getbinlist(dir "/" subdirs[nsd])
427 func getnmlist(lib, cmd)
430 while (cmd | getline) {
431 if (($2 == "T" || $2 == "L") && $3 !~ "^_"){
435 List[Renamelib[sym]] = lib " as " sym