220 lines
4.5 KiB
Bash
Executable file
220 lines
4.5 KiB
Bash
Executable file
#!/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
|
|
getline<f
|
|
close(f)
|
|
n=$1
|
|
printf("%02d %s\n", n/100, s);
|
|
next
|
|
}
|
|
{
|
|
print
|
|
}' >fmt/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
|