2006-09-05 17:50:55 +02:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
echo This script takes a minute to run. Be patient. 1>&2
|
|
|
|
|
2007-08-08 11:29:18 +02:00
|
|
|
LC_CTYPE=C export LC_CTYPE
|
|
|
|
|
2006-09-05 17:50:55 +02:00
|
|
|
# pad stdin to multiple of 120 lines
|
|
|
|
pad()
|
|
|
|
{
|
|
|
|
awk '{print} END{for(; NR%120!=0; NR++) print ""}'
|
|
|
|
}
|
|
|
|
|
|
|
|
# create formatted (numbered) files
|
|
|
|
mkdir -p fmt
|
2006-09-08 16:40:59 +02:00
|
|
|
rm -f fmt/*
|
2006-09-05 17:50:55 +02:00
|
|
|
cp README fmt
|
|
|
|
files=`grep -v '^#' runoff.list | awk '{print $1}'`
|
|
|
|
n=99
|
|
|
|
for i in $files
|
|
|
|
do
|
2007-08-24 16:56:17 +02:00
|
|
|
./runoff1 -n $n $i >fmt/$i
|
2006-09-07 15:07:29 +02:00
|
|
|
nn=`tail -1 fmt/$i | sed 's/ .*//; s/^0*//'`
|
|
|
|
if [ "x$nn" != x ]; then
|
|
|
|
n=$nn
|
|
|
|
fi
|
2006-09-05 17:50:55 +02:00
|
|
|
done
|
|
|
|
|
|
|
|
# create table of contents
|
2006-09-08 15:53:18 +02:00
|
|
|
cat toc.hdr >fmt/toc
|
2006-09-05 17:50:55 +02:00
|
|
|
pr -e8 -t runoff.list | awk '
|
2006-09-08 15:53:18 +02:00
|
|
|
/^[a-z0-9]/ {
|
2006-09-05 17:50:55 +02:00
|
|
|
s=$0
|
|
|
|
f="fmt/"$1
|
|
|
|
getline<f
|
|
|
|
close(f)
|
|
|
|
n=$1
|
|
|
|
printf("%02d %s\n", n/100, s);
|
2007-08-14 20:42:34 +02:00
|
|
|
printf("TOC: %04d %s\n", n, s) >"fmt/tocdata"
|
2006-09-05 17:50:55 +02:00
|
|
|
next
|
|
|
|
}
|
|
|
|
{
|
|
|
|
print
|
2006-09-08 15:53:18 +02:00
|
|
|
}' | pr -3 -t >>fmt/toc
|
|
|
|
cat toc.ftr >>fmt/toc
|
2006-09-05 17:50:55 +02:00
|
|
|
|
2007-08-14 20:42:34 +02:00
|
|
|
# check for bad alignments
|
|
|
|
perl -e '
|
2009-08-08 10:07:30 +02:00
|
|
|
$leftwarn = 0;
|
2007-08-14 20:42:34 +02:00
|
|
|
while(<>){
|
|
|
|
chomp;
|
|
|
|
s!#.*!!;
|
|
|
|
s!\s+! !g;
|
|
|
|
s! +$!!;
|
|
|
|
next if /^$/;
|
|
|
|
|
|
|
|
if(/TOC: (\d+) (.*)/){
|
|
|
|
$toc{$2} = $1;
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(/even: (.*)/){
|
|
|
|
$file = $1;
|
|
|
|
if(!defined($toc{$file})){
|
|
|
|
print STDERR "Have no toc for $file\n";
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
if($toc{$file} =~ /^\d\d[^0]/){
|
|
|
|
print STDERR "$file does not start on a fresh page.\n";
|
|
|
|
}
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(/odd: (.*)/){
|
|
|
|
$file = $1;
|
|
|
|
if(!defined($toc{$file})){
|
|
|
|
print STDERR "Have no toc for $file\n";
|
|
|
|
next;
|
|
|
|
}
|
2009-08-08 10:07:30 +02:00
|
|
|
if($toc{$file} !~ /^\d\d5/){
|
2007-08-14 20:42:34 +02:00
|
|
|
print STDERR "$file does not start on a second half page.\n";
|
|
|
|
}
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
|
2009-08-08 10:07:30 +02:00
|
|
|
if(/(left|right): (.*)/){
|
|
|
|
$what = $1;
|
|
|
|
$file = $2;
|
|
|
|
if(!defined($toc{$file})){
|
|
|
|
print STDERR "Have no toc for $file\n";
|
|
|
|
next;
|
|
|
|
}
|
2010-08-31 23:33:04 +02:00
|
|
|
# this assumes that sheet 1 of code is a right page
|
|
|
|
# double-check the PDF. swap the two regexps below
|
|
|
|
# otherwise.
|
2009-08-08 10:07:30 +02:00
|
|
|
if(!$leftwarn++) {
|
2010-08-31 23:33:04 +02:00
|
|
|
print STDERR "assuming that sheet 1 is a right page. double-check!\n";
|
2009-08-08 10:07:30 +02:00
|
|
|
}
|
2010-08-31 23:33:04 +02:00
|
|
|
if($what eq "left" && !($toc{$file} =~ /^\d[02468]0/)){
|
2009-08-08 10:07:30 +02:00
|
|
|
print STDERR "$file does not start on a fresh left page [$toc{$file}]\n";
|
|
|
|
}
|
|
|
|
# why does this not work if I inline $x in the if?
|
2010-08-31 23:33:04 +02:00
|
|
|
$x = ($toc{$file} =~ /^\d[13579]0/);
|
2009-08-08 10:07:30 +02:00
|
|
|
if($what eq "right" && !$x){
|
|
|
|
print STDERR "$file does not start on a fresh right page [$toc{$file}] [$x]\n";
|
|
|
|
}
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
|
2007-08-14 20:42:34 +02:00
|
|
|
print STDERR "Unknown spec: $_\n";
|
|
|
|
}
|
|
|
|
' fmt/tocdata runoff.spec
|
|
|
|
|
2006-09-05 17:50:55 +02:00
|
|
|
# make definition list
|
|
|
|
cd fmt
|
2006-09-06 21:43:59 +02:00
|
|
|
perl -e '
|
|
|
|
while(<>) {
|
|
|
|
chomp;
|
|
|
|
|
|
|
|
s!//.*!!;
|
|
|
|
s!/\*([^*]|[*][^/])*\*/!!g;
|
|
|
|
s!\s! !g;
|
|
|
|
s! +$!!;
|
|
|
|
|
|
|
|
# look for declarations like char* x;
|
|
|
|
if (/^[0-9]+ typedef .* u(int|short|long|char);/) {
|
|
|
|
next;
|
2006-09-05 17:50:55 +02:00
|
|
|
}
|
2006-09-06 21:43:59 +02:00
|
|
|
if (/^[0-9]+ extern/) {
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
if (/^[0-9]+ struct [a-zA-Z0-9_]+;/) {
|
|
|
|
next;
|
|
|
|
}
|
2007-08-08 11:29:18 +02:00
|
|
|
if (/^([0-9]+) #define +([A-za-z0-9_]+) +?\(.*/) {
|
2006-09-06 21:43:59 +02:00
|
|
|
print "$1 $2\n"
|
|
|
|
}
|
2007-08-08 11:29:18 +02:00
|
|
|
elsif (/^([0-9]+) #define +([A-Za-z0-9_]+) +([^ ]+)/) {
|
2006-09-06 21:43:59 +02:00
|
|
|
print "$1 $2 $3\n";
|
|
|
|
}
|
|
|
|
elsif (/^([0-9]+) #define +([A-Za-z0-9_]+)/) {
|
|
|
|
print "$1 $2\n";
|
|
|
|
}
|
|
|
|
|
2007-08-28 21:25:04 +02:00
|
|
|
if(/^^([0-9]+) \.globl ([a-zA-Z0-9_]+)/){
|
|
|
|
$isglobl{$2} = 1;
|
|
|
|
}
|
|
|
|
if(/^^([0-9]+) ([a-zA-Z0-9_]+):$/ && $isglobl{$2}){
|
|
|
|
print "$1 $2\n";
|
|
|
|
}
|
|
|
|
|
2007-08-08 11:29:18 +02:00
|
|
|
if (/\(/) {
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
|
2008-10-12 20:45:30 +02:00
|
|
|
if (/^([0-9]+) (((static|struct|extern|union|enum) +)*([A-Za-z0-9_]+))( .*)? +([A-Za-z_][A-Za-z0-9_]*)(,|;|=| =)/) {
|
|
|
|
print "$1 $7\n";
|
2007-08-08 11:29:18 +02:00
|
|
|
}
|
|
|
|
|
2006-09-06 21:43:59 +02:00
|
|
|
elsif(/^([0-9]+) (enum|struct|union) +([A-Za-z0-9_]+) +{/){
|
|
|
|
print "$1 $3\n";
|
|
|
|
}
|
|
|
|
# TODO: enum members
|
2006-09-05 17:50:55 +02:00
|
|
|
}
|
|
|
|
' $files >defs
|
2006-09-06 21:22:24 +02:00
|
|
|
|
2007-08-28 20:23:48 +02:00
|
|
|
(for i in $files
|
|
|
|
do
|
|
|
|
case "$i" in
|
|
|
|
*.S)
|
|
|
|
cat $i | sed 's;#.*;;; s;//.*;;;'
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
cat $i | sed 's;//.*;;; s;"([^"\\]|\\.)*";;;'
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
) >alltext
|
|
|
|
|
|
|
|
perl -n -e 'print if s/^([0-9]+ [a-zA-Z0-9_]+)\(.*$/\1/;' alltext |
|
2008-10-12 21:54:11 +02:00
|
|
|
egrep -v ' (STUB|usage|main|if|for)$' >>defs
|
|
|
|
#perl -n -e 'print if s/^([0-9]+) STUB\(([a-zA-Z0-9_]+)\)$/\1 \2/;' alltext \
|
|
|
|
# >>defs
|
2006-09-05 17:50:55 +02:00
|
|
|
(
|
|
|
|
>s.defs
|
|
|
|
|
|
|
|
# make reference list
|
2008-10-12 20:33:14 +02:00
|
|
|
for i in `awk '{print $2}' defs | sort -f | uniq`
|
2006-09-05 17:50:55 +02:00
|
|
|
do
|
|
|
|
defs=`egrep '^[0-9]+ '$i'( |$)' defs | awk '{print $1}'`
|
|
|
|
echo $i $defs >>s.defs
|
2007-08-28 20:23:48 +02:00
|
|
|
uses=`egrep -h '([^a-zA-Z_0-9])'$i'($|[^a-zA-Z_0-9])' alltext | awk '{print $1}'`
|
|
|
|
if [ "x$defs" != "x$uses" ]; then
|
|
|
|
echo $i $defs
|
|
|
|
echo $uses |fmt -24 | sed 's/^/ /'
|
|
|
|
fi
|
2006-09-05 17:50:55 +02:00
|
|
|
done
|
|
|
|
) >refs
|
|
|
|
|
|
|
|
# build defs list
|
|
|
|
awk '
|
|
|
|
{
|
|
|
|
printf("%04d %s\n", $2, $1);
|
|
|
|
for(i=3; i<=NF; i++)
|
|
|
|
printf("%04d \" \n", $i);
|
|
|
|
}
|
|
|
|
' s.defs > t.defs
|
|
|
|
|
|
|
|
# format the whole thing
|
|
|
|
(
|
2006-09-08 15:53:18 +02:00
|
|
|
../pr.pl README
|
|
|
|
../pr.pl -h "table of contents" toc
|
|
|
|
# pr -t -2 t.defs | ../pr.pl -h "definitions" | pad
|
|
|
|
pr -t -l50 -2 refs | ../pr.pl -h "cross-references" | pad
|
|
|
|
# pr.pl -h "definitions" -2 t.defs | pad
|
|
|
|
# pr.pl -h "cross-references" -2 refs | pad
|
2006-09-06 21:43:59 +02:00
|
|
|
for i in $files
|
|
|
|
do
|
2006-09-08 15:53:18 +02:00
|
|
|
../pr.pl -h "xv6/$i" $i
|
2006-09-06 21:43:59 +02:00
|
|
|
done
|
|
|
|
) | mpage -m50t50b -o -bLetter -T -t -2 -FCourier -L60 >all.ps
|
2006-09-05 17:50:55 +02:00
|
|
|
grep Pages: all.ps
|
|
|
|
|
|
|
|
# if we have the nice font, use it
|
2008-08-20 20:00:24 +02:00
|
|
|
nicefont=../LucidaSans-Typewriter83
|
2006-09-05 17:50:55 +02:00
|
|
|
if [ -f $nicefont ]
|
|
|
|
then
|
2008-08-20 20:00:24 +02:00
|
|
|
echo nicefont
|
2006-09-05 17:50:55 +02:00
|
|
|
(sed 1q all.ps; cat $nicefont; sed '1d; s/Courier/LucidaSans-Typewriter83/' all.ps) >allf.ps
|
|
|
|
else
|
2008-08-20 20:00:24 +02:00
|
|
|
echo ugly font!
|
2006-09-05 17:50:55 +02:00
|
|
|
cp all.ps allf.ps
|
|
|
|
fi
|
|
|
|
ps2pdf allf.ps ../xv6.pdf
|
2007-08-30 16:12:19 +02:00
|
|
|
cd ..
|
|
|
|
pdftops xv6.pdf xv6.ps
|