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