mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 04:27:37 +00:00
205 lines
6.1 KiB
Plaintext
205 lines
6.1 KiB
Plaintext
# @(#)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
|