gecko-dev/db/dist/man.error/run
1998-10-15 03:56:37 +00:00

205 lines
6.1 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# @(#)run 8.14 (Sleepycat) 11/6/97
# run --
# A mother of a shell script. It creates lists of functions which
# can cause the public functions to fail. It depends on the code
# using a Kernel Normal Form (KNF) coding style, but it shouldn't
# be horrible to adapt to other styles.
s=../../
TF="_1 _2 _3 _4 _5 _6 _7 _8 _9 _10 OK awk.out diff.out r_sub.1 r_sub.2"
trap "rm -f $TF INPUT; exit 1" 1 2 3 13 15
rm -f $TF INPUT
# Clean out the error file directory -- it must exist.
edir=../../man/man.error
[ ! -d $edir ] && {
echo "$edir: no such directory."
exit 1
}
rm -f $edir/*
# Clean out the debug directory if it exists.
dd=./dd
[ -d $dd ] && rm -f $dd/*
# Find all the function calls.
echo "find the function calls..."
>_1
for i in btree common db dbm hash hsearch lock log mp mutex os txn; do
cat $s/$i/*.c | sed -f func.sed >> _1
done
# Tokenize, converting all whitespace and ^A characters into single
# <newline> characters.
echo "tokenize..."
cat _1 | tr '[:space:]' '\n' | tr -s '\001' '\n' > _2
[ -d $dd ] && mv _1 $dd || rm -f _1
# Pull out all the tokens that interest us, i.e. the ones that have a ^B,
# and then delete that character.
echo "extract function names/calls..."
cat _2 | egrep '' | tr -d '\002' > _3
[ -d $dd ] && mv _2 $dd || rm -f _2
# Delete the strings that we know can't be function calls in any package.
# This has to happen before the next step so that we know that function
# calls immediately precede their respective @START lines.
echo "delete impossible function names/calls..."
cat _3 | sed -f delete.sed > _4
[ -d $dd ] && mv _3 $dd || rm -f _3
# It's easy to end up with STOP lines that don't have matching START lines,
# as it's not uncommon to find closing } characters on lines by themselves.
# Delete anything between a STOP and the line before the next START.
echo "delete singleton STOP lines..."
cat _4 | awk -f stop.awk > _5
[ -d $dd ] && mv _4 $dd || rm -f _4
# Make adjustments for special DB names.
echo "apply special DB corrections..."
cat _5 | sed -f db.sed > _6
[ -d $dd ] && mv _5 $dd || rm -f _5
# Indent the function calls inside of the function names, and delete the
# leading @ characters.
echo "indent function call lines..."
cat _6 | sed '/@START/,/@STOP/s/^/ !/' | tr -d '@' > _7
[ -d $dd ] && mv _6 $dd || rm -f _6
# Eliminate duplicate calls inside of each function.
echo "eliminate duplicate function calls..."
cat _7 | awk -f clean.awk > INPUT
[ -d $dd ] && mv _7 $dd || rm -f _7
# Build a set of sed commands that will do substitution on the names.
echo "build sed commands for substitution..."
cat INPUT | sed -n -f sub.sed | tr '' '\012' > r_sub.1
# Put a list of the public names into _8.
echo "extract public names..."
awk -f pub.awk < INPUT > _8
[ -d $dd ] && mv INPUT $dd
# Loop, substituting names until there are no more names to substitute.
#
# We can get into a place where we're just shuffling stuff and not making
# any forward progress -- you'll see the reference count climb and then
# drop, and eventually it's staying about the same over several iterations.
# That's what OK is for. Create the OK file and we break out of the loop
# and continue on.
echo "loop, substituting inside public names..."
echo "create file named \"OK\" to terminate loop."
cnt=0
while (true); do
cnt=`expr $cnt + 1`
printf "run #%02d... " $cnt
# Do a substitution pass, and then sort the names, eliminating
# any duplicates.
sed -f r_sub.1 < _8 | sed '/^$/d' | awk -f clean.awk > _9
# If you want to see what changed.
# diff _8 _9 > diff.out
# Print out a progress report.
a=`egrep __ _8 | wc -l`
b=`egrep __ _9 | wc -l`
printf "unexpanded calls: orig: %d new: %d\n" $a $b
# If no substitution was done, then we're finished. This never
# happens, at least in DB, because we have places where A calls
# B and B calls A, so we end up simply swapping call expansions
# forever. Once the reference counts aren't getting any further,
# create the file "OK" and the script will proceed.
if cmp _8 _9 > /dev/null; then
break;
fi
mv _9 _8
if [ -f OK ]; then
break;
fi
done
rm -f OK
# Check for stuff we missed...
#echo "Functions that were never resolved:"
#egrep __ _8
# At this point, we're simply swapping calls between routines that call each
# other and we're not making any forward progress. Strip out all of the DB
# internal routines from the replacement process and do a final replacement
# to finish up.
echo "final substitution pass for co-routines..."
sed -e '/^ /s/__.*\(.\)$/DISCARD\1/' < r_sub.1 > r_sub.2
sed -f r_sub.2 < _8 | sed -e '/DISCARD/d' -e '/^$/d' > _9
[ -d $dd ] && mv _8 $dd || rm -f _8
[ -d $dd ] && mv r_sub.1 $dd || rm -f r_sub.1
[ -d $dd ] && mv r_sub.2 $dd || rm -f r_sub.2
# Convert all of the entries into man page references.
echo "convert to man page references..."
sed -f conv.sed < _9 > _10
[ -d $dd ] && mv _9 $dd || rm -f _9
# Put each function's information into a separate file, which we include
# from the actual man page.
echo "create error return files..."
cat _10 | while read one rest; do
if [ "$one" = "FUNCTION" ]; then
file=`echo "$rest" | sed 's/.*->//'`
else
echo "$one $rest" >> "$edir/$file"
fi
done
[ -d $dd ] && mv _10 $dd || rm -f _10
# We translated all the special function names into xxxDB, convert them
# back to the correct name here.
echo "clean up DB names in error files..."
for i in $edir/*; do
sed -e 's/xxxDB/DB/g' < $i > _1
mv _1 $i
done
rm -f _1
# Create the C++ version of the file.
echo "create c++ error files..."
for i in $edir/*; do
sed -f cxx.sed < $i > $i.cxx
done
# Sort the names in each file, eliminating duplicates.
echo "sort and discard duplicates..."
for i in $edir/*; do
sort -u < $i > _1
mv _1 $i
done
rm -f _1
# Replace the last comma with a period. If it's more than a single entry,
# add an "and" before the last line.
echo "final cleanup of error files..."
for i in $edir/*; do
cnt=`wc -l $i | awk '{print $1}'`
if [ $cnt -gt 1 ] ; then
sed -e '1i\' -e '.na\' -e '.Nh' -e '$s/,/./' \
-e '$i\' -e 'and' -e '$a\' -e '.Hy\' -e '.ad' < $i > _1
else
sed -e '1i\' -e '.na\' -e '.Nh' -e '$s/,/./' \
-e '$a\' -e '.Hy\' -e '.ad' < $i > _1
fi
mv _1 $i
done
rm -f _1
# Set the permissions.
chmod 444 $edir/*
# Cleanup.
rm -f $TF INPUT
exit 0