xref: /xv6-public/runoff (revision 2c73068e)
1#!/bin/sh
2
3echo This script takes a minute to run.  Be patient. 1>&2
4
5LC_CTYPE=C export LC_CTYPE
6
7# pad stdin to multiple of 120 lines
8pad()
9{
10	awk '{print} END{for(; NR%120!=0; NR++) print ""}'
11}
12
13# create formatted (numbered) files
14mkdir -p fmt
15rm -f fmt/*
16cp README fmt
17echo > fmt/blank
18files=`grep -v '^#' runoff.list | awk '{print $1}'`
19n=99
20for i in $files
21do
22	./runoff1 -n $n $i >fmt/$i
23	nn=`tail -1 fmt/$i | sed 's/ .*//; s/^0*//'`
24	if [ "x$nn" != x ]; then
25		n=$nn
26	fi
27done
28
29# create table of contents
30cat toc.hdr >fmt/toc
31pr -e8 -t runoff.list | awk '
32/^[a-z0-9]/ {
33	s=$0
34	f="fmt/"$1
35	getline<f
36	close(f)
37	n=$1
38	printf("%02d %s\n", n/100, s);
39	printf("TOC: %04d %s\n", n, s) >"fmt/tocdata"
40	next
41}
42{
43	print
44}' | pr -3 -t >>fmt/toc
45cat toc.ftr >>fmt/toc
46
47# check for bad alignments
48perl -e '
49	$leftwarn = 0;
50	while(<>){
51		chomp;
52		s!#.*!!;
53		s!\s+! !g;
54		s! +$!!;
55		next if /^$/;
56
57		if(/TOC: (\d+) (.*)/){
58			$toc{$2} = $1;
59			next;
60		}
61
62		if(/sheet1: (left|right)$/){
63			print STDERR "assuming that sheet 1 is a $1 page.  double-check!\n";
64			$left = $1 eq "left" ? "13579" : "02468";
65			$right = $1 eq "left" ? "02468" : "13579";
66			next;
67		}
68
69		if(/even: (.*)/){
70			$file = $1;
71			if(!defined($toc{$file})){
72				print STDERR "Have no toc for $file\n";
73				next;
74			}
75			if($toc{$file} =~ /^\d\d[^0]/){
76				print STDERR "$file does not start on a fresh page.\n";
77			}
78			next;
79		}
80
81		if(/odd: (.*)/){
82			$file = $1;
83			if(!defined($toc{$file})){
84				print STDERR "Have no toc for $file\n";
85				next;
86			}
87			if($toc{$file} !~ /^\d\d5/){
88				print STDERR "$file does not start on a second half page.\n";
89			}
90			next;
91		}
92
93		if(/(left|right): (.*)/){
94			$what = $1;
95			$file = $2;
96			if(!defined($toc{$file})){
97				print STDERR "Have no toc for $file\n";
98				next;
99			}
100			if($what eq "left" && !($toc{$file} =~ /^\d[$left][05]/)){
101				print STDERR "$file does not start on a left page [$toc{$file}]\n";
102			}
103			# why does this not work if I inline $x in the if?
104			$x = ($toc{$file} =~ /^\d[$right][05]/);
105			if($what eq "right" && !$x){
106				print STDERR "$file does not start on a right page [$toc{$file}] [$x]\n";
107			}
108			next;
109		}
110
111		print STDERR "Unknown spec: $_\n";
112	}
113' fmt/tocdata runoff.spec
114
115# make definition list
116cd fmt
117perl -e '
118	while(<>) {
119		chomp;
120
121		s!//.*!!;
122		s!/\*([^*]|[*][^/])*\*/!!g;
123		s!\s! !g;
124		s! +$!!;
125
126		# look for declarations like char* x;
127		if (/^[0-9]+ typedef .* u(int|short|long|char);/) {
128			next;
129		}
130		if (/^[0-9]+ extern/) {
131			next;
132		}
133		if (/^[0-9]+ struct [a-zA-Z0-9_]+;/) {
134			next;
135		}
136		if (/^([0-9]+) #define +([A-za-z0-9_]+) +?\(.*/) {
137			print "$1 $2\n"
138		}
139		elsif (/^([0-9]+) #define +([A-Za-z0-9_]+) +([^ ]+)/) {
140			print "$1 $2 $3\n";
141		}
142		elsif (/^([0-9]+) #define +([A-Za-z0-9_]+)/) {
143			print "$1 $2\n";
144		}
145
146		if(/^^([0-9]+) \.globl ([a-zA-Z0-9_]+)/){
147			$isglobl{$2} = 1;
148		}
149		if(/^^([0-9]+) ([a-zA-Z0-9_]+):$/ && $isglobl{$2}){
150			print "$1 $2\n";
151		}
152
153		if (/\(/) {
154			next;
155		}
156
157		if (/^([0-9]+) (((static|struct|extern|union|enum) +)*([A-Za-z0-9_]+))( .*)? +([A-Za-z_][A-Za-z0-9_]*)(,|;|=| =)/) {
158			print "$1 $7\n";
159		}
160
161		elsif(/^([0-9]+) (enum|struct|union) +([A-Za-z0-9_]+) +{/){
162			print "$1 $3\n";
163		}
164		# TODO: enum members
165	}
166' $files >defs
167
168(for i in $files
169do
170	case "$i" in
171	*.S)
172		cat $i | sed 's;#.*;;; s;//.*;;;'
173		;;
174	*)
175		cat $i | sed 's;//.*;;; s;"([^"\\]|\\.)*";;;'
176	esac
177done
178) >alltext
179
180perl -n -e 'print if s/^([0-9]+ [a-zA-Z0-9_]+)\(.*$/\1/;' alltext |
181	egrep -v ' (STUB|usage|main|if|for)$' >>defs
182#perl -n -e 'print if s/^([0-9]+) STUB\(([a-zA-Z0-9_]+)\)$/\1 \2/;' alltext \
183#	>>defs
184(
185>s.defs
186
187# make reference list
188for i in `awk '{print $2}' defs | sort -f | uniq`
189do
190	defs=`egrep '^[0-9]+ '$i'( |$)' defs | awk '{print $1}'`
191	echo $i $defs >>s.defs
192	uses=`egrep -h '([^a-zA-Z_0-9])'$i'($|[^a-zA-Z_0-9])' alltext | awk '{print $1}'`
193	if [ "x$defs" != "x$uses" ]; then
194		echo $i $defs
195		echo $uses |fmt -29 | sed 's/^/    /'
196#	else
197#		echo $i defined but not used >&2
198	fi
199done
200) >refs
201
202# build defs list
203awk '
204{
205	printf("%04d %s\n", $2, $1);
206	for(i=3; i<=NF; i++)
207		printf("%04d    \" \n", $i);
208}
209' s.defs > t.defs
210
211# format the whole thing
212(
213	../pr.pl README
214	../pr.pl -h "table of contents" toc
215	# pr -t -2 t.defs | ../pr.pl -h "definitions" | pad
216	pr -t -l50 -2 refs | ../pr.pl -h "cross-references" | pad
217	# pr.pl -h "definitions" -2 t.defs | pad
218	# pr.pl -h "cross-references" -2 refs | pad
219	../pr.pl blank  # make sheet 1 start on left page
220	../pr.pl blank
221	for i in $files
222	do
223		../pr.pl -h "xv6/$i" $i
224	done
225) | mpage -m50t50b -o -bLetter -T -t -2 -FCourier -L60 >all.ps
226grep Pages: all.ps
227
228# if we have the nice font, use it
229nicefont=LucidaSans-Typewriter83
230if [ ! -f ../$nicefont ]
231then
232	if git cat-file blob font:$nicefont > ../$nicefont~; then
233		mv ../$nicefont~ ../$nicefont
234	fi
235fi
236if [ -f ../$nicefont ]
237then
238	echo nicefont
239	(sed 1q all.ps; cat ../$nicefont; sed "1d; s/Courier/$nicefont/" all.ps) >allf.ps
240else
241	echo ugly font!
242	cp all.ps allf.ps
243fi
244ps2pdf allf.ps ../xv6.pdf
245# cd ..
246# pdftops xv6.pdf xv6.ps
247