Exemplo n.º 1
0
Symbol *
lookup(char *s)
{	Symbol *sp; Ordered *no;
	int h = hash(s);

	for (sp = symtab[h]; sp; sp = sp->next)
		if (strcmp(sp->name, s) == 0
		&&  samename(sp->context, context)
		&&  samename(sp->owner, owner))
			return sp;		/* found */

	if (context)				/* in proctype */
	for (sp = symtab[h]; sp; sp = sp->next)
		if (strcmp(sp->name, s) == 0
		&& !sp->context
		&&  samename(sp->owner, owner))
			return sp;		/* global */

	sp = (Symbol *) emalloc(sizeof(Symbol));
	sp->name = (char *) emalloc((int) strlen(s) + 1);
	strcpy(sp->name, s);
	sp->nel = 1;
	sp->setat = depth;
	sp->context = context;
	sp->owner = owner;			/* if fld in struct */

	if (NamesNotAdded == 0)
	{	sp->next = symtab[h];
		symtab[h] = sp;
		no = (Ordered *) emalloc(sizeof(Ordered));
		no->entry = sp;
		if (!last_name)
			last_name = all_names = no;
		else
		{	last_name->next = no;
			last_name = no;
	}	}

	return sp;
}
Exemplo n.º 2
0
Arquivo: sym.c Projeto: 99years/plan9
Symbol *
lookup(char *s)
{	Symbol *sp; Ordered *no;
	int h = hash(s);

	if (old_scope_rules)
	{	/* same scope - global refering to global or local to local */
		for (sp = symtab[h]; sp; sp = sp->next)
		{	if (strcmp(sp->name, s) == 0
			&&  samename(sp->context, context)
			&&  samename(sp->owner, owner))
			{	return sp;		/* found */
		}	}
	} else
	{	/* added 6.0.0: more traditional, scope rule */
		for (sp = symtab[h]; sp; sp = sp->next)
		{	if (strcmp(sp->name, s) == 0
			&&  samename(sp->context, context)
			&&  (strcmp((const char *)sp->bscp, CurScope) == 0
			||   strncmp((const char *)sp->bscp, CurScope, strlen((const char *)sp->bscp)) == 0)
			&&  samename(sp->owner, owner))
			{
				if (!samename(sp->owner, owner))
				{	printf("spin: different container %s\n", sp->name);
					printf("	old: %s\n", sp->owner?sp->owner->name:"--");
					printf("	new: %s\n", owner?owner->name:"--");
				/*	alldone(1);	*/
				}
				return sp;		/* found */
	}	}	}

	if (context)				/* in proctype, refers to global */
	for (sp = symtab[h]; sp; sp = sp->next)
	{	if (strcmp(sp->name, s) == 0
		&& !sp->context
		&&  samename(sp->owner, owner))
		{	return sp;		/* global */
	}	}

	sp = (Symbol *) emalloc(sizeof(Symbol));
	sp->name = (char *) emalloc(strlen(s) + 1);
	strcpy(sp->name, s);
	sp->nel = 1;
	sp->setat = depth;
	sp->context = context;
	sp->owner = owner;			/* if fld in struct */
	sp->bscp = (unsigned char *) emalloc(strlen((const char *)CurScope)+1);
	strcpy((char *)sp->bscp, CurScope);

	if (NamesNotAdded == 0)
	{	sp->next = symtab[h];
		symtab[h] = sp;
		no = (Ordered *) emalloc(sizeof(Ordered));
		no->entry = sp;
		if (!last_name)
			last_name = all_names = no;
		else
		{	last_name->next = no;
			last_name = no;
	}	}

	return sp;
}
Exemplo n.º 3
0
bool saveDotaData (char const* dest)
{
  MPQFILE file = MPQOpenFile (((CDotAReplayApp*) ::AfxGetApp ())->res, dest, MPQFILE_REWRITE);
  if (file)
  {
    static int hsub[256];
    static int isub[512];
    memset (hsub, 0, sizeof hsub);
    memset (isub, 0, sizeof isub);
    int mxh = bk_numHeroes;
    for (int i = 1; i < numHeroes; i++)
    {
      bool found = false;
      for (int j = 1; j < bk_numHeroes && !found; j++)
      {
        if (samename (heroes[i].name, bk_heroes[j].name))
        {
          hsub[j] = i;
          found = true;
        }
      }
      if (!found)
        hsub[mxh++] = i;
    }
    int mxi = bk_numItems;
    for (int i = 1; i < numItems; i++)
    {
      bool found = false;
      for (int j = 1; j < bk_numItems && !found; j++)
      {
        if (items[i].type/2 == bk_items[j].type/2 && samename (items[i].name, bk_items[j].name))
        {
          isub[j] = i;
          found = true;
        }
      }
      if (!found)
        isub[mxi++] = i;
    }
    MPQFilePuts (file, "[HERO]\r\n");
    for (int m = 0; m < mxh; m++)
    {
      int i = hsub[m];
      DotaHero* hero = &heroes[i];
      MPQFilePuts (file, mprintf ("\"%s\",\"%s\",%d,\"%s\",%d,%d", hero->name, hero->oname, hero->tavern,
        hero->imgTag, hero->slot, hero->point));
      for (int j = 0; j < 5; j++)
        MPQFilePuts (file, mprintf (",%s", make_id (hero->abils[j])));
      for (int j = 0; j < hero->numIds; j++)
        MPQFilePuts (file, mprintf (",%s", make_id (hero->ids[j])));
      MPQFilePuts (file, "\r\n");
    }
    MPQFilePuts (file, "[ITEM]\r\n");
    for (int m = 0; m < mxi; m++)
    {
      int i = isub[m];
      DotaItem* item = getItem (i);
      MPQFilePuts (file, mprintf ("\"%s\",%d,\"%s\"", item->name, item->cost, item->imgTag));
      for (int j = 0; j < item->numIds; j++)
        MPQFilePuts (file, mprintf (",%s", make_id (item->ids[j])));
      MPQFilePuts (file, "\r\n");
    }
    MPQFilePuts (file, "[ABILITY]\r\n");
    for (int i = 1; i < numAbilities; i++)
    {
      DotaAbility* abil = getAbility (i);
      MPQFilePuts (file, mprintf ("\"%s\",%d,\"%s\"", abil->name, abil->slot, abil->imgTag));
      for (int j = 0; j < abil->numIds; j++)
        MPQFilePuts (file, mprintf (",%s", make_id (abil->ids[j])));
      MPQFilePuts (file, "\r\n");
    }
    MPQFilePuts (file, "[RECIPE]\r\n");
    for (int i = 0; i < numRecipes; i++)
    {
      DotaRecipe* recipe = getRecipe (i);
      MPQFilePuts (file, make_id (recipe->result));
      for (int j = 0; j < recipe->numsrc; j++)
        MPQFilePuts (file, mprintf (",%s,%d", make_id (recipe->srcid[j]), recipe->srccount[j]));
      MPQFilePuts (file, "\r\n");
    }
    MPQCloseFile (file);
  }
  else
    return false;
  MPQFlushListfile (((CDotAReplayApp*) ::AfxGetApp ())->res);
  return true;
}
Exemplo n.º 4
0
static int iconforms(AbstractType a, AbstractType b, int l)
{
  OID ao, bo;
  int result, i, j, k, found, foundincache = 0;
  ATOpVectorElement aove, bove;

  if (!conformMap) conformMap = OOIScCreate();
  assert(assumeMap);
  if (ISNIL(a) || ISNIL(b)) {
    TRACE(conform, 0, ("emx: conforms on nil type"));
    return 1;
  }

  ao = OIDOf(a);
  bo = OIDOf(b);
  TRACE(conform, 2, ((pad(l), "==> %.*s (%#x) vs %.*s (%#x)"), 
		     a->d.name->d.items,
		     a->d.name->d.data,
		     ao.Seq,
		     b->d.name->d.items,
		     b->d.name->d.data,
		     bo.Seq));
  l++;
  result = OOIScLookup(conformMap, ao, bo);
  if (result >= 0) {
    TRACE(conform, 2, ((pad(l), "Found answer in cache")));
    foundincache = 1;
    DONE(result);
  }
  result = OOIScLookup(assumeMap, ao, bo);
  if (result >= 0) {
    TRACE(conform, 2, ((pad(l), "We are assuming these conform")));
    DONE(result);
  }
  if (a == BuiltinInstAT(NILI)) {
    TRACE(conform, 2, ((pad(l), "%.*s is None"),
	   a->d.name->d.items,
	   a->d.name->d.data));
    DONE(1);
  }
  if (b == BuiltinInstAT(ANYI)) {
    TRACE(conform, 2, ((pad(l), "%.*s is Any"),
		       b->d.name->d.items,
		       b->d.name->d.data));
    DONE(1);
  } 
  if (b == BuiltinInstAT(NILI)) {
    TRACE(conform, 2, ((pad(l), "%.*s is None"),
		       b->d.name->d.items,
		       b->d.name->d.data));
    DONE(0);
  } 
  if (a == b) {
    TRACE(conform, 2, ((pad(l), "%.*s == %.*s"),
		       a->d.name->d.items,
		       a->d.name->d.data,
		       b->d.name->d.items,
		       b->d.name->d.data));
    DONE(1);
  } 
  if (EqOID(ao, bo)) {
    TRACE(conform, 2, ((pad(l), "%.*s = %.*s"),
		       a->d.name->d.items,
		       a->d.name->d.data,
		       b->d.name->d.items,
		       b->d.name->d.data));
    DONE(1);
  } 
  if (b->d.flags & AT_ISVECTOR) {
    if (!(a->d.flags & AT_ISVECTOR)) {
      TRACE(conform, 2, ((pad(l), "%.*s is a vector and %.*s is not"),
			 a->d.name->d.items,
			 a->d.name->d.data,
			 b->d.name->d.items,
			 b->d.name->d.data));
      DONE(0);
    }
  } else if (isNoNode(bo) && isBuiltinINSTAT(bo.Seq) &&
	     (bo.Seq == OIDOfBuiltin(B_INSTAT, BOOLEANI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, CHARACTERI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, INTEGERI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, NODEI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, SIGNATUREI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, REALI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, STRINGI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, TIMEI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, NODELISTELEMENTI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, NODELISTI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, INSTREAMI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, OUTSTREAMI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, BITCHUNKI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, CONCRETETYPEI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, COPVECTORI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, COPVECTOREI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, AOPVECTORI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, AOPVECTOREI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, APARAMLISTI) ||
	      bo.Seq == OIDOfBuiltin(B_INSTAT, INTERPRETERSTATEI))) {
    TRACE(conform, 2, ((pad(l), "%.*s is a cannot-be-conformed-to builtin"),
		       b->d.name->d.items,
		       b->d.name->d.data));
    DONE(0);
  } 
  if (b->d.flags & AT_ISIMMUTABLE
      && !a->d.flags & AT_ISIMMUTABLE) {
    TRACE(conform, 2, ((pad(l), "%.*s is not immutable"), 
		       a->d.name->d.items,
		       a->d.name->d.data));
    DONE(0);
  } 
  if (a->d.ops->d.items < b->d.ops->d.items) {
    TRACE(conform, 2, ((pad(l), "%.*s doesn't have enough operations"),
		       a->d.name->d.items,
		       a->d.name->d.data));
    DONE(0);
  }
  OOIScInsert(assumeMap, ao, bo, 1);
  for (i = 0; i < b->d.ops->d.items; i++) {
    bove = b->d.ops->d.data[i];
    found = 0;
    TRACE(conform, 4, ((pad(l-1), "Looking for operation %.*s[%d]"),
		       bove->d.name->d.items,
		       bove->d.name->d.data,
		       VLen(bove->d.arguments)));
    for (j = 0;
	 j < a->d.ops->d.items;
	 j++) {
      aove = a->d.ops->d.data[j];
      if (samename(aove, bove)) {
	if (bove->d.isFunction
	    && !aove->d.isFunction) {
	  TRACE(conform, 2, ((pad(l), "Operation %.*s[%d] is not a function"),
			     aove->d.name->d.items,
			     aove->d.name->d.data,
			     VLen(aove->d.arguments)));
	  DONE(0);
	}
	if (!ISNIL(aove->d.arguments)) {
	  for (k = 0; k < aove->d.arguments->d.items; k++) {
	    TRACE(conform, 4, ((pad(l-1), "Checking argument %d"), k));
	    if (!iconforms(bove->d.arguments->
			   d.data[k],
			   aove->d.arguments->
			   d.data[k], l+1)) {
	      TRACE(conform, 2, ((pad(l), "Operation %.*s[%d] argument %d doesn't conform"),
				 aove->d.name->d.items,
				 aove->d.name->d.data,
				 VLen(aove->d.arguments), k));
	      DONE(0);
	    }
	  }
	}
	if (!ISNIL(aove->d.results)) {
	  for (k = 0;
	       k < aove->d.results->d.items;
	       k++) {
	    TRACE(conform, 4, ((pad(l-1), "Checking result %d"), k));
	    if (!iconforms(aove->d.results->
			   d.data[k],
			   bove->d.results->
			   d.data[k], l+1)) {
	      TRACE(conform, 2, ((pad(l), "Operation %.*s[%d] result %d doesn't conform"),
				 aove->d.name->d.items,
				 aove->d.name->d.data, k));
	      DONE(0);
	    }
	  }
	}
	found = 1;
	break;
      }
    }
    if (!found) {
      TRACE(conform, 2, ((pad(l), "Operation %.*s[%d] is not defined"),
			 bove->d.name->d.items,
			 bove->d.name->d.data,
			 VLen(bove->d.arguments)));
      DONE(0);
    }
  }
  result = 1;
 done:
  l--;
  TRACE(conform, 2, ((pad(l), "<== %s"), result ? "yes" : "no"));
  if (l == 0 && !foundincache) {
    OOIScInsert(conformMap, ao, bo, result);
  }
  return result;
}
Exemplo n.º 5
0
void  setclades(int** tree, int nbotu, char** nom, int l1, char** list1, int l2, char** list2, int** dclade, int** gclade, int**ddist, int** gdist, int nbdclade, int nbgclade, char** dcladename, char** gcladename){

  int i, j, k, l, d0, d1, g0, g1, *prov, **prov2, ** dprov2, nbd=0, nbg=0, sum, val;
  int *cladesz;
  char c1, c2, **provc, **clname, *ch, *droitgauche;


  droitgauche=(char*)check_alloc(nbotu, sizeof(char));

  if(l1>l2) {k=l2; provc=list2; c1='g'; c2='d';}
  else {k=l1; provc=list1; c1='d'; c2='g';}

  for(i=0;i<nbotu;i++){
    for(j=0;j<k;j++){
      if(samename(nom[i], provc[j])){
	droitgauche[i]=c1;
	break;
      }
    }
    if(j==k) droitgauche[i]=c2;
  }

		/* peripheric clades */

  for(i=0;i<nbotu;i++){
    if(droitgauche[i]=='d') {prov2=dclade; prov=&nbd; clname=dcladename;} 
    else { prov2=gclade; prov=&nbg; clname=gcladename;}
    for(j=0;j<nbotu;j++)
      prov2[*prov][j]=0;
    prov2[*prov][i]=1;
    sprintf(clname[*prov], "(%s)", nom[i]);
    *prov=*prov+1;
  }


		/* internal clades */

  for(i=nbd;i<nbdclade;i++){
    sprintf(dcladename[i], "(");
  }
  for(i=nbg;i<nbgclade;i++){
    sprintf(gcladename[i], "(");
  }

  for(i=0;i<nbotu-3;i++){
    d0=d1=g0=g1=0;
    for(j=0;j<nbotu;j++){
      if(tree[j][i]==0 && droitgauche[j]=='d') d0=1;
      if(tree[j][i]==1 && droitgauche[j]=='d') d1=1;
      if(tree[j][i]==0 && droitgauche[j]=='g') g0=1;
      if(tree[j][i]==1 && droitgauche[j]=='g') g1=1;
    }
    sum=d0+d1+g0+g1;
    if(sum!=2 && sum!=3) {printf("probleme faire clades\n"); exit(EXIT_FAILURE);}

    if(sum==2){ /* root branch -> 2 full clades */
      for(j=0;j<nbotu;j++)
	if(droitgauche[j]=='d'){
	  dclade[nbd][j]=1;
	  strcat(dcladename[nbd], nom[j]);
	  strcat(dcladename[nbd], ",");
	}
      for(j=0;j<nbotu;j++) 
	if(droitgauche[j]=='g'){ 
	  gclade[nbg][j]=1;
	  strcat(gcladename[nbg], nom[j]);
	  strcat(gcladename[nbg], ",");
	}
      ch=dcladename[nbd];
      while(*ch) ch++; while(*ch!=',' && *ch!=')') ch--; *ch=')';
      ch=gcladename[nbg];
      while(*ch) ch++; while(*ch!=',' && *ch!=')') ch--; *ch=')';
      nbd++; nbg++;
    }
    else if(d0 && d1){  /* right clade */
      for(j=0;j<nbotu;j++){
	if(g0) val=tree[j][i];
	else val=1-tree[j][i];
	dclade[nbd][j]=val;
	if(val){
	  strcat(dcladename[nbd], nom[j]);
	  strcat(dcladename[nbd], ",");
	}
      }
      ch=dcladename[nbd];
      while(*ch) ch++; while(*ch!=',' && *ch!=')') ch--; *ch=')';
      nbd++;
    }
    else if(g0 && g1){  /* left clade */
      for(j=0;j<nbotu;j++){
	if(d0) val=tree[j][i];
	else val=1-tree[j][i];
	gclade[nbg][j]=val;
	if(val){
	  strcat(gcladename[nbg], nom[j]);
	  strcat(gcladename[nbg], ",");
	}
      }
      ch=gcladename[nbg];
      while(*ch) ch++; while(*ch!=',' && *ch!=')') ch--; *ch=')';
      nbg++;
    }
    else{ printf("erreur setting clades\n"); exit(EXIT_FAILURE); }
  }

		/* last clade */

  if(nbd<nbdclade){
    for(i=0;i<nbotu;i++){
      if(droitgauche[i]=='d'){
	dclade[nbd][i]=1;
	strcat(dcladename[nbd], nom[i]);
	strcat(dcladename[nbd], ",");
      }
      else
	dclade[nbd][i]=0;
    }
    ch=dcladename[nbd];
    while(*ch) ch++; while(*ch!=',' && *ch!=')') ch--; *ch=')';
    nbd++;
  }

  if(nbg<nbgclade){
    for(i=0;i<nbotu;i++){
      if(droitgauche[i]=='g'){
	gclade[nbg][i]=1;
	strcat(gcladename[nbg], nom[i]);
	strcat(gcladename[nbg], ",");
      }
      else
	gclade[nbg][i]=0;
    }
    ch=gcladename[nbg];
    while(*ch) ch++; while(*ch!=',' && *ch!=')') ch--; *ch=')';
    nbg++;
  }

  if(nbd!=nbdclade || nbg!=nbgclade) {
    printf("wrong number of clades\n");
    exit(EXIT_FAILURE);
  }
  		/* distances */

  if(nbd>nbg) k=nbd; else k=nbg;
  cladesz=(int*)check_alloc(k, sizeof(int));


  for(k=0;k<2;k++){
    if(k==0){ 		/* right */
      prov=&nbd;
      prov2=dclade;
      for(i=0;i<*prov;i++)
        for(j=0;j<*prov;j++)
	  ddist[i][j]=-2*nbotu;
      dprov2=ddist;
      c1='d';
    }
    else{		/* left  */
      prov=&nbg;
      prov2=gclade;
      for(i=0;i<*prov;i++)
        for(j=0;j<*prov;j++)
	  gdist[i][j]=-2*nbotu;
      dprov2=gdist;
      c1='g';
    }

  /* sizes of clades */
    for(i=0;i<*prov;i++){
      cladesz[i]=0;
      for(j=0;j<nbotu;j++) 
	cladesz[i]+=prov2[i][j]; 
    }

  /* distances between nested clades */
    for(i=0;i<*prov;i++){
      if(droitgauche[i]==c1)
        nesteddist(prov2, nbotu, *prov, cladesz, i, dprov2);  
    }

  /* distances between non-nested clades */
    for(i=0;i<*prov;i++){
      for(j=i+1;j<*prov;j++){
	if(dprov2[i][j]>-2*nbotu) continue;
	l=lca(prov2, *prov, nbotu, i, j);
	dprov2[i][j]=dprov2[j][i]=abs(dprov2[i][l])+abs(dprov2[j][l]);
      }
    }
  }

  free(droitgauche);
  free(cladesz);
}
Exemplo n.º 6
0
double shake(int nb, char** seq, char** seqname, char* ctree, options opt, char** eval_input, int nb_eval_input){

  int nb2, i, j, ii, jj, k, l, *ttree[MAXNSP], **curtree, **newtree, **evaltree, nbbi, nbdclade, nbgclade, print1, print2;
  int nochange, pres_grossiere=-1, l1, l2, restart_d, restart_g, oldmovedist;
  int **dclade, **gclade, **newdclade, **newgclade, **ddist, **gdist, movedist, maxmovedist;
  int **list_tree, lliste, *solid;
  long nblist, nblistmax;
  double *lgbp, *sortedlgbp, *lgbi, *bootvals, fracroot1, lkh, maxlkh, maxlcrossedbranch;
  char *nom[MAXNSP], *nom2[MAXNSP], **dcladename, **gcladename, **list1, **list2, racine, *ctreenew, *ctreenew_nobl, *treedeb, *ctree1, *ctree2;
  FILE* outfile1, *outfile2;
  print_option trueprint, noprint;


  print1=opt->print->PRINT1;
  print2=opt->print->PRINT2;
  noprint=check_alloc(1, sizeof(struct print_option));
  noprint->PRINT3=0;
  if(opt->print->PRINT2)
    noprint->PRINT1=noprint->PRINT2=1;
  else
    noprint->PRINT1=noprint->PRINT2=0;
  if(print1) noprint->PRINT0=1; else noprint->PRINT0=0;
  trueprint=opt->print;
  opt->print=noprint;
  maxlcrossedbranch=opt->SH_MAXLCROSSED;



		/* READ TREE STRING */

  lgbp=(double*)check_alloc(nb+1, sizeof(double));
  sortedlgbp=(double*)check_alloc(nb+1, sizeof(double));
  lgbi=(double*)check_alloc(nb+1, sizeof(double));
  for(i=0;i<nb+1;i++)
    lgbp[i]=lgbi[i]=-1.;

  solid=(int*)check_alloc(nb+1, sizeof(int));
  bootvals=(double*)check_alloc(nb+1, sizeof(double));
  if(nb>=MAXNSP) {printf("Too many sequences\n"); exit(EXIT_FAILURE);}
  for(i=0;i<=nb;i++){
    nom[i]=(char*)check_alloc(MAXLNAME+1, sizeof(char));
    nom2[i]=(char*)check_alloc(MAXLNAME+1, sizeof(char));
    ttree[i]=(int*)check_alloc(nb, sizeof(int));
  }
  list1=check_alloc(nb, sizeof(char*));
  list2=check_alloc(nb, sizeof(char*));
  curtree=(int**)check_alloc(nb+1, sizeof(int*));
  newtree=(int**)check_alloc(nb+1, sizeof(int*));
  evaltree=(int**)check_alloc(nb+1, sizeof(int*));
  for(i=0;i<nb+1;i++) newtree[i]=(int*)check_alloc(nb-2, sizeof(int));
  ctreenew=(char*)check_alloc(2*MAXLNAME*nb, sizeof(char));
  ctree1=(char*)check_alloc(2*MAXLNAME*nb, sizeof(char));
  ctree2=(char*)check_alloc(2*MAXLNAME*nb, sizeof(char));
  ctreenew_nobl=(char*)check_alloc(2*MAXLNAME*nb, sizeof(char));


  nb2=ctot(ctree, ttree, lgbi, lgbp, bootvals, nom, &racine, &nbbi);

  if(nb2<nb){
    printf("More species in sequence file than in tree file\n");
    exit(EXIT_FAILURE);
  }
  if(nb2>nb){
    printf("More species in tree file than in sequence file\n");
    exit(EXIT_FAILURE);
  }


	/* PREPARE TREE : UNROOT, SET LEFT and RIGHT LISTS, SORT TAXA */

  if(racine=='r'){
    unroot(ttree, nb, lgbi, lgbp, bootvals, nom, list1, list2, &l1, &l2, &fracroot1);
  }
  else{
    printf("Tree must be rooted\n");
    exit(EXIT_FAILURE);
  }
  nbbi--;
  if(nbbi!=nb-3){
    printf("Tree must be bifurcating\n");
    exit(EXIT_FAILURE);
  }

  for(i=0;i<nb;i++){
    for(j=0;j<nb;j++){
      if(samename(seqname[i], nom[j])){
	curtree[i]=ttree[j];
	sortedlgbp[i]=lgbp[j];
	break;
      }
    }
  }

  for(i=0;i<nb-3;i++) if(bootvals[i]>opt->SH_MAXBOOTCROSSED) solid[i]=1;

  ctree_noblbs(ctree, ctreenew_nobl, strlen(ctree));

	/* EVALUATE INITIAL TREE */

  if(print1)
    printf("\nEvaluating initial tree : \n%s\n", ctreenew_nobl);
  if(print2)
    printf("\n");

  maxlkh=maxlike(nb, seq, seqname, curtree, lgbi, sortedlgbp, nbbi, l1, list1, l2, list2, opt, NULL, NULL, NULL);
  if(opt->SH_RESTART) save_current_best("current_best_tree", ctreenew_nobl, maxlkh, 1);
  if(opt->SH_RESTART) save_evaluated("evaluated_trees", ctreenew_nobl, maxlkh, 1);

	/* ALLOCATE SHAKE VARIABLES */

  nbdclade=2*l1-1;
  nbgclade=2*l2-1;
  dclade=(int**)check_alloc(nbdclade, sizeof(int*));
  for(i=0;i<nbdclade;i++)
    dclade[i]=(int*)check_alloc(nb, sizeof(int));
  gclade=(int**)check_alloc(2*nb, sizeof(int*));
  for(i=0;i<nbgclade;i++)
    gclade[i]=(int*)check_alloc(nb, sizeof(int));
  newdclade=(int**)check_alloc(nbdclade, sizeof(int*));
  for(i=0;i<nbdclade;i++)
    newdclade[i]=(int*)check_alloc(nb, sizeof(int));
  newgclade=(int**)check_alloc(nbgclade, sizeof(int*));
  for(i=0;i<nbgclade;i++)
    newgclade[i]=(int*)check_alloc(nb, sizeof(int));
  ddist=(int**)check_alloc(nbdclade, sizeof(int*));
  gdist=(int**)check_alloc(nbgclade, sizeof(int*));
  for(i=0;i<nbdclade;i++) ddist[i]=(int*)check_alloc(nbdclade, sizeof(int));
  for(i=0;i<nbgclade;i++) gdist[i]=(int*)check_alloc(nbgclade, sizeof(int));
  dcladename=(char**)check_alloc(nbdclade, sizeof(char*));
  gcladename=(char**)check_alloc(nbgclade, sizeof(char*));
  for(i=0;i<nbdclade;i++)
    dcladename[i]=(char*)check_alloc(nb*(MAXLNAME+3)+1, sizeof(char));
  for(i=0;i<nbgclade;i++)
    gcladename[i]=(char*)check_alloc(nb*(MAXLNAME+3)+1, sizeof(char));
  nblistmax=nb*nb;
  if(nblistmax<MIN_NBLISTMAX) nblistmax=MIN_NBLISTMAX;
  if(nblistmax<nb_eval_input) nblistmax=nb_eval_input;
  if(nblistmax>MAX_NBLISTMAX) nblistmax=MAX_NBLISTMAX;
  while(1){
    lliste=(nblistmax*(nb-3)+lmot-1)/lmot;
    list_tree=(int**)check_alloc(nb, sizeof(int*));
    for(i=0;i<nb;i++)
      list_tree[i]=(int*)calloc(lliste, sizeof(int));
    if(list_tree[nb-1]) break;
    nblistmax/=2;
    if(nblistmax==0){
      printf("Not enough memory\n");
      exit(EXIT_FAILURE);
    }
  }


	/* SET LIST OF EVALUATED TREES */

  if(eval_input){
    nblist=0;
    for(k=0;k<nb_eval_input;k++){
      for(i=0;i<=nb;i++) ttree[i]=check_alloc(nb, sizeof(int));
      nb2=ctot(eval_input[k], ttree, NULL, NULL, NULL, nom2, &racine, NULL);
      if(racine=='r')
        unroot(ttree, nb, NULL, NULL, NULL, nom2, NULL, NULL, NULL, NULL, NULL);
      else{ printf("Evaluated trees must be rooted\n"); exit(EXIT_FAILURE);}
      for(i=0;i<nb;i++){
        for(j=0;j<nb;j++){
          if(samename(seqname[i], nom2[j])){
	    evaltree[i]=ttree[j];
	    break;
          }
        }
      }
      if(deja_evalue(evaltree, nb, list_tree, nblist, nblistmax)) continue;
      addtolist(evaltree, nb, list_tree, nblist, nblistmax);
      nblist++;
    }
    printf("%d already evaluated topologies loaded\n", nblist);
  }
  else{
    addtolist(curtree, nb, list_tree, 0, nblistmax);
    nblist=1;
  }


	/* SHAKE */

  treedeb=ctreenew;
  nochange=1; movedist=0; 
  if(opt->SH_G>0 && opt->SH_G<nb-3) 
    maxmovedist=opt->SH_G;
  else
    maxmovedist=nb-3;

  if(print1)
    printf("\nStarting rearrangements\n");
  
  do{

    oldmovedist=movedist;

    if(nochange==1) movedist++;
    else movedist=1;

    if(print1 && !(nochange==0 && oldmovedist==1)){
      printf("\nCrossing %d internal branch", movedist);
      if(movedist>1) printf("es");
      printf("\n");
    }

    nochange=1;





    while(1){
      setclades(curtree, nb, seqname, l1, list1, l2, list2, dclade, gclade, ddist, gdist, nbdclade, nbgclade, dcladename, gcladename);
      restart_d=0;
      for(i=0;i<nbdclade;i++){
        for(j=0;j<nbdclade;j++){
	  if(abs(ddist[i][j])!=movedist) continue; 
	  if(ddist[i][j]<0) continue;
	  moveclade(dclade, newdclade, nbdclade, nb, ddist, i, j);
	  settree(newdclade, nbdclade, gclade, nbgclade, nb, newtree);

	  if(deja_evalue(newtree, nb, list_tree, nblist, nblistmax))
	    continue;
          if(solid_branch_crossed(newtree, curtree, nb, solid))
	    continue;

	  addtolist(newtree, nb, list_tree, nblist, nblistmax);
  	  nblist++;
	  if(print1){
	    printf("\nMoving %s toward %s\n", dcladename[i], dcladename[j]);
          }
	  if(print2)
	    printf("\n");
	  lkh=maxlike(nb, seq, seqname, newtree, NULL, NULL, nbbi, l1, list1, l2, list2, opt, ctreenew, NULL, NULL);

	  if(lkh>maxlkh){
  	    ctree_noblbs(ctreenew, ctreenew_nobl, strlen(ctreenew));
	    if(print1)
	      printf("New tree is optimal : \n%s\n\nRestarting rearrangements\n", ctreenew_nobl);
	    maxlkh=lkh;
	    copytree(newtree, curtree, nb);
            if(opt->SH_RESTART) save_current_best("current_best_tree", ctreenew_nobl, lkh, 0);
            if(opt->SH_RESTART) save_evaluated("evaluated_trees", ctreenew_nobl, lkh, 0);
	    restart_d=1;
	    nochange=0;
	    ctreenew=treedeb;
	    while(*ctreenew) {*ctreenew=0; ctreenew++; }
	    ctreenew=treedeb;
	    break;
	  }
	  else{
	    if(print1)
	      printf("No improvement:\n");
            ctree_noblbs(ctreenew, ctreenew_nobl, strlen(ctreenew));
            if(print1)
              printf("%s\n", ctreenew_nobl);
            if(opt->SH_RESTART) save_evaluated("evaluated_trees", ctreenew_nobl, lkh, 0);
	  }
	  ctreenew=treedeb;
	  while(*ctreenew) {*ctreenew=0; ctreenew++; }
	  ctreenew=treedeb;
        }
      if(restart_d) break;
      }
      if(!restart_d || movedist>1) break;
    }

    if(restart_d && movedist>1) continue;

    while(1){
      setclades(curtree, nb, seqname, l1, list1, l2, list2, dclade, gclade, ddist, gdist, nbdclade, nbgclade, dcladename, gcladename);
      restart_g=0;
      for(i=0;i<nbgclade;i++){
        for(j=0;j<nbgclade;j++){
	  if(abs(gdist[i][j])!=movedist) continue;
	  if(gdist[i][j]<0) continue;

	  moveclade(gclade, newgclade, nbgclade, nb, gdist, i, j);
	  settree(dclade, nbdclade, newgclade, nbgclade, nb, newtree);

	  if(deja_evalue(newtree, nb, list_tree, nblist, nblistmax))
	    continue;
          if(solid_branch_crossed(newtree, curtree, nb, solid))
	    continue;
	  addtolist(newtree, nb, list_tree, nblist, nblistmax);
	  nblist++;
	  if(print1){
	    printf("\nMoving %s toward %s\n", gcladename[i], gcladename[j]);
          }
	  if(print2){
	    printf("\n");
          }

	  lkh=maxlike(nb, seq, seqname, newtree, NULL, NULL, nbbi, l1, list1, l2, list2, opt, ctreenew, NULL, NULL);

	  if(lkh>maxlkh){
  	    ctree_noblbs(ctreenew, ctreenew_nobl, strlen(ctreenew));
	    if(print1)
	      printf("New tree is optimal : \n%s\n\nRestarting rearrangements\n", ctreenew_nobl);
	    maxlkh=lkh;
	    copytree(newtree, curtree, nb);
	    if(opt->SH_RESTART) save_current_best("current_best_tree", ctreenew_nobl, lkh, 0);
            if(opt->SH_RESTART) save_evaluated("evaluated_trees", ctreenew_nobl, lkh, 0);
            restart_g=1;
	    nochange=0;
	    ctreenew=treedeb;
	    while(*ctreenew) {*ctreenew=0; ctreenew++; }
	    ctreenew=treedeb;
	    break;
	  }
	  else{
	    if(print1)
	      printf("No improvement:\n");
            ctree_noblbs(ctreenew, ctreenew_nobl, strlen(ctreenew));
            if(print1)
              printf("%s\n", ctreenew_nobl);
            if(opt->SH_RESTART) save_evaluated("evaluated_trees", ctreenew_nobl, lkh, 0);
	  }
	  ctreenew=treedeb;
	  while(*ctreenew) {*ctreenew=0; ctreenew++; }
	  ctreenew=treedeb;
        }
      if(restart_g) break;
      }
      if(!restart_g || movedist>1) break;
    }
  } while(nochange==0 || movedist!=maxmovedist);



  	/* FINAL EVALUATION */

  if(print1)
    printf("\nFinal evaluation\n");
  if(print2)
    printf("\n");
  opt->print=trueprint;

  maxlkh=maxlike(nb, seq, seqname, curtree, NULL, NULL, nbbi, l1, list1, l2, list2, opt, NULL, ctree1, ctree2);

  if(ctree1){
    outfile1=fopen("treefile.eqgc", "w");
    outfile2=fopen("treefile.ndgc", "w");
    if(outfile1==NULL || outfile2==NULL){ printf("Cannot write tree file\n"); exit(EXIT_FAILURE); }
    fprintf(outfile1, "%s\n", ctree1);
    fprintf(outfile2, "%s\n", ctree2);
    if(print1){
      printf("Tree is written into files : treefile.eqgc (equilibrium G+C content)\n");
      printf("                             treefile.ndgc (G+C content at each node)\n\n");
    }
  }


  free(lgbp); free(sortedlgbp); free(lgbi);
  free(bootvals);
  for(i=0;i<nb;i++){ free(nom[i]); free(ttree[i]); }
  free(list1); free(list2); free(curtree);

  
  return maxlkh;
}