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