blob: 3142301a6d68d797707d5a527980085312dfce27 [file] [log] [blame]
#
# RUN: mkdir -p %t
#
# RUN: python %s --function=sscanf > %t/sscanftest.c
# RUN: test.sh -p -t %t %t/sscanftest.c
#
# RUN: python %s --function=vsscanf > %t/vsscanftest.c
# RUN: test.sh -p -t %t %t/vsscanftest.c
#
#
# Generate a C program to test sscanf() or vsscanf().
#
Str = 0 # string
Int = 1 # integer
Flt = 2 # float
Dbl = 3 # double
Ldb = 4 # long double
Arr = 5 # array of bytes of given size
Wst = 6 # wide character string
Nsp = 7 # %n specifier (as int)
basictests = \
[
# input format string return write
[ 'abc ', '%s', 1, [ (Str, 'abc') ] ],
[ ' abc', '%1[ ]', 1, [ (Str, ' ') ] ],
[ ' abc', '%[] a]', 1, [ (Str, ' a') ] ],
[ '\\n123', '%2d%1d', 2, [ (Int, '12'), (Int, '3') ] ],
[ '%ab\\n ', '%%%s', 1, [ (Str, 'ab') ] ],
[ '[][][]', '%[][]', 1, [ (Str, '[][][]') ] ],
[ 'abcde', '%3[^ ]%s', 2, [ (Str, 'abc'), (Str, 'de') ] ],
[ '123.4', '%i.%i', 2, [ (Int, '123'), (Int, '4') ] ],
[ '123.4', '%Lf', 1, [ (Ldb, '123.4l') ] ],
[ '6.6e-3', '%1Le', 1, [ (Ldb, '6.0l') ] ],
[ '6.6e-3', '%7Le', 1, [ (Ldb, '6.6e-3l') ] ],
[ '6.6e-3', '%lg', 1, [ (Dbl, '6.6e-3') ] ],
[ 'yy x', '%3c', 1, [ (Arr, 'yy ') ] ],
[ '-0x1.6p+2', '%Lf', 1, [ (Ldb, '-5.5l') ] ],
[ '100ent', '%e', 0, [ ], ],
[ '100e', '%e', 'EOF', [ ], ],
[ '10010', '%*2i%o', 1, [ (Int, '8') ] ],
[ ' \\na', '%[^a]', 1, [ (Str, ' \\n') ] ],
[ '-6', '%f', 1, [ (Flt, '-6.f') ] ],
[ ' ans', '%1s', 1, [ (Str, 'a') ] ],
[ 'abcdefgh', '%[a-f]%[g-h]', 2, [ (Str, 'abcdef'), (Str, 'gh') ] ],
[ '123.4', '%3ls', 1, [ (Wst, '123') ] ],
[ 'str', '%ls', 1, [ (Wst, 'str') ] ],
[ 'this', '%[nmop]', 0, [ ], ],
[ '%', '%%%n', 0, [ (Nsp, '1') ], ],
[ ' string', '%10s%n', 1, [ (Str, 'string'), (Nsp, '7') ] ],
[ ' ', '%c%n%c', 2,[ (Arr, ' '), (Nsp, '1'), (Arr, ' ') ] ],
[ 'i', '%n%ni', 0, [ (Nsp, '0'), (Nsp, '0') ] ],
[ 'i', '%ni%n', 0, [ (Nsp, '0'), (Nsp, '1') ] ],
[ 'abc 1', '%ls%n%d', 2, [ (Wst,'abc'), (Nsp,'3'), (Int,'1') ] ],
[ '1234', '%2c%n', 1, [ (Arr, '12'), (Nsp, '2') ] ],
[ 'xyzab', '%[x-z]%nab', 1, [ (Str, 'xyz'), (Nsp, '3') ] ],
[ '456789', '%[4-7]%n%i', 2,[ (Str,'4567'), (Nsp,'4'), (Int,'89') ]],
[ '456789', '%4i%n%i', 2,[ (Int,'4567'), (Nsp,'4'), (Int,'89') ]],
]
quote = lambda s : '"' + s + '"'
def build_test(n, input, fmt, rval, wrvals, function):
strcount = 0
intcount = 0
fltcount = 0
dblcount = 0
ldbcount = 0
wstcount = 0
nspcount = 0
front = 'result = %s(%s, %s' % (function, quote(input), quote(fmt))
args = []
comparisons = []
for wrval in wrvals:
valtype = wrval[0]
compare = wrval[1]
if valtype == Str:
strcount += 1
args.append('s%i' % strcount)
comparisons.append('strcmp(s%i, %s) == 0' % (strcount, quote(compare)))
elif valtype == Int:
intcount += 1
args.append('&i%i' % intcount)
comparisons.append('i%i == %s' % (intcount, compare))
elif valtype == Flt:
fltcount += 1
args.append('&f%i' % fltcount)
comparisons.append('flteq(f%i, %s)' % (fltcount, compare))
elif valtype == Dbl:
dblcount += 1
args.append('&d%i' % dblcount)
comparisons.append('dbleq(d%i, %s)' % (dblcount, compare))
elif valtype == Ldb:
ldbcount += 1
args.append('&ldb%i' % ldbcount)
comparisons.append('ldbeq(ldb%i, %s)' % (ldbcount, compare))
elif valtype == Arr:
size = len(compare)
strcount += 1
args.append('s%i' % strcount)
comparisons.append(
'memcmp((void *) s%i, (void *) %s, %i) == 0'
% (strcount, quote(compare), size)
)
elif valtype == Wst:
wstcount += 1
args.append('w%i' % wstcount)
comparisons.append('wcscmp(w%i, L%s) == 0' % (wstcount, quote(compare)))
elif valtype == Nsp:
nspcount += 1
args.append('&n%i' % nspcount)
comparisons.append('n%i == %s' % (nspcount, compare))
args.append('(void *) buf') # Don't segfault bad implementations that write
# one more argument than they should.
if args != []:
argv = ', ' + ', '.join(args)
else:
argv = ''
command = front + argv + ');'
tests = [command]
for ctest in comparisons:
tests.append(
'if (!(%s)) { fail = 1; puts("failure on test %s"); }' % (ctest, n)
)
tests.append(
'if (result != %s) { fail = 1; puts("failure on test %s"); }' % (rval, n)
)
return ' ' + '\n '.join(tests)
top = \
'''#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
int mysscanf(char *buf, const char *fmt, ...)
{
int result;
va_list ap;
va_start(ap, fmt);
result = vsscanf(buf, fmt, ap);
va_end(ap);
return result;
}
/* Very crude floating point equality tests. */
int ldbeq(long double a, long double b)
{
return (a - b) < 0.00001l && (a - b) > -0.00001l;
}
int dbleq(double a, double b)
{
return (a - b) < 0.00001 && (a - b) > -0.00001;
}
int flteq(float a, float b)
{
return (a - b) < 0.00001f && (a - b) > -0.00001f;
}
int main(int argc, char *argv[])
{
char buf[100];
char s1[100], s2[100], s3[100], s4[100], s5[100];
wchar_t w1[100], w2[100], w3[100], w4[100], w5[100];
int i1, i2, i3, i4, i5;
int n1, n2, n3, n4, n5;
long double ldb1, ldb2, ldb3, ldb4, ldb5;
double d1, d2, d3, d4, d5;
float f1, f2, f3, f4, f5;
int fail, result;
fail = 0;
/* Begin tests. */
'''
bottom = \
''' /* End tests. */
return fail;
}
'''
import cStringIO
import optparse
import sys
if __name__ == '__main__':
parser = optparse.OptionParser()
parser.set_defaults(function='sscanf')
parser.add_option('--function', dest='function',
help='function to test: sscanf or vsscanf')
(options, args) = parser.parse_args()
if options.function == 'sscanf':
function = 'sscanf'
elif options.function == 'vsscanf':
function = 'mysscanf'
else:
sys.stderr.write('specify either sscanf or vsscanf!\n')
sys.exit(1)
count = 0
output = cStringIO.StringIO()
output.write(top)
for basic_test in basictests:
count += 1
input = basic_test[0]
fmt = basic_test[1]
rval = basic_test[2]
wrvals = basic_test[3]
result = build_test(count, input, fmt, rval, wrvals, function)
output.write(result)
output.write('\n\n')
output.write(bottom)
sys.stdout.write(output.getvalue())
output.close()