Skip to content

Instantly share code, notes, and snippets.

@submachine
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save submachine/b42d16167271ec714935 to your computer and use it in GitHub Desktop.
Save submachine/b42d16167271ec714935 to your computer and use it in GitHub Desktop.
[committed] script to automatically modify as many glibc test cases as possible into using test-skeleton.c
#!/bin/bash
SRC_DIR=~/src/glibc/
pushd $SRC_DIR &> /dev/null \
|| { echo Unable to enter directory $SRC_DIR 1>&2; exit 1; }
let blkl=0
let good=0
let main=0
let spln=0
let incl=0
let sedf=0
let fixd=0
for f in $(find . -regex '.*t[e]?st-.*\.c'); do
# Ignore tests that are known to break upon making this change.
blacklist=()
blacklist+=("./stdlib/tst-bsearch.c") # 'struct entry' conflicts with search.h
blacklist+=("./elf/tst-initorder2.c") # conditionally compiled based on -DNAME
blacklist+=("./elf/tst-array4.c") # sets up .fini_array causing spurious output
# from the skeleton's parent process
blacklist+=("./libio/tst-fopenloc.c") # fails with skeleton due to fputws bug
blacklist+=("./nptl/tst-fini1.c") # defines a destructor that causes a SIGSEGV
# on the skeletons' parent process
blacklist+=("./sysdeps/pthread/tst-timer.c") # killed by skeleton's timeout
blacklist+=("./stdio-common/tst-fseek.c") # killed by skeleton's timeout
blacklist+=("./stdlib/gen-tst-strtod-round.c") # tst-strtod-round's generator
if grep -q $f <(echo "${blacklist[@]}"); then
echo BLKL: $f 1>&2
let blkl+=1
continue
fi
# Ignore tests that already use the skeleton:
if grep -q 'include.*test-skeleton\.c' $f; then
echo GOOD: $f
let good+=1
continue
fi
# Report tests that do not have a 'main' function as broken;
# we cannot generate code to fix them:
if ! grep -Pzq 'int\s+main\s*\(\s*void\s*\)\s*{' $f; then
echo MAIN: $f 1>&2
let main+=1
continue
fi
# Now that we have a sane test that does not use the skeleton,
# we want to do three things:
#
# 1. Change 'int main (void)' to 'static int do_test (void)';
# 2. Define 'TEST_FUNCTION' as 'do_test ()';
# 3. Include test-skeleton.c.
#
# But first, we want to make sure of a few more things:
special_names=()
# The test file doesn't already use names we will add to it:
special_names+=("do_test" "TEST_FUNCTION" "PREPARE")
# The test doesn't do special things that might interfere with
# the set-up done by the skeleton, causing spurious PASS in future:
special_names+=("kill\s*\(" "signal\s*\(" "sigaction\s*\(" "mallopt\s*\(" \
"setbuf\s*\(" "setvbuf\s*\(" "atexit\s*\(" "fork\s*\(" "setrlimit\s*\(" \
"alarm\s*\(")
for n in ${special_names[@]}; do
if grep -Pzq "$n" $f; then
echo SPLN: "($n)" $f 1>&2
let spln+=1
continue 2
fi
done
# The test file isn't being #include'ed in another test:
if grep -qrI "#\s*include.*$(basename $f)" $(dirname $f); then
echo INCL: $f 1>&2
let incl+=1
continue
fi
# Finally, we can try and apply the fix:
sed -i '/int/{$!{N;s/int[\s\n]\+main\s*(\s*void\s*)/static int\ndo_test (void)/;ty;P;D;:y}}' $f
# HINT: sed magic comes from here: http://unix.stackexchange.com/a/26290
# If unfortunately, sed does not succeed, we report it and move on:
if ! grep -Pzq 'static\sint\sdo_test\s\(void\)' $f; then
echo SEDF: $f 1>&2
let sedf+=1
continue
fi
# We want './sysdeps/x86_64/tst-audit10.c' to include '../../test-skeleton.c':
prefix=$(echo $f | sed 's|^./||' | sed 's|[^/]||g' | sed 's|/|../|g')
echo -e "\n#define TEST_FUNCTION do_test ()\n#include \"${prefix}test-skeleton.c\"" >> $f
echo FIXD: $f
let fixd+=1
done
echo Total BLKL: $blkl 1>&2
echo Total GOOD: $good
echo Total MAIN: $main 1>&2
echo Total SPLN: $spln 1>&2
echo Total INCL: $incl 1>&2
echo Total SEDF: $sedf 1>&2
echo Total FIXD: $fixd
echo '---------- ---'
echo Total TEST: $((blkl+good+main+spln+incl+sedf+fixd))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment