3 # mangen - generate manual entries for library
6 # 02g,16jul93,abh Added compatibility for FORTRAN "C" style comments. See
7 # STAR programming guidelines for template.
8 # 02f,08may90,jdi nroff lines: took out colrm, added tbl and -Tlp.
9 # 02e,12mar90,jdi made NOMANUAL work for module entries;
10 # added CS/CE macros to routine declarations in lib synopsis.
11 # 02d,25jan90,rbr works with "#!/bin/awk -f" and the like
12 # 02c,10apr89,dnw changed to always put individual routine manual entries in
13 # chapter 2 instead of in (summary chapter + 1), so driver
14 # routines end up in 2 rather than 4.
15 # 02b,05apr89,dnw removed NOT_GENERIC filter
16 # added removing of mg.out and mgr.out before starting
17 # 02a,05nov87,jlf changed to allow mangen'ing of scripts
18 # changed so routine definitions that don't fit on one
19 # one line, have a '...' appended in synopses.
20 # changed documentation format so mangen can be mangen'ed.
24 # mangen [-d] [-n] [-l] chapter file
27 # generates: <name>.<chapter#> (manual entry for module)
28 # and if "-l": <name>.<chapter#+1> (manual entries for each routine)
30 # where <name> is the "root" of the "tail" of the specified file
31 # (i.e. if file="/usr/dave/gronk.c", then name="gronk");
32 # and <chapter#> is the single digit chapter number
33 # (i.e. just the specified chapter number if one was given,
34 # or the number from the table below if a chapter name was given).
36 # <chapter> can be any digit or any of the following chapter abbreviations:
39 # = ==== =========== ====================================
41 # over* conventions - conventions and overview material
42 # 1 lib* libraries - subroutine library summaries
43 # 2 routines - individual library routines
46 # dr* drivers - tasks and drivers
47 # 4 tool* tools - Unix development/maintenence tools
49 # NOTE: Specifying the chapter as "lib" automatically selects the -l option.
51 # "-l" flag causes a special library module style manual entry to be created.
52 # The manual entry for a library has a specially constructed synopsis section
53 # that contains the titles and calling sequence of each routine in the library.
54 # Also a seperate manual entry is generated for each of the routines in the
55 # library. These routine manual entries will be put in a file named libxxx.2.
57 # "-d" flag causes the intermediate nroff source files to NOT be deleted.
58 # These are called "mg.out" and "mgr.out" for the module manual entry
59 # and individual routine entries (only if -l option specified), respectively.
60 # This option is useful for debugging manual entries that don't look the
63 # "-n" flag causes nroff sources not to be deleted, and not to be nroffed
64 # either. In this case, "mg.out" (and "mgr.out") will be the ONLY output
68 # % mangen lib /usr/vw/lib/lstlib.c
69 # will create "lstlib.1" and "liblst.2" in the current directory.
72 trap "rm -f mg.out mgr.out /tmp/mangen$$; exit" 1 2 3 15
74 rm -f mg.out mgr.out # start with a clean slate
76 # set home to directory that contains this script
78 home=`expr $0 : '\(.*/\)[^/]' '|' ./`
90 -n) dontdelete=1; dontnroff=1 ;;
92 con* | over*) chapter=0 ;;
93 lib*) chapter=1; lib=1 ;;
94 task* | tsk* | dr*) chapter=3 ;;
96 *) echo "flag not recognized:" $1; exit 1 ;;
105 # remove trailing component, eg. ".xx"
107 section=`expr $name : '\(.*\)\..*' '|' $name`
109 # create awk program found at end of this script, and
110 # make substitutions in the awk program source
112 awk '/^#START_AWK$/,/^#STOP_AWK$/' <$0 | \
113 sed -e "s^\%filename^$name^g" \
114 -e "s/\%chapter/$chapter/g" \
118 # generate the nroff source of the manual entries
120 awk -f /tmp/mangen$$ <$1
124 # nroff them unless -n option
126 if (test $dontnroff -eq 0) then
127 #tbl mg.out | nroff -man -Tman >$section.$chapter
128 #tbl mg.out | nroff -man -Tlp >$section.$chapter
129 #tbl mg.out | nroff -mangen -Tlp >$section.$chapter
130 tbl mg.out | nroff >$section.$chapter
132 mv mg.out $section.$chapter
135 if (test $lib -eq 1) then
136 if (test $dontnroff -eq 0) then
137 #tbl mgr.out | nroff -man -Tman >$section.2
138 #tbl mgr.out | nroff -mangen -Tlp >$section.2
139 tbl mgr.out | nroff >$section.2
141 mv mgr.out $section.2
144 # delete the nroff source, unless -d or -n option
146 if (test $dontdelete -eq 0) then
154 # mangen.awk - awk program to generate manual entries
156 # the variable "s" holds the current state of the scan:
158 # title - get title line (initial state
159 # mh0 - skip to start of modification history
160 # mh - skip to end of modification history
161 # desc0 - skip to start of module description
162 # desc - process module description
164 # the following additional states are used if the "lib" flag is specified:
166 # rtn - skip to start of next routine
167 # rtitle - skip to, and process, routine title line
168 # rdesc - skip to, and process, routine description
169 # rsy0 - skip to start of routine synopsis
170 # rsy - process routine synopsis
176 # the following values preceded by a "%" are substituted
177 # for by a "sed" program
179 filename = "%filename" # source filename
180 chapter = %chapter # chapter number
181 lib = %lib # 1 = make routine entries, 0 = don't
185 dbg = 0 # 1 = output debug stuff
186 s = "title" # initial state
188 # get module name w/o the extension and the output file names
190 dot = index (filename, ".")
195 modname = substr (filename, 1, dot - 1)
202 print s "\n" $0 >outfile
205 # ignore lint directive lines
211 # get ss = line without leading '/* ' or '* ' or '# ' and trailing '*/'
212 # subhead = subheading (all caps at beginning of line w/ optional ':')
213 # subheadl = remainder of subheading line following ':'
218 nf = split ($0, words, "\t")
226 for (i = 2; i <= nf; i++)
227 l = l substr(" ", 1, 8-(length(l) % 8)) words[i]
230 # strip off leading and trailing comment indicators
232 if ((l ~ /^C>/) || (l ~ /^\/\*/))
234 if ((l ~ /^C> /) || (l ~ /^\/\* /))
239 else if ((l ~ /^C/) || (l ~ /^\*/))
241 if ((l ~ /^C /) || (l ~ /^\* /))
258 if ((l ~ /C<$/) || (l ~ /\*\/$/))
261 ss = substr (l, start, end - start + 1)
264 # check for sub heading line
266 if ((ss !~ /^[A-Z][^a-z]*:/) && \
267 (ss !~ /^[A-Z][^a-z]*$/))
271 colon = index (ss, ":")
280 subhead = substr (ss, 1, colon - 1)
282 subheadl = substr (ss, colon + 2)
283 if (subheadl ~ /^ *$/)
289 # get module name and title: 1st line in file
292 # This gets rid of .yacc first lines ("%{"), and the first
293 # line or two of a script ("#!/bin/sh", etc.).
295 if (NF == 1 || index($1, "#!"))
298 # check that title matches module name
300 dot = index ($2, ".")
304 titlename = substr (ss, 1, dot - 1)
306 if (titlename != modname)
308 print "ERROR: on line " NR \
309 ": module name inconsistent w/ file name."
319 # skip modification history: skip, looking for 'modification history' then blank
322 if (l ~ /modification history/)
336 # get module description: ignore leading blank lines; turn capital lines
337 # into subheadings; accumulate rest looking for '*/'
348 # suppress manual entry if NOMANUAL specified
350 if (l ~ /NO[ _-]?MANUAL/)
355 # check for end of description section
357 if ((l ~ /^\#*C</) || (l ~ /^\#*\*\//))
369 # check for description section missing entirely
371 if ((l ~ /-----------------------------/) || (l ~ /\*\*\*\*\*\*\*\*\*\*/))
373 print "ERROR: on line " NR ": module description missing."
378 # skip leading blank lines
380 if ((xdesc == 0) && (ss ~ /^ *$/))
384 # check for subheading line and accumulate description
393 if (subhead ~ /^INTERNAL/)
397 desc[++xdesc] = ".SH " subhead
399 desc[++xdesc] = subheadl
407 # skip to routine start: skip looking for '**********'
410 if ((l ~ /--------------------------/) || (l ~ /\*\*\*\*\*\*\*\*\*\*/))
411 { rtitle = ""; rnm = ""; xrdesc = 0; xrsy = 0; s = "rtitle" }
415 # get routine title: skip looking for 1st non-blank line
419 { rtitle = ss; rnm = $2; ignore = 0; s = "rdesc" }
423 # get routine description: skip leading blank lines; make capital lines
424 # be subheadings; accumulate rest looking for '*/' or blank line
427 # check for end of routine description
429 if ((l ~ /^C</) || (l ~ /^\*\//) || (l ~ /^ *$/))
435 # skip leading blank lines
437 if (xrdesc == 0 && ss ~ /^ *$/)
440 # suppress manual entry if NOMANUAL specified
442 if (l ~ /NO[ _-]?MANUAL/)
448 # check for sub heading and accumulate routine description
449 # ignore INTERNAL sections
458 if (subhead ~ /^INTERNAL/)
462 rdesc[++xrdesc] = ".SH " subhead
464 rdesc[++xrdesc] = subheadl
471 # get routine synopsis: throw away local routines; check declared name matches
472 # title; accumulate rest looking for "{"; then output routine manual
475 # skip to next non-blank line
480 # found the function declaration line
481 # quit processing of local functions: don't make manual
483 l = substr (ss, 1, index (ss, "(") - 1)
486 if ((words[1] == "LOCAL") || (words[1] == "static"))
492 # check that declared name matches name in title
494 if ((words[n] != rnm) && (words[n] != ("*" rnm)))
496 print "ERROR on line " NR \
497 ": title inconsistent with declaration:\n" rtitle "\n" l
500 # save routine declaration line
511 # accumulate synopsis til '{' or blank line, then output manual
513 # if ((l !~ /^ *{/) && (l !~ /^ *$/))
514 if ((l !~ /^ *\{/) && (l !~ /^ *$/))
518 # get real part up to ';' and note longest declaration
530 if (($1 == "FAST") || ($1 == "register") || ($1 == "*"))
535 rsy [xrsy] = substr (l, i, is - i + 1)
546 rsyc [xrsy] = substr (l, ic)
550 # note maximum length of line
556 # note minimum gap between code and comment
558 if ((ic != 0) && (is != 0))
560 gap = ic - is - 1 + i - 5
567 # end of synopsis reached; output routine name, then
568 # manual for this routine, then form-feed
573 stitle [++xrtn] = rtitle
576 # print name and title
578 print ".TH " rnm " 2" \
579 " \"\" \"ALICE Reference Manual\"" >rtnfile
580 print ".ad b" >rtnfile
581 print ".SH NAME\n" rtitle >rtnfile
583 # print routine synopsis
585 # figure out if we should squeeze decls and comments
590 squeeze = maxlen - 60
591 if (squeeze > (mingap - 1))
595 print ".SH SYNOPSIS" >rtnfile
598 print rsy[1] >rtnfile
599 for (i = 2; i <= xrsy; i++)
604 n = rsyci[i] - length(rsy[i]) - 5 - squeeze
605 print " " rsy[i] substr(blanks,0,n) rsyc[i] >rtnfile
612 if ((xrdesc != 0) && (rdesc[1] !~ /^\.SH/))
613 print ".SH DESCRIPTION" >rtnfile
617 for (i = 1; i <= xrdesc; i++)
619 print rdesc[i] >rtnfile
621 if (rdesc[i] ~ /^.SH SEE ALSO/)
623 print modname "(" chapter ")," >rtnfile
628 # print see also if not already done above
632 print ".SH SEE ALSO" >rtnfile
633 print modname "(" chapter ")" >rtnfile
643 # end of file: output module manual
648 # print name and title
650 print ".TH " modname " " chapter \
651 " \"\" \"ALICE Reference Manual\"" >outfile
652 print ".ad b" >outfile
653 print ".SH NAME\n" title >outfile
656 # print specially constructed synopsis, if library
657 # If no routines, say so.
661 print ".SH SYNOPSIS" >outfile
663 for (i = 1; i <= xrtn; i++)
664 print stitle[i] >outfile
667 print "NO CALLABLE ROUTINES" >outfile
669 for (i = 1; i <= xrtn; i++)
671 if (substr(ssy[i], length (ssy[i])) == ")")
672 print ssy[i] >outfile
674 print ssy[i], "..." >outfile
681 # print module description
683 if ((xdesc != 0) && (desc[1] !~ /^\.SH/))
684 print ".SH DESCRIPTION" >outfile
685 for (i = 1; i <= xdesc; i++)
686 print desc[i] >outfile