goo blog サービス終了のお知らせ 

役立たずのプログラマーブログ

自分の得た知識や経験をブログに書くことで整理し、考えをまとめることが目標

TopCoderのローカルテスト用スクリプト for linux C++ その2

2008-01-17 12:30:06 | プログラム
TopCoderの問題を練習に使っているんだけど、ものすごく詰まったときに、
サーバー上でやってるとなんか色々とムズムズする。
なのでだいぶ前にローカルでmakeしてテストするためのファイルを一式作るスクリプトを書いた。
んが、非常に使いにくい。なので修正した。

注意としては、autoconfやらautomakeやらcppunitのdevelとかが要ります。
あとlinuxかつC++でないとダメ。

-- 使い方 ---
以下のスクリプトをコピーしてmaketest.shとでもして保存。
topcoderのローカルファイルがあるディレクトリ内で、

$./maketest.sh filename.cpp

としてやると、filenameというディレクトリを作り、色々とファイルを作って、
automakeやらやって、./configureとmakeまでやります。
filename_test.cppにテストケースを書きます。

$cd filename;./filename_test

でテスト開始。

今度は↓をコピペして動くことを確認済(以前のはしてなかった!)
#!/bin/sh

if [ ! -e "$1" ]
then
    echo "ファイル$1が存在しません"
    echo "存在するファイル名を指定してください"
    exit 1
fi

filename=`basename $1`
filename=${filename%.cpp}
tmpconfig=configure.tmp


if [ ! -d "$filename" ]
then
    echo "$filename ディレクトリ作成"
    mkdir $filename
fi

cd $filename
touch NEWS
touch README
touch COPYING
touch AUTHORS
touch INSTALL
touch ChangeLog

testcpp=${filename}"_test.cpp"
testhead=${filename}"_test.h"

if [ ! -e "$testcpp" ]
then
echo "#include \"$testhead\"" > $testcpp
echo "#include <sys/time.h>" >> $testcpp
echo "void ${filename}_test::test_ex0()" >> $testcpp
echo "{" >> $testcpp
echo "	struct timeval t1;" >> $testcpp
echo "	gettimeofday(&t1, NULL);" >> $testcpp
echo "	struct timeval t2;" >> $testcpp
echo "" >> $testcpp
echo "	${filename} M;" >> $testcpp
echo "	// implement from here" >> $testcpp
echo "" >> $testcpp
echo "	gettimeofday(&t2, NULL);" >> $testcpp
echo "	double diff =   t2.tv_sec + (double)t2.tv_usec*1e-6" >> $testcpp
echo "			- ( t1.tv_sec + (double)t1.tv_usec*1e-6 );" >> $testcpp
echo "	cout << \"time=\" << diff << endl;" >> $testcpp
echo "//	CPPUNIT_ASSERT_EQUAL(,);" >> $testcpp
echo "//	CPPUNIT_ASSERT_THROW( ?=?, type);" >> $testcpp
echo "}" >> $testcpp
echo "" >> $testcpp
echo "int main(int argc, char* argv[])" >> $testcpp
echo "{" >> $testcpp
echo "	CppUnit::TestSuite *suite = ${filename}_test::suite();" >> $testcpp
echo "	CppUnit::TextUi::TestRunner runner;" >> $testcpp
echo "	runner.addTest(suite);" >> $testcpp
echo "	bool retcode = runner.run();" >> $testcpp
echo "	return retcode;" >> $testcpp
echo "}">> $testcpp
fi

if [ ! -e "$testhead" ]
then
cat > $testhead <<EOF
#ifndef `echo $filename | tr 'a-z' 'A-Z'`_H
#define `echo $filename | tr 'a-z' 'A-Z'`_H

#include "../${filename}.cpp"

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/TestAssert.h>

/* テストクラスは TestCase を継承する。 */
class ${filename}_test:public CppUnit::TestFixture {
	CPPUNIT_TEST_SUITE( ${filename}_test );
	CPPUNIT_TEST( test_ex0 );
//	CPPUNIT_TEST( );
	CPPUNIT_TEST_SUITE_END();
public:
    ${filename}_test(){}
    /* テストは testXXX という名前にする。 */
    void test_ex0();
    void setUp(){}
    void tearDown(){}
};
#endif
EOF
fi

autoscan
if [ ! -e "configure.in" ]
then
    mv configure.scan configure.in
fi

#####################################
##  make.am
#####################################
cat > Makefile.am <<EOF
TESTS = ${filename}_test

INCLUDES = -I\$(top_srcdir) -I\$(includedir)
# bin_PROGRAMS = ${filename}_test
noinst_PROGRAMS = ${filename}_test

${filename}_test_SOURCES=\\
	${filename}_test.cpp\\
	${filename}_test.h
#	../${filename}.cpp\

${filename}_test_CPPFLAGS = -Wall -g
${filename}_test_LDFLAGS = -L\$(libdir) -g -Wall
${filename}_test_LDADD = -lcppunit -ldl
EOF

#####################################
##  add some line to Configure.in
#####################################
if grep "AM_INIT_AUTOMAKE" ./configure.in > /dev/null
then
    echo "既にconfigure.in書き換え済み"
else
    if [ -e $tmpconfig ] 
    then
	unlink $tmpconfig
    fi

    cat ./configure.in | 
    sed -e "s=\(AC_CONFIG_HEADER.*\)=\1\nAM_INIT_AUTOMAKE( ${filename}\.cpp, 0\.1 )\n=" |
    sed -e 's=\(AC_OUTPUT\)=AC_CONFIG_FILES([Makefile])\n\1=' > $tmpconfig

    mv $tmpconfig configure.in
fi

aclocal
autoheader
automake -a -c
autoconf
./configure
make clean all



大したことはしてないんだけども、なんか二時間ぐらいかかった。
手直ししたいところも有るけど、もうこれ以上は時間かけたくないので止め。

最新の画像もっと見る