Hi, I tested your patch and oss and jack outputs work fine. With alsa there is only silence.
24 березня 2009 о 02:00 +0100 Samuel Thibault написав(-ла): > Hello, > > Here is an updated patch. I've checked all the places that upstream > marked as "ISSUE: 64-bit", but also a few other. I could run all the > basic examples with success. Could you make some tests? > > Samuel > diff -ur chuck-1.2.0.8.dfsg.orig/debian/rules chuck-1.2.0.8.dfsg/debian/rules > --- chuck-1.2.0.8.dfsg.orig/debian/rules 2009-03-23 23:33:48.000000000 > +0100 > +++ chuck-1.2.0.8.dfsg/debian/rules 2009-03-23 23:34:11.000000000 +0100 > @@ -6,7 +6,7 @@ > # Uncomment this to turn on verbose mode. > #export DH_VERBOSE=1 > > -CFLAGS = -Wall -g > +CFLAGS = -Wall -g -fno-strict-aliasing > > ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) > CFLAGS += -O0 > diff -ur chuck-1.2.0.8.dfsg.orig/src/chuck_emit.cpp > chuck-1.2.0.8.dfsg/src/chuck_emit.cpp > --- chuck-1.2.0.8.dfsg.orig/src/chuck_emit.cpp 2007-03-22 > 07:36:02.000000000 +0100 > +++ chuck-1.2.0.8.dfsg/src/chuck_emit.cpp 2009-03-24 00:55:04.000000000 > +0100 > @@ -371,9 +371,9 @@ > // if decl, then expect only one word per var > if( exp->s_type == ae_exp_decl ) > emit->append( new Chuck_Instr_Reg_Pop_Word3( > exp->decl.num_var_decls ) ); > - else if( exp->type->size == 4 ) // ISSUE: 64-bit > + else if( exp->type->size == sz_INT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Reg_Pop_Word ); > - else if( exp->type->size == 8 ) // ISSUE: 64-bit > + else if( exp->type->size == sz_FLOAT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Reg_Pop_Word2 ); > else > { > @@ -606,9 +606,9 @@ > return FALSE; > > // HACK! > - if( stmt->c3->type->size == 8 ) // ISSUE: 64-bit > + if( stmt->c3->type->size == sz_FLOAT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Reg_Pop_Word2 ); > - else if( stmt->c3->type->size == 4 ) // ISSUE: 64-bit > + else if( stmt->c3->type->size == sz_INT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Reg_Pop_Word ); > else if( stmt->c3->type->size != 0 ) > { > @@ -1027,8 +1027,7 @@ > emit->code->stack_break.push_back( NULL ); > > // push the value of the loop counter > - // TODO: get rid of hard code 4 > - emit->append( new Chuck_Instr_Reg_Push_Deref( (t_CKUINT)counter, 4 ) ); > // ISSUE: 64-bit > + emit->append( new Chuck_Instr_Reg_Push_Deref( (t_CKUINT)counter, sz_INT > ) ); > > // get the type, taking cast into account > Chuck_Type * type = stmt->cond->cast_to ? stmt->cond->cast_to : > stmt->cond->type; > @@ -2122,9 +2121,9 @@ > else > { > // assign primitive > - if( right->size == 4 ) // ISSUE: 64-bit > + if( right->size == sz_INT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Assign_Primitive ); > - else if( right->size == 8 ) // ISSUE: 64-bit > + else if( right->size == sz_FLOAT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Assign_Primitive2 ); > else > { > @@ -2644,7 +2643,7 @@ > is_str = TRUE; > > // make sure > - if( type->size != 4 && type->size != 8 ) // ISSUE: 64-bit > + if( type->size != sz_INT && type->size != sz_FLOAT ) > { > EM_error2( array->linepos, > "(emit): internal error: array with datasize of %i...", > type->size ); > @@ -2705,7 +2704,7 @@ > t_CKUINT size = type->size; > if( func->def->s_type == ae_func_builtin ) > { > - if( size == 0 || size == 4 || size == 8 ) // ISSUE: 64-bit > + if( size == 0 || size == sz_INT || size == sz_FLOAT ) > { > // is member > if( is_member ) > @@ -3165,9 +3164,9 @@ > /* if( !is_init && first_exp ) > { > // push 0 > - if( type->size == 4 ) // ISSUE: 64-bit > + if( type->size == sz_INT ) > emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) ); > - else if( type->size == 8 ) // ISSUE: 64-bit > + else if( type->size == sz_FLOAT ) > emit->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) ); > else > { > @@ -3184,9 +3183,9 @@ > if( value->is_member ) > { > // zero out location in object, and leave addr on operand stack > - if( type->size == 4 ) // ISSUE: 64-bit > + if( type->size == sz_INT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Alloc_Member_Word( > value->offset ) ); > - else if( type->size == 8 ) // ISSUE: 64-bit > + else if( type->size == sz_FLOAT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Alloc_Member_Word2( > value->offset ) ); > else > { > @@ -3218,9 +3217,9 @@ > // TODO: this is wrong for static > // BAD: > // FIX: > - if( type->size == 4 ) // ISSUE: 64-bit > + if( type->size == sz_INT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Alloc_Word( local->offset > ) ); > - else if( type->size == 8 ) // ISSUE: 64-bit > + else if( type->size == sz_FLOAT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Alloc_Word2( local->offset > ) ); > else > { > @@ -3273,11 +3272,11 @@ > // if obj > if( is_obj ) > emit->append( new Chuck_Instr_Assign_Object ); > - // size 4 primitive > - else if( type->size == 4 ) // ISSUE: 64-bit > + // size int primitive > + else if( type->size == sz_INT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Assign_Primitive ); > - // size 8 primitive > - else if( type->size == 8 ) // ISSUE: 64-bit > + // size float primitive > + else if( type->size == sz_FLOAT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Assign_Primitive2 ); > else > assert( FALSE ); > @@ -3672,7 +3671,7 @@ > // handle member function > // TODO: this is a hack - what if exp is not func_call? > // if( emit->code->need_this ) > - // size += 4; > + // size += sz_UINT; > > // emit instruction that will put the code on the stack > emit->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT)code ) ); > @@ -3746,9 +3745,9 @@ > if( v->func_ref ) > emit->append( new Chuck_Instr_Reg_Push_Imm( > (t_CKUINT)v->func_ref ) ); > // check size > - else if( v->type->size == 4 ) // ISSUE: 64-bit > + else if( v->type->size == sz_INT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Reg_Push_Mem( v->offset, > v->is_context_global ) ); > - else if( v->type->size == 8 ) // ISSUE: 64-bit > + else if( v->type->size == sz_FLOAT ) // ISSUE: 64-bit > emit->append( new Chuck_Instr_Reg_Push_Mem2( v->offset, > v->is_context_global ) ); > else > { > diff -ur chuck-1.2.0.8.dfsg.orig/src/chuck_instr.cpp > chuck-1.2.0.8.dfsg/src/chuck_instr.cpp > --- chuck-1.2.0.8.dfsg.orig/src/chuck_instr.cpp 2007-03-22 > 07:36:02.000000000 +0100 > +++ chuck-1.2.0.8.dfsg/src/chuck_instr.cpp 2009-03-24 01:41:20.000000000 > +0100 > @@ -1105,7 +1105,7 @@ > > //----------------------------------------------------------------------------- > void Chuck_Instr_Reg_Push_Deref::execute( Chuck_VM * vm, Chuck_VM_Shred * > shred ) > { > - if( m_size == 4 ) // ISSUE: 64-bit > + if( m_size == sz_UINT ) > { > t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp; > push_( reg_sp, *((t_CKUINT *)m_val) ); > @@ -2526,12 +2526,12 @@ > Chuck_VM_Code * func = (Chuck_VM_Code *)*reg_sp; > // get the local stack depth - caller local variables > t_CKUINT local_depth = *(reg_sp+1); > - // convert to number of 4-byte words, extra partial word counts as > additional word > - local_depth = ( local_depth >> 2 ) + ( local_depth & 0x3 ? 1 : 0 ); > + // convert to number of int words, extra partial word counts as > additional word > + local_depth = ( local_depth / sz_UINT ) + ( local_depth & 0x3 ? 1 : 0 ); > // get the stack depth of the callee function args > - t_CKUINT stack_depth = ( func->stack_depth >> 2 ) + ( func->stack_depth > & 0x3 ? 1 : 0 ); > + t_CKUINT stack_depth = ( func->stack_depth / sz_UINT ) + ( > func->stack_depth & 0x3 ? 1 : 0 ); > // get the previous stack depth - caller function args > - t_CKUINT prev_stack = ( *(mem_sp-1) >> 2 ) + ( *(mem_sp-1) & 0x3 ? 1 : 0 > ); > + t_CKUINT prev_stack = ( *(mem_sp-1) / sz_UINT ) + ( *(mem_sp-1) & 0x3 ? > 1 : 0 ); > > // jump the sp > mem_sp += prev_stack + local_depth; > @@ -2605,13 +2605,13 @@ > // MOVED TO BELOW: f_mfun f = (f_mfun)func->native_func; > // get the local stack depth - caller local variables > t_CKUINT local_depth = *(reg_sp+1); > - // convert to number of 4-byte words, extra partial word counts as > additional word > - local_depth = ( local_depth >> 2 ) + ( local_depth & 0x3 ? 1 : 0 ); > + // convert to number of int words, extra partial word counts as > additional word > + local_depth = ( local_depth / sz_UINT ) + ( local_depth & 0x3 ? 1 : 0 ); > // get the stack depth of the callee function args > - t_CKUINT stack_depth = ( func->stack_depth >> 2 ) + ( func->stack_depth > & 0x3 ? 1 : 0 ); > + t_CKUINT stack_depth = ( func->stack_depth / sz_UINT ) + ( > func->stack_depth & 0x3 ? 1 : 0 ); > // UNUSED: get the previous stack depth - caller function args > - // UNUSED: t_CKUINT prev_stack = ( *(mem_sp-1) >> 2 ) + ( *(mem_sp-1) & > 0x3 ? 1 : 0 ); > - // the amount to push in 4-byte words > + // UNUSED: t_CKUINT prev_stack = ( *(mem_sp-1) / sz_UINT ) + ( > *(mem_sp-1) & 0x3 ? 1 : 0 ); > + // the amount to push in int words > t_CKUINT push = local_depth; > // push the mem stack passed the current function variables and arguments > mem_sp += push; > @@ -2661,12 +2661,12 @@ > mem_sp -= push; > > // push the return > - if( m_val == 4 ) // ISSUE: 64-bit > + if( m_val == sz_UINT ) > { > // push the return args > push_( reg_sp, retval.v_uint ); > } > - else if( m_val == 8 ) // ISSUE: 64-bit > + else if( m_val == sz_FLOAT ) > { > // push the return args > t_CKFLOAT *& sp_double = (t_CKFLOAT *&)reg_sp; > @@ -2703,13 +2703,13 @@ > f_sfun f = (f_sfun)func->native_func; > // get the local stack depth - caller local variables > t_CKUINT local_depth = *(reg_sp+1); > - // convert to number of 4-byte words, extra partial word counts as > additional word > - local_depth = ( local_depth >> 2 ) + ( local_depth & 0x3 ? 1 : 0 ); > + // convert to number of int words, extra partial word counts as > additional word > + local_depth = ( local_depth / sz_UINT ) + ( local_depth & 0x3 ? 1 : 0 ); > // get the stack depth of the callee function args > - t_CKUINT stack_depth = ( func->stack_depth >> 2 ) + ( func->stack_depth > & 0x3 ? 1 : 0 ); > + t_CKUINT stack_depth = ( func->stack_depth / sz_UINT ) + ( > func->stack_depth & 0x3 ? 1 : 0 ); > // UNUSED: get the previous stack depth - caller function args > - // UNUSED: t_CKUINT prev_stack = ( *(mem_sp-1) >> 2 ) + ( *(mem_sp-1) & > 0x3 ? 1 : 0 ); > - // the amount to push in 4-byte words > + // UNUSED: t_CKUINT prev_stack = ( *(mem_sp-1) / sz_UINT ) + ( > *(mem_sp-1) & 0x3 ? 1 : 0 ); > + // the amount to push in int words > t_CKUINT push = local_depth; > // push the mem stack passed the current function variables and arguments > mem_sp += push; > @@ -2747,12 +2747,12 @@ > mem_sp -= push; > > // push the return > - if( m_val == 4 ) // ISSUE: 64-bit > + if( m_val == sz_UINT ) // ISSUE: 64-bit > { > // push the return args > push_( reg_sp, retval.v_uint ); > } > - else if( m_val == 8 ) // ISSUE: 64-bit > + else if( m_val == sz_FLOAT ) // ISSUE: 64-bit > { > // push the return args > t_CKFLOAT *& sp_double = (t_CKFLOAT *&)reg_sp; > @@ -2985,7 +2985,7 @@ > t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp; > > // allocate the array > - if( m_type_ref->size == 4 ) // ISSUE: 64-bit > + if( m_type_ref->size == sz_INT ) // ISSUE: 64-bit > { > // pop the values > pop_( reg_sp, m_length ); > @@ -3003,10 +3003,10 @@ > // push the pointer > push_( reg_sp, (t_CKUINT)array ); > } > - else if( m_type_ref->size == 8 ) // ISSUE: 64-bit > + else if( m_type_ref->size == sz_FLOAT ) // ISSUE: 64-bit > { > // pop the values > - pop_( reg_sp, 2 * m_length ); > + pop_( reg_sp, (sz_FLOAT / sz_INT) * m_length ); > // instantiate array > Chuck_Array8 * array = new Chuck_Array8( m_length ); > // problem > @@ -3114,7 +3114,7 @@ > if( capacity >= top ) > { > // check size > - if( size == 4 ) // ISSUE: 64-bit > + if( size == sz_INT ) // ISSUE: 64-bit > { > Chuck_Array4 * base = new Chuck_Array4( is_obj, *capacity ); > if( !base ) goto out_of_memory; > @@ -3312,8 +3312,7 @@ > // check pointer > if( !(*sp) ) goto null_pointer; > > - // 4 or 8 > - if( m_size == 4 ) // ISSUE: 64-bit > + if( m_size == sz_INT ) // ISSUE: 64-bit > { > // get array > Chuck_Array4 * arr = (Chuck_Array4 *)(*sp); > @@ -3335,7 +3334,7 @@ > push_( sp, val ); > } > } > - else if( m_size == 8 ) // ISSUE: 64-bit > + else if( m_size == sz_FLOAT ) // ISSUE: 64-bit > { > // get array > Chuck_Array8 * arr = (Chuck_Array8 *)(*sp); > @@ -3404,8 +3403,7 @@ > // check pointer > if( !(*sp) ) goto null_pointer; > > - // 4 or 8 > - if( m_size == 4 ) // ISSUE: 64-bit > + if( m_size == sz_INT ) // ISSUE: 64-bit > { > // get array > Chuck_Array4 * arr = (Chuck_Array4 *)(*sp); > @@ -3427,7 +3425,7 @@ > push_( sp, val ); > } > } > - else if( m_size == 8 ) // ISSUE: 64-bit > + else if( m_size == sz_FLOAT ) // ISSUE: 64-bit > { > // get array > Chuck_Array8 * arr = (Chuck_Array8 *)(*sp); > @@ -3522,8 +3520,7 @@ > } > } > > - // 4 or 8 > - if( m_size == 4 ) // ISSUE: 64-bit > + if( m_size == sz_INT ) // ISSUE: 64-bit > { > // get arry > Chuck_Array4 * arr = base; > @@ -3545,7 +3542,7 @@ > push_( sp, val ); > } > } > - else if( m_size == 8 ) // ISSUE: 64-bit > + else if( m_size == sz_FLOAT ) // ISSUE: 64-bit > { > // get array > Chuck_Array8 * arr = (Chuck_Array8 *)(base); > @@ -3626,9 +3623,8 @@ > } > else > { > - // 4 or 8 > - if( m_size == 4 ) { push_( sp, *((t_CKUINT *)data) ); } // ISSUE: > 64-bit > - else if( m_size == 8 ) { push_float( sp, *((t_CKFLOAT *)data) ); } > // ISSUE: 64-bit > + if( m_size == sz_UINT ) { push_( sp, *((t_CKUINT *)data) ); } // > ISSUE: 64-bit > + else if( m_size == sz_FLOAT ) { push_float( sp, *((t_CKFLOAT *)data) > ); } // ISSUE: 64-bit > else assert( FALSE ); > } > > @@ -3717,9 +3713,8 @@ > } > else > { > - // 4 or 8 > - if( m_size == 4 ) { push_( sp, *((t_CKUINT *)data) ); } // ISSUE: > 64-bit > - else if( m_size == 8 ) { push_float( sp, *((t_CKFLOAT *)data) ); } > // ISSUE: 64-bit > + if( m_size == sz_UINT ) { push_( sp, *((t_CKUINT *)data) ); } // > ISSUE: 64-bit > + else if( m_size == sz_FLOAT ) { push_float( sp, *((t_CKFLOAT *)data) > ); } // ISSUE: 64-bit > else assert( FALSE ); > } > } > @@ -3744,9 +3739,8 @@ > } > else > { > - // 4 or 8 > - if( m_size == 4 ) { push_( sp, *((t_CKUINT *)m_addr) ); } // ISSUE: > 64-bit > - else if( m_size == 8 ) { push_float( sp, *((t_CKFLOAT *)m_addr) ); } > // ISSUE: 64-bit > + if( m_size == sz_UINT ) { push_( sp, *((t_CKUINT *)m_addr) ); } // > ISSUE: 64-bit > + else if( m_size == sz_FLOAT ) { push_float( sp, *((t_CKFLOAT > *)m_addr) ); } // ISSUE: 64-bit > else assert( FALSE ); > } > } > @@ -4110,27 +4104,37 @@ > void Chuck_Instr_Hack::execute( Chuck_VM * vm, Chuck_VM_Shred * shred ) > { > // look at the type > - if( m_type_ref->size == 4 ) // ISSUE: 64-bit > + switch (m_type_ref->xid) { > + case te_int: > + case te_uint: > { > t_CKINT * sp = (t_CKINT *)shred->reg->sp; > - if( !isa( m_type_ref, &t_string ) ) > - // print it > - fprintf( stderr, "%d :(%s)\n", *(sp-1), m_type_ref->c_name() ); > - else > - fprintf( stderr, "\"%s\" : (%s)\n", ((Chuck_String > *)*(sp-1))->str.c_str(), m_type_ref->c_name() ); > + // print it > + fprintf( stderr, "%d :(%s)\n", *(sp-1), m_type_ref->c_name() ); > + break; > } > - else if( m_type_ref->size == 8 ) // ISSUE: 64-bit > + case te_string: > + { > + t_CKINT * sp = (t_CKINT *)shred->reg->sp; > + // print it > + fprintf( stderr, "\"%s\" : (%s)\n", ((Chuck_String > *)*(sp-1))->str.c_str(), m_type_ref->c_name() ); > + break; > + } > + case te_single: > + case te_float: > + case te_double: > + case te_time: > + case te_dur: > { > t_CKFLOAT * sp = (t_CKFLOAT *)shred->reg->sp; > // print it > fprintf( stderr, "%f :(%s)\n", *(sp-1), m_type_ref->c_name() ); > + break; > } > - else if( m_type_ref->size == 0 ) > - { > + default: > fprintf( stderr, "... :(%s)\n", m_type_ref->c_name() ); > + break; > } > - else > - assert( FALSE ); > > // flush > fflush( stderr ); > @@ -4186,37 +4190,48 @@ > Chuck_Type * type = m_type_refs[i]; > > // look at the type > - if( type->size == 4 ) // ISSUE: 64-bit > - { > + switch (type->xid) { > + case te_int: > + case te_uint: > + { > t_CKINT * sp = (t_CKINT *)the_sp; > - if( !isa( type, &t_string ) ) > - { > - if( isa( type, &t_object ) ) > - // print it > - fprintf( stderr, "0x%x ", *(sp) ); > - else > - // print it > - fprintf( stderr, "%d ", *(sp) ); > - } > - else > - fprintf( stderr, "%s ", ((Chuck_String *)*(sp))->str.c_str() > ); > - > - the_sp += 4; > - } > - else if( type->size == 8 ) // ISSUE: 64-bit > - { > + // print it > + fprintf( stderr, "%d ", *(sp) ); > + the_sp += sz_INT; > + break; > + } > + case te_object: > + { > + t_CKINT * sp = (t_CKINT *)the_sp; > + // print it > + fprintf( stderr, "0x%x ", *(sp) ); > + the_sp += sz_INT; > + break; > + } > + case te_string: > + { > + t_CKINT * sp = (t_CKINT *)the_sp; > + // print it > + fprintf( stderr, "%s ", ((Chuck_String *)*(sp))->str.c_str() ); > + the_sp += sz_INT; > + break; > + } > + case te_single: > + case te_float: > + case te_double: > + case te_time: > + case te_dur: > + { > t_CKFLOAT * sp = (t_CKFLOAT *)the_sp; > // print it > fprintf( stderr, "%f ", *(sp) ); > - > - the_sp += 8; > - } > - else if( type->size == 0 ) > - { > + the_sp += sz_FLOAT; > + break; > + } > + default: > fprintf( stderr, "... " ); > - } > - else > - assert( FALSE ); > + break; > + } > } > > fprintf( stderr, "\n" ); > diff -ur chuck-1.2.0.8.dfsg.orig/src/chuck_oo.h > chuck-1.2.0.8.dfsg/src/chuck_oo.h > --- chuck-1.2.0.8.dfsg.orig/src/chuck_oo.h 2007-03-22 07:36:01.000000000 > +0100 > +++ chuck-1.2.0.8.dfsg/src/chuck_oo.h 2009-03-24 00:53:01.000000000 +0100 > @@ -152,8 +152,8 @@ > > > > -#define CHUCK_ARRAY4_DATASIZE 4 > -#define CHUCK_ARRAY8_DATASIZE 8 > +#define CHUCK_ARRAY4_DATASIZE sz_INT > +#define CHUCK_ARRAY8_DATASIZE sz_FLOAT > > //----------------------------------------------------------------------------- > // name: struct Chuck_Array > // desc: native ChucK arrays ( virtual base class ) > diff -ur chuck-1.2.0.8.dfsg.orig/src/ulib_std.cpp > chuck-1.2.0.8.dfsg/src/ulib_std.cpp > --- chuck-1.2.0.8.dfsg.orig/src/ulib_std.cpp 2007-03-22 07:36:01.000000000 > +0100 > +++ chuck-1.2.0.8.dfsg/src/ulib_std.cpp 2009-03-24 01:02:23.000000000 > +0100 > @@ -549,8 +549,8 @@ > // randi > CK_DLL_SFUN( rand2_impl ) // inclusive. > { > - int min = *(int *)ARGS, max = *((int *)ARGS + 1); > - int range = max - min; > + t_CKINT min = *(t_CKINT *)ARGS, max = *((t_CKINT *)ARGS + 1); > + t_CKINT range = max - min; > if ( range == 0 ) > { > RETURN->v_int = min; > @@ -562,11 +562,11 @@ > { > if( range > 0 ) > { > - RETURN->v_int = min + (int) ( (1.0 + range) * ( > ::rand()/(RAND_MAX+1.0) ) ); > + RETURN->v_int = min + (t_CKINT) ( (1.0 + range) * ( > ::rand()/(RAND_MAX+1.0) ) ); > } > else > { > - RETURN->v_int = min - (int) ( (-range + 1.0) * ( > ::rand()/(RAND_MAX+1.0) ) ); > + RETURN->v_int = min - (t_CKINT) ( (-range + 1.0) * ( > ::rand()/(RAND_MAX+1.0) ) ); > } > } > }
signature.asc
Description: Digital signature