/* * $Id: testb.i,v 1.2 2009-09-11 02:20:03 dhmunro Exp $ * A comprehensive test of the native-Yorick binary I/O functions. * * Also, read back PDB files created by Stewart Brown's pdtest program, * and create facsimile of such files (although doesn't write PDB-style * pointers). */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ func testb(do_stats) /* DOCUMENT testb or testb, 1 (prints yorick_stats) Perform systematic test of all features of Yorick's binary I/O package. This extends the simple test in testp.i. */ { local varCs, varCa, varSs, varSa, varIs, varIa, varLs, varLa; local varFs, varFa, varDs, varDa, varZs, varZa, varSIs, varSIa; local bundle; local varQs, varPs, varQa, varPa, linkedList, mixed; /* begin by writing a simple flat file */ write, " First test is to write flat files:"; tester1, "junk", write_flat, read_flat; /* continue by writing a file with lots of indirections */ write, "\n Second test is to write files with pointers:"; tester1, "junk", write_ptrs, read_ptrs; /* update the indirect files and write the flat stuff */ write, "\n Third test is to update pointered files with flat data:"; tester2, "junk", write_flat, read_flat, read_ptrs; /* exhaustive test to and from all other primitive formats */ write, "\n Fourth test is exhaustive check of other primitive formats:"; now= split= array(0.0, 3); timer, now; tester3; timer, now, split; timer_print, "Time to write/test all formats", split; /* Contents Log tests */ write, "\n Fifth test is check of Contents Log machinery:"; tester4; /* History tests */ write, "\n Sixth test is flat history files (be patient):"; timer, now; tester5; timer, now, split; timer_print, "Time to write history files", split; write, "\n Seventh test is a pointered history file:"; tester6; rm_hist; remove, "junk.clog"; remove, "junk.pdb"; remove, "junk.pdbL"; remove, "junkd.pdb"; remove, "junkd.pdbL"; remove, "junkc.pdb"; remove, "junkc.pdbL"; remove, "junks.pdb"; remove, "junks.pdbL"; write, "\n Eighth test is vsave in-memory files:"; f = createb(char); write_flat, f, 0; b = vclose(f); read_flat, openb(b), 0; read_flat, openb(b), 1; f = createb(char); write_flat, f, 1; b = vclose(f); read_flat, openb(b), 0; read_flat, openb(b), 1; f = createb(char); write_ptrs, f, 0; b = vclose(f); read_ptrs, openb(b), 0; read_ptrs, openb(b), 1; f = createb(char); write_ptrs, f, 1; b = vclose(f); read_ptrs, openb(b), 0; read_ptrs, openb(b), 1; write, "\n Ninth test is vpack in-memory files:"; b = vpack_flat(0); bb = vpack_flat(1); if (numberof(b)!=numberof(bb) || anyof(b!=bb)) write, "vpack_flat failed write order test"; vunpack_flat, b, 0; vunpack_flat, b, 1; } func rm_hist { for (i=0 ; i<22 ; i++) remove, swrite(format="junk%02ld.pdb", i); for (i=0 ; i<22 ; i++) remove, swrite(format="junk%02ld.pdbL", i); } func tester1(base, writer, reader) { if (do_stats) "Begin1 "+print(yorick_stats())(1); write, "Write using native formats" f= createb(base+".pdb"); if (do_stats) "Created "+print(yorick_stats())(1); writer, f, 0; close, f; if (do_stats) "Closed "+print(yorick_stats())(1); f= openb(base+".pdb"); if (do_stats) "Opened "+print(yorick_stats())(1); reader, f, 0; write, "Write using DEC primitive formats" g= createb(base+"d.pdb", dec_primitives); if (do_stats) "Created "+print(yorick_stats())(1); writer, g, 1; reader, g, 0; write, "Write using Sun primitive formats" h= createb(base+"s.pdb", sun_primitives); if (do_stats) "Created "+print(yorick_stats())(1); writer, h, 0; reader, h, 1; close, h; if (do_stats) "Closed S "+print(yorick_stats())(1); write, "Write using Cray primitive formats" h= createb(base+"c.pdb", cray_primitives); if (do_stats) "Created "+print(yorick_stats())(1); writer, h, 1; reader, h, 1; close, h; if (do_stats) "Closed C "+print(yorick_stats())(1); close, g; if (do_stats) "Closed D "+print(yorick_stats())(1); close, f; if (do_stats) "Closed N "+print(yorick_stats())(1); } func tester2(base, writer, reader, reader2) { if (do_stats) "Begin2 "+print(yorick_stats())(1); write, "Update using native formats" f= updateb(base+".pdb"); if (do_stats) "Updating "+print(yorick_stats())(1); writer, f, 1; close, f; if (do_stats) "Closed "+print(yorick_stats())(1); f= updateb(base+".pdb"); if (do_stats) "Opened "+print(yorick_stats())(1); reader, f, 1; reader2, f, 1; write, "Update using DEC primitive formats" g= updateb(base+"d.pdb", dec_primitives); if (do_stats) "Updating "+print(yorick_stats())(1); writer, g, 0; reader, g, 1; reader2, g, 1; write, "Update using Sun primitive formats" h= updateb(base+"s.pdb", sun_primitives); if (do_stats) "Created "+print(yorick_stats())(1); writer, h, 1; reader, h, 0; reader2, h, 0; close, h; if (do_stats) "Closed S "+print(yorick_stats())(1); write, "Update using Cray primitive formats" h= updateb(base+"c.pdb", cray_primitives); if (do_stats) "Created "+print(yorick_stats())(1); writer, h, 0; reader, h, 0; reader2, h, 0; close, h; if (do_stats) "Closed C "+print(yorick_stats())(1); close, g; if (do_stats) "Closed D "+print(yorick_stats())(1); close, f; if (do_stats) "Closed N "+print(yorick_stats())(1); } func tester3 { write, "Testing Sun format"; test_full, "junk", sun_primitives; write, "Testing i86 format"; test_full, "junk", i86_primitives; write, "Testing alpha format"; test_full, "junk", alpha_primitives; write, "Testing sgi64 format"; test_full, "junk", sgi64_primitives; write, "Testing DEC format"; test_full, "junk", dec_primitives; write, "Testing Cray format"; test_full, "junk", cray_primitives; write, "Testing XDR format"; test_full, "junk", xdr_primitives; write, "Testing Mac format"; test_full, "junk", mac_primitives; write, "Testing Mac long-double format"; test_full, "junk", macl_primitives; write, "Testing IBM PC format"; test_full, "junk", pc_primitives; write, "Testing VAX format"; test_full, "junk", vax_primitives; write, "Testing VAX G-double format"; test_full, "junk", vaxg_primitives; write, "Testing Sun-3/Sun-2 format"; test_full, "junk", sun3_primitives; write, "Testing native format"; test_full, "junk"; } func test_full(base, primitives) { write_ptrs, createb(base+".pdb", primitives), 0; write_flat, updateb(base+".pdb"), 0; read_flat, openb(base+".pdb"), 0; read_ptrs, openb(base+".pdb"), 0; } func tester4 { write, "Contents Log -- testing Sun format"; test_clog, "junk", sun_primitives; write, "Contents Log -- testing DEC format"; test_clog, "junk", dec_primitives; write, "Contents Log -- testing Cray format"; test_clog, "junk", cray_primitives; write, "Contents Log -- testing VAX format"; test_clog, "junk", vax_primitives; write, "Contents Log -- testing native format"; test_clog, "junk"; write, "Non-PDB Contents Log -- testing Sun format"; test_clog, "junk", sun_primitives, 1; write, "Non-PDB Contents Log -- testing DEC format"; test_clog, "junk", dec_primitives, 1; write, "Non-PDB Contents Log -- testing Cray format"; test_clog, "junk", cray_primitives, 1; write, "Non-PDB Contents Log -- testing VAX format"; test_clog, "junk", vax_primitives, 1; write, "Non-PDB Contents Log -- testing native format"; test_clog, "junk",, 1; } func test_clog(base, primitives, nonpdb) { if (!nonpdb) { f= createb(base+".pdb", primitives); } else { f= open(base+".pdb", "w+b"); if (is_func(primitives)) primitives, f; _init_clog, f; } write_ptrs, f, 0; write_flat, f, 0; if (!nonpdb) dump_clog, f, base+".clog"; close, f; if (!nonpdb) f= openb(base+".pdb", base+".clog"); else f= openb(base+".pdb"); read_flat, f, 0; read_ptrs, f, 0; } func tester5 { write, "History -- testing Sun format"; test_hist, "junk00", sun_primitives; rm_hist; write, "History -- testing DEC format"; test_hist, "junk00", dec_primitives; rm_hist; write, "History -- testing Cray format"; test_hist, "junk00", cray_primitives; rm_hist; write, "History -- testing VAX format"; test_hist, "junk00", vax_primitives; rm_hist; write, "History -- testing native format"; test_hist, "junk00"; rm_hist; } func test_hist(base, primitives) { /* No non-record variables in 1st test. */ f= createb(base+".pdb", primitives); write_hist, f; close, f; f= openb(base+".pdb"); read_hist, f; close, f; } test_records= 100; test_filesize= 8000; /* each record is about 1 kbyte long */ func write_hist(f) { for (i=1 ; i<=test_records ; i++) { time= double(i-1); ncyc= i; add_record, f, time, ncyc; if (i==1) set_filesize, f, test_filesize; save, f, time, ncyc; write_flat, f, 0; } } func read_hist(f) { n= test_records/3; prime= 27; if (n%prime == 0) { prime= 13; if (n%prime == 0) prime= 0; } for (i=1 ; i<=test_records/3 ; i++) { if (prime) j= (i%prime) + 1; else j= i; jt, double(j-1); if (f.time!=double(j-1) || f.ncyc!=j) "time or ncyc bad at record "+print(j)(1); read_flat, f, 0; } for (i=test_records/3+1 ; i<=2*(test_records/3) ; i++) { jc, f, i; if (f.time!=double(i-1) || f.ncyc!=i) "time or ncyc bad at record "+print(i)(1); read_flat, f, 0; } i= 2*(test_records/3); do { restore, f, time, ncyc; if (f.time!=double(i-1) || f.ncyc!=i) "time or ncyc bad at record "+print(i)(1); read_flat, f, 0; i++; } while (jt(f)); if (ncyc6.022e11, varZs!=1-1i, anyof(varFa!=float([[0,0,0],[0,-100,100]])), anyof(varDa!=double([[[1,2,3,4],[-30,-20,-10,0],[-1,2,-3,4]], [[0,-30,20,-10],[4,3,2,1],[3,-4,1,-2]]])), anyof(varZa!=[123456789-3.5i, -987654321+0i]), struct_neq(varSIs, Simple(one='Q', two= -137., three= -37s)), struct_neq(varSIa, [varSIs, Simple(one='\370', two= 1.5, three= 37s)]), struct_neq(bundle, Flat(varCs=varCs, varSs=varSs, varIs=varIs, varLs=varLs, varCa=varCa, varSa=varSa, varIa=varIa, varLa=varLa, varFs=varFs, varDs=varDs, varZs=varZs, varFa=varFa, varDa=varDa, varZa=varZa, varSIs=varSIs, varSIa=varSIa))]; if (anyof(goofs)) { "read_flat failed -- goof flags are:"; goofs; } if (do_stats) "Checked "+print(yorick_stats())(1); } func vpack_flat(how) { extern varCs, varCa, varSs, varSa, varIs, varIa, varLs, varLa; extern varFs, varFa, varDs, varDa, varZs, varZa, varQs, varQa; /* invent a bunch of garbage to be written */ varCs= 'A'; varSs= -37s; varIs= 76n; varLs= 144; varCa= ['Z', '\370', 'a']; varSa= short([[0,0,0],[0,-100,100]]); varIa= int([[[1,2,3,4],[-30,-20,-10,0],[-1,2,-3,4]], [[0,-30,20,-10],[4,3,2,1],[3,-4,1,-2]]]); varLa= [123456789, -987654321]; varFs= 1.5f; varDs= -6.022e23; varZs= 1-1i; varFa= float([[0,0,0],[0,-100,100]]); varDa= double([[[1,2,3,4],[-30,-20,-10,0],[-1,2,-3,4]], [[0,-30,20,-10],[4,3,2,1],[3,-4,1,-2]]]); varZa= [123456789-3.5i, -987654321+0i]; varQs= ""; varQa= [["hello", string(0), "World", "", "!"], ["a", "b", string(0), "", "e"]]; null = []; if (!how) { b = vpack(varCs, varSs, varIs, varLs, varCa, varSa, varIa, varLa, varQs, varFs, varDs, varZs, varFa, null, varQa, varDa, varZa); } else { f = vopen(,1); vpack, f, varCs, varSs, varIs, varLs, varCa, varSa, varIa; vpack, f, varLa; vpack, f, varQs, varFs, varDs; vpack, f, varZs, varFa, null, varQa, varDa, varZa; b = vpack(f); } if (do_stats) "Packed "+print(yorick_stats())(1); return b; } func vunpack_flat(b, how) { local varCs, varCa, varSs, varSa, varIs, varIa, varLs, varLa; local varFs, varFa, varDs, varDa, varZs, varZa, varQs, varQa; null = 1; if (!how) { neof = !vunpack(b, varCs, varSs, varIs, varLs, varCa, varSa, varIa, varLa, varQs, varFs, varDs, varZs, varFa, null, varQa, varDa, varZa); neof += 2*(!vunpack(b)); vunpack, b; /* test reset feature */ neof += 4*vunpack(b); } else { eof1 = vunpack(b, v1, v2); bad1 = (v1!='A' || v2!=-37s); vunpack, b; /* test reset feature */ eof2 = vunpack(b, varCs, varSs, varIs, varLs, varCa); varSa = vunpack(b, -); eof3 = vunpack(b, varIa, varLa, varQs, varFs, varDs); varZs = vunpack(b, -); eof4 = !vunpack(b, varFa, null, varQa, varDa, varZa); neof = eof1 + 2*eof2 + 4*eof3 + 8*eof4 + 16*bad1; } if (do_stats) "Restored "+print(yorick_stats())(1); goofs= [varCs!='A', varSs!=-37s, varIs!=76n, varLs!=144, anyof(varCa!=['Z', '\370', 'a']), anyof(varSa!=short([[0,0,0],[0,-100,100]])), anyof(varIa!=int([[[1,2,3,4],[-30,-20,-10,0],[-1,2,-3,4]], [[0,-30,20,-10],[4,3,2,1],[3,-4,1,-2]]])), anyof(varLa!=[123456789, -987654321]), varFs!=1.5f, abs(varDs+6.022e23)>6.022e11, varZs!=1-1i, anyof(varFa!=float([[0,0,0],[0,-100,100]])), anyof(varDa!=double([[[1,2,3,4],[-30,-20,-10,0],[-1,2,-3,4]], [[0,-30,20,-10],[4,3,2,1],[3,-4,1,-2]]])), anyof(varZa!=[123456789-3.5i, -987654321+0i]), varQs!="", anyof(varQa != [["hello", string(0), "World", "", "!"], ["a", "b", string(0), "", "e"]]), !is_void(null), neof]; if (anyof(goofs)) { "vunpack_flat failed -- goof flags are:"; goofs; } if (do_stats) "Checked "+print(yorick_stats())(1); } func write_ptrs(f, how) { extern varQs, varPs, varQa, varPa, linkedList, mixed; extern varCs, varZa, varFa, varDa; /* referenced by ptrs */ varCs= 'A'; varFa= float([[0,0,0],[0,-100,100]]); varDa= double([[[1,2,3,4],[-30,-20,-10,0],[-1,2,-3,4]], [[0,-30,20,-10],[4,3,2,1],[3,-4,1,-2]]]); varZa= [123456789-3.5i, -987654321+0i]; /* invent a bunch of garbage to be written */ varQs= "Hello, world!"; varPs= pointer(varQs); varQa= [["a", "bc"], ["def", "ghij"], ["klmn", "op"], [string(0), ""]]; varPa= [[[&varCs, &varDa], [&varZa, &varDa], [&varPs, &varDa]], [[&varFa, &varDa], [&varDa, &varPs], [&varQa, &varQa]]]; linkedList= &Link(name="second", index=2); linkedList->next= &Link(next=linkedList, name="third", index=3); linkedList->next->next= &Link(name="last", index=4); linkedList= &Link(next=linkedList, name="first", index=1); mixed= Mixed(varPs=varPs, s=-37s, varQa=varQa, varQs=varQs, links=linkedList, varPa=varPa); if (!how) { /* This should produce maximum number of duped pointers. */ if (!for_hist_test) save, f, complex, Link; save, f, varQs, varQa, varPs, varPa, linkedList, mixed; } else { /* Piecemeal writes result in some pointee rewrites. */ add_variable, f, -1, "varQs", string; add_variable, f, -1, "varQa", "string", 2, 4; add_variable, f, -1, "varPs", "pointer"; add_variable, f, -1, "varPa", pointer, [3,2,3,2]; save, f, complex, varQs; f.varQa(,::-1)= varQa(,::-1); f.varPs= varPs; f.varPa(2,1:3)= varPa(2,1:3); f.varPa(1,4:6)= varPa(1,4:6); add_member, f, "Link", -1, "next", pointer; add_member, f, "Link", -1, "name", "string"; add_member, f, "Link", -1, "index", "long"; install_struct, f, "Link"; add_variable, f, -1, "linkedList", "pointer"; save, f, mixed; f.linkedList= linkedList; f.varPa(2,4:6)= varPa(2,4:6); f.varPa(1,1:3)= varPa(1,1:3); } if (do_stats) "Saved ps "+print(yorick_stats())(1); } func read_ptrs(f, how) { local varQs, varPs, varQa, varPa, linkedList, mixed; extern varCs, varZa, varFa, varDa; /* referenced by ptrs */ if (!how) { /* This should produce maximum number of duped pointers. */ restore, f, varQs, varPs, varQa, varPa, linkedList, mixed; } else { /* Piecemeal reads result in some pointee rereads. */ varQs= f.varQs; varQa= array(string, 2, 4); mixed= f.mixed; varQa(,::-1)= f.varQa(,::-1); varPa= array(pointer, 2, 3, 2); varPa(1,::-1,2)= f.varPa(1,::-1,2); linkedList= f.linkedList; varPa(2,,2)= f.varPa(2,,2); varPs= f.varPs; varPa(..,1)= f.varPa(..,1); mixed.varPa= &[]; mixed.varPa(::-1,..)= f.mixed.varPa(::-1,..) } if (do_stats) "Restored "+print(yorick_stats())(1); goofs= [varQs!="Hello, world!", anyof(varQa!=[["a", "bc"], ["def", "ghij"], ["klmn", "op"], [string(0), ""]]), string(varPs)!="Hello, world!", *varPa(1,1,1)!=varCs, anyof(*varPa(2,1,1)!=varDa), anyof(*varPa(1,2,1)!=varZa), anyof(*varPa(2,2,1)!=varDa), string(*varPa(1,3,1))!="Hello, world!", anyof(*varPa(2,3,1)!=varDa), anyof(*varPa(1,1,2)!=varFa), anyof(*varPa(2,1,2)!=varDa), anyof(*varPa(1,2,2)!=varDa), string(*varPa(2,2,2))!="Hello, world!", anyof(*varPa(1,3,2)!=varQa), anyof(*varPa(2,3,2)!=varQa)]; if (anyof(goofs)) { "read_ptrs failed on simple string or pointer -- goof flags are:"; goofs; } ll1= linkedList; ll3= linkedList->next->next; goofs= [ll1->name!="first", ll1->index!=1, ll1->next->name!="second", ll1->next->index!=2, ll3->name!="third", ll3->index!=3, ll3->next->name!="last", ll3->next->index!=4, !is_void(*ll3->next->next)]; if (anyof(goofs)) { "read_ptrs failed on linked list -- goof flags are:"; goofs; } ll1= mixed.links; ll3= mixed.links->next->next; goofs= [ll1->name!="first", ll1->index!=1, ll1->next->name!="second", ll1->next->index!=2, ll3->name!="third", ll3->index!=3, ll3->next->name!="last", ll3->next->index!=4, !is_void(*ll3->next->next), string(mixed.varPs)!="Hello, world!", mixed.s!=-37s, anyof(mixed.varQa!=[["a", "bc"], ["def", "ghij"], ["klmn", "op"], [string(0), ""]]), mixed.varQs!="Hello, world!", anyof(*mixed.varPa(1,2,1)!=varZa), anyof(*mixed.varPa(2,2,1)!=varDa), string(*mixed.varPa(1,3,1))!="Hello, world!", anyof(*mixed.varPa(2,3,1)!=varDa), anyof(*mixed.varPa(1,1,2)!=varFa), anyof(*mixed.varPa(2,1,2)!=varDa), anyof(*mixed.varPa(1,2,2)!=varDa), string(*mixed.varPa(2,2,2))!="Hello, world!", anyof(*mixed.varPa(1,3,2)!=varQa), anyof(*mixed.varPa(2,3,2)!=varQa)]; if (anyof(goofs)) { "read_ptrs failed on mixed object -- goof flags are:"; goofs; } if (do_stats) "Checkedp "+print(yorick_stats())(1); } func struct_neq(x, y) { members= strtok(strtok(print(structof(x))(2:-1))(2,)," (;")(1,); m= numberof(members); for (i=1 ; i<=m ; i++) { xm= get_member(x, members(i)); ym= get_member(y, members(i)); if (typeof(xm)=="struct_instance") { if (struct_neq(xm, ym)) return 1; } else { if (anyof(xm!=ym)) return 1; } } return 0; } struct Simple { char one; double two; short three; } struct Flat { int varIs, varIa(4,3,2); double varDs; char varCs; float varFs, varFa(3,2); complex varZs, varZa(2); short varSs, varSa(3,2); double varDa(4,3,2); Simple varSIs, varSIa(2); long varLs, varLa(2); char varCa(3); } struct Link { pointer next; string name; long index; } struct Mixed { pointer varPs; short s; string varQa(2,4), varQs; pointer links, varPa(2,3,2); } func pdcheck1(prefix) { write, "Testing <- native..."; pdtest1_check, prefix+"-nat.db1"; write, "Testing <- cray..."; pdtest1_check, prefix+"-cray.db1"; write, "Testing <- dos..."; pdtest1_check, prefix+"-dos.db1"; write, "Testing <- mac..."; pdtest1_check, prefix+"-mac.db1"; write, "Testing <- mips..."; pdtest1_check, prefix+"-mips.db1"; write, "Testing <- sun3..."; pdtest1_check, prefix+"-sun3.db1"; write, "Testing <- sun4..."; pdtest1_check, prefix+"-sun4.db1"; write, "Testing <- vax..."; pdtest1_check, prefix+"-vax.db1"; } func pdcheck2 { write, "Testing sun_primitives db1 write..."; pdtest1_write,"junk.pdb", sun_primitives; pdtest1_check,"junk.pdb"; write, "Testing dec_primitives db1 write..."; pdtest1_write,"junk.pdb", dec_primitives; pdtest1_check,"junk.pdb"; write, "Testing cray_primitives db1 write..."; pdtest1_write,"junk.pdb", cray_primitives; pdtest1_check,"junk.pdb"; write, "Testing mac_primitives db1 write..."; pdtest1_write,"junk.pdb", mac_primitives; pdtest1_check,"junk.pdb"; write, "Testing macl_primitives db1 write..."; pdtest1_write,"junk.pdb", macl_primitives; pdtest1_check,"junk.pdb"; write, "Testing pc_primitives db1 write..."; pdtest1_write,"junk.pdb", pc_primitives; pdtest1_check,"junk.pdb"; write, "Testing sun3_primitives db1 write..."; pdtest1_write,"junk.pdb", sun3_primitives; pdtest1_check,"junk.pdb"; write, "Testing vax_primitives db1 write..."; pdtest1_write,"junk.pdb", vax_primitives; pdtest1_check,"junk.pdb"; write, "Testing vaxg_primitives db1 write..."; pdtest1_write,"junk.pdb", vaxg_primitives; pdtest1_check,"junk.pdb"; write, "Testing xdr_primitives db1 write..."; pdtest1_write,"junk.pdb", xdr_primitives; pdtest1_check,"junk.pdb"; write, "Testing sun_primitives db1 write w/PDB-style pointers..."; pdtest1_write,"junk.pdb", sun_primitives, 1; pdtest1_check,"junk.pdb"; write, "Testing dec_primitives db1 write w/PDB-style pointers..."; pdtest1_write,"junk.pdb", dec_primitives, 1; pdtest1_check,"junk.pdb"; write, "Testing cray_primitives db1 write w/PDB-style pointers..."; pdtest1_write,"junk.pdb", cray_primitives, 1; pdtest1_check,"junk.pdb"; write, "Testing native db1 write..."; pdtest1_write,"junk.pdb"; pdtest1_check,"junk.pdb"; } func pdtest1_check(filename) { f= openb(filename); vars= *get_vars(f)(1); if (numberof(vars)!=15) write, "Should be 15 variables in "+filename; local cs, ss, is, fs, ds, ca, sa, ia, fa2, da, cap, fa2_app, fs_app; local view, graph; restore, f; if (typeof(cs)!="char" || dimsof(cs)(1)!=0 || cs!='Q' /* 0x51 */) write, "variable cs bad in "+filename; if (typeof(ss)!="short" || dimsof(ss)(1)!=0 || ss!=-514) write, "variable ss bad in "+filename; if (typeof(is)!="int" || dimsof(is)(1)!=0 || is!=10) write, "variable is bad in "+filename; if (typeof(fs)!="float" || dimsof(fs)(1)!=0 || float_neq(fs,3.14159)) write, "variable fs bad in "+filename; if (typeof(ds)!="double" || dimsof(ds)(1)!=0 || double_neq(ds,exp(1))) write, "variable ds bad in "+filename; if (typeof(ca)!="char" || dimsof(ca)(1)!=1 || dimsof(ca)(2)!=10 || string(&ca)!="Hi there!") write, "variable ca bad in "+filename; if (typeof(sa)!="short" || dimsof(sa)(1)!=1 || dimsof(sa)(2)!=5 || anyof(sa!=[2,1,0,-1,-2])) write, "variable sa bad in "+filename; if (typeof(ia)!="int" || dimsof(ia)(1)!=1 || dimsof(ia)(2)!=5 || anyof(ia!=[-2,-1,0,1,2])) write, "variable ia bad in "+filename; if (typeof(fa2)!="float" || dimsof(fa2)(1)!=2 || anyof(dimsof(fa2)!=[2,3,4]) || anyof(float_neq(fa2, [[1,1,1],[2,4,8],[3,9,27],[4,16,64]]))) write, "variable fa2 bad in "+filename; if (typeof(da)!="double" || dimsof(da)(1)!=1 || dimsof(da)(2)!=4 || anyof(double_neq(da, exp([1,2,3,4])))) write, "variable da bad in "+filename; if (typeof(cap)!="pointer" || dimsof(cap)(1)!=1 || dimsof(cap)(2)!=3 || typeof(*cap(1))!="char" || string(cap(1))!="lev1" || typeof(*cap(2))!="char" || string(cap(2))!="lev2" || typeof(*cap(3))!="char" || string(cap(3))!="tar fu blat") write, "variable cap bad in "+filename; if (typeof(fs_app)!="float" || dimsof(fs_app)(1)!=0 || float_neq(fs_app,-3.14159)) write, "variable fs_app bad in "+filename; if (typeof(fa2_app)!="float" || dimsof(fa2_app)(1)!=2 || anyof(dimsof(fa2_app)!=[2,3,4]) || anyof(float_neq(fa2_app, [[1,2,3],[1,4,9],[1,8,27],[1,16,81]]))) write, "variable fa2_app bad in "+filename; if (nameof(structof(view))!="l_frame" || dimsof(view)(1)!=0 || float_neq(view.x_min,0.1) || float_neq(view.x_max,1.0) || float_neq(view.y_min,-0.5) || float_neq(view.y_max,0.5)) write, "variable view bad in "+filename; if (nameof(structof(graph))!="plot" || dimsof(graph)(1)!=0 || anyof(float_neq(graph.x_axis,[0,.1,.2,.3,.4,.5,.6,.7,.8,.9])) || anyof(float_neq(graph.y_axis,[.5,.4,.3,.2,.1,0,-.1,-.2,-.3,-.4])) || float_neq(graph.view.x_min,0.1) || float_neq(graph.view.x_max,1.0) || float_neq(graph.view.y_min,-0.5) || float_neq(graph.view.y_max,0.5) || graph.npts!=10 || string(graph.label)!="test graph") write, "variable graph bad in "+filename; } func float_neq(a, b) { return abs(a-b)/(abs(a)+abs(b)+1.e-99) > 1.e-6; } func double_neq(a, b) { return abs(a-b)/(abs(a)+abs(b)+1.e-99) > 1.e-12; } struct l_frame { float x_min, x_max, y_min, y_max; } struct plot { float x_axis(10), y_axis(10); int npts; pointer label; l_frame view; } func pdtest1_write(filename, primitives, pdbptrs) { cs= 'Q'; ss= -514s; is= 10n; fs= 3.14159; ds= exp(1); ca= *pointer("Hi there!"); sa= [2s,1s,0s,-1s,-2s]; ia= [-2n,-1n,0n,1n,2n]; fa2= [[1.f,1.f,1.f],[2.f,4.f,8.f],[3.f,9.f,27.f],[4.f,16.f,64.f]]; da= exp([1,2,3,4]); cap= [pointer("lev1"), pointer("lev2"), pointer("tar fu blat")]; fs= 3.14159f; view= l_frame(x_min=0.1,x_max=1.0,y_min=-0.5,y_max=0.5); graph= plot(x_axis=[0,.1,.2,.3,.4,.5,.6,.7,.8,.9], y_axis=[.5,.4,.3,.2,.1,0,-.1,-.2,-.3,-.4], npts=10, label=pointer("test graph"), view=view); fa2_app= float([[1,2,3],[1,4,9],[1,8,27],[1,16,81]]); fs_app= -3.14159f; if (!pdbptrs) { save, createb(filename, primitives),\ cs,ss,is,fs,ds, ca,sa,ia,fa2,da, cap, view,graph; } else { f= createb(filename, primitives); save, f, l_frame; add_member, f, "plot", -1, "x_axis", float, 10; add_member, f, "plot", -1, "y_axis", float, 10; add_member, f, "plot", -1, "npts", int; add_member, f, "plot", -1, "label", "char *"; add_member, f, "plot", -1, "view", l_frame; install_struct, f, "plot"; save, f, cs,ss,is,fs,ds, ca,sa,ia,fa2,da; add_variable, f, -1, "cap", "char*", 3; save, f, cap, view,graph; close, f; } save, updateb(filename), fa2_app,fs_app; }