summaryrefslogtreecommitdiff
path: root/libstdc++-v3/mkcheck.in
blob: 310e627d3f56270543bfdc7b699ff55f487c3eea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
#!/usr/bin/env bash

# 2000-05-17 bkoz 

# Script to do automated testing and data collection
# for various test files, so that we don't have to do this by hand on
# every test file.  It attempts to collect some diagnostic info about
# size and speed that should be useful in the future as the library
# gets tuned for size and speed. In addition, it tests static and
# shared linkage.

# Invocation 
# mkcheck [01] (path to build) (path to src) (path to install)

if [ $# != 3 ] && [ $# != 4 ]; then
    echo 'Usage: mkcheck 0 (path to build) (path to src)'
    echo '       mkcheck 1 (path to build) (path to src) (path to install)'
    exit 1
fi
echo "running mkcheck"

#
# 1: variables
#
# WHICH determines if you are testing the installed binary and headers, or
# the build binary and headers.
WHICH=$1
if [ $WHICH != "1" ]; then
  WHICH=0
  echo "$0: testing the build directory"
elif [ $WHICH -eq 1 ]; then
  echo "$0: testing the install directory $1"
fi

BUILD_DIR=$2
if [ ! -d "$BUILD_DIR" ]; then
  echo "build directory $BUILD_DIR not found, exiting."
  exit 1
fi

SRC_DIR=$3
if [ ! -d "$SRC_DIR" ]; then
  echo "source directory $SRC_DIR not found, exiting."
  exit 1
fi

if [ $WHICH -eq 1 ]; then 
    PREFIX_DIR=$4
    if [ ! -d "$PREFIX_DIR" ]; then
    echo "install directory $PREFIX_DIR not found, exiting."
    exit 1
    fi
fi

# INC_PATH == include path to new headers for use on gcc command-line
if [ $WHICH != "1" ]; then
  INC_PATH="-I$BUILD_DIR -I$BUILD_DIR/libio -I$SRC_DIR/@ctype_include_dir@ -I$SRC_DIR/@cpu_include_dir@  -I$SRC_DIR/std -I$SRC_DIR -I$SRC_DIR/libio"
elif [ $WHICH -eq 1 ]; then
  INC_PATH=""
fi

#LIB_PATH == where to find the build library binaries.
if [ $WHICH != "1" ]; then
  LIB_PATH="-L$BUILD_DIR/src/.libs"
  CXX="../../gcc/g++ -B../../gcc/"
elif [ $WHICH -eq 1 ]; then
  LIB_PATH="-L$PREFIX_DIR/lib"
  CXX="$PREFIX_DIR/bin/g++"
fi

# gcc compiler flags
#CXX_FLAG="-fsquangle -fhonor-std -fnew-exceptions -g -O2 -DDEBUG_ASSERT "
#CXX_FLAG="-g -O2 -DDEBUG_ASSERT "
CXX_FLAG="-g -DDEBUG_ASSERT "

# a specific flag to force the use of shared libraries, if any
SH_FLAG=""

# a specific flag to force the use of static libraries, if any
ST_FLAG="-static"

# Set up the testing directory, which should be in a directory called
# "testsuite" in the root level of the build directory.
TEST_DIR="`pwd`/testsuite"
if [ ! -d "$TEST_DIR" ]; then
    echo "making directory $TEST_DIR"
    mkdir $TEST_DIR
    chmod 777 $TEST_DIR
fi

# the name of the file that will collect and hold all this useful data:
RESULTS_FILE="$TEST_DIR/$(date +%Y%m%d)-mkcheck.txt"

# the name of the log file that will append compiler diagnostics:
LOG_FILE="$TEST_DIR/$(date +%Y%m%d)-mkchecklog.txt"

# the names of the specific test files to be run
TESTS_FILE="$TEST_DIR/$(date +%Y%m%d)-mkcheckfiles.txt"


#
# 2: clean, make files, append general test info
#
if [ -f $RESULTS_FILE ]; then
    rm $RESULTS_FILE
fi
if [ -f $LOG_FILE ]; then
    rm $LOG_FILE
fi

# Make a list of the files we're going to run, or use an old one if it exists.
if [ ! -f "$TESTS_FILE" ]; then
    echo "making file $TESTS_FILE"
    for LONG_NAME in $SRC_DIR/testsuite/*/*.cc
    do
	DIR_NAME=$(dirname $LONG_NAME)
	SHORT_NAME="`basename $DIR_NAME`/`basename $LONG_NAME`"
	echo "$SHORT_NAME" >> $TESTS_FILE
    done
fi

# Nasty solution to replace GNU date(1)'s %s time_t output function.
if [ ! -x "$TEST_DIR/printnow" ]; then
    echo "making utility $TEST_DIR/printnow"
    gcc -o "$TEST_DIR/printnow" "$SRC_DIR/testsuite/printnow.c"
    strip "$TEST_DIR/printnow"
fi

# Remove old executables.
rm -rf "$TEST_DIR"/*exe

# Remove old core files (which now get left in cwd, not $TEST_DIR).
rm -rf ./*core

# Copy over the data files for filebufs in read-only mode
cp $SRC_DIR/testsuite/27_io/*.txt $TEST_DIR
cp $SRC_DIR/testsuite/27_io/*.tst $TEST_DIR

# Emit useful info about compiler and platform
echo "host: $(uname -mrsv)" >> $RESULTS_FILE
echo "compiler: $($CXX --version)" >> $RESULTS_FILE
echo "compiler flags: $CXX_FLAG" >> $RESULTS_FILE
echo "date: $(date +%Y%m%d)" >> $RESULTS_FILE
echo "" >> $RESULTS_FILE

echo "p == pass/fail execution test" >> $RESULTS_FILE
echo "ctime == time to compile and link" >> $RESULTS_FILE
echo "etime == time for executable to run" >> $RESULTS_FILE
echo "text == size of the executable text section" >> $RESULTS_FILE
echo "data == size of the executable data section" >> $RESULTS_FILE
echo "total == size of the executable" >> $RESULTS_FILE
echo "(First static, then shared.)" >> $RESULTS_FILE
echo "" >> $RESULTS_FILE

echo "p" | awk '{printf("%s ", $1)}' >> $RESULTS_FILE
echo "ctime" "etime" | awk '{printf("%s\t%s\t", $1, $2)}' >> $RESULTS_FILE
echo "text" "data" | awk '{printf("%s\t%s\t", $1, $2)}' >> $RESULTS_FILE
echo "total" "name" | awk '{printf("%s\t%s\t", $1, $2)}' >> $RESULTS_FILE
echo "" >> $RESULTS_FILE
    

#
# 3: compile, link, execute, time
#
# Abstract out the common code for compiling, linking, executing and printing.
test_file()
{
    # NB: S_FLAG has to be last argument because it may be null, and
    # error checking hasn't been invented yet.
    FILENAME=$1
    EXENAME=$2
    S_FLAG=$3

    # This would be deliciously easy if GNU date's %s were always around.
    # There are three ways to do this:  1) use the builtin 'time' like we
    # do later; then getting compiler errors into LOG_FILE is a nightmare.
    # 2) Grab the output of a formatted date(1) and do the math; harder
    # and harder as we try compiling at, say, top of the hour; we would
    # eventually have to calculate time_t anyhow.  Or 3) just grab two
    # time_t's (no more overhead than grabbing two date(1)'s).
    COMP_TIME_START=$($TEST_DIR/printnow)
    $CXX $CXX_FLAG $S_FLAG $INC_PATH $LIB_PATH $FILENAME \
	 -o $EXENAME 2>> $LOG_FILE
    COMP_TIME_END=$($TEST_DIR/printnow)

    if [ $COMP_TIME_START -lt $COMP_TIME_END ]; then
	C_TIME=$[ $COMP_TIME_END - $COMP_TIME_START ]
    else
	C_TIME="0"
    fi

    if [ -f $EXENAME ]; then
        case @host_os@ in
          *solaris2.8*)
            # These numbers seem to match up to text/data/total,
            # although their meanings seem to be different.  Very
            # important to not compare these numbers across platforms.
            ## Get rid of the banner information.  I don't recall this
            ## happening under previous Solarises.  Maybe it's an 8 thing.
            TEXT="$(size $EXENAME | grep $EXENAME | awk '{print $1}')"
            DATA="$(size $EXENAME | grep $EXENAME | awk '{print $3}')"
            SIZE="$(size $EXENAME | grep $EXENAME | awk '{print $7}')"
            ;;
          *solaris*)
            # These numbers seem to match up to text/data/total,
            # although their meanings seem to be different.  Very
            # important to not compare these numbers across platforms.
            TEXT="$(size $EXENAME | awk '{print $1}')"
            DATA="$(size $EXENAME | awk '{print $3}')"
            SIZE="$(size $EXENAME | awk '{print $7}')"
            ;;
          *)
            TEXT="$(size -A $EXENAME | grep text | awk '{print $2}')"
            DATA="$(size -A $EXENAME | grep data | awk '{print $2}')"
            SIZE="$(size -A $EXENAME | grep otal | awk '{print $2}')"
            ;;
        esac

        # Actually run the executable and time it . . .
        TIMEFORMAT='timemark %R'
        E_TIME_TEXT="$(exec 2>&1; time $EXENAME)"
	E_ABNORMAL_TERMINATION=$?
        E_TIME="$(echo $E_TIME_TEXT | awk '{print $2}')"
        # joining those two commands does not work due to quoting problems:
        #E_TIME="$(exec 2>&1; time $EXENAME | awk '{print $2}')"
        # this will work as a fallback on certain systems...?
        #E_TIME=$(exec 2>&1; time $EXENAME | cut -d ' ' -f 2)
 
       if [ "$E_ABNORMAL_TERMINATION" -ne 0 ]; then
            RESULT='-'
	    rm -f ./*core
	    # sometimes you want to save all core files for review:
	    #mv ./core $EXENAME.core
	    # sometimes the OS names core files as programname.core:
	    #mv ./*core $EXENAME.core
	else
	    # XXX this should probably be a function? 

	    # This checks for emitted output files, which is useful
	    # when testing file-related output. The rules for this
	    # working are as follows: the emitted file must have the
	    # ".txt" extension, and be based on the actual *.cc file's
	    # name. For example, 27/filbuf.cc currently outputs files
	    # named 27/filebuf-2.txt and 27/filebuf-3.txt. Also, the first
	    # emitted file must be in the form $NAME-1.txt. The
	    # control file must follow the same constraints, but have
	    # a ".tst" extension. Thus, you have 27/filebuf-2.tst, etc
	    # etc.

	    # NAME contains the source name, like 27/filebuf.cc
	    # From that NAME, we want to generate some possible names, using
	    # ls on MATCH, a pattern description generated with sed.

	    # this is the name of the resulting diff file, if any
	    DIFF_FILE="`echo $PRE_NAME | sed 's/cc$/diff/'`"
	    # construct wildcard names,ie for $NAME=filebuf.cc, makes
	    # "filebuf*.tst"
	    DATA_FILES="`echo $NAME | sed 's/\.cc/\*\.tst/g'`"
	    # make sure there is at least one, then go
	    ST_E="`echo $NAME | sed 's/\.cc/\-1\.tst/g'`"
	    if [ -f $ST_E ]; then
		# list of actual files that match the wildcard above, ie
		# "filebuf-1.tst"
		ST_MATCH_LIST="`ls $DATA_FILES`"
		for i in $ST_MATCH_LIST
		    do
			# ST_OUT_FILE is generated in the build directory.
			PRE_NAME2="$TEST_DIR/`basename $i`"
			ST_OUT_FILE="`echo $PRE_NAME2 | sed 's/tst$/txt/'`"
			diff $ST_OUT_FILE $i > $DIFF_FILE
			if [ -s $DIFF_FILE ]; then
			    RESULT="-"
			    echo "$ST_OUT_FILE has some problems, dude"
			else
			    RESULT="+"
			fi
			rm $DIFF_FILE
		    done
		else
		    # the file does no output, and didn't abnormally
		    # terminate, so assume passed.
		    RESULT="+"
		fi
	    fi
	rm "$EXENAME"
	# sometimes you want to save all failing exe files for review:
	#if [ "$RESULT" = "+" ]; then
	#    rm "$EXENAME"
	#fi
    else
        # the file did not compile. Write out compilation info to the log file.
	echo "$CXX $CXX_FLAG $ST_FLAG $INC_PATH $LIB_PATH $CNAME -o $EXENAME" \
        2>> $LOG_FILE

	RESULT="-"
	TEXT="0"
	DATA="0"
	SIZE="0"
    fi

    echo $RESULT | awk '{printf("%s\t", $1)}'
    echo $RESULT | awk '{printf ("%.1s ", $1)}'>>$RESULTS_FILE
    echo $C_TIME $E_TIME |awk '{printf("%d\t%.3f\t", $1, $2)}'>>$RESULTS_FILE
    echo $TEXT $DATA | awk '{printf("%s\t%s\t", $1, $2)}'>>$RESULTS_FILE
    echo $SIZE | awk '{printf("%s\t", $1)}'>>$RESULTS_FILE
    echo $NAME | awk '{printf("%s\n", $1)}'>>$RESULTS_FILE
};    

echo "detailed test information in $RESULTS_FILE"
echo "------------------------------------------------------------------------"
echo "static" | awk '{printf("%s\t", $1)}'
echo "shared" | awk '{printf("%s\t", $1)}'
echo "test" | awk '{printf("%s\n", $1)}'
echo "------------------------------------------------------------------------"

TEST_TIME_START=$($TEST_DIR/printnow)
for NAME in `cat $TESTS_FILE`
do
    PRE_NAME="$TEST_DIR/`basename $NAME`"
    ST_NAME="`echo $PRE_NAME | sed 's/cc$/st-exe/'`"
    SH_NAME="`echo $PRE_NAME | sed 's/cc$/sh-exe/'`"
    CNAME="$SRC_DIR/testsuite/$NAME"

    test_file $CNAME $ST_NAME $ST_FLAG 
    test_file $CNAME $SH_NAME $SH_FLAG 
    echo "$NAME" | awk '{printf("%s\n", $1)}'

    echo "" >> $RESULTS_FILE
done
TEST_TIME_END=$($TEST_DIR/printnow)


#
# 4: summary
#
# grep can count faster than we can...
total_failures=$(egrep -c "^\-" $RESULTS_FILE)
total_successes=$(egrep -c "^\+" $RESULTS_FILE)
resultstext="pass/fail results:  ${total_successes}/${total_failures}"
if [ $total_failures -eq 0 ]; then
    resultstext="${resultstext}, WIN WIN"
fi
sed -e "/^date:/a\\
$resultstext" $RESULTS_FILE > ${RESULTS_FILE}.tmp
mv ${RESULTS_FILE}.tmp $RESULTS_FILE

if [ $TEST_TIME_START -lt $TEST_TIME_END ]; then
    TEST_TIME=$[ $TEST_TIME_END - $TEST_TIME_START ]
    echo "testrun == $TEST_TIME"
fi

exit 0