void MADIMPENTRY( RegUpdateEnd )( mad_registers *mr, unsigned flags, unsigned bit_start, unsigned bit_size ) { unsigned i; unsigned bit_end; mr = mr; flags = flags; bit_end = bit_start + bit_size; #define IN_RANGE( i, bit ) \ ((bit) >= RegList[i].info.bit_start && (bit) < (unsigned)( RegList[i].info.bit_start + RegList[i].info.bit_size )) for( i = 0; i < IDX_LAST_ONE; ++i ) { if( IN_RANGE( i, bit_start ) || IN_RANGE( i, bit_end ) ) { MCNotify( MNT_MODIFY_REG, (void *)&RegSet[RegList[i].reg_set] ); break; } } switch( bit_start ) { case BIT_OFF( iar ): MCNotify( MNT_MODIFY_IP, NULL ); break; case BIT_OFF( u1 ): // sp MCNotify( MNT_MODIFY_SP, NULL ); break; case BIT_OFF( r31 ): // fp NYI: can float MCNotify( MNT_MODIFY_FP, NULL ); break; } }
void MADIMPENTRY( RegUpdateEnd )( mad_registers *mr, unsigned flags, unsigned bit_start, unsigned bit_size ) { unsigned i; unsigned bit_end; mr = mr; flags = flags; memset( &mr->axp.u31, 0, sizeof( mr->axp.u31 ) ); memset( &mr->axp.f31, 0, sizeof( mr->axp.f31 ) ); bit_end = bit_start + bit_size; #define IN_RANGE( i, bit ) \ ((bit) >= RegList[i].info.bit_start && (bit) < (unsigned)( RegList[i].info.bit_start + RegList[i].info.bit_size )) for( i = 0; i < IDX_LAST_ONE; ++i ) { if( (IN_RANGE(i, bit_start) || IN_RANGE( i, bit_end )) && (RegList[i].pal == PAL_all || RegList[i].pal == mr->axp.active_pal) ) { MCNotify( MNT_MODIFY_REG, (void *)&RegSet[RegList[i].reg_set] ); break; } } switch( bit_start ) { case BIT_OFF( pal.nt.fir ): MCNotify( MNT_MODIFY_IP, NULL ); break; case BIT_OFF( u30 ): // sp MCNotify( MNT_MODIFY_SP, NULL ); break; case BIT_OFF( u15 ): // fp MCNotify( MNT_MODIFY_FP, NULL ); break; } }
mad_status MADIMPENTRY( RegModified )( const mad_reg_set_data *rsd, const mad_reg_info *ri, const mad_registers *old, const mad_registers *cur ) { unsigned_64 new_ip; unsigned_8 *p_old; unsigned_8 *p_cur; unsigned mask; unsigned size; rsd = rsd; if( ri->bit_start == BIT_OFF( pal.nt.fir ) ) { new_ip = old->axp.pal.nt.fir; //NYI: 64 bit new_ip.u._32[0] += sizeof( unsigned_32 ); if( new_ip.u._32[0] != cur->axp.pal.nt.fir.u._32[0] ) { return( MS_MODIFIED_SIGNIFICANTLY ); } else if( old->axp.pal.nt.fir.u._32[0] != cur->axp.pal.nt.fir.u._32[0] ) { return( MS_MODIFIED ); } } else { p_old = (unsigned_8 *)old + BYTEIDX( ri->bit_start ); p_cur = (unsigned_8 *)cur + BYTEIDX( ri->bit_start ); size = ri->bit_size; if( size >= BYTES2BITS( 1 ) ) { /* it's going to be byte aligned */ return( memcmp( p_old, p_cur, BITS2BYTES( size ) ) != 0 ? MS_MODIFIED_SIGNIFICANTLY : MS_OK ); } else { mask = (1 << size) - 1; #define GET_VAL( w ) (((*p_##w >> BITIDX( ri->bit_start ))) & mask) return( GET_VAL( old ) != GET_VAL( cur ) ? MS_MODIFIED_SIGNIFICANTLY : MS_OK ); } } return( MS_OK ); }
void Character::move(Vec2 dir) { if ((_state & BAN_MOVE))return; if (_state & IS_MOVING)return; //if (LOCK)return; //dir.y-=0.1f; if (dir.x < 0)dir = Vec2(-MOVE_SPEED_PER_F,0); else dir=Vec2(MOVE_SPEED_PER_F, 0); //if(dir.x>0?CH_RIGHT:CH_LEFT; auto call = [&]() { BIT_OFF(_state,IS_MOVING); }; // auto callEnd = [&]() { //this->stateFlag&=~flag;}; auto action = MoveBy::create(MOVE_DURATION, dir); auto actionSeq = Sequence::create( action, CallFunc::create(call), NULL ); BIT_ON(_state, IS_MOVING); actionSeq->setTag(MOVE_TAG); this->runAction(actionSeq); //this->runActionWithFlag(actionMove,flag); log("WH:ch moved to (%f,%f)" , this->getPositionX() , this->getPositionY()); }
mad_status DIGENTRY MIRegModified( const mad_reg_set_data *rsd, const mad_reg_info *ri, const mad_registers *old, const mad_registers *cur ) { unsigned_64 new_ip; unsigned_8 *p_old; unsigned_8 *p_cur; unsigned mask; unsigned size; if( ri->bit_start == BIT_OFF( iar ) ) { new_ip = old->ppc.iar; //NYI: 64 bit new_ip.u._32[I64LO32] += sizeof( unsigned_32 ); if( new_ip.u._32[I64LO32] != cur->ppc.iar.u._32[I64LO32] ) { return( MS_MODIFIED_SIGNIFICANTLY ); } else if( old->ppc.iar.u._32[I64LO32] != cur->ppc.iar.u._32[I64LO32] ) { return( MS_MODIFIED ); } } else { p_old = (unsigned_8 *)old + (ri->bit_start / BITS_PER_BYTE); p_cur = (unsigned_8 *)cur + (ri->bit_start / BITS_PER_BYTE); size = ri->bit_size; if( size >= BITS_PER_BYTE ) { /* it's going to be byte aligned */ return( memcmp( p_old, p_cur, size / BITS_PER_BYTE ) != 0 ? MS_MODIFIED_SIGNIFICANTLY : MS_OK ); } else { mask = (1 << size) - 1; #define GET_VAL( w ) (((*p_##w >> (ri->bit_start % BITS_PER_BYTE))) & mask) return( GET_VAL( old ) != GET_VAL( cur ) ? MS_MODIFIED_SIGNIFICANTLY : MS_OK ); } } return( MS_OK ); }
/* Query whether a register value differs between the two register sets 'old' and 'cur'. The following return codes are possible: MS_OK - value is unchanged MS_MODIFIED - value is different MS_MODIFIED_SIGNIFICANTLY - value has changed in a way that the user cares about */ mad_status DIGENTRY MIRegModified( const mad_reg_set_data *rsd, const mad_reg_info *ri, const mad_registers *old, const mad_registers *cur ) { addr_ptr new_ip; unsigned_8 *p_old; unsigned_8 *p_cur; unsigned mask; unsigned size; if( ri->bit_start == BIT_OFF( pc ) ) { new_ip = old->jvm.pc; //NYI: find length of instruction new_ip.offset += sizeof( unsigned_32 ); if( new_ip.segment != cur->jvm.pc.segment || new_ip.offset != cur->jvm.pc.offset ) { return( MS_MODIFIED_SIGNIFICANTLY ); } else if( old->jvm.pc.segment != cur->jvm.pc.segment || old->jvm.pc.offset != cur->jvm.pc.offset ) { return( MS_MODIFIED ); } } else { p_old = (unsigned_8 *)old + (ri->bit_start / BITS_PER_BYTE); p_cur = (unsigned_8 *)cur + (ri->bit_start / BITS_PER_BYTE); size = ri->bit_size; if( size >= BITS_PER_BYTE ) { /* it's going to be byte aligned */ return( memcmp( p_old, p_cur, size / BITS_PER_BYTE ) != 0 ? MS_MODIFIED_SIGNIFICANTLY : MS_OK ); } else { mask = (1 << size) - 1; #define GET_VAL( w ) (((*p_##w >> (ri->bit_start % BITS_PER_BYTE))) & mask) return( GET_VAL( old ) != GET_VAL( cur ) ? MS_MODIFIED_SIGNIFICANTLY : MS_OK ); } } return( MS_OK ); }
void Character::resetTo(Vec2 pos) { //this->stopActionByTag(DROP_TAG); //this->stopActionByTag(JUMPSEQ_TAG); //BIT_ON(_state, IS_MOVING); //this->setRotation(0); //auto size = this->getContentSize(); //auto prePos = this->getPosition(); this->setPosition(Vec2(pos.x,pos.y)); this->stopAllActions(); _jumpCnt = 0; BIT_OFF(_state,IS_JUMPING) ; BIT_OFF(_state, IS_DROPPING); BIT_OFF(_state, IS_MOVING); //_state = 0; }
/* The client has just finished modifying a register (or registers). The MAD should take this chance to notify the client on what displays need to be updated. MCNotify should be called for the following MNT_MODIFY_REG - to notify client which register set has changed (2d parm is register set pointer). MNT_MODIFY_IP - instruction pointer special reg has changed. MNT_MODIFY_SP - stack pointer special reg has changed. MNT_MODIFY_FP - frame pointer special reg has changed. */ void DIGENTRY MIRegUpdateEnd( mad_registers *mr, unsigned flags, unsigned bit_start, unsigned bit_size ) { unsigned bit_end; bit_end = bit_start + bit_size; MCNotify( MNT_MODIFY_REG, (void *)&RegSet[CPU_REG_SET] ); switch( bit_start ) { case BIT_OFF( pc ): MCNotify( MNT_MODIFY_IP, NULL ); break; case BIT_OFF( optop ): MCNotify( MNT_MODIFY_SP, NULL ); break; case BIT_OFF( frame ): MCNotify( MNT_MODIFY_FP, NULL ); break; } }
mad_status DIGENTRY MIRegInspectAddr( const mad_reg_info *ri, mad_registers const *mr, address *a ) { unsigned bit_start; unsigned_64 *p; memset( a, 0, sizeof( *a ) ); bit_start = ri->bit_start; if( bit_start == BIT_OFF( iar ) ) { a->mach.offset = mr->ppc.iar.u._32[I64LO32]; return( MS_OK ); } if( bit_start >= BIT_OFF( f0 ) && bit_start < (BIT_OFF( f31 ) + 64) ) { return( MS_FAIL ); } p = (unsigned_64 *)((unsigned_8 *)mr + (bit_start / BITS_PER_BYTE)); a->mach.offset = p->u._32[I64LO32]; return( MS_OK ); }
mad_status MADIMPENTRY( RegSetDisplayModify )( const mad_reg_set_data *rsd, const mad_reg_info *ri, const mad_modify_list **possible_p, int *num_possible_p ) { rsd = rsd; switch( ri->bit_start ) { case BIT_OFF( u31 ): case BIT_OFF( f31 ): *possible_p = NULL; *num_possible_p = 0; return( MS_FAIL ); } *num_possible_p = 1; if( ri->type == AXPT_DOUBLE ) { *possible_p = &FltReg; } else { *possible_p = &IntReg; } return( MS_OK ); }
mad_status MADIMPENTRY( RegInspectAddr )( const mad_reg_info *ri, const mad_registers *mr, address *a ) { unsigned bit_start; unsigned_32 *p; memset( a, 0, sizeof( *a ) ); bit_start = ri->bit_start; if( bit_start == BIT_OFF( pal.nt.fir ) ) { a->mach.offset = mr->axp.pal.nt.fir.u._32[0]; return( MS_OK ); } if( IS_FP_BIT( bit_start ) ) { return( MS_FAIL ); } if( bit_start >= BIT_OFF( pal ) ) { return( MS_FAIL ); } p = (unsigned_32 *)((unsigned_8 *)mr + BYTEIDX( bit_start )); a->mach.offset = *p; return( MS_OK ); }
mcxstatus mclpARextend ( mclpAR* ar , long idx , double val ) { mclp* ivp = NULL ; if (ar->n_ivps >= ar->n_alloc) { long n_new_alloc = 4 + 1.22 * ar->n_alloc ; if (! ( ar->ivps = mcxNRealloc ( ar->ivps , n_new_alloc , ar->n_alloc , sizeof(mclp) , mclpInit_v , RETURN_ON_FAIL ) ) ) return STATUS_FAIL ; ar->n_alloc = n_new_alloc ; } ivp = ar->ivps + ar->n_ivps ; ivp->val = val ; ivp->idx = idx ; if (ar->n_ivps && ivp[-1].idx >= idx) { if (ivp[-1].idx > idx) BIT_OFF(ar->sorted, MCLPAR_SORTED | MCLPAR_UNIQUE) ; else BIT_OFF(ar->sorted, MCLPAR_UNIQUE) ; } ar->n_ivps++ ; return STATUS_OK ; }
//========================================================================= // blinkLED: routine that will blink an led when vxWorks is running //========================================================================= // from winSH: -> show_active starts the thread // -> td "show_active" kills the thread //========================================================================= static void blinkLED() { static int count=0; int leds=GET_LEDS; while (1) { if(count) BIT_ON(leds,HOST_ACTIVE_LED); else BIT_OFF(leds,HOST_ACTIVE_LED); SET_LEDS(leds); count=count?0:1; taskDelay(calcSysClkTicks(83)); /* taskDelay(5); */ } }
mad_status MADIMPENTRY( RegInspectAddr )( const mad_reg_info *ri, mad_registers const *mr, address *a ) { unsigned bit_start; unsigned_64 *p; memset( a, 0, sizeof( *a ) ); bit_start = ri->bit_start; if( bit_start == BIT_OFF( iar ) ) { a->mach.offset = mr->ppc.iar.u._32[I64LO32]; return( MS_OK ); } if( IS_FP_BIT( bit_start ) ) { return( MS_FAIL ); } p = (unsigned_64 *)((unsigned_8 *)mr + BYTEIDX( bit_start )); a->mach.offset = p->u._32[I64LO32]; return( MS_OK ); }
void Character::drop() { //if (_state & IS_DROPPING)return; //this->stopActionByTag(JUMP_TAG); //_jumpAction->retain(); //auto pos = this->getParent()->convertToWorldSpace(this->getPosition()); /*auto pos = this->getPosition(); auto height = pos.y + DROP_HEIGHT_EX; auto downAction = MoveBy::create(height / DROP_SPEED_PER_H, Vec2(0, -height)); //downAction->setTag(DROP_TAG); auto esiDown = EaseSineIn::create(downAction); esiDown->setTag(DROP_TAG);*/ BIT_OFF(_state, IS_JUMPING); //BIT_ON(_state, IS_DROPPING); //this->runAction(esiDown); //this->runAction(downAction); //BIT_OFF(_state,IN_AIR); //_playerState = PS_JUMPBACK; }
int main ( int argc , const char* argv[] ) { mcxIO *xfcl = NULL , *xfctrl = NULL , *xfcoarse= NULL , *xfbase = NULL , *xfcone = NULL , *xfstack = NULL ; mclx* mxbase, *cl, *cl_coarse, *clprev, *clctrl = NULL ; mcxTing* shared = mcxTingNew("-I 4 -overlap split") ; mcxbool root = TRUE ; mcxbool have_bootstrap = FALSE ; const char* plexprefix = NULL ; const char* stem = "mcl" ; mcxbool same = FALSE ; mcxbool plex = TRUE ; mcxbool add_transpose = FALSE ; const char* b2opts = NULL ; const char* b1opts = NULL ; mcxbits write_modes = 0 ; mclAlgParam* mlp = NULL ; mcxstatus status = STATUS_OK ; mcxstatus parse_status = STATUS_OK ; int multiplex_idx = 1 ; int N = 0 ; int n_ite = 0 ; dim n_components = 0, n_cls = 0 ; int a = 1, i= 0 ; int n_arg_read = 0 ; int delta = 0 ; mcxOption* opts, *opt ; mcxTing* cline = mcxOptArgLine(argv+1, argc-1, '\'') ; mclgTF* transform = NULL ; mcxTing* transform_spec = NULL ; double iaf = 0.84 ; mclx_app_init(stderr) ; if (0) mcxLogLevel = MCX_LOG_AGGR | MCX_LOG_MODULE | MCX_LOG_IO | MCX_LOG_GAUGE | MCX_LOG_WARN ; else mcxLogLevelSetByString("xf4g1") ; mcxOptAnchorSortById(options, sizeof(options)/sizeof(mcxOptAnchor) -1) ; if (argc == 2 && argv[1][0] == '-' && mcxOptIsInfo(argv[1], options)) delta = 1 ; else if (argc < 2) { help(options, shared) ; exit(0) ; } opts = mcxOptExhaust (options, (char**) argv, argc, 2-delta, &n_arg_read, &parse_status) ; if (parse_status != STATUS_OK) { mcxErr(me, "initialization failed") ; exit(1) ; } ; for (opt=opts;opt->anch;opt++) { mcxOptAnchor* anch = opt->anch ; switch(anch->id) { case MY_OPT_HELP : help(options, shared) ; exit(0) ; case MY_OPT_APROPOS : help(options, shared) ; exit(0) ; break ; case MY_OPT_NMAX : N = atoi(opt->val) ; break ; case MY_OPT_Z : help(NULL, shared) ; exit(0) ; break ; case MY_OPT_SHARED : mcxTingPrintAfter(shared, " %s", opt->val) ; break ; case MY_OPT_TRANSFORM : transform_spec = mcxTingNew(opt->val) ; break ; case MY_OPT_B1 : b1opts = opt->val ; break ; case MY_OPT_B2 : b2opts = opt->val ; break ; case ALG_OPT_SETENV : mcxSetenv(opt->val) ; break ; case ALG_OPT_QUIET : mcxLogLevelSetByString(opt->val) ; break ; case MY_OPT_HDP : hdp_g = atof(opt->val) ; break ; case MY_OPT_ADDTP : add_transpose = TRUE ; break ; case MY_OPT_ANNOT /* only used in command-line copying */ : break ; case MY_OPT_IAF : iaf = atof(opt->val) / 100 ; break ; case MY_OPT_WRITE : if (strstr(opt->val, "stack")) write_modes |= OUTPUT_STACK ; if (strstr(opt->val, "cone")) write_modes |= OUTPUT_CONE ; if (strstr(opt->val, "levels")) write_modes |= OUTPUT_STEPS ; if (strstr(opt->val, "coarse")) write_modes |= OUTPUT_COARSE ; if (strstr(opt->val, "base")) write_modes |= OUTPUT_BASE ; break ; case MY_OPT_BASENAME : xfbase = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_COARSE : xfcoarse = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_CONE : xfcone = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_ROOT : root = strchr("1yY", (u8) opt->val[0]) ? TRUE : FALSE ; break ; case MY_OPT_STACK : xfstack = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_STEM : stem = opt->val ; break ; case MY_OPT_MULTIPLEX : plex = strchr("yY1", (unsigned char) opt->val[0]) ? TRUE : FALSE ; break ; case MY_OPT_DISPATCH : dispatch_g = TRUE ; break ; case MY_OPT_INTEGRATE : integrate_g = TRUE ; break ; case MY_OPT_CONTRACT : break ; case MY_OPT_SUBCLUSTERX : subclusterx_g = TRUE, subcluster_g = TRUE ; break ; case MY_OPT_SUBCLUSTER : subcluster_g = TRUE ; break ; case MY_OPT_CONTROL : xfctrl = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_CL : xfcl = mcxIOnew(opt->val, "r") ; have_bootstrap = TRUE ; break ; case MY_OPT_VERSION : app_report_version(me) ; exit(0) ; default : mcxExit(1) ; } } mcxOptFree(&opts) ; a = 2 + n_arg_read ; if (a < argc) { if (strcmp(argv[a], "--")) mcxDie ( 1 , me , "trailing %s options require standalone '--' separator (found %s)" , integrate_g ? "integrate" : "mcl" , argv[a] ) ; a++ ; } if (subcluster_g + dispatch_g + integrate_g > 1) mcxDie(1, me, "too many modes!") ; if (N && N < argc-a) mcxErr(me, "-n argument leaves spurious option specifications") ; srandom(mcxSeed(89315)) ; signal(SIGALRM, mclSigCatch) ; if (dispatch_g) plexprefix = "dis" ; else if (!write_modes || (write_modes & OUTPUT_STEPS)) plexprefix = stem ; { mcxTing* tg = mcxTingEmpty(NULL, 30) ; if ((write_modes & OUTPUT_COARSE) && !xfcoarse) mcxTingPrint(tg, "%s.%s", stem, "coarse") , xfcoarse = mcxIOnew(tg->str, "w") ; if ((write_modes & OUTPUT_BASE) && !xfbase) mcxTingPrint(tg, "%s.%s", stem, "base") , xfbase = mcxIOnew(tg->str, "w") ; if ( (!write_modes || (write_modes & OUTPUT_CONE)) && !xfcone ) { mcxTingPrint(tg, "%s.%s", stem, "cone") ; xfcone = mcxIOnew(tg->str, "w") ; mcxIOopen(xfcone, EXIT_ON_FAIL) ; fprintf(xfcone->fp, "# %s %s\n", argv[0], cline->str) ; } if ((write_modes & OUTPUT_STACK) && !xfstack) { mcxTingPrint(tg, "%s.%s", stem, "stack") ; xfstack = mcxIOnew(tg->str, "w") ; mcxIOopen(xfstack, EXIT_ON_FAIL) ; fprintf(xfstack->fp, "# %s %s\n", argv[0], cline->str) ; } mcxTingFree(&tg) ; } if (integrate_g) { for (i=a;i<argc;i++) { mcxIO* xf = mcxIOnew(argv[i], "r") ; mclx* cl = mclxRead(xf, EXIT_ON_FAIL) ; mclxCatPush(&stck_g, cl, NULL, NULL, mclxCBdomStack, NULL, "dummy-integrate", n_cls++) ; } integrate_results(&stck_g) ; if (xfstack) mclxCatWrite(xfstack, &stck_g, MCLXIO_VALUE_NONE, RETURN_ON_FAIL) ; if (xfcone) mclxCatConify(&stck_g) , mclxCatWrite(xfcone, &stck_g, MCLXIO_VALUE_NONE, RETURN_ON_FAIL) ; return 0 ; } for (i=a;i<argc;i++) { if (get_interface(NULL, argv[1], shared->str, argv[i], NULL, 0, RETURN_ON_FAIL)) mcxDie(1, me, "error while testing mcl options viability (%s)", argv[i]) ; } mcxLog(MCX_LOG_APP, me, "pid %ld", (long) getpid()) /* make sure clusters align with this cluster * status: does not seem promising. */ ; if (xfctrl) clctrl = mclxRead(xfctrl, EXIT_ON_FAIL) ; /* * Below: compute cl and mxbase. */ ; if (xfcl) { cl = mclxRead(xfcl, EXIT_ON_FAIL) ; write_clustering (cl, NULL, xfcone, xfstack, plexprefix, multiplex_idx++, NULL) ; if (subcluster_g || dispatch_g) mclxCatPush(&stck_g, cl, NULL, NULL, mclxCBdomStack, NULL, "dummy-mclcm", n_cls++) ; mcxIOfree(&xfcl) ; if (!b1opts && !b2opts) b1opts = "" ; mxbase = get_base(argv[1], NULL, b1opts, b2opts) ; } else { mcxbits CACHE = b1opts || b2opts ? ALG_CACHE_INPUT /* cache, transform later */ : ALG_CACHE_START ; get_interface ( &mlp , argv[1] , shared->str , a < argc ? argv[a] : NULL , NULL , CACHE , EXIT_ON_FAIL ) ; if (a < argc) a++ ; if ((status = mclAlgorithm(mlp)) == STATUS_FAIL) { mcxErr(me, "failed at initial run") ; exit(1) ; } cl_coarse = mclAlgParamRelease(mlp, mlp->cl_result) ; cl_coarse = control_test(cl_coarse, clctrl) ; write_clustering (cl_coarse, NULL, xfcone, xfstack, plexprefix, multiplex_idx++, mlp) ; if (subcluster_g || dispatch_g) mclxCatPush(&stck_g, cl_coarse, NULL, NULL, mclxCBdomStack, NULL, "dummy-mclcm", n_cls++) ; cl = cl_coarse ; n_ite++ ; if (b1opts || b2opts) { mclx* mx_input = mclAlgParamRelease(mlp, mlp->mx_input) ; mxbase = get_base(NULL, mx_input, b1opts, b2opts) /* ^ get_base frees mx_input */ ; } else mxbase = mclAlgParamRelease(mlp, mlp->mx_start) ; } clprev = cl ; mclAlgParamFree(&mlp, TRUE) ; if (xfbase) { dim nre = mclxNrofEntries(mxbase) ; mcxLog(MCX_LOG_APP, me, "base has %lu entries", (ulong) nre) ; mclxaWrite(mxbase, xfbase, MCLXIO_VALUE_GETENV, EXIT_ON_FAIL) ; mcxIOclose(xfbase) ; } if (subcluster_g || dispatch_g) iaf = iaf ? 1/iaf : 1.414 ; while ( (!dispatch_g && (!N || n_ite < N)) || (dispatch_g && a < argc) ) { mclx* mx_coarse = NULL, *clnext = NULL ; dim dist_new_prev = 0, dist_prev_new = 0 ; mclx* clnew = NULL ; mcxbool faith = FALSE ; double inflation = -1.0 ; if (subcluster_g) mx_coarse = subclusterx_g ? mclxBlockPartition(mxbase, clprev, 50) : mclxBlockUnion(mxbase, clprev) /* have to copy mxbase as mx_coarse is freed. * Even if it were not freed, it is probably transformed. */ ; else if (dispatch_g) mx_coarse = mclxCopy(mxbase) ; else { mx_coarse = get_coarse(mxbase, clprev, add_transpose) ; if (n_ite == 1) { mclx* cc = clmUGraphComponents(mx_coarse, NULL) /* fixme; mx_coarse garantueed UD ? */ ; n_components = N_COLS(cc) ; mclxFree(&cc) ; } } if (xfcoarse) write_coarse(xfcoarse, mx_coarse) ; get_interface ( &mlp , NULL , shared->str , a < argc ? argv[a] : NULL , mx_coarse , ALG_CACHE_START , EXIT_ON_FAIL ) ; inflation = mlp->mpp->mainInflation ; BIT_OFF(mlp->modes, ALG_DO_SHOW_PID | ALG_DO_SHOW_JURY) ; if ((status = mclAlgorithm(mlp)) == STATUS_FAIL) { mcxErr(me, "failed") ; mcxExit(1) ; } cl_coarse = mclAlgParamRelease(mlp, mlp->cl_result) ; if (xfcoarse) mclxaWrite(cl_coarse, xfcoarse, MCLXIO_VALUE_NONE, RETURN_ON_FAIL) ; if (dispatch_g || subcluster_g) clnext = cl_coarse ; else clnext = mclxCompose(clprev, cl_coarse, 0) , clnext = control_test(clnext, clctrl) , mclxFree(&cl_coarse) ; clmSJDistance (clprev, clnext, NULL, NULL, &dist_prev_new, &dist_new_prev) ; if (dist_prev_new + dist_new_prev) { write_clustering (clnext, clprev, xfcone, xfstack, plexprefix, multiplex_idx++, mlp) ; clnew = clnext ; if (subcluster_g || dispatch_g) mclxCatPush(&stck_g, clnext, NULL, NULL, mclxCBdomStack, NULL, "dummy-mclcm", n_cls++) ; else mclxFree(&clprev) ; clprev = clnew ; } else if ( N_COLS(clnext) > n_components && inflation * iaf > 1.2 && inflation * iaf < 10 ) { mclxFree(&clnext) ; inflation *= iaf ; mcxTingPrintAfter(shared, " -I %.2f", inflation) ; mcxLog(MCX_LOG_APP, me, "setting inflation to %.2f", inflation) ; faith = TRUE ; } /* i.e. vanilla mode, contraction */ else if (!subcluster_g && !dispatch_g) { mclx* cc ; mclxFree(&clnext) ; mclxAddTranspose(mx_coarse, 1.0) ; cc = clmUGraphComponents(mx_coarse, NULL) ; if (N_COLS(cc) < N_COLS(clprev)) { mclx* ccback = mclxCompose(clprev, cc, 0) ; write_clustering (ccback, clprev, xfcone, xfstack, plexprefix, multiplex_idx++, NULL) ; mclxFree(&clprev) ; clprev = ccback ; mcxTell(me, "connected components added as root clustering") ; } if (root && N_COLS(cc) > 1) { mclx* root = mclxCartesian ( mclvCanonical(NULL, 1, 0) , mclvCopy(NULL, mxbase->dom_cols) , 1.0 ) ; write_clustering (root, clprev, xfcone, xfstack, plexprefix, multiplex_idx++, NULL) ; mclxFree(&clprev) ; mcxTell(me, "universe added as root clustering") ; clprev = root ; clnew = NULL ; } mclxFree(&cc) ; } else if (subcluster_g || dispatch_g) mclxFree(&clnext) ; mclAlgParamFree(&mlp, TRUE) /* frees mx_coarse */ ; if (!clnew && !faith) { same = TRUE ; break ; } a++ ; if (dispatch_g && a == argc) break ; n_ite++ ; } if (same) mcxLog(MCX_LOG_MODULE, me, "no further contraction: halting") ; if (dispatch_g) integrate_results(&stck_g) ; else if (subcluster_g) mclxCatReverse(&stck_g) ; if (dispatch_g || subcluster_g) { dim j ; if (xfstack) mclxCatWrite(xfstack, &stck_g, MCLXIO_VALUE_NONE, RETURN_ON_FAIL) ; if (xfcone && ! mclxCatConify(&stck_g)) mclxCatWrite(xfcone, &stck_g, MCLXIO_VALUE_NONE, RETURN_ON_FAIL) ; for (j=0;j<stck_g.n_level;j++) { mclxAnnot* an = stck_g.level+j ; mclxFree(&an->mx) ; } mcxFree(stck_g.level) ; } mcxIOfree(&xfcoarse) ; mcxIOfree(&xfbase) ; mcxIOfree(&xfcone) ; mcxIOfree(&xfstack) ; mcxTingFree(&shared) ; if (!dispatch_g && !subcluster_g) /* fixme fixme fixme */ mclxFree(&clprev) ; mclxFree(&mxbase) ; mclvFree(&start_col_sums_g) ; mcxTingFree(&cline) ; helpful_reminder() ; return STATUS_OK ; }
int main ( int argc , const char* argv[] ) { mcxIO* xf_tab = NULL ; mcxIO* xf_tabr = NULL ; mcxIO* xf_tabc = NULL ; mcxIO* xf_restrict_tab = NULL ; mcxIO* xf_restrict_tabr = NULL ; mcxIO* xf_restrict_tabc = NULL ; mcxIO* xf_mx = mcxIOnew("-", "r") ; mcxIO* xfout = NULL ; const char* fndump = "-" ; mclTab* tabr = NULL ; mclTab* tabc = NULL ; mclTab* restrict_tabr = NULL ; mclTab* restrict_tabc = NULL ; mcxbool transpose = FALSE ; mcxbool lazy_tab = FALSE ; mcxbool write_tabc = FALSE ; mcxbool write_tabr = FALSE ; mcxbool cat = FALSE ; mcxbool tree = FALSE ; mcxbool skel = FALSE ; mcxbool newick = FALSE ; mcxbits newick_bits = 0 ; mcxbits cat_bits = 0 ; dim catmax = 1 ; dim n_max = 0 ; dim table_nlines = 0 ; dim table_nfields = 0 ; int split_idx = 1 ; int split_inc = 1 ; const char* split_stem = NULL ; const char* sort_mode = NULL ; mcxTing* line = mcxTingEmpty(NULL, 10) ; mcxbits modes = MCLX_DUMP_VALUES ; mcxbits mode_dump = MCLX_DUMP_PAIRS ; mcxbits mode_part = 0 ; mcxbits mode_loop = MCLX_DUMP_LOOP_ASIS ; mcxbits mode_matrix = 0 ; int digits = MCLXIO_VALUE_GETENV ; mcxOption* opts, *opt ; mcxstatus parseStatus = STATUS_OK ; mcxLogLevel = MCX_LOG_AGGR | MCX_LOG_MODULE | MCX_LOG_IO | MCX_LOG_GAUGE | MCX_LOG_WARN ; mclxIOsetQMode("MCLXIOVERBOSITY", MCL_APP_VB_YES) ; mclx_app_init(stderr) ; mcxOptAnchorSortById(options, sizeof(options)/sizeof(mcxOptAnchor) -1) ; opts = mcxOptParse(options, (char**) argv, argc, 1, 0, &parseStatus) ; if (!opts) exit(0) ; for (opt=opts;opt->anch;opt++) { mcxOptAnchor* anch = opt->anch ; switch(anch->id) { case MY_OPT_HELP : case MY_OPT_APROPOS : mcxOptApropos(stdout, me, syntax, 0, 0, options) ; return 0 ; case MY_OPT_VERSION : app_report_version(me) ; return 0 ; case MY_OPT_TAB : xf_tab = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_TABC : xf_tabc = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_TABR : xf_tabr = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_OUTPUT : fndump = opt->val ; break ; case MY_OPT_SEP_LEAD : sep_lead_g = opt->val ; break ; case MY_OPT_SEP_FIELD : sep_row_g = opt->val ; break ; case MY_OPT_SEP_CAT : sep_cat_g = opt->val ; break ; case MY_OPT_SEP_VAL : sep_val_g = opt->val ; break ; case MY_OPT_PREFIXC : prefixc_g = opt->val ; break ; case MY_OPT_RESTRICT_TAB : xf_restrict_tab = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_RESTRICT_TABC : xf_restrict_tabc = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_RESTRICT_TABR : xf_restrict_tabr = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_LAZY_TAB : lazy_tab = TRUE ; break ; case MY_OPT_NO_VALUES : BIT_OFF(modes, MCLX_DUMP_VALUES) ; break ; case MY_OPT_DUMP_RLINES : mode_dump = MCLX_DUMP_LINES ; BIT_ON(modes, MCLX_DUMP_NOLEAD) ; break ; case MY_OPT_DUMP_VLINES : mode_dump = MCLX_DUMP_LINES ; BIT_ON(modes, MCLX_DUMP_LEAD_VALUE) ; break ; case MY_OPT_DUMP_LINES : mode_dump = MCLX_DUMP_LINES ; break ; case MY_OPT_OMIT_EMPTY : BIT_ON(modes, MCLX_DUMP_OMIT_EMPTY) ; break ; case MY_OPT_SORT : sort_mode = opt->val ; break ; case MY_OPT_NO_LOOPS : mode_loop = MCLX_DUMP_LOOP_NONE ; break ; case MY_OPT_CAT_LIMIT : n_max = atoi(opt->val) ; break ; case MY_OPT_SPLIT_STEM : split_stem = opt->val ; sep_cat_g = NULL ; break ; case MY_OPT_FORCE_LOOPS : mode_loop = MCLX_DUMP_LOOP_FORCE ; break ; case MY_OPT_SKEL : skel = TRUE ; break ; case MY_OPT_WRITE_TABC : write_tabc = TRUE ; break ; case MY_OPT_DIGITS : digits = strtol(opt->val, NULL, 10) ; break ; case MY_OPT_WRITE_TABR : write_tabr = TRUE ; break ; case MY_OPT_DUMP_RDOM : transpose = TRUE ; skel = TRUE ; mode_dump = MCLX_DUMP_LINES ; break ; case MY_OPT_DUMP_CDOM : skel = TRUE ; mode_dump = MCLX_DUMP_LINES ; break ; case MY_OPT_IMX : mcxIOnewName(xf_mx, opt->val) ; break ; case MY_OPT_ICL : mcxIOnewName(xf_mx, opt->val) ; mode_dump = MCLX_DUMP_LINES ; BIT_ON(modes, MCLX_DUMP_NOLEAD) ; BIT_OFF(modes, MCLX_DUMP_VALUES) ; break ; case MY_OPT_TREECAT : mcxIOnewName(xf_mx, opt->val) ; tree = TRUE ; cat_bits |= MCLX_PRODUCE_DOMSTACK ; break ; case MY_OPT_CAT : mcxIOnewName(xf_mx, opt->val) ; cat = TRUE ; break ; case MY_OPT_DUMP_MATRIX : mode_matrix |= MCLX_DUMP_MATRIX ; break ; case MY_OPT_TRANSPOSE : transpose = TRUE ; break ; case MY_OPT_DUMP_UPPER : mode_part = MCLX_DUMP_PART_UPPER ; break ; case MY_OPT_DUMP_UPPERI : mode_part = MCLX_DUMP_PART_UPPERI ; break ; case MY_OPT_DUMP_LOWER : mode_part = MCLX_DUMP_PART_LOWER ; break ; case MY_OPT_DUMP_LOWERI : mode_part = MCLX_DUMP_PART_LOWERI ; break ; case MY_OPT_DUMP_NOLEAD : BIT_ON(modes, MCLX_DUMP_NOLEAD) ; break ; case MY_OPT_NEWICK_MODE : if (strchr(opt->val, 'N')) newick_bits |= (MCLX_NEWICK_NONL | MCLX_NEWICK_NOINDENT) ; if (strchr(opt->val, 'I')) newick_bits |= MCLX_NEWICK_NOINDENT ; if (strchr(opt->val, 'B')) newick_bits |= MCLX_NEWICK_NONUM ; if (strchr(opt->val, 'S')) newick_bits |= MCLX_NEWICK_NOPTHS ; newick = TRUE ; break ; case MY_OPT_DUMP_NEWICK : newick = TRUE ; break ; case MY_OPT_DUMP_TABLE : mode_dump = MCLX_DUMP_TABLE ; break ; case MY_OPT_TABLE_NFIELDS : table_nfields = atoi(opt->val) ; break ; case MY_OPT_TABLE_NLINES : table_nlines = atoi(opt->val) ; break ; case MY_OPT_DUMP_PAIRS : mode_dump = MCLX_DUMP_PAIRS ; break ; } } ; if (skel) cat_bits |= MCLX_READ_SKELETON ; modes |= mode_loop | mode_dump | mode_part | mode_matrix ; xfout = mcxIOnew(fndump, "w") ; mcxIOopen(xfout, EXIT_ON_FAIL) ; mcxIOopen(xf_mx, EXIT_ON_FAIL) ; if (cat || tree) catmax = n_max ? n_max : 0 ; if ((write_tabc || write_tabr) && !xf_tab) mcxDie(1, me, "need a single tab file (-tab option) with --write-tabc or --write-tabr") ; if (xf_tab && mcxIOopen(xf_tab, RETURN_ON_FAIL)) mcxDie(1, me, "no tab") ; else { if (xf_tabr && mcxIOopen(xf_tabr, RETURN_ON_FAIL)) mcxDie(1, me, "no tabr") ; if (xf_tabc && mcxIOopen(xf_tabc, RETURN_ON_FAIL)) mcxDie(1, me, "no tabc") ; } { if (xf_restrict_tab && mcxIOopen(xf_restrict_tab, RETURN_ON_FAIL)) mcxDie(1, me, "no restriction tab") ; else { if (xf_restrict_tabr && mcxIOopen(xf_restrict_tabr, RETURN_ON_FAIL)) mcxDie(1, me, "no restriction tabr") ; if (xf_restrict_tabc && mcxIOopen(xf_restrict_tabc, RETURN_ON_FAIL)) mcxDie(1, me, "no restriction tabc") ; } /* fixme: below is pretty boilerplate, happens in other places as well */ if (xf_restrict_tab) { if (!(restrict_tabr = mclTabRead (xf_restrict_tab, NULL, RETURN_ON_FAIL))) mcxDie(1, me, "error reading restriction tab") ; restrict_tabc = restrict_tabr ; mcxIOclose(xf_restrict_tab) ; } else { if (xf_restrict_tabr) { if (!(restrict_tabr = mclTabRead(xf_restrict_tabr, NULL, RETURN_ON_FAIL))) mcxDie(1, me, "error reading restriction tabr") ; mcxIOclose(xf_restrict_tabr) ; } if (xf_restrict_tabc) { if (!(restrict_tabc = mclTabRead(xf_restrict_tabc, NULL, RETURN_ON_FAIL))) mcxDie(1, me, "error reading restriction tabc") ; mcxIOclose(xf_restrict_tabc) ; } } } /* fixme: restructure code to include bit below */ if (write_tabc || write_tabr) { mclv* dom_cols = mclvInit(NULL) ; mclv* dom_rows = mclvInit(NULL) ; mclv* dom = write_tabc ? dom_cols : dom_rows ; if (!(tabc = mclTabRead(xf_tab, NULL, RETURN_ON_FAIL))) mcxDie(1, me, "error reading tab file") ; if (mclxReadDomains(xf_mx, dom_cols, dom_rows)) mcxDie(1, me, "error reading matrix file") ; mcxIOclose(xf_mx) /* fixme check status */ ; mclTabWrite(tabc, xfout, dom, RETURN_ON_FAIL) ; mcxIOclose(xfout) ; return 0 ; } if (newick) { mcxTing* thetree ; mclxCat cat ; if (xf_tab && !(tabr = mclTabRead(xf_tab, NULL, RETURN_ON_FAIL))) mcxDie(1, me, "error reading tab file") ; mclxCatInit(&cat) ; if ( mclxCatRead ( xf_mx , &cat , 0 , NULL , tabr ? tabr->domain : NULL , MCLX_CATREAD_CLUSTERTREE | MCLX_ENSURE_ROOT ) ) mcxDie(1, me, "failure reading file") ; thetree = mclxCatNewick(&cat, tabr, newick_bits) ; fwrite(thetree->str, 1, thetree->len, xfout->fp) ; fputc('\n', xfout->fp) ; mcxIOclose(xfout) ; return 0 ; } while (1) { mclxIOdumper dumper ; mclxCat cat ; dim i ; if (xf_tab && !lazy_tab) cat_bits |= MCLX_REQUIRE_GRAPH ; mclxCatInit(&cat) ; if (mclxCatRead(xf_mx, &cat, catmax, NULL, NULL, cat_bits)) break ; for (i=0;i<cat.n_level;i++) { mclx* mx = cat.level[i].mx ; if (restrict_tabr || restrict_tabc) { mclx* sub ; sub = mclxSub ( mx , restrict_tabc ? restrict_tabc->domain : mx->dom_cols , restrict_tabr ? restrict_tabr->domain : mx->dom_rows ) ; mx = sub ; } /* noteme fixme dangersign mx now may violate some 'cat' invariant */ if (sort_mode) { if (!strcmp(sort_mode, "size-ascending")) mclxColumnsRealign(mx, mclvSizeCmp) ; else if (!strcmp(sort_mode, "size-descending")) mclxColumnsRealign(mx, mclvSizeRevCmp) ; else mcxErr(me, "unknown sort mode <%s>", sort_mode) ; if (catmax != 1) mcxErr(me, "-sort option and cat mode may fail or corrupt") ; } if (xf_tab && !tabr) { if (!( tabr = mclTabRead (xf_tab, lazy_tab ? NULL : mx->dom_rows, RETURN_ON_FAIL) ) ) mcxDie(1, me, "consider using --lazy-tab option") ; tabc = tabr ; mcxIOclose(xf_tab) ; } else { if (!tabr && xf_tabr) { if (!(tabr = mclTabRead (xf_tabr, lazy_tab ? NULL : mx->dom_rows, RETURN_ON_FAIL) ) ) mcxDie(1, me, "consider using --lazy-tab option") ; mcxIOclose(xf_tabr) ; } if (!tabc && xf_tabc) { if (!( tabc = mclTabRead (xf_tabc, lazy_tab ? NULL : mx->dom_cols, RETURN_ON_FAIL) ) ) mcxDie(1, me, "consider using --lazy-tab option") ; mcxIOclose(xf_tabc) ; } } ; if (transpose) { mclx* tp = mclxTranspose(mx) ; mclxFree(&mx) ; mx = tp ; if (tabc || tabr) { mclTab* tabt = tabc ; tabc = tabr ; tabr = tabt ; } } if (mode_dump == MCLX_DUMP_TABLE) BIT_ON(modes, MCLX_DUMP_TABLE_HEADER) ; mclxIOdumpSet(&dumper, modes, sep_lead_g, sep_row_g, sep_val_g) ; dumper.table_nlines = table_nlines ; dumper.table_nfields = table_nfields ; dumper.prefixc = prefixc_g ; if (split_stem) { mcxTing* ting = mcxTingPrint(NULL, "%s.%03d", split_stem, split_idx) ; mcxIOclose(xfout) ; mcxIOrenew(xfout, ting->str, "w") ; split_idx += split_inc ; } if ( mclxIOdump ( mx , xfout , &dumper , tabc , tabr , digits , RETURN_ON_FAIL ) ) mcxDie(1, me, "something suboptimal") ; mclxFree(&mx) ; if (sep_cat_g && i+1 < cat.n_level) fprintf(xfout->fp, "%s\n", sep_cat_g) ; } break ; } mcxIOfree(&xf_mx) ; mcxIOfree(&xfout) ; mcxIOfree(&xf_tab) ; mcxIOfree(&xf_tabr) ; mcxIOfree(&xf_tabc) ; mcxTingFree(&line) ; return 0 ; }