#!/bin/sh echo This script takes a minute to run. Be patient. 1>&2 # pad stdin to multiple of 120 lines pad() { awk '{print} END{for(; NR%120!=0; NR++) print ""}' } # create formatted (numbered) files mkdir -p fmt rm fmt/* cp README fmt files=`grep -v '^#' runoff.list | awk '{print $1}'` n=99 for i in $files do perl -e '$n='$n';' -e ' $n = int(($n+49)/50)*50 - 1; @lines = <>; foreach (@lines) { chomp; s/\s+$//; if(length() >= 75){ print "$ARGV[0]:$.: line too long"; } } @outlines = (); $nextout = 0; for($i=0; $i<@lines; ){ # Skip leading blank lines. $i++ while $i<@lines && $lines[$i] =~ /^$/; last if $i>=@lines; # If the rest of the file fits, use the whole thing. if(@lines <= $i+50){ $breakbefore = @lines; }else{ # Find a good next page break; # Hope for end of function. # but settle for a blank line (but not first blank line # in function, which comes after variable declarations). $breakbefore = $i; $lastblank = $i; $sawbrace = 0; $breaksize = 15; # 15 lines to get to function for($j=$i; $j<$i+50 && $j < @lines; $j++){ if($lines[$j] =~ /PAGEBREAK:\s*([0-9]+)/){ $breaksize = int($2); $breakbefore = $j; $lines[$j] = ""; } if($lines[$j] =~ /^}$/){ $breakbefore = $j+1; } if($lines[$j] =~ /^{$/){ $sawbrace = 1; } if($lines[$j] =~ /^$/){ if($sawbrace){ $sawbrace = 0; }else{ $lastblank = $j; } } } if($j<@lines && $lines[$j] =~ /^$/){ $lastblank = $j; } # If we are not putting enough on a page, try a blank line. if($breakbefore - $i < 50 - $breaksize && $lastblank > $breakbefore && $lastblank >= $i+50 - 5){ $breakbefore = $lastblank; $breaksize = 5; # only 5 lines to get to blank line } # If we are not putting enough on a page, force a full page. if($breakbefore - $i < 50 - $breaksize && $breakbefore != @lines){ $breakbefore = $i + 50; $breakbefore = @lines if @lines < $breakbefore; } if($breakbefore < $i+2){ $breakbefore = $i+2; } } # Emit the page. $i50 = $i + 50; for(; $i<$breakbefore; $i++){ printf "%04d %s\n", ++$n, $lines[$i]; } # Finish page for($j=$i; $j<$i50; $j++){ printf "%04d \n", ++$n; } } ' $i >fmt/$i nn=`tail -1 fmt/$i | sed 's/ .*//; s/^0*//'` if [ "x$nn" != x ]; then n=$nn fi done # create table of contents pr -e8 -t runoff.list | awk ' /^[a-z]/ { s=$0 f="fmt/"$1 getlinefmt/toc # make definition list cd fmt 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; } if (/^[0-9]+ extern/) { next; } if (/^[0-9]+ struct [a-zA-Z0-9_]+;/) { next; } if (/\(/) { next; } if (/^([0-9]+) (((static|struct|extern|union|enum) +)*([A-Za-z0-9_]+))( .*)? +([A-Za-z_][A-Za-z0-9_]*)[,;]/) { print "$1 $7\n" } elsif (/^([0-9]+) #define +([A-za-z0-9_]+) +?\(.*/) { print "$1 $2\n" } elsif (/^([0-9]+) #define +([A-Za-z0-9_]+) +([^ ]+)$/) { print "$1 $2 $3\n"; } elsif (/^([0-9]+) #define +([A-Za-z0-9_]+)/) { print "$1 $2\n"; } elsif(/^([0-9]+) (enum|struct|union) +([A-Za-z0-9_]+) +{/){ print "$1 $3\n"; } # TODO: enum members } ' $files >defs perl -n -e 'print if s/^([0-9]+ [a-zA-Z0-9_]+)\(.*$/\1/;' $files | egrep -v ' (usage|main|if|for)$' >>defs ( >s.defs # make reference list for i in `awk '{print $2}' defs | sort -fu` do defs=`egrep '^[0-9]+ '$i'( |$)' defs | awk '{print $1}'` echo $i $defs >>s.defs uses=`egrep -h '([^a-zA-Z_0-9])'$i'($|[^a-zA-Z_0-9])' $files | awk '{print $1}'` echo $i $defs echo $uses |fmt -24 | sed 's/^/ /' 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 ( pr -l60 -e8 README pr -l60 -h "table of contents" -e8 -2 toc pr -l60 -h "definitions" -2 t.defs | pad pr -l60 -h "cross-references" -2 refs | pad for i in $files do cat $i | pr -l60 -e8 -h "xv6/$i" done ) | mpage -m50t50b -o -bLetter -T -t -2 -FCourier -L60 >all.ps grep Pages: all.ps # if we have the nice font, use it nicefont=~rsc/plan9/sys/lib/postscript/font/LucidaSans-Typewriter83 if [ -f $nicefont ] then (sed 1q all.ps; cat $nicefont; sed '1d; s/Courier/LucidaSans-Typewriter83/' all.ps) >allf.ps else cp all.ps allf.ps fi ps2pdf allf.ps ../xv6.pdf