mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
v2: more informative assert output; string interpolation formatting
This commit is contained in:
parent
6892a3e0a8
commit
f489c89987
@ -99,7 +99,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
|
||||
//////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames)
|
||||
csymbols := backtrace_symbols(&buffer[skipframes], nr_actual_frames)
|
||||
for i in 0 .. nr_actual_frames {
|
||||
sframes << tos2(csymbols[i])
|
||||
sframes << tos2( byteptr( voidptr(csymbols[i]) ) )
|
||||
}
|
||||
for sframe in sframes {
|
||||
executable := sframe.all_before('(')
|
||||
|
116
vlib/builtin/string_strip_margin_test.v
Normal file
116
vlib/builtin/string_strip_margin_test.v
Normal file
@ -0,0 +1,116 @@
|
||||
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
fn test_strip_margins_no_tabs() {
|
||||
no_tabs := ['Hello there',
|
||||
'This is a string',
|
||||
'With multiple lines',
|
||||
].join('\n')
|
||||
no_tabs_stripped := 'Hello there
|
||||
|This is a string
|
||||
|With multiple lines'.strip_margin()
|
||||
assert no_tabs == no_tabs_stripped
|
||||
}
|
||||
|
||||
fn test_strip_margins_text_before() {
|
||||
text_before := ['There is text',
|
||||
'before the delimiter',
|
||||
'that should be removed as well',
|
||||
].join('\n')
|
||||
text_before_stripped := 'There is text
|
||||
f lasj asldfj j lksjdf |before the delimiter
|
||||
Which is removed hello |that should be removed as well'.strip_margin()
|
||||
assert text_before_stripped == text_before
|
||||
}
|
||||
|
||||
fn test_strip_margins_white_space_after_delim() {
|
||||
tabs := [' Tab',
|
||||
' spaces',
|
||||
' another tab',
|
||||
].join('\n')
|
||||
tabs_stripped := ' Tab
|
||||
| spaces
|
||||
| another tab'.strip_margin()
|
||||
assert tabs == tabs_stripped
|
||||
}
|
||||
|
||||
fn test_strip_margins_alternate_delim() {
|
||||
alternate_delimiter := ['This has a different delim,',
|
||||
'but that is ok',
|
||||
'because everything works',
|
||||
].join('\n')
|
||||
alternate_delimiter_stripped := 'This has a different delim,
|
||||
#but that is ok
|
||||
#because everything works'.strip_margin(`#`)
|
||||
assert alternate_delimiter_stripped == alternate_delimiter
|
||||
}
|
||||
|
||||
fn test_strip_margins_multiple_delims_after_first() {
|
||||
delim_after_first_instance := ['The delimiter used',
|
||||
'only matters the |||| First time it is seen',
|
||||
'not any | other | times',
|
||||
].join('\n')
|
||||
delim_after_first_instance_stripped := 'The delimiter used
|
||||
|only matters the |||| First time it is seen
|
||||
|not any | other | times'.strip_margin()
|
||||
assert delim_after_first_instance_stripped == delim_after_first_instance
|
||||
}
|
||||
|
||||
fn test_strip_margins_uneven_delims() {
|
||||
uneven_delims := ['It doesn\'t matter if the delims are uneven,',
|
||||
'The text will still be delimited correctly.',
|
||||
'Maybe not everything needs 3 lines?',
|
||||
'Let us go for 4 then',
|
||||
].join('\n')
|
||||
uneven_delims_stripped := 'It doesn\'t matter if the delims are uneven,
|
||||
|The text will still be delimited correctly.
|
||||
|Maybe not everything needs 3 lines?
|
||||
|Let us go for 4 then'.strip_margin()
|
||||
assert uneven_delims_stripped == uneven_delims
|
||||
}
|
||||
|
||||
fn test_strip_margins_multiple_blank_lines() {
|
||||
multi_blank_lines := ['Multiple blank lines will be removed.',
|
||||
' I actually consider this a feature.',
|
||||
].join('\n')
|
||||
multi_blank_lines_stripped := 'Multiple blank lines will be removed.
|
||||
|
||||
|
||||
|
||||
| I actually consider this a feature.'.strip_margin()
|
||||
assert multi_blank_lines == multi_blank_lines_stripped
|
||||
}
|
||||
|
||||
fn test_strip_margins_end_newline() {
|
||||
end_with_newline := ['This line will end with a newline',
|
||||
'Something cool or something.',
|
||||
'',
|
||||
].join('\n')
|
||||
end_with_newline_stripped := 'This line will end with a newline
|
||||
|Something cool or something.
|
||||
|
||||
'.strip_margin()
|
||||
assert end_with_newline_stripped == end_with_newline
|
||||
}
|
||||
|
||||
fn test_strip_margins_space_delimiter() {
|
||||
space_delimiter := ['Using a white-space char will',
|
||||
'revert back to default behavior.',
|
||||
].join('\n')
|
||||
space_delimiter_stripped := 'Using a white-space char will
|
||||
|revert back to default behavior.'.strip_margin(`\n`)
|
||||
assert space_delimiter == space_delimiter_stripped
|
||||
}
|
||||
|
||||
fn test_strip_margins_crlf() {
|
||||
crlf := ['This string\'s line endings have CR as well as LFs.',
|
||||
'This should pass',
|
||||
'Definitely',
|
||||
].join('\r\n')
|
||||
crlf_stripped := 'This string\'s line endings have CR as well as LFs.\r
|
||||
|This should pass\r
|
||||
|Definitely'.strip_margin()
|
||||
|
||||
assert crlf == crlf_stripped
|
||||
}
|
@ -20,11 +20,6 @@ fn test_add() {
|
||||
assert a.ends_with('bbbbb')
|
||||
a += '123'
|
||||
assert a.ends_with('3')
|
||||
mut foo := Foo{10, 'hi'}
|
||||
assert foo.str == 'hi'
|
||||
assert foo.bar == 10
|
||||
foo.str += '!'
|
||||
assert foo.str == 'hi!'
|
||||
}
|
||||
|
||||
fn test_ends_with() {
|
||||
@ -481,20 +476,6 @@ fn test_reverse() {
|
||||
assert 'a'.reverse() == 'a'
|
||||
}
|
||||
|
||||
fn (f Foo) baz() string {
|
||||
return 'baz'
|
||||
}
|
||||
|
||||
fn test_interpolation() {
|
||||
num := 7
|
||||
mut s := 'number=$num'
|
||||
assert s == 'number=7'
|
||||
foo := Foo{}
|
||||
s = 'baz=${foo.baz()}'
|
||||
assert s == 'baz=baz'
|
||||
|
||||
}
|
||||
|
||||
fn test_bytes_to_string() {
|
||||
mut buf := vcalloc(10)
|
||||
buf[0] = `h`
|
||||
@ -703,115 +684,3 @@ fn test_split_into_lines() {
|
||||
}
|
||||
}
|
||||
|
||||
fn test_strip_margins_no_tabs() {
|
||||
no_tabs := ['Hello there',
|
||||
'This is a string',
|
||||
'With multiple lines',
|
||||
].join('\n')
|
||||
no_tabs_stripped := 'Hello there
|
||||
|This is a string
|
||||
|With multiple lines'.strip_margin()
|
||||
assert no_tabs == no_tabs_stripped
|
||||
}
|
||||
|
||||
fn test_strip_margins_text_before() {
|
||||
text_before := ['There is text',
|
||||
'before the delimiter',
|
||||
'that should be removed as well',
|
||||
].join('\n')
|
||||
text_before_stripped := 'There is text
|
||||
f lasj asldfj j lksjdf |before the delimiter
|
||||
Which is removed hello |that should be removed as well'.strip_margin()
|
||||
assert text_before_stripped == text_before
|
||||
}
|
||||
|
||||
fn test_strip_margins_white_space_after_delim() {
|
||||
tabs := [' Tab',
|
||||
' spaces',
|
||||
' another tab',
|
||||
].join('\n')
|
||||
tabs_stripped := ' Tab
|
||||
| spaces
|
||||
| another tab'.strip_margin()
|
||||
assert tabs == tabs_stripped
|
||||
}
|
||||
|
||||
fn test_strip_margins_alternate_delim() {
|
||||
alternate_delimiter := ['This has a different delim,',
|
||||
'but that is ok',
|
||||
'because everything works',
|
||||
].join('\n')
|
||||
alternate_delimiter_stripped := 'This has a different delim,
|
||||
#but that is ok
|
||||
#because everything works'.strip_margin(`#`)
|
||||
assert alternate_delimiter_stripped == alternate_delimiter
|
||||
}
|
||||
|
||||
fn test_strip_margins_multiple_delims_after_first() {
|
||||
delim_after_first_instance := ['The delimiter used',
|
||||
'only matters the |||| First time it is seen',
|
||||
'not any | other | times',
|
||||
].join('\n')
|
||||
delim_after_first_instance_stripped := 'The delimiter used
|
||||
|only matters the |||| First time it is seen
|
||||
|not any | other | times'.strip_margin()
|
||||
assert delim_after_first_instance_stripped == delim_after_first_instance
|
||||
}
|
||||
|
||||
fn test_strip_margins_uneven_delims() {
|
||||
uneven_delims := ['It doesn\'t matter if the delims are uneven,',
|
||||
'The text will still be delimited correctly.',
|
||||
'Maybe not everything needs 3 lines?',
|
||||
'Let us go for 4 then',
|
||||
].join('\n')
|
||||
uneven_delims_stripped := 'It doesn\'t matter if the delims are uneven,
|
||||
|The text will still be delimited correctly.
|
||||
|Maybe not everything needs 3 lines?
|
||||
|Let us go for 4 then'.strip_margin()
|
||||
assert uneven_delims_stripped == uneven_delims
|
||||
}
|
||||
|
||||
fn test_strip_margins_multiple_blank_lines() {
|
||||
multi_blank_lines := ['Multiple blank lines will be removed.',
|
||||
' I actually consider this a feature.',
|
||||
].join('\n')
|
||||
multi_blank_lines_stripped := 'Multiple blank lines will be removed.
|
||||
|
||||
|
||||
|
||||
| I actually consider this a feature.'.strip_margin()
|
||||
assert multi_blank_lines == multi_blank_lines_stripped
|
||||
}
|
||||
|
||||
fn test_strip_margins_end_newline() {
|
||||
end_with_newline := ['This line will end with a newline',
|
||||
'Something cool or something.',
|
||||
'',
|
||||
].join('\n')
|
||||
end_with_newline_stripped := 'This line will end with a newline
|
||||
|Something cool or something.
|
||||
|
||||
'.strip_margin()
|
||||
assert end_with_newline_stripped == end_with_newline
|
||||
}
|
||||
|
||||
fn test_strip_margins_space_delimiter() {
|
||||
space_delimiter := ['Using a white-space char will',
|
||||
'revert back to default behavior.',
|
||||
].join('\n')
|
||||
space_delimiter_stripped := 'Using a white-space char will
|
||||
|revert back to default behavior.'.strip_margin(`\n`)
|
||||
assert space_delimiter == space_delimiter_stripped
|
||||
}
|
||||
|
||||
fn test_strip_margins_crlf() {
|
||||
crlf := ['This string\'s line endings have CR as well as LFs.',
|
||||
'This should pass',
|
||||
'Definitely',
|
||||
].join('\r\n')
|
||||
crlf_stripped := 'This string\'s line endings have CR as well as LFs.\r
|
||||
|This should pass\r
|
||||
|Definitely'.strip_margin()
|
||||
|
||||
assert crlf == crlf_stripped
|
||||
}
|
||||
|
@ -1,36 +1,57 @@
|
||||
|
||||
fn test_simple_string_interpolation(){
|
||||
fn test_simple_string_interpolation() {
|
||||
a := 'Hello'
|
||||
b := 'World'
|
||||
res := '$a $b'
|
||||
assert res == 'Hello World'
|
||||
}
|
||||
|
||||
fn test_mixed_string_interpolation() {
|
||||
num := 7
|
||||
str := 'abc'
|
||||
s1 := 'number=$num'
|
||||
assert s1 == 'number=7'
|
||||
s2 := 'string=$str'
|
||||
assert s2 == 'string=abc'
|
||||
s3 := 'a: $num | b: $str'
|
||||
assert s3 == 'a: 7 | b: abc'
|
||||
}
|
||||
|
||||
fn test_formatted_string_interpolation() {
|
||||
x := 'abc'
|
||||
axb := 'a:$x:b'
|
||||
assert axb == 'a:abc:b'
|
||||
x_10 := 'a:${x:10s}:b'
|
||||
x10_ := 'a:${x:-10s}:b'
|
||||
assert x_10 == 'a: abc:b'
|
||||
assert x10_ == 'a:abc :b'
|
||||
i := 23
|
||||
si_right := '${i:10d}'
|
||||
si__left := '${i:-10d}'
|
||||
assert si_right == ' 23'
|
||||
assert si__left == '23 '
|
||||
}
|
||||
|
||||
fn test_excape_dollar_in_string() {
|
||||
i := 42
|
||||
|
||||
assert '($i)' == '(42)'
|
||||
assert '(\$i)'.contains('i') && !'(\$i)'.contains('42')
|
||||
assert !'(\\$i)'.contains('i') && '(\\$i)'.contains('42') && '(\\$i)'.contains('\\')
|
||||
assert '(\\\$i)'.contains('i') && !'(\\\$i)'.contains('42') && '(\\$i)'.contains('\\')
|
||||
assert !'(\\\\$i)'.contains('i') && '(\\\\$i)'.contains('42') && '(\\\\$i)'.contains('\\\\')
|
||||
|
||||
assert '(${i})' == '(42)'
|
||||
assert '(\${i})'.contains('i') && !'(\${i})'.contains('42')
|
||||
assert !'(\\${i})'.contains('i') && '(\\${i})'.contains('42') && '(\\${i})'.contains('\\')
|
||||
assert '(\\\${i})'.contains('i') && !'(\\\${i})'.contains('42') && '(\\${i})'.contains('\\')
|
||||
assert !'(\\\\${i})'.contains('i') && '(\\\\${i})'.contains('42') && '(\\\\${i})'.contains('\\\\')
|
||||
assert i==42
|
||||
i := 42
|
||||
assert '($i)' == '(42)'
|
||||
assert '(\$i)'.contains('i') && !'(\$i)'.contains('42')
|
||||
assert !'(\\$i)'.contains('i') && '(\\$i)'.contains('42') && '(\\$i)'.contains('\\')
|
||||
assert '(\\\$i)'.contains('i') && !'(\\\$i)'.contains('42') && '(\\$i)'.contains('\\')
|
||||
assert !'(\\\\$i)'.contains('i') && '(\\\\$i)'.contains('42') && '(\\\\$i)'.contains('\\\\')
|
||||
assert '(${i})' == '(42)'
|
||||
assert '(\${i})'.contains('i') && !'(\${i})'.contains('42')
|
||||
assert !'(\\${i})'.contains('i') && '(\\${i})'.contains('42') && '(\\${i})'.contains('\\')
|
||||
assert '(\\\${i})'.contains('i') && !'(\\\${i})'.contains('42') && '(\\${i})'.contains('\\')
|
||||
assert !'(\\\\${i})'.contains('i') && '(\\\\${i})'.contains('42') && '(\\\\${i})'.contains('\\\\')
|
||||
assert i == 42
|
||||
}
|
||||
|
||||
fn test_implicit_str() {
|
||||
i := 42
|
||||
assert 'int $i' == 'int 42'
|
||||
assert '$i' == '42'
|
||||
|
||||
check := '$i' == '42'
|
||||
assert check
|
||||
|
||||
text := '$i' + '42'
|
||||
assert text == '4242'
|
||||
i := 42
|
||||
assert 'int $i' == 'int 42'
|
||||
assert '$i' == '42'
|
||||
check := '$i' == '42'
|
||||
assert check
|
||||
text := '$i' + '42'
|
||||
assert text == '4242'
|
||||
}
|
||||
|
25
vlib/compiler/tests/string_struct_interpolation_test.v
Normal file
25
vlib/compiler/tests/string_struct_interpolation_test.v
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
struct Foo {
|
||||
bar int
|
||||
mut:
|
||||
str string
|
||||
}
|
||||
|
||||
fn (f Foo) baz() string {
|
||||
return 'baz'
|
||||
}
|
||||
|
||||
fn test_string_method_interpolation() {
|
||||
foo := Foo{}
|
||||
s := 'baz=${foo.baz()}'
|
||||
assert s == 'baz=baz'
|
||||
}
|
||||
|
||||
fn test_adding_to_mutable_string_field() {
|
||||
mut foo := Foo{10, 'hi'}
|
||||
assert foo.bar == 10
|
||||
assert foo.str == 'hi'
|
||||
foo.str += '!'
|
||||
eprintln( foo.str )
|
||||
assert foo.str == 'hi!'
|
||||
}
|
@ -59,6 +59,9 @@ pub fn (node &FnDecl) str(t &table.Table) string {
|
||||
// string representaiton of expr
|
||||
pub fn (x Expr) str() string {
|
||||
match x {
|
||||
Ident {
|
||||
return it.name
|
||||
}
|
||||
InfixExpr {
|
||||
return '(${it.left.str()} $it.op.str() ${it.right.str()})'
|
||||
}
|
||||
|
@ -269,16 +269,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||
// g.writeln('//// stmt start')
|
||||
match node {
|
||||
ast.AssertStmt {
|
||||
g.writeln('// assert')
|
||||
g.write('if ((')
|
||||
g.expr(it.expr)
|
||||
g.writeln(')) {')
|
||||
g.writeln('g_test_oks++;')
|
||||
// g.writeln('puts("OK $g.fn_decl.name");')
|
||||
g.writeln('} else {')
|
||||
g.writeln('g_test_fails++;')
|
||||
g.writeln('puts("FAILED $g.fn_decl.name $it.pos.line_nr");')
|
||||
g.writeln('}')
|
||||
g.gen_assert_stmt(it)
|
||||
}
|
||||
ast.AssignStmt {
|
||||
g.gen_assign_stmt(it)
|
||||
@ -366,7 +357,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||
g.writeln('}')
|
||||
}
|
||||
ast.ForInStmt {
|
||||
g.for_in(it)
|
||||
g.for_in(it)
|
||||
}
|
||||
ast.ForStmt {
|
||||
g.write('while (')
|
||||
@ -522,6 +513,29 @@ fn (g mut Gen) expr_with_cast(expr ast.Expr, got_type table.Type, exp_type table
|
||||
g.expr(expr)
|
||||
}
|
||||
|
||||
fn (g mut Gen) gen_assert_stmt(a ast.AssertStmt) {
|
||||
g.writeln('// assert')
|
||||
g.write('if( ')
|
||||
g.expr(a.expr)
|
||||
s_assertion := a.expr.str().replace('"', "\'")
|
||||
g.write(' )')
|
||||
if g.is_test {
|
||||
g.writeln('{')
|
||||
g.writeln(' g_test_oks++;')
|
||||
// g.writeln(' println(_STR("OK ${g.file.path}:${a.pos.line_nr}: fn ${g.fn_decl.name}(): assert $s_assertion"));')
|
||||
g.writeln('}else{')
|
||||
g.writeln(' g_test_fails++;')
|
||||
g.writeln(' eprintln(_STR("${g.file.path}:${a.pos.line_nr}: FAIL: fn ${g.fn_decl.name}(): assert $s_assertion"));')
|
||||
g.writeln(' exit(1);')
|
||||
g.writeln('}')
|
||||
} else {
|
||||
g.writeln('{}else{')
|
||||
g.writeln(' eprintln(_STR("${g.file.path}:${a.pos.line_nr}: FAIL: fn ${g.fn_decl.name}(): assert $s_assertion"));')
|
||||
g.writeln(' exit(1);')
|
||||
g.writeln('}')
|
||||
}
|
||||
}
|
||||
|
||||
fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||
// g.write('/*assign_stmt*/')
|
||||
if assign_stmt.left.len > assign_stmt.right.len {
|
||||
@ -537,7 +551,7 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||
else {
|
||||
panic('expected call')
|
||||
}
|
||||
}
|
||||
}
|
||||
mr_var_name := 'mr_$assign_stmt.pos.pos'
|
||||
g.expr_var_name = mr_var_name
|
||||
if table.type_is_optional(return_type) {
|
||||
@ -738,9 +752,9 @@ fn (g mut Gen) free_scope_vars(pos int) {
|
||||
continue
|
||||
}
|
||||
else {
|
||||
g.writeln('// other' + t)
|
||||
g.writeln('// other ' + t)
|
||||
}
|
||||
}
|
||||
}
|
||||
g.writeln('string_free($var.name); // autofreed')
|
||||
}
|
||||
}
|
||||
@ -2031,24 +2045,39 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||
// }
|
||||
// else {}
|
||||
// }
|
||||
if node.expr_types[i] == table.string_type {
|
||||
|
||||
sfmt := node.expr_fmts[i]
|
||||
if sfmt.len > 0 {
|
||||
fspec := sfmt[sfmt.len-1]
|
||||
if fspec == `s` && node.expr_types[i] != table.string_type {
|
||||
verror('only V strings can be formatted with a ${sfmt} format')
|
||||
}
|
||||
g.write('%' + sfmt[1..])
|
||||
}else if node.expr_types[i] == table.string_type {
|
||||
g.write('%.*s')
|
||||
}
|
||||
else if node.expr_types[i] == table.int_type {
|
||||
}else {
|
||||
g.write('%d')
|
||||
}
|
||||
}
|
||||
g.write('", ')
|
||||
// Build args
|
||||
for i, expr in node.exprs {
|
||||
if node.expr_types[i] == table.string_type {
|
||||
sfmt := node.expr_fmts[i]
|
||||
if sfmt.len > 0 {
|
||||
fspec := sfmt[sfmt.len-1]
|
||||
if fspec == `s` && node.expr_types[i] == table.string_type {
|
||||
g.expr(expr)
|
||||
g.write('.str')
|
||||
}else{
|
||||
g.expr(expr)
|
||||
}
|
||||
} else if node.expr_types[i] == table.string_type {
|
||||
// `name.str, name.len,`
|
||||
g.expr(expr)
|
||||
g.write('.len, ')
|
||||
g.expr(expr)
|
||||
g.write('.str')
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g.expr(expr)
|
||||
}
|
||||
if i < node.exprs.len - 1 {
|
||||
@ -2366,15 +2395,36 @@ fn (g &Gen) type_default(typ table.Type) string {
|
||||
}
|
||||
|
||||
pub fn (g mut Gen) write_tests_main() {
|
||||
g.definitions.writeln('int g_test_oks = 0;')
|
||||
g.definitions.writeln('int g_test_fails = 0;')
|
||||
g.writeln('int main() {')
|
||||
g.writeln('\t_vinit();')
|
||||
mut tfuncs := []string
|
||||
mut tsuite_begin := ''
|
||||
mut tsuite_end := ''
|
||||
for _, f in g.table.fns {
|
||||
if f.name == 'testsuite_begin' {
|
||||
tsuite_begin = f.name
|
||||
}
|
||||
if f.name == 'testsuite_end' {
|
||||
tsuite_end = f.name
|
||||
}
|
||||
if !f.name.starts_with('test_') {
|
||||
continue
|
||||
}
|
||||
g.writeln('\t${f.name}();')
|
||||
tfuncs << f.name
|
||||
}
|
||||
g.writeln('return 0; }')
|
||||
if tsuite_begin.len > 0 {
|
||||
g.writeln('\t${tsuite_begin}();\n')
|
||||
}
|
||||
for t in tfuncs {
|
||||
g.writeln('\t${t}();')
|
||||
}
|
||||
if tsuite_end.len > 0 {
|
||||
g.writeln('\t${tsuite_end}();\n')
|
||||
}
|
||||
g.writeln('\treturn 0;')
|
||||
g.writeln('}')
|
||||
}
|
||||
|
||||
fn (g &Gen) is_importing_os() bool {
|
||||
|
@ -186,8 +186,6 @@ extern wchar_t **_wenviron;
|
||||
|
||||
//================================== GLOBALS =================================*/
|
||||
byte g_str_buf[1024];
|
||||
int g_test_fails = 0;
|
||||
int g_test_oks = 0;
|
||||
int load_so(byteptr);
|
||||
void reload_so();
|
||||
void _vinit();
|
||||
|
Loading…
Reference in New Issue
Block a user