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