2 # Copyright (C) 2001-2010, Parrot Foundation.
7 use lib qw( . lib ../lib ../../lib );
10 use Parrot::Config qw(%PConfig);
14 t/pmc/nci.t - test the Native Call Interface
22 This tests the Native Call Interface, that is the ParrotLibrary PMC.
23 Most tests are skipped when the F<libnci_test.so> shared library is not found.
27 F<docs/pdds/pdd16_native_call.pod>
28 F<config/gen/makefiles/root.in>
33 $ENV{TEST_PROG_ARGS} ||= '';
36 unless ( -e "runtime/parrot/dynext/libnci_test$PConfig{load_ext}" ) {
37 plan skip_all => "Please make libnci_test$PConfig{load_ext}";
41 pir_output_is( << 'CODE', << 'OUTPUT', 'load library fails' );
43 .local pmc libnci_test
44 .local int lib_defined
45 libnci_test = loadlib "no_such_library"
46 lib_defined = defined libnci_test
47 if lib_defined goto LIB_DEFINED
64 pir_output_is( << 'CODE', << 'OUTPUT', 'dlfunc on undef' );
66 .local pmc libnci_test
68 .local int func_defined
69 libnci_test = loadlib "no_such_library"
70 dlfunc func, libnci_test, "no_such_function", "v"
71 func_defined = defined func
72 if func_defined goto FUNC_DEFINED
88 pir_output_is( << 'CODE', << 'OUTPUT', 'dlfunc function not found' );
90 .local pmc libnci_test
92 .local int func_defined
93 libnci_test = loadlib "libnci_test"
94 unless libnci_test goto NOT_LOADED
95 print "libnci_test was successfully loaded\n"
97 dlfunc func, libnci_test, "no_such_function", "v"
98 func_defined = defined func
99 if func_defined goto FUNC_DEFINED
100 branch FUNC_UNDEFINED
111 print "Could not load libnci_test\n"
117 libnci_test was successfully loaded
121 pir_output_is( << 'CODE', << "OUTPUT", "nci_c - return a char in an INTEGER register" );
123 .include "datatypes.pasm"
128 .local pmc libnci_test
129 libnci_test = loadlib "libnci_test"
130 unless libnci_test goto NOT_LOADED
131 print "libnci_test was successfully loaded\n"
133 # calling a function in libnci_test
135 dlfunc nci_c, libnci_test, "nci_c", "c"
137 ( nci_c_out ) = nci_c( )
143 libnci_test was successfully loaded
147 pir_output_is( << 'CODE', << 'OUTPUT', "nci_d and nci_dlvar_double" );
149 .include "datatypes.pasm"
153 # load libnci_test.so
154 .local string library_name
155 library_name = 'libnci_test'
156 .local pmc libnci_test
157 libnci_test = loadlib library_name
158 unless libnci_test goto NOT_LOADED
160 print " was successfully loaded\n"
162 # address of nci_dlvar_double
163 .local pmc nci_dlvar_double
164 nci_dlvar_double = dlvar libnci_test, "nci_dlvar_double"
166 # the contained structure pointer
167 .local pmc nci_dlvar_double_decl
168 nci_dlvar_double_decl = new ['ResizablePMCArray']
169 push nci_dlvar_double_decl, .DATATYPE_DOUBLE
170 push nci_dlvar_double_decl, 0
171 push nci_dlvar_double_decl, 0
172 assign nci_dlvar_double, nci_dlvar_double_decl
174 $N2 = nci_dlvar_double[0]
179 nci_d = dlfunc libnci_test, "nci_d", "d"
181 ( nci_d_out ) = nci_d( )
184 ( nci_d_out ) = nci_d( )
187 ( nci_d_out ) = nci_d( )
190 ( nci_d_out ) = nci_d( )
193 ( nci_d_out ) = nci_d( )
200 libnci_test was successfully loaded
209 pir_output_is( << 'CODE', << 'OUTPUT', "nci_f and nci_dlvar_float" );
211 .include "datatypes.pasm"
215 # load libnci_test.so
216 .local string library_name
217 library_name = 'libnci_test'
218 .local pmc libnci_test
219 libnci_test = loadlib library_name
220 unless libnci_test goto NOT_LOADED
222 print " was successfully loaded\n"
224 # address of nci_dlvar_float
225 .local pmc nci_dlvar_float
226 nci_dlvar_float = dlvar libnci_test, "nci_dlvar_float"
228 # the contained structure pointer
229 .local pmc nci_dlvar_float_decl
230 nci_dlvar_float_decl = new ['ResizablePMCArray']
231 push nci_dlvar_float_decl, .DATATYPE_FLOAT
232 push nci_dlvar_float_decl, 0
233 push nci_dlvar_float_decl, 0
234 assign nci_dlvar_float, nci_dlvar_float_decl
236 $N2 = nci_dlvar_float[0]
241 nci_f = dlfunc libnci_test, "nci_f", "f"
243 ( nci_f_out ) = nci_f( )
246 ( nci_f_out ) = nci_f( )
249 ( nci_f_out ) = nci_f( )
252 ( nci_f_out ) = nci_f( )
255 ( nci_f_out ) = nci_f( )
262 libnci_test was successfully loaded
271 pir_output_is( << 'CODE', << "OUTPUT", "nci_l - return a long in an INTEGER register" );
273 .include "datatypes.pasm"
278 .local pmc libnci_test
279 libnci_test = loadlib "libnci_test"
280 unless libnci_test goto NOT_LOADED
281 print "libnci_test was successfully loaded\n"
283 # calling a function in libnci_test
285 dlfunc nci_l, libnci_test, "nci_l", "l"
287 ( nci_l_out ) = nci_l( )
293 libnci_test was successfully loaded
297 pir_output_is( << 'CODE', << "OUTPUT", "nci_p - return a pointer to int" );
299 .include "datatypes.pasm"
304 .local pmc libnci_test
305 libnci_test = loadlib "libnci_test"
306 unless libnci_test goto NOT_LOADED
307 print "libnci_test was successfully loaded\n"
309 # calling a function in libnci_test
311 dlfunc nci_p, libnci_test, "nci_p", "p"
313 ( nci_p_out ) = nci_p( )
315 # the contained structure pointer
316 .local pmc nci_p_out_decl
317 nci_p_out_decl = new ['ResizablePMCArray']
318 push nci_p_out_decl, .DATATYPE_INT
319 push nci_p_out_decl, 0
320 push nci_p_out_decl, 0
321 assign nci_p_out, nci_p_out_decl
329 libnci_test was successfully loaded
333 pir_output_is( << 'CODE', << "OUTPUT", "nci_t - return a C-string" );
335 .include "datatypes.pasm"
340 .local pmc libnci_test
341 libnci_test = loadlib "libnci_test"
342 unless libnci_test goto NOT_LOADED
343 print "libnci_test was successfully loaded\n"
345 # calling a function in libnci_test
347 dlfunc nci_t, libnci_test, "nci_t", "t"
348 .local string nci_t_out
349 ( nci_t_out ) = nci_t( )
354 libnci_test was successfully loaded
358 pir_output_is( << 'CODE', << "OUTPUT", "nci_s - return a short in an INTEGER register" );
360 .include "datatypes.pasm"
365 .local pmc libnci_test
366 libnci_test = loadlib "libnci_test"
367 unless libnci_test goto NOT_LOADED
368 print "libnci_test was successfully loaded\n"
370 # calling a function in libnci_test
372 dlfunc nci_s, libnci_test, "nci_s", "s"
374 ( nci_s_out ) = nci_s( )
380 libnci_test was successfully loaded
387 skip( "nci_dlvar_int hangs on HP-UX", 1 ) if $^O eq 'hpux';
389 pir_output_is( << 'CODE', << 'OUTPUT', "nci_v and nci_dlvar_int" );
391 .include "datatypes.pasm"
395 # load libnci_test.so
396 .local string library_name
397 library_name = 'libnci_test'
398 .local pmc libnci_test
399 libnci_test = loadlib library_name
400 unless libnci_test goto NOT_LOADED
402 print " was successfully loaded\n"
404 # address of nci_dlvar_int
405 .local pmc nci_dlvar_int
406 nci_dlvar_int = dlvar libnci_test, "nci_dlvar_int"
408 # the contained structure pointer
409 .local pmc nci_dlvar_int_decl
410 nci_dlvar_int_decl = new ['ResizablePMCArray']
411 push nci_dlvar_int_decl, .DATATYPE_INT
412 push nci_dlvar_int_decl, 0
413 push nci_dlvar_int_decl, 0
414 assign nci_dlvar_int, nci_dlvar_int_decl
416 $I2 = nci_dlvar_int[0]
421 nci_v = dlfunc libnci_test, "nci_v", "v"
423 $I1 = nci_dlvar_int[0]
427 $I1 = nci_dlvar_int[0]
431 $I1 = nci_dlvar_int[0]
435 $I1 = nci_dlvar_int[0]
441 libnci_test was successfully loaded
450 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_dd - PASM" );
451 loadlib P1, "libnci_test"
453 dlfunc P0, P1, "nci_dd", "dd"
461 nok_1: print "nok 1\n"
471 pir_output_is( << 'CODE', << 'OUTPUT', "nci_dd - PIR" );
474 .local string library_name
475 library_name = 'libnci_test'
476 .local pmc libnci_test
477 libnci_test = loadlib library_name
478 unless libnci_test goto NOT_LOADED
480 print " was successfully loaded\n"
482 twice = dlfunc libnci_test, "nci_dd", "dd"
490 libnci_test was successfully loaded
494 pir_output_is( << 'CODE', << "OUTPUT", "get_string()" );
497 .local string library_name
498 library_name = 'libnci_test'
499 .local pmc libnci_test
500 libnci_test = loadlib library_name
501 unless libnci_test goto NOT_LOADED
502 .local string filename_with_path
503 filename_with_path = libnci_test
504 # depending on the platform, 'filename' has path info or not
505 .local int start_of_filename
506 start_of_filename = index filename_with_path, 'libnci_test'
507 if start_of_filename == -1 goto NOT_LOADED
508 .local string filename
509 filename = substr filename_with_path, start_of_filename
511 print " was successfully loaded"
516 libnci_test was successfully loaded
519 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_fff" );
520 loadlib P1, "libnci_test"
522 dlfunc P0, P1, "nci_fff", "fff"
526 set_args "0,0", N5, N6
532 nok_1: print "nok 1\n"
542 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_isc" );
543 loadlib P1, "libnci_test"
545 dlfunc P0, P1, "nci_isc", "isc"
549 set_args "0,0", I5, I6
555 nok_1: print "nok 1\n"
565 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_ssc" );
566 loadlib P1, "libnci_test"
568 dlfunc P0, P1, "nci_ssc", "ssc"
572 set_args "0,0", I5, I6
578 nok_1: print "nok 1\n"
588 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_csc" );
589 loadlib P1, "libnci_test"
591 dlfunc P0, P1, "nci_csc", "csc"
595 set_args "0,0", I5, I6
601 nok_1: print "nok 1\n"
611 pir_output_is( <<'CODE', <<'OUTPUT', "nci_it" );
614 loadlib $P1, "libnci_test"
616 dlfunc $P0, $P1, "nci_it", "it"
617 printerr "dlfunced\n"
625 nok_1: printerr "nok 1\n"
629 nok_2: printerr "nok 2\n"
638 pir_output_is( <<'CODE', <<'OUTPUT', "nci_it" );
640 .include "datatypes.pasm"
644 loadlib $P1, "libnci_test"
647 nci_it = dlfunc $P1, "nci_it", "it"
648 printerr "dlfunced\n"
649 ( $I5 ) = nci_it( "ko" )
655 nok_1: printerr "nok 1\n"
659 nok_2: printerr "nok 2\n"
669 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_tt" );
670 loadlib P1, "libnci_test"
672 dlfunc P0, P1, "nci_tt", "tt"
680 nok_1: print "nok 1\n"
684 nok_2: print "nok 2\n"
692 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_dd - stress test" );
693 loadlib P1, "libnci_test"
698 dlfunc P0, P1, "nci_dd", "dd"
708 nok_1: print "nok 1\n"
712 nok_2: print "nok 2\n"
720 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_dd - clone" );
721 loadlib P1, "libnci_test"
723 dlfunc P0, P1, "nci_dd", "dd"
737 nok_1: print "nok 1\n"
748 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_iiii" );
749 loadlib P1, "libnci_test"
750 dlfunc P0, P1, "nci_iiii", "iiii"
754 set_args "0,0,0", I5,I6,I7
765 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_i4i" );
766 loadlib P1, "libnci_test"
767 dlfunc P0, P1, "nci_i4i", "i4i"
771 set_args "0,0", P5,I5
781 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_ii3" );
782 .include "datatypes.pasm"
783 loadlib P1, "libnci_test"
784 dlfunc P0, P1, "nci_ii3", "ii3"
790 set_args "0,0", I5,P5
804 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_tb" );
805 loadlib P1, "libnci_test"
806 dlfunc P0, P1, "nci_tb", "tb"
817 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_tB" );
818 loadlib P1, "libnci_test"
819 dlfunc P0, P1, "nci_tB", "tB"
830 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_pi - struct with ints" );
831 loadlib P1, "libnci_test"
832 dlfunc P0, P1, "nci_pi", "pi"
833 # this test function returns a struct { int[2]; char }
838 new P2, ['ResizablePMCArray']
839 .include "datatypes.pasm"
840 push P2, .DATATYPE_INT
841 push P2, 2 # 2 elem array
843 push P2, .DATATYPE_CHAR
863 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_pi - struct with floats" );
864 loadlib P1, "libnci_test"
865 dlfunc P0, P1, "nci_pi", "pi"
866 # this test function returns a struct { float[2]; double }
870 new P2, ['ResizablePMCArray']
871 .include "datatypes.pasm"
872 push P2, .DATATYPE_FLOAT
873 push P2, 2 # 2 elem array
875 push P2, .DATATYPE_DOUBLE
895 pasm_output_like( <<'CODE', <<'OUTPUT', "nci_pi - align" );
896 loadlib P1, "libnci_test"
897 dlfunc P0, P1, "nci_pi", "pi"
898 # this test function returns a struct { char; int }
902 new P2, ['ResizablePMCArray']
903 .include "datatypes.pasm"
904 push P2, .DATATYPE_CHAR
907 push P2, .DATATYPE_INT
917 # check the offset of the int
929 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_pi - char*" );
930 loadlib P1, "libnci_test"
931 dlfunc P0, P1, "nci_pi", "pi"
932 # this test function returns a struct { char*; int }
936 new P2, ['ResizablePMCArray']
937 .include "datatypes.pasm"
938 push P2, .DATATYPE_CSTR
941 push P2, .DATATYPE_INT
957 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_pi - nested struct *" );
958 loadlib P1, "libnci_test"
959 dlfunc P0, P1, "nci_pi", "pi"
960 # this test function returns a struct { char; x->{int, double} }
964 .include "datatypes.pasm"
965 # the contained structure
966 new P3, ['ResizablePMCArray']
967 push P3, .DATATYPE_INT
970 push P3, .DATATYPE_INT
973 push P3, .DATATYPE_DOUBLE
976 new P4, ['UnManagedStruct'], P3
978 new P2, ['ResizablePMCArray']
979 push P2, .DATATYPE_CHAR
982 push P2, .DATATYPE_STRUCT_PTR
983 # attach the unmanged struct as property
985 setprop P1, "_struct", P4
988 # attach struct initializer
1000 # get item x->double
1012 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_pi - nested struct * w named access" );
1013 loadlib P1, "libnci_test"
1014 dlfunc P0, P1, "nci_pi", "pi"
1018 .include "datatypes.pasm"
1019 # the contained structure pointer
1020 new P6, 'OrderedHash'
1021 set P6[ 'i' ], .DATATYPE_INT
1024 set P6[ 'j' ], .DATATYPE_INT
1027 new P7, ['UnManagedStruct'], P6
1028 # the contained structure
1029 new P3, 'OrderedHash'
1030 set P3[ 'i' ], .DATATYPE_INT
1033 set P3[ 'j' ], .DATATYPE_INT
1036 set P3[ '_z' ], .DATATYPE_STRUCT_PTR
1038 setprop P1, "_struct", P7
1041 new P4, ['UnManagedStruct'], P3
1043 new P2, ['OrderedHash']
1044 set P2[ 'x' ], .DATATYPE_INT
1047 set P2[ '_y' ], .DATATYPE_STRUCT
1048 # attach the unmanged struct as property
1050 setprop P1, "_struct", P4
1053 set P2[ 'z' ], .DATATYPE_INT
1056 # attach struct initializer
1061 set I0, P5[ '_y'; 'i' ]
1064 set I0, P5[ '_y'; 'j' ]
1067 set I0, P5[ '_y'; '_z'; 'i' ]
1070 set I0, P5[ '_y'; '_z'; 'j' ]
1082 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_pi - func_ptr* with signature" );
1083 loadlib P1, "libnci_test"
1084 dlfunc P0, P1, "nci_pi", "pi"
1085 # this test function returns a struct { int (*f)(char *) }
1089 new P2, ['ResizablePMCArray']
1090 .include "datatypes.pasm"
1091 push P2, .DATATYPE_FUNC_PTR
1092 # attach function signature property to this type
1096 setprop P1, "_signature", P3
1100 # now we get a callable NCI PMC
1102 set_args "0", "hello call_back"
1113 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_pi - nested struct aligned" );
1114 loadlib P1, "libnci_test"
1115 dlfunc P0, P1, "nci_pi", "pi"
1116 # this test function returns a struct { int; {int; int} int }
1120 .include "datatypes.pasm"
1121 # the nested structure
1122 new P3, ['ResizablePMCArray']
1123 push P3, .DATATYPE_INT
1126 push P3, .DATATYPE_INT
1129 new P4, ['UnManagedStruct'], P3
1131 new P2, ['ResizablePMCArray']
1132 push P2, .DATATYPE_INT
1135 push P2, .DATATYPE_STRUCT
1136 # attach the unmanged struct as property
1138 setprop P1, "_struct", P4
1141 push P2, .DATATYPE_INT
1144 # attach struct initializer
1168 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_pi - nested struct unaligned" );
1169 loadlib P1, "libnci_test"
1170 dlfunc P0, P1, "nci_pi", "pi"
1171 # this test function returns a struct { char; {char; int} char }
1175 .include "datatypes.pasm"
1176 # the nested structure
1177 new P3, ['ResizablePMCArray']
1178 push P3, .DATATYPE_CHAR
1181 push P3, .DATATYPE_INT
1184 new P4, ['UnManagedStruct'], P3
1186 new P2, ['ResizablePMCArray']
1187 push P2, .DATATYPE_CHAR
1190 push P2, .DATATYPE_STRUCT
1191 # attach the unmanged struct as property
1193 setprop P1, "_struct", P4
1196 push P2, .DATATYPE_CHAR
1199 # attach struct initializer
1223 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_pi - nested, unaligned, named" );
1224 loadlib P1, "libnci_test"
1225 dlfunc P0, P1, "nci_pi", "pi"
1226 # this test function returns a struct { char; {char; int} char }
1230 .include "datatypes.pasm"
1231 # the nested structure
1232 new P3, ['OrderedHash']
1233 set P3["i"], .DATATYPE_CHAR
1236 set P3["j"], .DATATYPE_INT
1239 new P4, ['UnManagedStruct'], P3
1241 new P2, ['OrderedHash']
1242 set P2["x"], .DATATYPE_CHAR
1245 set P2["_y"], .DATATYPE_STRUCT
1246 # attach the unmanged struct as property
1248 setprop P1, "_struct", P4
1251 set P2["z"], .DATATYPE_CHAR
1254 # attach struct initializer
1260 set I0, P5["_y";"i"]
1264 set I0, P5["_y"; "j"]
1278 pir_output_is( << 'CODE', << "OUTPUT", "nci_pi - int" );
1280 .include "datatypes.pasm"
1285 .local pmc libnci_test
1286 libnci_test = loadlib "libnci_test"
1287 unless libnci_test goto NOT_LOADED
1288 print "libnci_test was successfully loaded\n"
1290 # calling a function in libnci_test
1292 dlfunc nci_pi, libnci_test, "nci_pi", "pi"
1293 .local pmc nci_pi_out
1294 ( nci_pi_out ) = nci_pi( 9 )
1296 # the contained structure pointer
1297 .local pmc nci_pi_out_decl
1298 nci_pi_out_decl = new ['ResizablePMCArray']
1299 push nci_pi_out_decl, .DATATYPE_INT
1300 push nci_pi_out_decl, 0
1301 push nci_pi_out_decl, 0
1303 # attach struct initializer
1304 assign nci_pi_out, nci_pi_out_decl
1305 set $I0, nci_pi_out[0]
1311 libnci_test was successfully loaded
1315 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_ip" );
1316 loadlib P1, "libnci_test"
1317 dlfunc P0, P1, "nci_ip", "ip"
1318 # this test function wants a struct
1319 # { double d; float f; int i; char*}
1320 # and returns the sum of these values
1321 new P2, ['ResizablePMCArray']
1322 .include "datatypes.pasm"
1323 push P2, .DATATYPE_DOUBLE
1326 push P2, .DATATYPE_FLOAT
1327 push P2, 0 # 1 elem array
1329 push P2, .DATATYPE_INT
1330 push P2, 0 # 1 elem array
1332 push P2, .DATATYPE_CSTR
1333 push P2, 0 # 1 elem array
1335 new P5, ['ManagedStruct'], P2
1339 set P5[3], "hello from Parrot\x0"
1352 pir_output_is( << 'CODE', << "OUTPUT", "nci_pi - null" );
1354 .include "datatypes.pasm"
1359 .local pmc libnci_test
1360 libnci_test = loadlib "libnci_test"
1361 unless libnci_test goto FAILED
1363 # calling a function in libnci_test
1365 dlfunc nci_pi, libnci_test, "nci_pi", "pi"
1367 result = nci_pi( 10 )
1368 unless_null result, FAILED
1377 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_vP", todo => 'Disabled to avoid linkage problems, see src/nci_test.c' );
1378 loadlib P1, "libnci_test"
1379 dlfunc P0, P1, "nci_vP", "vP"
1393 # Tests with callback functions
1394 my @todo = $ENV{TEST_PROG_ARGS} =~ /--runcore=jit/ ?
1395 ( todo => 'TT #1316, add scheduler tasks to JIT' ) : ();
1397 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_cb_C1 - PASM", @todo );
1399 # we need a flag if the call_back is already done
1400 new P10, ['Integer']
1401 set_global "cb_done", P10
1402 # first attempt - create cb manually (this step will be hidden later)
1403 .const 'Sub' P6 = "_call_back"
1407 new_callback P5, P6, P7, "vtU" # Z in pdd16
1409 # now call the external sub, that takes a call_back and user_data
1410 loadlib P1, "libnci_test"
1411 dlfunc P0, P1, "nci_cb_C1", "vpP"
1415 set_args "0,0", P5, P7
1417 # call_back will be called at any time
1423 get_global P11, "cb_done"
1431 print "cb didnt run\n"
1434 .pcc_sub _call_back:
1435 get_params "0,0", P5, S5
1436 print "in callback\n"
1440 print "external data: "
1443 get_global P12, "cb_done"
1452 external data: succeeded
1456 pir_output_is( <<'CODE', <<'OUTPUT', "nci_cb_C1 - PIR", @todo );
1460 # this flag will be set by the callback function
1462 cb_done = new ['Integer']
1464 set_global "cb_done", cb_done
1467 .local pmc user_data
1468 user_data = new ['Integer']
1471 # A Sub that can be given to the library
1472 # this callback function will eventually by called by the library
1473 .const 'Sub' cb = "_call_back"
1474 .local pmc cb_wrapped
1475 cb_wrapped = new_callback cb, user_data, "vtU" # Z in pdd16
1476 print "created a callback sub\n"
1478 # now call the external sub, that takes a callback and user data
1479 .local pmc libnci_test
1480 libnci_test = loadlib "libnci_test"
1481 .local pmc nci_cb_C1
1482 nci_cb_C1 = dlfunc libnci_test, "nci_cb_C1", "vpP"
1483 print "loaded a function that takes a callback\n"
1484 nci_cb_C1( cb_wrapped, user_data )
1486 # callback will be called at any time
1488 .local int sleep_cnt
1493 .local pmc callback_has_run
1494 callback_has_run = get_global "cb_done"
1495 if callback_has_run goto FINISHED
1496 if sleep_cnt > 10 goto ERROR
1499 print "the callback has run\n"
1502 print "the callback didnt run\n"
1509 print "in callback\n"
1513 print "external data: "
1516 get_global $P12, "cb_done"
1522 created a callback sub
1523 loaded a function that takes a callback
1526 external data: succeeded
1527 the callback has run
1530 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_cb_C2 - PASM", @todo );
1531 # we need a flag if the call_back is already done
1532 new P10, ['Integer']
1533 set_global "cb_done", P10
1534 # first attempt - create cb manually (this step will be hidden later)
1535 .const 'Sub' P6 = "_call_back"
1539 new_callback P5, P6, P7, "viU" # Z in pdd16
1541 # now call the external sub, that takes a call_back and user_data
1542 loadlib P1, "libnci_test"
1543 dlfunc P0, P1, "nci_cb_C2", "vpP"
1547 set_args "0,0", P5, P7
1549 # call_back will be called at any time
1555 get_global P11, "cb_done"
1563 print "cb didnt run\n"
1566 .pcc_sub _call_back:
1567 get_params "0,0", P5, I5
1568 print "in callback\n"
1572 print "external data: "
1575 get_global P12, "cb_done"
1589 pir_output_is( <<'CODE', <<'OUTPUT', "nci_cb_C3 - PIR", @todo );
1592 .include "datatypes.pasm"
1596 # this flag will be set by the callback function
1598 cb_done = new ['Integer']
1600 set_global "cb_done", cb_done
1603 .local pmc user_data
1604 user_data = new ['Integer']
1607 # A Sub that can be given to the library
1608 # this callback function will eventually by called by the library
1609 .const 'Sub' cb = "_call_back"
1610 .local pmc cb_wrapped
1611 cb_wrapped = new_callback cb, user_data, "vpU" # Z in pdd16
1612 print "created a callback sub\n"
1614 # now call the external sub, that takes a callback and user data
1615 .local pmc libnci_test
1616 libnci_test = loadlib "libnci_test"
1617 .local pmc nci_cb_C3
1618 nci_cb_C3 = dlfunc libnci_test, "nci_cb_C3", "vpP"
1619 print "loaded a function that takes a callback\n"
1620 nci_cb_C3( cb_wrapped, user_data )
1622 # callback will be called at any time
1624 .local int sleep_cnt
1629 .local pmc callback_has_run
1630 callback_has_run = get_global "cb_done"
1631 if callback_has_run goto FINISHED
1632 if sleep_cnt > 10 goto ERROR
1635 print "the callback has run\n"
1638 print "the callback didnt run\n"
1643 get_params "0,0", $P5, $P6
1644 print "in callback\n"
1649 # P6 is a UnManagedStruct PMC containing a pointer to an integer
1650 new $P2, ['ResizablePMCArray']
1651 push $P2, .DATATYPE_INT
1656 # print referenced integer in libnci_test.so
1658 print "external data: "
1662 get_global $P12, "cb_done"
1668 created a callback sub
1669 loaded a function that takes a callback
1673 the callback has run
1676 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_cb_D1 - PASM", @todo );
1678 # we need a flag if the call_back is already done
1679 new P10, ['Integer']
1680 set_global "cb_done", P10
1681 # first attempt - create cb manually (this step will be hidden later)
1682 .const 'Sub' P6 = "_call_back"
1686 new_callback P5, P6, P7, "vUt" # Z in pdd16
1688 # now call the external sub, that takes a call_back and user_data
1689 loadlib P1, "libnci_test"
1690 dlfunc P0, P1, "nci_cb_D1", "vpP"
1694 set_args "0,0", P5, P7
1696 # call_back will be called at any time
1702 get_global P11, "cb_done"
1710 print "cb didnt run\n"
1713 .pcc_sub _call_back:
1714 get_params "0,0", P5, S5
1715 print "in callback\n"
1719 print "external data: "
1722 get_global P12, "cb_done"
1731 external data: succeeded
1735 pasm_output_is( <<'CODE', <<'OUTPUT', "nci_cb_D2 - PASM", @todo );
1736 # we need a flag if the call_back is already done
1737 new P10, ['Integer']
1738 set_global "cb_done", P10
1739 # first attempt - create cb manually (this step will be hidden later)
1740 .const 'Sub' P6 = "_call_back"
1744 new_callback P5, P6, P7, "vUi" # Z in pdd16
1746 # now call the external sub, that takes a call_back and user_data
1747 loadlib P1, "libnci_test"
1748 dlfunc P0, P1, "nci_cb_D2", "vpP"
1752 set_args "0,0", P5, P7
1754 # call_back will be called at any time
1760 get_global P11, "cb_done"
1768 print "cb didnt run\n"
1771 .pcc_sub _call_back:
1772 get_params "0,0", P5, I5
1773 print "in callback\n"
1777 print "external data: "
1780 get_global P12, "cb_done"
1794 pir_output_is( <<'CODE', <<'OUTPUT', "nci_cb_D2 - PIR", @todo );
1798 # this flag will be set by the callback function
1800 cb_done = new ['Integer']
1802 set_global "cb_done", cb_done
1805 .local pmc user_data
1806 user_data = new ['Integer']
1809 # A Sub that can be given to the library
1810 # this callback function will eventually by called by the library
1811 .const 'Sub' cb = "_call_back"
1812 .local pmc cb_wrapped
1813 cb_wrapped = new_callback cb, user_data, "vUi" # Z in pdd16
1814 print "created a callback sub\n"
1816 # now call the external sub, that takes a callback and user data
1817 .local pmc libnci_test
1818 libnci_test = loadlib "libnci_test"
1819 .local pmc nci_cb_D2
1820 nci_cb_D2 = dlfunc libnci_test, "nci_cb_D2", "vpP"
1821 print "loaded a function that takes a callback\n"
1822 nci_cb_D2( cb_wrapped, user_data )
1824 # callback will be called at any time
1826 .local int sleep_cnt
1831 .local pmc callback_has_run
1832 callback_has_run = get_global "cb_done"
1833 if callback_has_run goto FINISHED
1834 if sleep_cnt > 10 goto ERROR
1837 print "the callback has run\n"
1840 print "the callback didnt run\n"
1847 print "in callback\n"
1851 print "external data: "
1854 get_global $P12, "cb_done"
1860 created a callback sub
1861 loaded a function that takes a callback
1865 the callback has run
1868 pir_output_is( <<'CODE', <<'OUTPUT', "nci_cb_D3 - PIR", @todo );
1871 .include "datatypes.pasm"
1875 # this flag will be set by the callback function
1877 cb_done = new ['Integer']
1879 set_global "cb_done", cb_done
1882 .local pmc user_data
1883 user_data = new ['Integer']
1886 # A Sub that can be given to the library
1887 # this callback function will eventually by called by the library
1888 .const 'Sub' cb = "_call_back"
1889 .local pmc cb_wrapped
1890 cb_wrapped = new_callback cb, user_data, "vUp" # Z in pdd16
1891 print "created a callback sub\n"
1893 # now call the external sub, that takes a callback and user data
1894 .local pmc libnci_test
1895 libnci_test = loadlib "libnci_test"
1896 .local pmc nci_cb_D3
1897 nci_cb_D3 = dlfunc libnci_test, "nci_cb_D3", "vpP"
1898 print "loaded a function that takes a callback\n"
1899 nci_cb_D3( cb_wrapped, user_data )
1901 # callback will be called at any time
1903 .local int sleep_cnt
1908 .local pmc callback_has_run
1909 callback_has_run = get_global "cb_done"
1910 if callback_has_run goto FINISHED
1911 if sleep_cnt > 10 goto ERROR
1914 print "the callback has run\n"
1917 print "the callback didnt run\n"
1924 print "in callback\n"
1929 # s is a UnManagedStruct PMC containing a pointer to an integer
1930 new $P2, ['ResizablePMCArray']
1931 push $P2, .DATATYPE_INT
1936 # print referenced integer in libnci_test.so
1938 print "external data: "
1942 get_global $P12, "cb_done"
1948 created a callback sub
1949 loaded a function that takes a callback
1953 the callback has run
1956 pir_output_is( <<'CODE', <<'OUTPUT', "nci_cb_D4 - synchronous callbacks" );
1959 .include "datatypes.pasm"
1963 # turn off JIT or special core - no events yet
1966 .local pmc user_data
1967 user_data = new ['Integer']
1971 .local pmc libnci_test
1972 libnci_test = loadlib "libnci_test"
1974 # reset int_cb_D4 to 1
1975 .local pmc int_cb_D4
1976 int_cb_D4 = dlvar libnci_test, "int_cb_D4"
1977 .local pmc int_cb_D4_decl
1978 int_cb_D4_decl = new ['ResizablePMCArray']
1979 push int_cb_D4_decl, .DATATYPE_INT
1980 push int_cb_D4_decl, 0
1981 push int_cb_D4_decl, 0
1982 assign int_cb_D4, int_cb_D4_decl
1985 # A Sub that can be given to the library
1986 # this callback function will eventually by called by the library
1987 .const 'Sub' cb = "_call_back"
1988 .local pmc cb_wrapped
1989 cb_wrapped = new_callback cb, user_data, "vUp" # Z in pdd16
1990 print "created a callback sub\n"
1992 # now call the external sub, that takes a callback and user data
1993 .local pmc nci_cb_D4
1994 nci_cb_D4 = dlfunc libnci_test, "nci_cb_D4", "vpP"
1995 print "loaded a function that takes a callback\n"
1996 nci_cb_D4( cb_wrapped, user_data )
1998 # reset int_cb_D4 to 1
2001 .local pmc synchronous
2002 synchronous = new ['Integer']
2004 setprop user_data, "_synchronous", synchronous
2005 print "marked callback as synchronous\n"
2006 nci_cb_D4( cb_wrapped, user_data )
2014 # s is a UnManagedStruct PMC containing a pointer to an integer
2015 new $P2, ['ResizablePMCArray']
2016 push $P2, .DATATYPE_INT
2021 print "external data: "
2032 created a callback sub
2033 loaded a function that takes a callback
2037 external data: 10000
2038 external data: 100000
2039 external data: 1000000
2040 external data: 10000000
2041 external data: 100000000
2042 external data: 1000000000
2043 marked callback as synchronous
2048 external data: 11111
2049 external data: 111111
2050 external data: 1111111
2051 external data: 11111111
2052 external data: 111111111
2055 pasm_output_is( <<'CODE', <<'OUTPUT', 'nci_pip - array of structs' );
2057 .include "datatypes.pasm"
2058 new P3, ['OrderedHash']
2059 set P3["x"], .DATATYPE_INT
2062 set P3["y"], .DATATYPE_INT
2065 set P3["w"], .DATATYPE_INT
2068 set P3["h"], .DATATYPE_INT
2071 new P6, ['UnManagedStruct'], P3
2073 new P4, ['OrderedHash']
2074 set P4["Rect"], .DATATYPE_STRUCT
2076 setprop P1, "_struct", P6
2080 new P5, ['ManagedStruct'], P4
2081 set P5[0;0;'x'], 100
2082 set P5[0;0;'y'], 110
2083 set P5['Rect';0;'w'], 120
2084 set P5[0;0;'h'], 130
2086 set P5[0;1;'x'], 200
2087 set P5[0;1;'y'], 210
2088 set P5[0;1;'w'], 220
2089 set P5[0;1;'h'], 230
2091 set P5[0;2;'x'], 300
2092 set P5[0;2;'y'], 310
2093 set P5[0;2;'w'], 320
2094 set P5[0;2;'h'], 330
2096 set P5[0;3;'x'], 400
2097 set P5[0;3;'y'], 410
2098 set P5[0;3;'w'], 420
2099 set P5[0;3;'h'], 430
2101 loadlib P1, "libnci_test"
2102 set_args "0,0", 4, P5
2103 dlfunc P0, P1, "nci_pip", "pip"
2127 pasm_output_is( <<'CODE', <<'OUTPUT', 'nci_i33 - out parameters and return values' );
2129 .include "datatypes.pasm"
2135 loadlib P1, "libnci_test"
2136 set_args "0,0", P2, P3
2137 dlfunc P0, P1, "nci_i33", "i33"
2156 pasm_output_is( <<'CODE', <<'OUTPUT', 'nci_vpii - nested structs' );
2158 .include "datatypes.pasm"
2159 new P8, 'OrderedHash'
2160 set P8[ 'y' ], .DATATYPE_INT
2163 new P9, 'ManagedStruct', P8
2165 new P6, 'OrderedHash'
2166 set P6[ 'x' ], .DATATYPE_INT
2169 set P6[ 'nested' ], .DATATYPE_STRUCT_PTR
2172 setprop P7, '_struct', P9
2177 new P5, 'ManagedStruct', P6
2178 set P5[ 'nested'; 'y' ], 200
2182 set I1, P5[ 'nested'; 'y' ]
2188 set_args "0,0,0", P5, 1, 2
2189 loadlib P1, "libnci_test"
2190 dlfunc P0, P1, "nci_vpii", "vpii"
2194 set P6, P5[ 'nested' ]
2201 set P6, P5[ 'nested' ]
2213 pasm_output_is( <<'CODE', <<'OUTPUT', 'nci_piiii - nested array in a struct' );
2214 .include "datatypes.pasm"
2216 loadlib P1, "libnci_test"
2217 dlfunc P0, P1, "nci_piiii", "piiii"
2218 set_args "0,0,0,0", 100,200,400,800
2222 new P6, 'OrderedHash'
2223 set P6[ 'count' ], .DATATYPE_INT
2227 new P7, 'OrderedHash'
2228 set P7[ 'array' ], .DATATYPE_INT
2231 new P8, ['UnManagedStruct'], P7
2232 # yes, the array within the struct has _4_ elements
2233 # but with an UnManagedStruct, you can't always know the amount beforehand
2234 set P6[ 'array' ], .DATATYPE_STRUCT_PTR
2236 setprop P9, "_struct", P8
2241 set I0, P5[ 'count' ]
2247 # now that we do know, update the UnManagedStruct appropriately
2251 set I0, P5[1; 'array'; 0 ]
2252 set I1, P5[ 1;'array'; 1 ]
2253 set I2, P5[ 1;'array'; 2 ]
2254 set I3, P5[ 1;'array'; 3 ]
2274 pir_output_is( << 'CODE', << "OUTPUT", "nci_pii - writing back to libnci_test.so" );
2276 .include "datatypes.pasm"
2281 .local pmc libnci_test
2282 libnci_test = loadlib "libnci_test"
2283 unless libnci_test goto NOT_LOADED
2284 print "libnci_test was successfully loaded\n"
2286 # calling a function in libnci_test
2288 multiply = dlfunc libnci_test, "nci_pii", "pii"
2289 .local pmc product_pointer
2290 ( product_pointer ) = multiply( -5, 11111 )
2292 # the contained structure pointer
2293 .local pmc product_pointer_decl
2294 product_pointer_decl = new ['ResizablePMCArray']
2295 push product_pointer_decl, .DATATYPE_INT
2296 push product_pointer_decl, 0
2297 push product_pointer_decl, 0
2298 assign product_pointer, product_pointer_decl
2300 # check result of multiplication
2302 product = product_pointer[0]
2306 # Write back into libnci_test and check it
2307 product_pointer[0] = 333
2312 dlfunc nci_i, libnci_test, "nci_i", "i"
2313 ( product ) = nci_i()
2321 libnci_test was successfully loaded
2330 skip( "nci_dlvar_int hangs on HP-UX", 1 ) if $^O eq 'hpux';
2332 pir_output_is( << 'CODE', << 'OUTPUT', "nci_vv and nci_dlvar_int" );
2334 .include "datatypes.pasm"
2338 # load libnci_test.so
2339 .local string library_name
2340 library_name = 'libnci_test'
2341 .local pmc libnci_test
2342 libnci_test = loadlib library_name
2343 unless libnci_test goto NOT_LOADED
2345 print " was successfully loaded\n"
2347 # address of nci_dlvar_int
2348 .local pmc nci_dlvar_int
2349 nci_dlvar_int = dlvar libnci_test, "nci_dlvar_int"
2351 # the contained structure pointer
2352 .local pmc nci_dlvar_int_decl
2353 nci_dlvar_int_decl = new ['ResizablePMCArray']
2354 push nci_dlvar_int_decl, .DATATYPE_INT
2355 push nci_dlvar_int_decl, 0
2356 push nci_dlvar_int_decl, 0
2357 assign nci_dlvar_int, nci_dlvar_int_decl
2359 $I2 = nci_dlvar_int[0]
2364 nci_vv = dlfunc libnci_test, "nci_vv", ""
2366 $I1 = nci_dlvar_int[0]
2370 $I1 = nci_dlvar_int[0]
2374 $I1 = nci_dlvar_int[0]
2378 $I1 = nci_dlvar_int[0]
2384 libnci_test was successfully loaded
2393 pir_output_is( << 'CODE', << 'OUTPUT', "dlvar - unknown symbol" );
2395 .include "datatypes.pasm"
2399 # load libnci_test.so
2400 .local string library_name
2401 library_name = 'libnci_test'
2402 .local pmc libnci_test
2403 libnci_test = loadlib library_name
2404 unless libnci_test goto NOT_LOADED
2406 print " was successfully loaded\n"
2408 # address of nci_dlvar_int
2409 .local pmc non_existing
2410 non_existing = dlvar libnci_test, "non_existing"
2411 .local int is_defined
2412 is_defined = defined non_existing
2413 if is_defined goto IS_DEFINED
2414 print "'non_existing' is not defined\n"
2419 libnci_test was successfully loaded
2420 'non_existing' is not defined
2423 pir_output_is( << 'CODE', << 'OUTPUT', "dlfunc - unknown symbol" );
2425 .include "datatypes.pasm"
2429 # load libnci_test.so
2430 .local string library_name
2431 library_name = 'libnci_test'
2432 .local pmc libnci_test
2433 libnci_test = loadlib library_name
2434 unless libnci_test goto NOT_LOADED
2436 print " was successfully loaded\n"
2438 # address of nci_dlvar_int
2439 .local pmc non_existing
2440 non_existing = dlfunc libnci_test, "non_existing", "iiii"
2441 .local int is_defined
2442 is_defined = defined non_existing
2443 if is_defined goto IS_DEFINED
2444 print "'non_existing' is not defined\n"
2449 libnci_test was successfully loaded
2450 'non_existing' is not defined
2453 pasm_output_is( << 'CODE', << 'OUTPUT', "loading same library twice" );
2454 loadlib P1, "libnci_test"
2458 loadlib P2, "libnci_test"
2475 pir_output_is( << 'CODE', << 'OUTPUT', "opcode 'does'" );
2479 pmc1 = new ['ParrotLibrary']
2481 does bool1, pmc1, "scalar"
2484 does bool1, pmc1, "library"
2487 does bool1, pmc1, "no_interface"
2498 pir_output_is( << 'CODE', << 'OUTPUT', "conversion d <-> P" );
2500 .local string library_name
2501 library_name = 'libnci_test'
2502 .local pmc libnci_test
2503 libnci_test = loadlib library_name
2505 twice = dlfunc libnci_test, "nci_dd", "dd"
2517 pir_output_is( << 'CODE', << 'OUTPUT', "conversion S <-> P" );
2519 .local string library_name
2520 library_name = 'libnci_test'
2521 .local pmc libnci_test
2522 libnci_test = loadlib library_name
2524 reverse = dlfunc libnci_test, "nci_tt", "tt"
2535 pir_output_is( << 'CODE', << 'OUTPUT', "conversion I <-> P" );
2537 .local string library_name
2538 library_name = 'libnci_test'
2539 .local pmc libnci_test
2540 libnci_test = loadlib library_name
2542 mult = dlfunc libnci_test, "nci_i4i", "i4i"
2546 j = mult( 21, i ) # call signature is PI
2554 << 'CODE', << 'OUTPUT', 'nested structs should be independent' );
2555 .include 'datatypes.pasm'
2558 .local string library_name
2559 library_name = 'libnci_test'
2561 .local pmc libnci_test
2562 libnci_test = loadlib library_name
2565 types = new ['OrderedHash']
2566 types['y'] = .DATATYPE_INT
2571 nested = new ['ManagedStruct'], types
2574 outer = make_outer_struct( nested )
2576 outer[ 'nested'; 'y' ] = 0
2579 nci_func = dlfunc libnci_test, 'nci_vpii', 'vpii'
2581 print_values( outer )
2582 nci_func( outer, 1, 100 )
2583 print_values( outer )
2586 other = make_outer_struct( nested )
2588 # autovivify the nested hash
2589 other[ 'nested'; 'y' ] = 1
2590 nci_func( other, 2, 200 )
2592 print_values( outer )
2593 print_values( other )
2601 y = outer[ 'nested'; 'y' ]
2608 .sub 'make_outer_struct'
2612 types = new ['OrderedHash']
2613 types[ 'x' ] = .DATATYPE_INT
2616 types[ 'nested' ] = .DATATYPE_STRUCT_PTR
2618 .local pmc struct_ptr
2619 struct_ptr = types[-1]
2620 setprop struct_ptr, '_struct', nested
2625 outer = new ['ManagedStruct'], types
2640 pir_output_is( << 'CODE', << 'OUTPUT', "arity" );
2642 .local string library_name
2643 library_name = 'libnci_test'
2644 .local pmc libnci_test
2645 libnci_test = loadlib library_name
2648 nci_c = dlfunc libnci_test, "nci_c", "c"
2649 $I0 = nci_c.'arity'()
2653 multiply = dlfunc libnci_test, "nci_pii", "pii"
2654 $I0 = multiply.'arity'()
2658 nci_iiii = dlfunc libnci_test, "nci_iiii", "iiii"
2659 $I0 = nci_iiii.'arity'()
2668 pir_output_is( << 'CODE', << 'OUTPUT', "nci_vVi - void** out parameter" );
2670 .local string library_name
2671 library_name = 'libnci_test'
2672 .local pmc libnci_test
2673 libnci_test = loadlib library_name
2676 nci_vVi = dlfunc libnci_test, "nci_vVi", "vVi"
2679 nci_vp = dlfunc libnci_test, "nci_vp", "vp"
2685 opaque = new ['Pointer']
2687 nci_vVi(opaque, $I0)
2695 pir_output_is( << 'CODE', << 'OUTPUT', "nci_ttt - t_tt parameter" );
2697 .local string library_name
2698 library_name = 'libnci_test'
2699 .local pmc libnci_test
2700 libnci_test = loadlib library_name
2703 nci_ttt = dlfunc libnci_test, "nci_ttt", "ttt"
2705 $S0 = nci_ttt("Hello", "Waldo")
2713 pir_output_is( << 'CODE', << 'OUTPUT', "nci_vfff - v_fff parameter" );
2715 .local string library_name
2716 library_name = 'libnci_test'
2717 .local pmc libnci_test
2718 libnci_test = loadlib library_name
2721 nci_vfff = dlfunc libnci_test, "nci_vfff", "vfff"
2723 nci_vfff(3456.54, 10.1999, 14245.567)
2731 pir_output_is( << 'CODE', << 'OUTPUT', "nci_vV - char** out parameter" );
2733 .local string library_name
2734 library_name = 'libnci_test'
2735 .local pmc libnci_test
2736 libnci_test = loadlib library_name
2739 nci_vV = dlfunc libnci_test, "nci_vV", "vV"
2742 char_s_s = new ['Pointer']
2748 Hello bright new world
2751 pir_output_is( << 'CODE', << 'OUTPUT', "nci_vVV - multiple char** out parameters" );
2753 .local string library_name
2754 library_name = 'libnci_test'
2755 .local pmc libnci_test
2756 libnci_test = loadlib library_name
2759 nci_vVVV = dlfunc libnci_test, "nci_vVVV", "vVVV"
2761 .local pmc char_s_s1, char_s_s2, char_s_s3
2762 char_s_s1 = new ['Pointer']
2763 char_s_s2 = new ['Pointer']
2764 char_s_s3 = new ['Pointer']
2765 nci_vVVV(char_s_s1, char_s_s2, char_s_s3)
2774 Hello bright new world!
2775 It is a beautiful day!
2781 # cperl-indent-level: 4
2784 # vim: expandtab shiftwidth=4: