Example #1
0
void Character::jump()
{
	if ((_state&BAN_JUMP))return;
	//if (_state & IS_DROPPING)return;
	/*if (_jumpCnt == 0 && _playerState != PS_WALK) {
		return false;
	}

	if (_jumpCnt >= 2) {
		return false;
	}

	if (!touchBegin) {
		if (_playerState == PS_JUMP) {
			_jumpAction->change();
		}
		return false;
	}*/
	if (_jumpCnt >=1)return;

	//if (_state == PS_JUMP || _playerState == PS_JUMPBACK) 
	if(_state & IS_JUMPING)
	{
		//this->stopActionByTag(11);//rotate
		this->stopActionByTag(JUMPSEQ_TAG);//jumpseq
		//this->stopActionByTag(DROP_TAG);//jumpdone
	}
	
	BIT_ON(_state , IS_JUMPING);
	

	//runRotateAction();
	// _jumpAction = MyJump::create((float)240 / (float)80 / (float)10, ccp(0, 240), 60, 1);
	auto _jumpAction = JumpBy::create(JUMP_DURATION, Vec2(0, JUMP_HEIGHT), JUMP_HEIGHT, 1);
	//auto _jumpAction = MoveBy::create(JUMP_DURATION, Vec2(0, JUMP_HEIGHT*2));
	_jumpAction->setTag(JUMP_TAG);
	auto jumpSeq = Sequence::create(
		_jumpAction,
		CallFunc::create(CC_CALLBACK_0(Character::drop,this)),
		NULL);
	jumpSeq->setTag(JUMPSEQ_TAG);

	_jumpCnt++;
	//BIT_OFF(_state, IS_DROPPING);
	BIT_ON(_state, IS_JUMPING);
	this->runAction(jumpSeq);

	/*GameLayer * gl = (GameLayer *)this->getParent();
	if (gl->soundIsOn()){
		if (_jumpCnt == 1) {
			cd::SimpleAudioEngine::sharedEngine()->playEffect("sounds/jumpA.wav");
		}
		else if (_jumpCnt == 2) {
			cd::SimpleAudioEngine::sharedEngine()->playEffect("sounds/jumpB.wav");
		}
	}*/
	//return true;
}
Example #2
0
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());
}
Example #3
0
//=========================================================================
// 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); */
    }
}
Example #4
0
static void*
unixfs_internal_init(const char* dmg, uint32_t flags, fs_endian_t fse,
                     char** fsname, char** volname)
{
    int fd = -1;
    if ((fd = open(dmg, O_RDONLY)) < 0) {
        perror("open");
        return NULL;
    }

    int err, i;
    struct stat stbuf;
    struct super_block* sb = (struct super_block*)0;
    struct filsys* fs = (struct filsys*)0;

    assert(sizeof(struct spcl) == BSIZE);

    if ((err = fstat(fd, &stbuf)) != 0) {
        perror("fstat");
        goto out;
    }

    if (!S_ISREG(stbuf.st_mode) && !(flags & UNIXFS_FORCE)) {
        err = EINVAL;
        fprintf(stderr, "%s is not a tape dump image file\n", dmg);
        goto out;
    }

    if ((stbuf.st_size % TAPE_BSIZE) && !(flags & UNIXFS_FORCE)) {
        err = EINVAL;
        fprintf(stderr, "%s is not a multiple of tape block size\n", dmg);
        goto out;
    }

    if (S_ISREG(stbuf.st_mode) && (stbuf.st_size < TAPE_BSIZE)) {
        err = EINVAL;
        fprintf(stderr, "*** fatal error: %s is smaller in size than a "
                "physical tape block\n", dmg);
        goto out;
    }

    sb = malloc(sizeof(struct super_block));
    if (!sb) {
        err = ENOMEM;
        goto out;
    }

    fs = calloc(1, sizeof(struct filsys));
    if (!fs) {
        free(sb);
        err = ENOMEM;
        goto out;
    }

    unixfs = sb;

    unixfs->s_flags = flags;
    unixfs->s_endian = (fse == UNIXFS_FS_INVALID) ? UNIXFS_FS_PDP : fse;
    unixfs->s_fs_info = (void*)fs;
    unixfs->s_bdev = fd;

    unixfs->s_statvfs.f_bsize = BSIZE;
    unixfs->s_statvfs.f_frsize = BSIZE;

    fs->s_fsize += stbuf.st_size / BSIZE;

    /* must initialize the inode layer before sanity checking */
    if ((err = unixfs_inodelayer_init(sizeof(struct tap_node_info))) != 0)
        goto out;

    struct spcl spcl;

    if (ancientfs_dump_readheader(fd, &spcl) != 0) {
        fprintf(stderr, "failed to read dump header\n");
        err = EINVAL;
        goto out;
    }

    if (spcl.c_type != TS_TAPE) {
       fprintf(stderr, "failed to recognize image as a tape dump\n");
       err = EINVAL;
       goto out;
    }

    fs->s_date = fs32_to_host(unixfs->s_endian, spcl.c_date);
    fs->s_ddate = fs32_to_host(unixfs->s_endian, spcl.c_ddate);

    int done = 0;

    while (!done) {
        err = ancientfs_dump_readheader(fd, &spcl);
        if (err) {
            if (err != 1) {
                fprintf(stderr, "*** warning: no tape header: retrying\n");
                continue;
            } else {
                fprintf(stderr, "failed to read next header (%d)\n", err);
                err = EINVAL;
                goto out;
            }
        }

next:
        switch (spcl.c_type) {

        case TS_TAPE:
             break;

        case TS_END:
             done = 1;
             break;

        case TS_BITS:
            if (!fs->s_initialized) {
                fs->s_initialized = 1;
                int count = spcl.c_count;
                char* bmp = (char*)fs->s_dumpmap;
                while (count--) {
                   if (read(fd, bmp, BSIZE) != BSIZE) {
                       fprintf(stderr,
                               "*** fatal error: failed to read bitmap\n");
                       err = EIO;
                       goto out;
                   }
                   /* fix up endian-ness */
                   int idx;
                   for (idx = 0; idx < BSIZE/sizeof(uint16_t); idx++)
                       bmp[idx] = fs16_to_host(unixfs->s_endian, bmp[idx]);
                   bmp += BSIZE / sizeof(uint16_t);
               }
           } else {
               fprintf(stderr, "*** warning: duplicate inode map\n");
               /* ignore the data */
               (void)lseek(fd, (off_t)(spcl.c_count * BSIZE), SEEK_CUR);
           }
           break;

        case TS_INODE: {
            struct dinode* dip = &spcl.c_dinode;
            a_ino_t candidate = spcl.c_inumber;

            if ((!BIT_ON(candidate, fs->s_dumpmap)) || (candidate == BADINO))
                continue;

            struct inode* ip = unixfs_inodelayer_iget((ino_t)candidate);
            if (!ip) {
                fprintf(stderr, "*** fatal error: no inode for %llu\n",
                        (ino64_t)candidate);
                abort();
            }

            struct tap_node_info* ti = (struct tap_node_info*)ip->I_private;
            ti->ti_daddr = NULL;

            assert(!ip->I_initialized);

            ip->I_number       = (ino_t)candidate;
            ip->I_mode         = dip->di_mode;
            ip->I_nlink        = dip->di_nlink;
            ip->I_uid          = dip->di_uid;
            ip->I_gid          = dip->di_gid;
            ip->I_size         = dip->di_size;
            ip->I_atime_sec = dip->di_atime;
            ip->I_mtime_sec = dip->di_mtime;
            ip->I_ctime_sec = dip->di_ctime;

            if (S_ISDIR(ip->I_mode))
                fs->s_directories++;
            else
                fs->s_files++;

            /* populate i_daddr */
            
            off_t nblocks = (off_t)((ip->I_size + (BSIZE - 1)) / BSIZE);

            ti->ti_daddr = (uint32_t*)calloc(nblocks, sizeof(uint32_t));
            if (!ti->ti_daddr) {
                fprintf(stderr, "*** fatal error: cannot allocate memory\n");
                abort();
            }

            int block_index = 0;

            for (i = 0; i < nblocks; i++) {
                if (block_index >= spcl.c_count) {
                    if (ancientfs_dump_readheader(fd, &spcl) == -1) {
                        fprintf(stderr,
                                "*** fatal error: cannot read header\n");
                        abort();
                    }
                    if (spcl.c_type != TS_ADDR) {
                        fprintf(stderr, "*** warning: expected TS_ADDR but "
                                        "got %hd\n", spcl.c_type);
                        int k = i;
                        for (; k < nblocks; k++)
                            ti->ti_daddr[k] = 0;
                        goto next;
                    }
                    block_index = 0;
                }

                if (spcl.c_addr[block_index]) {
                    off_t nextb = lseek(fd, (off_t)BSIZE, SEEK_CUR);
                    if (nextb == -1) {
                        fprintf(stderr, "*** fatal error: cannot read tape\n");
                        abort();
                    }
                    ti->ti_daddr[i] = spcl.c_tapea + block_index + 1;
                } else {
                    ti->ti_daddr[i] = 0; /* zero fill */
                }

                block_index++;
            }

            if (S_ISCHR(ip->I_mode) || S_ISBLK(ip->I_mode)) {
                char* p1 = (char*)(ip->I_daddr);
                char* p2 = (char*)(dip->di_addr);
                for (i = 0; i < 4; i++) {
                    *p1++ = *p2++;
                    *p1++ = 0;
                    *p1++ = *p2++;
                    *p1++ = *p2++;
                }
                ip->I_daddr[0] = fs32_to_host(unixfs->s_endian, ip->I_daddr[0]);
                uint32_t rdev = ip->I_daddr[0];
                ip->I_rdev = makedev((rdev >> 8) & 255, rdev & 255);
            }

            if (ip->I_ino > fs->s_lastino)
                fs->s_lastino = ip->I_ino;

            unixfs_inodelayer_isucceeded(ip);
            }
            break;
         }
    }
Example #5
0
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
;  }