START_MARKER |
test_true([["$Id: testsuite.in,v 1.791 2007/10/20 13:49:36 grubba Exp $"]]); |
|
// This triggered a bug only if run sufficiently early. |
test_compile_any([[#pike 7.2]]) |
test_compile_any([[#pike 7.4]]) |
test_compile_any([[#pike 7.0]]) |
test_compile_any([[#pike 0.6]]) |
|
cond([[all_constants()->_verify_internals]], |
[[ |
test_do(_verify_internals()) |
]]); |
test_eq(1e1,10.0); |
test_eq(1E1,10.0); |
test_eq(1e+1,10.0); |
test_eq(1.1e1,11.0); |
test_eq(1e-1,0.1); |
test_eq('\x20',32); |
test_eq("\x20","\040"); |
test_eq("\d32","\x20"); |
test_eq('Ã…',"Ã…"[0]); |
test_eq('\7777',"\7777"[0]); |
test_eq('\77777777',"\77777777"[0]); |
test_eq("\x10000","\x10000"); |
test_eq(0x80000000-0x80000000, 0); |
test_eq(0xf0000000-0xf0000000, 0); |
test_eq(0x80000001-0x80000000, 1); |
test_eq(0x80000000-0x80000001,-1); |
test_eq(-2147483648*-1, -2147483648/-1); |
cond([[ 0x8000000000000000 ]], |
[[ |
test_eq(0x8000000000000000-0x8000000000000000, 0); |
test_eq(0xf000000000000000-0xf000000000000000, 0); |
test_eq(0x8000000000000001-0x8000000000000000, 1); |
test_eq(0x8000000000000000-0x8000000000000001,-1); |
test_eq(-9223372036854775808*-1, -9223372036854775808/-1); |
]]) |
test_true([[1.0e-40]]); |
test_eq([[#"foo |
bar"]],[["foo\nbar"]]); |
test_eq([[#"foo\ |
bar"]],[["foobar"]]); |
test_true([[stringp(#string "Makefile")]]); |
test_any([[class Bar { array(int) foo = ({}); }; |
class Foo { inherit Bar; array(int) foo = ({1}); }; |
return sizeof(Foo()->foo);]],1); |
|
test_eq(8, 0b1000); |
test_eq(-8, -0b1000); |
test_eq(16, 0b10000); |
test_eq(-16, -0b10000); |
|
test_true(1e-100000000000000000000000000000000000000000000000000000000000<=1e-10000) |
test_true(1e-10000<=1e-1000) |
test_true(1e-1000<=1e-100) |
test_true(1e-100<=1e-10) |
test_true(1e-10<=1e-1) |
test_true(1e-1<=1e1) |
test_true(1e1<=1e10) |
test_true(1e10<=1e100) |
test_true(1e100<=1e1000) |
test_true(1e1000<=1e10000) |
test_true(1e10000<=1e100000000000000000000000000000000000000000000000000000000000) |
|
test_compile_warning('\3434523423423523423423423423') |
test_compile_warning("\3434523423423523423423423423") |
test_compile_warning("\d109827346981234561823743412654") |
test_compile_warning("\x109a27bc69e256c83deaa34c26b4") |
test_compile_error('\u17fo') |
test_compile_warning("\u17fo") |
test_compile_error('\uu117f') |
test_eq("\uuuu17fo", "\\uuu17fo") |
test_eq('\u117f', 0x117f) |
test_eq("\u117foo", "\10577oo") |
test_eq("\u1117foo", "\10427foo") |
test_eq("\uuuu117foo", "\\uuu117foo") |
test_compile_error('\U117f') |
test_compile_warning("\U117f") |
test_compile_warning("\UdEaDbEaT") |
test_eq("\UUdEaDbEaT", "\\UdEaDbEaT") |
test_eq('\UDeaDBeEF', -559038737) |
test_eq("\UDeaDBeEFFF", "\33653337357FF") |
test_eq("\UUDeaDBeEFFF", "\\UDeaDBeEFFF") |
test_any([[ |
// Suppress warnings. |
class handler { |
void compile_warning (string file, int line, string err) {}; |
}; |
return compile_string("string s = \"\\3434523423423523423423423423\";", |
"-", handler())()->s; |
]], "\37777777777") |
test_any([[ |
// Suppress warnings. |
class handler { |
void compile_warning (string file, int line, string err) {}; |
}; |
return compile_string("int i = '\\3434523423423523423423423423';", |
"-", handler())()->i; |
]], -1) |
|
test_do([[ |
// bug 2677 |
int x; |
if (time()) |
x = 1; |
else |
foo: break foo; |
]]) |
|
test_any([[ |
// bug 2690 |
array(function) foo(void|int b) |
{ |
int add() { return b++; }; |
return ({ add, add }); |
}; |
array(function) bar = foo(); |
return equal(({`==(@bar),@bar()}), ({ 1, 0, 1 })); |
]], 1) |
|
test_any([[ |
int f (int i) {i = 0; return i;}; |
return f (1); |
]],0) |
|
test_any([[ |
// Test that F_TAIL_RECUR and RECUR work properly. |
class X |
{ |
int Ack(int M, int N) { |
if (M == 0) return( N + 1 ); |
if (N == 0) return( Ack(M - 1, 1) ); |
return( Ack(M - 1, Ack(M, (N - 1))) ); |
} |
}; |
|
return X()->Ack(3,5); |
]],253) |
|
test_any([[ |
// Test that F_COND_RECUR works properly. |
// This test forces F_COND_RECUR to fail. |
class X |
{ |
int Ack(int M, int N) { |
if (M == 0) return( N + 1 ); |
if (N == 0) return( Ack(M - 1, 1) ); |
return( Ack(M - 1, Ack(M, (N - 1))) ); |
} |
}; |
|
class Y { inherit X; |
int Ack(int M, int N) { return ::Ack(M, N); } |
}; |
|
return Y()->Ack(2,2); |
]],7) |
|
test_any([[ |
// Test that loop optimizer isn't too aggressive. |
// Thanks to Alexander Demenshin <aldem-pike@aldem.net> |
int x,y,a; |
for(;x<10000;x++) { |
y += (x - a++); |
} |
return a; |
]], 10000) |
|
test_any([[ |
// Test that loop optimizer isn't too aggressive. |
// Thanks to Alexander Demenshin <aldem-pike@aldem.net> |
mapping m = ([]); |
for(;m->x<10000;m->x++) { |
m->y += (m->x - m->a++); |
} |
return m->a; |
]], 10000) |
|
test_any([[ |
// Test that loop optimizer isn't too aggressive. |
// Thanks to me. / Marcus |
for(int i=0; i<3.0; i++) |
if(i>4.0) |
return -1; |
return 0; |
]], 0) |
|
test_any([[ |
// Test that optimizer notes side effects in arguments to `!= |
// Thanks to Marcus Agehall |
int j = 20, i; |
string end = "17"; |
for( ; i < j ; i++) |
if(sscanf(end, "%d%s", j, end) != 2) |
cd("."); |
return i; |
]], 17) |
|
test_any([[ |
// Another over-optimization test. |
string x(string i) { return i; }; |
return x("")+1+1; |
]], "11") |
|
test_compile_any([[ |
void foo() |
{ |
Stdio.File bar(int x, int y) |
{ |
return 0; |
}; |
} |
]]) |
|
test_compile_any([[ |
string foo (string a, string b, string c, string d, string e, string f, string g) |
{ |
string out; |
if (a) |
out = "foo"; |
else |
out = "bar"; |
return out; |
} |
]]) |
|
dnl number of variables/scope, number of scopes, expect_compiler_error |
define(test_scopes,[[ |
test_any([[ |
write("Testing scoped variables $1:$2%s...\n", |
$3?" expecting a compilation error":""); |
string line = sprintf("#line %d %O\n", __LINE__, __FILE__); |
string s = "{\n" + |
(map(indices(allocate($1)), lambda(int no) { |
no++; |
return sprintf(" int var_%d;\n" |
" if (var_%d)\n" |
" error(\"Variable var_%d not \"\n" |
" \"initialized to zero: \"\n" |
" \"%%O\\n\",\n" |
" var_%d);\n" |
" var_%d = %d;\n", |
no, no, no, no, no, no); |
}) + |
map(indices(allocate($1)), lambda(int no) { |
no++; |
return sprintf(" if (var_%d != %d)\n" |
" error(\"Variable var_%d was \"\n" |
" \"clobbered with %%O.\\n\",\n" |
" var_%d);\n", |
no, no, no, no); |
})) * "" + |
"}\n"; |
program p; |
if ($3) master()->set_inhibit_compile_errors (1); |
mixed err = catch { |
p = compile_string("int a() {\n" + line + (s * $2) + |
" return 0;\n" |
"}\n"); |
}; |
if ($3) { |
master()->set_inhibit_compile_errors (0); |
if (err) return 0; |
error("Expected a compilation error for $1 variables in $2 scope%s.\n", |
($2>1)?"s":""); |
} |
if (err) throw(err); |
return p()->a(); |
]], 0) |
]]) |
|
test_scopes(255, 1, 0) |
test_scopes(256, 1, 1) |
test_scopes(16, 17, 0) |
test_scopes(17, 16, 0) |
|
test_any([[ |
// LysLysKOM 14180500 |
if (1) { |
string var = "Reinitialization error."; |
} |
sscanf("", "%d", int zero); |
return zero; |
]], 0); |
|
test_any([[ |
// LysLysKOM 14189033 |
int i; |
for (i = 0; i < 4; i++) { |
sscanf("", "%d", int test); |
if (test) return test; |
test = i+1; |
} |
return 0; |
]], 0) |
|
dnl FIXME: Add test that local and local:: in combination |
dnl with recursion works correctly. |
|
test_eval_error([[mixed x; return mkmapping(x,x)]]); |
|
test_eval_error([[class Foo { |
void bar() {} |
void foo() {destruct(this_object());bar();} |
}; |
Foo()->foo(); |
]]) |
|
test_do([[ |
void foo (int i) { |
multiset res = (<>); |
if (i) res = res; |
}; |
foo (1); |
]]) |
|
test_any([[ |
array tmp=({}); |
tmp=({([])})+tmp; |
tmp->foo=7; |
tmp=({([])})+tmp; |
return sizeof(tmp[0]); |
]], 0) |
|
|
test_any([[int a=0xffffffff; return a+17]], 0x100000010); |
test_any([[int a=0xffffffff; return a-17]], 0xffffffee); |
test_any([[int a=0xffffffff; return a*17]], 0x10ffffffef); |
test_any([[int a=0xffffffff; return a^17]], 0xffffffee); |
test_any([[int a=0xffffffff; return a&17]], 17); |
test_any([[int a=0xffffffff; return a|17]], 0xffffffff); |
test_any([[int a=0xffffffff; return a<<17]], 0x1fffffffe0000); |
|
test_any([[ int a=0xffffffff; return a/17 ]], |
[[ (0xffffffff == -1)?-1:0x0f0f0f0f ]]); |
test_any([[ int a=0xffffffff; return a%17 ]], |
[[ (0xffffffff == -1)?16:0 ]]); |
test_any([[ int a=0xffffffff; return a>>17 ]], |
[[ (0xffffffff == -1)?-1:0x7fff ]]); |
|
test_any([[return sprintf("%O", typeof(aggregate("foo")));]], "array(string(0..255))"); |
test_any([[int a; return sprintf("%O", typeof(aggregate(a)));]], "array(int)"); |
test_any([[int|string a; |
string s = sprintf("%O", typeof(aggregate(a))); |
return (< "array(string) | array(int)", "array(string | int)", "array(int | string)" >)[s];]], 1); |
test_any([[return sprintf("%O", typeof(aggregate()));]], "array(zero)"); |
test_any([[int i; return (< "int", "int | zero", "zero | int" >) |
[sprintf("%O", typeof(max(i,0)))];]], 1) |
|
test_any([[array(string) a; return sprintf("%O", typeof(a[0])); ]], "string") |
|
test_any([[class foo { string a; }; |
object(foo) bar; |
return sprintf("%O", typeof(bar->a));]], "string"); |
|
test_any([[class foo { string a; }; |
array(object(foo)) bar; |
return sprintf("%O", typeof(bar[0]->a));]], "string"); |
|
test_any([[function(:string)|function(int:int) f; |
return sprintf("%O", typeof(f())); ]], |
"string") |
|
test_any([[function(:string)|function(int:int) f; |
return sprintf("%O", typeof(f(1))); ]], |
"int") |
|
test_any([[function(:string)|function(mixed, mixed...:int) f; |
return sprintf("%O", typeof(f())); ]], |
"string") |
|
test_any([[function(:string)|function(mixed, mixed ...:int) f; |
return sprintf("%O", typeof(f(1))); ]], |
"int") |
|
test_any([[mapping(object:string)|mapping(string:int) f; |
return sprintf("%O", typeof(f[class{}()])); ]], |
"string") |
|
test_any([[mapping(object:string)|mapping(string:int) f; |
return sprintf("%O", typeof(f[""])); ]], |
"int") |
|
test_any([[mapping(object:string)|mapping(string:int) f; |
return sort((sprintf("%O", typeof(f[0])) - " ")/"|")*"|"; ]], |
"int|string") |
|
test_any([[class Foo { string `[](mixed y) {return "";} }; |
object(Foo) foo; |
return sprintf("%O", typeof(foo[0])); ]], |
"string") |
|
test_any([[class Foo { array(int) _indices() {return ({0});} }; |
object(Foo) foo; |
return sprintf("%O", typeof(indices(foo))); ]], |
"array(int)") |
|
test_any([[class Foo { array(string) _values() {return ({""});} }; |
object(Foo) foo; |
return sprintf("%O", typeof(values(foo))); ]], |
"array(string)") |
|
test_any([[mapping(string:int) foo; |
array(string) bar; |
return sprintf("%O", typeof(rows(foo, bar))); ]], |
"array(int)") |
|
test_any([[{ |
class Foo |
{ |
mixed m; |
}; |
class Bar |
{ |
inherit Foo; |
string m; |
Foo b; |
mixed f() { |
return typeof(b->m); |
} |
}; |
Foo c; |
Bar d; |
return sprintf("%O$%O$%O$%O", |
Bar()->f(), typeof(c->m), typeof(d->m), typeof(d->b->m)); |
}]], "mixed$mixed$string$mixed") |
|
// las.c:find_return_type() checks. |
test_eq([[ |
// Test case from Robert J. Budzynski <Robert.Budzynski@fuw.edu.pl>. |
// When broken the return type will be mixed. |
sprintf("%O", typeof(lambda(string s){ |
return Locale.Charset.decoder("utf-8")->feed(s)->drain(); |
})) |
]], [[ "function(string : string)" ]]) |
|
// Test implicit lambda. |
test_eq([[ |
`()(){ return 1; } |
]], 1) |
|
// Argument checking |
|
// Test get_all_args. |
test_eval_error([[ |
// A trick to get some svalues to freed refcounted stuff on the stack. |
lambda (mixed a, mixed b, mixed c) {} (({time()}), ({time()}), ({time()})); |
// set_weak_flag is chosen since it calls get_all_args with an |
// argument spec that contains two arguments of different types. |
([function] set_weak_flag)(); |
]]) |
test_eval_error([[ |
lambda (mixed a, mixed b, mixed c) {} (({time()}), ({time()}), ({time()})); |
([function] set_weak_flag) (17); |
]]) |
test_eval_error([[ |
lambda (mixed a, mixed b, mixed c) {} (({time()}), ({time()}), ({time()})); |
([function] set_weak_flag) ("foo"); |
]]) |
test_eval_error([[ |
lambda (mixed a, mixed b, mixed c) {} (({time()}), ({time()}), ({time()})); |
([function] set_weak_flag) (17, "foo"); |
]]) |
|
// type checks |
|
define(test_type_error, [[ |
test_compile_error([[ $1 x; x=$3; ]]) |
test_compile_error_any([[ class ErrBa { $1 x() { return $3; } } ]]) |
test_compile_error_any([[ class ErrBa { $1 x() { $2 a=$3; return a; } } ]]) |
]]) |
|
test_type_error(int,float,17.23) |
test_type_error(int,array,({1,2,3})) |
test_type_error(int,mapping,([1:2,3:4])) |
test_type_error(int,multiset,(<1,2,3>)) |
test_type_error(int,function,lambda() { return 17; }) |
test_type_error(int,program,object_program(this_object())) |
test_type_error(int,object,this_object()) |
|
test_type_error(float,int,17) |
test_type_error(float,array,({1,2,3})) |
test_type_error(float,mapping,([1:2,3:4])) |
test_type_error(float,multiset,(<1,2,3>)) |
test_type_error(float,function,lambda() { return 17; }) |
test_type_error(float,program,object_program(this_object())) |
test_type_error(float,object,this_object()) |
|
test_type_error(array,int,17) |
test_type_error(array,float,17.23) |
test_type_error(array,mapping,([1:2,3:4])) |
test_type_error(array,multiset,(<1,2,3>)) |
test_type_error(array,function,lambda() { return 17; }) |
test_type_error(array,program,object_program(this_object())) |
test_type_error(array,object,this_object()) |
|
test_type_error(mapping,int,17) |
test_type_error(mapping,float,17.23) |
test_type_error(mapping,array,({1,2,3})) |
test_type_error(mapping,multiset,(<1,2,3>)) |
test_type_error(mapping,function,lambda() { return 17; }) |
test_type_error(mapping,program,object_program(this_object())) |
test_type_error(mapping,object,this_object()) |
|
test_type_error(multiset,int,17) |
test_type_error(multiset,float,17.23) |
test_type_error(multiset,array,({1,2,3})) |
test_type_error(multiset,mapping,([1:2,3:4])) |
test_type_error(multiset,function,lambda() { return 17; }) |
test_type_error(multiset,program,object_program(this_object())) |
test_type_error(multiset,object,this_object()) |
|
test_type_error(function,int,17) |
test_type_error(function,float,17.23) |
test_type_error(function,array,({1,2,3})) |
test_type_error(function,mapping,([1:2,3:4])) |
test_type_error(function,multiset,(<1,2,3>)) |
|
test_type_error(program,int,17) |
test_type_error(program,float,17.23) |
test_type_error(program,array,({1,2,3})) |
test_type_error(program,mapping,([1:2,3:4])) |
test_type_error(program,multiset,(<1,2,3>)) |
|
test_type_error(object,int,17) |
test_type_error(object,float,17.23) |
test_type_error(object,array,({1,2,3})) |
test_type_error(object,mapping,([1:2,3:4])) |
test_type_error(object,multiset,(<1,2,3>)) |
|
test_any([[ |
/* Detect bug in modify_shared_string(). |
* |
* Note: For proper operation this test depends on HASH_PREFIX being |
* <= 128, and the initial string in test having a single ref. |
*/ |
string prefix = "A"*128; |
string suffix = "B"*128; |
|
string test = prefix + "C" + suffix; |
string match = prefix + "D" + suffix; |
|
if (test == match) return("Early match!"); |
|
test[128] = 'D'; |
|
if (test != match) return("Late mismatch!"); |
]], 0) |
|
test_compile_error([[ string a="abcb"; a=a/"b"; ]]) |
test_compile_error([[ string a="abcb"; a/="b"; ]]) |
test_compile_error([[ string a="abcb"; string b="b"; a=a/b; ]]) |
test_compile_error([[ string a="abcb"; string b="b"; a/=b; ]]) |
test_compile_error([[ string a="x"; int b; b="x"*17; ]]) |
test_compile_error([[ string a="x"; array b; b="x"*17; ]]) |
test_compile_error([[ int b=17; string a; a=b*42; ]]) |
test_compile_error([[ int b=17; float c=42.0; b=b/c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b/=c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b=b*c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b*=c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b=b+c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b+=c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b=b-c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b-=c; ]]) |
test_compile_error([[ float b=17.0; string a; a=b*42; ]]) |
test_compile_error([[ float b=17.0; string a; a=b*42.0; ]]) |
|
test_compile_error([[class F {inherit master()->dirnode;};]]); |
|
// Warnings |
|
test_compile_warning([[ int *a ]]) |
test_compile_warning([[ int|float *a ]]) |
test_compile_warning([[ [mixed]1 ]]) |
test_compile_warning([[ |
class A { int a = 6; }; |
class B { |
constant a = 5; |
inherit A; |
}; |
]]) |
|
// |
|
test_any([[ |
class Foo { |
constant zero = 0; |
mapping(string:array(int)) m; |
string foo() { return sprintf("%O", typeof(m[""][zero])); } |
}; |
return Foo()->foo(); |
]], "int") |
|
test_compile_any([[ |
class { ; } |
]]) |
|
test_compile_any([[ |
class { ; ; } |
]]) |
|
test_compile_any([[ |
class { ; constant c = 0; } |
]]) |
|
test_compile_any([[ |
class { void a() { constant c = 17; } |
void b() { constant c = 17; } } |
]]) |
|
test_compile_any([[ |
constant FOO = 0; |
mapping(int:string) foo = ([FOO: "foo"]); |
]]) |
|
test_compile_error([[ |
function(...:int) foo; |
]]); |
|
test_compile_error([[ |
function(,...:int) foo; |
]]); |
|
test_compile_error([[ |
function(string,...:int) foo; |
]]); |
|
test_any([[return class Z { |
string bonk() { return "oiff"; } |
|
class A |
{ |
string bonk_me() { return bonk(); } |
} |
|
class B { inherit A; } |
|
class C |
{ |
string oiff() { return "bonk"; } |
class D { inherit B; } |
} |
}()->C()->D()->bonk_me()]],"oiff") |
|
test_compile_error([[ |
class A { constant q = "x"; } |
class B { inherit A; string z="z"; constant q="x"+z; } |
]]) |
|
test_compile_any([[ |
class A |
{ |
object x(int y) |
{ |
return B(y); |
} |
} |
|
class B |
{ |
void create(int y) |
{ |
} |
} |
]]) |
|
// Test that prototypes evaluate to zero. |
test_any([[ |
class Foo {int foo();}; |
return Foo()->foo == 0; |
]], 1) |
test_any_equal([[ |
class Foo {int foo();}; |
return indices(Foo()); |
]], ({"foo"})) |
test_any_equal([[ |
class Foo {int foo();}; |
return values(Foo()); |
]], ({0})) |
test_any([[ |
class Foo |
{ |
int foo(); |
int(0..1) f() |
{ |
return foo == 0; |
} |
}; |
return Foo()->f(); |
]], 1) |
test_any([[ |
class Foo |
{ |
int foo(); |
int(0..1) f() |
{ |
return functionp(foo); |
} |
}; |
class Bar |
{ |
inherit Foo; |
int foo() {} |
}; |
return Bar()->f(); |
]], 1) |
|
test_do([[ |
class Foo |
{ |
inherit Stdio.File; |
|
void create() { } |
}; |
|
class Bar |
{ |
int y; |
|
|
class Gazonk |
{ |
inherit Foo; |
|
|
void create(Stdio.File f) |
{ |
assign(f); |
} |
} |
|
void create() |
{ |
Gazonk(Stdio.stdin); |
} |
}; |
|
Bar(); |
|
]]) |
|
test_any([[ |
object f = class { |
array recursive(mixed func, array data, mixed ... args) |
{ |
array ret=({}); |
|
foreach(data, mixed foo) |
{ |
if(arrayp(foo)) |
{ |
ret+=({ recursive(func, foo, @args) }); |
}else{ |
ret+=({ foo }); |
} |
} |
|
return func(ret, @args); |
}; |
}(); |
|
mixed x = ({ "A", ({}) }); |
x = f->recursive(replace, x, "B", ({})); |
|
for(int i = 0; i < sizeof(x); i++) { |
if (!stringp(x[i]) && !arrayp(x[i])) return 0; |
} |
return 1; |
]], 1); |
|
test_compile_error( [[ |
// This triggs a compiler bug on old Pike 7.3. |
non_existant(17) { |
return 0; |
} |
]]) |
|
test_compile_error( [[ |
// This triggs a compiler bug on old Pike 7.5. |
return lambda(object (([mixed]a)->syntax_error) { return 0; }(0); |
]]) |
|
test_compile_error( [[ |
// [bug 4362] This triggs a segfault on some versions of Pike 7.7. |
mixed x = all_constants()[undefined_identifier]; |
]]) |
|
cond( [[ master()->resolv("Pike")->Security ]],[[ |
test_any( [[ |
// bug [2830] ------------------------------------------------------------ |
// http://community/crunch/show_bug.cgi?id=2830 |
class User{}; |
|
object luser = User(); |
|
object luser_creds = Pike.Security.Creds(luser, 0, 0); |
return !catch { |
return !!Pike.Security.call_with_creds(luser_creds, Stdio.File, |
"/dev/null"); |
}; |
|
return 0; |
]], 0 ) |
]]) |
|
test_any( [[ |
// bug [1996] ------------------------------------------------------------ |
// http://community/crunch/show_bug.cgi?id=1996 |
class Implementation |
{ |
int foo() { return 1; } |
}; |
class Prototype |
{ |
int foo(); |
int bar() { return foo(); } |
}; |
class Test |
{ |
inherit Implementation; |
inherit Prototype; |
int test() { return bar(); } |
}; |
return Test()->test(); |
]], 1 ); |
|
test_any( [[ |
// bug [721] ------------------------------------------------------------- |
// http://community/crunch/show_bug.cgi?id=721 |
int res=0; |
program p; |
catch |
{ |
add_constant("test_a",compile_string("int foo();","test_a")); |
add_constant("test_b",compile_string("int foo();","test_b")); |
add_constant("test_c",compile_string( |
"inherit test_a;\n" |
"inherit test_b;\n" |
"final int foo() { return 1; }\n","test_c")); |
res=compile_string("inherit test_c;\n","test_d")()->foo(); |
}; |
return res; |
]],1); |
test_do(add_constant("test_a")) |
test_do(add_constant("test_b")) |
test_do(add_constant("test_c")) |
|
test_any( [[ |
// bug [1858] ------------------------------------------------------------ |
// http://community/crunch/show_bug.cgi?id=1858 |
string s=#" |
constant foo=({this_object()}); |
int|string test() |
{ |
if (!foo[0]) return sprintf(\"foo is %O\\n\",foo)-\"\\n\"; |
if (foo[0]==this_object()) return 1; |
return sprintf(\"foo is %O\\n\",foo)-\"\\n\"; |
} |
"; |
class handler { void compile_error(string file, int line, string err) { }}; |
catch { |
program p=compile_string(s,"test",handler()); |
return p()->test(); |
}; |
return 1; // compile error is ok |
]],1); |
|
// ----------------------------------------------------------------------- |
|
|
|
// This test checks for excessive recursion in |
// destruct_objects_to_destruct, and also that it keeps the destruct |
// order sane. |
test_do([[ |
class Top |
{ |
int count = 0; |
|
class Foo |
{ |
int c; |
object foo; |
static void create(object o) |
{ |
foo = o; |
c = count++; |
} |
|
void destroy() |
{ |
count--; |
if (count != c) |
error ("Destruct out of sequence, " |
"%d destructed when %d should be.\n", c, count); |
object x = foo && Foo(0); |
x = 0; |
// Cause call to destruct_objects_to_destruct. |
for (int j = 0; j < 10; j++) write (""); |
} |
} |
|
mixed eat_stack(int|void probe) |
{ |
// Avoid eating as much C-stack by releasing the |
// catch at every level. |
if (probe) return 1; |
if (catch(eat_stack(1))) return 1; |
mixed err = 1; |
if ((err = eat_stack()) != 10) |
return intp(err) && err > 0 ? err + 1 : err; |
if (err = catch { |
|
Foo foo; |
for(int i=0; i < 10000; i++) |
foo = Foo(foo); |
foo = 0; |
// Cause call to destruct_objects_to_destruct. |
for (int j = 0; j < 10; j++) write (""); |
|
}) return err; |
} |
|
static void create() |
{ |
if (mixed err = eat_stack()) { |
catch (err[1] = err[1][sizeof (err[1]) - 50..]); |
throw (err); |
} |
} |
}; |
|
Top(); |
]]); |
|
// Testing stack popping wrt the various function call opcodes |
test_program([[ |
inherit Thread.Mutex : monitor; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
} |
int a() |
{ |
object key = monitor::lock(); |
return f (1); // F_CALL_LFUN_AND_RETURN |
}; |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
mixed g = f; |
int a() |
{ |
object key = monitor::lock(); |
return g (1); // F_CALL_FUNCTION_AND_RETURN |
} |
]]); |
test_program([[ |
Thread.Mutex monitor = Thread.Mutex(); |
int f (int x) |
{ |
if(monitor->trylock(1)) |
return 0; |
return x; |
} |
int a() |
{ |
add_constant ("f", f); |
add_constant ("monitor", monitor); |
return compile_string(#" |
int g() |
{ |
object key = monitor->lock(); |
return f (1); // F_APPLY_AND_RETURN |
}")()->g(); |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int dummy; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
int a() |
{ |
object key = monitor::lock(); |
int res = this->f (1); // F_CALL_OTHER (no `->) |
dummy = random (res); |
return res; |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
mixed `-> (string what) {return this[what];} |
int dummy; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
int a() |
{ |
object key = monitor::lock(); |
int res = this->f (1); // F_CALL_OTHER (with `->) |
dummy = random (res); |
return res; |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int res = 0; |
void f (int x) |
{ |
if(monitor::trylock(1)) |
res = 0; |
else |
res = x; |
}; |
int a() |
{ |
object key = monitor::lock(); |
this->f (1); // F_CALL_OTHER_AND_POP (no `->) |
return res; |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
mixed `-> (string what) {return this[what];} |
int res = 0; |
void f (int x) |
{ |
if(monitor::trylock(1)) |
res = 0; |
else |
res = x; |
}; |
int a() |
{ |
object key = monitor::lock(); |
this->f (1); // F_CALL_OTHER_AND_POP (with `->) |
return res; |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
int a() |
{ |
object key = monitor::lock(); |
return this->f (1); // F_CALL_OTHER_AND_RETURN (no `->) |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
mixed `-> (string what) {return this[what];} |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
int a() |
{ |
object key = monitor::lock(); |
return this->f (1); // F_CALL_OTHER_AND_RETURN (with `->) |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (iter == 1) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
object key = monitor::lock(); |
iter = 1; |
return a (1); // F_COND_RECUR |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
object key = monitor::lock(); |
iter = 2; |
return a (1); // F_TAIL_RECUR |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
object key = monitor::lock(); |
iter = 2; |
int res = a (1); // F_RECUR |
iter = -1; |
return res; |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
iter = 0; |
iter = x; |
} |
else { |
object key = monitor::lock(); |
iter = 2; |
a (1); // F_RECUR_AND_POP |
return iter; |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
} |
int a() |
{ |
foreach (({0, monitor::lock()}), mixed m) |
return f (1); // F_CALL_LFUN_AND_RETURN |
}; |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
mixed g = f; |
int a() |
{ |
foreach (({0, monitor::lock()}), mixed m) |
return g (1); // F_CALL_FUNCTION_AND_RETURN |
} |
]]); |
test_program([[ |
Thread.Mutex monitor = Thread.Mutex(); |
int f (int x) |
{ |
if(monitor->trylock(1)) |
return 0; |
return x; |
} |
int a() |
{ |
add_constant ("f", f); |
add_constant ("monitor", monitor); |
return compile_string(#" |
int g() |
{ |
foreach (({0, monitor->lock()}), mixed m) |
return f (1); // F_APPLY_AND_RETURN |
}")()->g(); |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int dummy; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
int a() |
{ |
int res; |
foreach (({0, monitor::lock()}), mixed m) { |
res = this->f (1); // F_CALL_OTHER (no `->) |
dummy = random (res); |
return res; |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
mixed `-> (string what) {return this[what];} |
int dummy; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
int a() |
{ |
int res; |
foreach (({0, monitor::lock()}), mixed m) { |
res = this->f (1); // F_CALL_OTHER (with `->) |
dummy = random (res); |
return res; |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int res = 0; |
void f (int x) |
{ |
if(monitor::trylock(1)) |
res = 0; |
else |
res = x; |
}; |
int a() |
{ |
foreach (({0, monitor::lock()}), mixed m) { |
this->f (1); // F_CALL_OTHER_AND_POP (no `->) |
return res; |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
mixed `-> (string what) {return this[what];} |
int res = 0; |
void f (int x) |
{ |
if(monitor::trylock(1)) |
res = 0; |
else |
res = x; |
}; |
int a() |
{ |
foreach (({0, monitor::lock()}), mixed m) { |
this->f (1); // F_CALL_OTHER_AND_POP (with `->) |
return res; |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
int a() |
{ |
foreach (({0, monitor::lock()}), mixed m) |
return this->f (1); // F_CALL_OTHER_AND_RETURN (no `->) |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
mixed `-> (string what) {return this[what];} |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
int a() |
{ |
foreach (({0, monitor::lock()}), mixed m) |
return this->f (1); // F_CALL_OTHER_AND_RETURN (with `->) |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (iter == 1) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
iter = 1; |
foreach (({0, monitor::lock()}), mixed m) |
return a (1); // F_COND_RECUR |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
iter = 2; |
foreach (({0, monitor::lock()}), mixed m) |
return a (1); // F_TAIL_RECUR |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
iter = 2; |
int res; |
foreach (({0, monitor::lock()}), mixed m) { |
res = a (1); // F_RECUR |
iter = random (res); |
return res; |
} |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
iter = 0; |
iter = x; |
} |
else { |
iter = 2; |
foreach (({0, monitor::lock()}), mixed m) { |
a (1); // F_RECUR_AND_POP |
return iter; |
} |
} |
} |
]]); |
test_do(add_constant("f")) |
test_do(add_constant("monitor")) |
|
// Testing scoped frames wrt the various function call opcodes |
test_program([[ |
int f (int x) |
{ |
return x; |
} |
int a (void|int x) |
{ |
function s = lambda () {return x;}; |
return f (1); // F_CALL_LFUN_AND_RETURN |
}; |
]]); |
test_program([[ |
int f (int x) |
{ |
return x; |
}; |
mixed g = f; |
int a (void|int x) |
{ |
function s = lambda () {return x;}; |
return g (1); // F_CALL_FUNCTION_AND_RETURN |
} |
]]); |
test_program([[ |
int f (int x) |
{ |
return x; |
} |
int a() |
{ |
add_constant ("f", f); |
return compile_string(#" |
int g (void|int x) |
{ |
function s = lambda () {return x;}; |
return f (1); // F_APPLY_AND_RETURN |
}")()->g(); |
} |
]]); |
test_program([[ |