/* file gbpath1.c */

#if !defined(COMPILE_ENVIRONMENT)
#include <gp/stdcenvf.h> /* std compile environment for functions */
#endif

void get_bpath_from_pcdrls1(struct BPATH *bpath,pcodeset *pcdrls,char tgbound,int *perr)
 
  /***********************************************/
  /*  Tries to deduce back-off path from pcdrls. */
  /*  Works only with tg_size == 1, now.         */
  /*  On return, *perr > 0 iff error.            */
  /***********************************************/
 {char *proc = "get_bpath_from_pcdrls1";
  char sxx[LINE_LENGTH], *sx = &sxx[0];
  int i,j,le_size,tg_size,re_size,i_keylen,j_keylen;
  int i_le_size,i_tg_size,i_re_size;
  int j_le_size,j_tg_size,j_re_size;
  boolean found;
  SUBSTRING sstgx, *ss_tg = &sstgx;
  SUBSTRING sslex, *ss_le = &sslex;
  SUBSTRING ssrex, *ss_re = &ssrex;
  struct RPARTS tmp_rpart;
 /* code */
db_enter_msg(proc,1); /* debug only */
  *perr = 0;
 /* initialize bpath */
  bpath->step1 = 1;
  bpath->stepn = 0;
  sx = strcpy(sx,"deduced from ");
  sx = strcat(sx,pcdrls->name);
  bpath->desc = strdup_safe(sx,proc);
 /* fill in bpath from pcdrls */
  for (i = 1; i < pcdrls->pctab_length; i++)
    {if (strlen(pcdrls->pc[i].ac) > 0)
       {parse_rule_key(ss_le,ss_tg,ss_re,pcdrls->pc[i].ac,tgbound);
        le_size = substr_length(ss_le);
        tg_size = substr_length(ss_tg);
        re_size = substr_length(ss_re);
	/* is this rpart already in bpath? */
        found = F;
        for (j=bpath->step1; ((!found)&&(j <= bpath->stepn)); j++)
          {if ((bpath->rpart[j].le == le_size)&&
               (bpath->rpart[j].tg == tg_size)&&
               (bpath->rpart[j].re == re_size))
             found = T;
          }
        /* if not, add it */
        if (!found)
          {if (++(bpath->stepn) <= MAX_BACKOFF_STEPS)
             {bpath->rpart[bpath->stepn].le = le_size;
              bpath->rpart[bpath->stepn].tg = tg_size;
              bpath->rpart[bpath->stepn].re = re_size;
             }
           else fatal_error(proc,"bpath OVF",MAX_BACKOFF_STEPS);
    }  }  }
  /* sort bpath into likely order */
  for (i = bpath->step1; i < bpath->stepn; i++)
    {i_le_size = bpath->rpart[i].le;
     i_tg_size = bpath->rpart[i].tg;
     i_re_size = bpath->rpart[i].re;
     i_keylen = i_le_size+i_tg_size+i_re_size;
     for (j = i+1; j <= bpath->stepn; j++)
       {j_le_size = bpath->rpart[j].le;
        j_tg_size = bpath->rpart[j].tg;
        j_re_size = bpath->rpart[j].re;
        j_keylen = j_le_size+j_tg_size+j_re_size;
        if ((j_keylen > i_keylen) ||
            ((j_keylen == i_keylen)&&(j_re_size > i_re_size)))
          {/* swap i, j rparts */
           tmp_rpart = bpath->rpart[i];
           bpath->rpart[i] = bpath->rpart[j];
           bpath->rpart[j] = tmp_rpart;
           /* re-calc rpart[i] sizes */
           i_le_size = bpath->rpart[i].le;
           i_tg_size = bpath->rpart[i].tg;
           i_re_size = bpath->rpart[i].re;
           i_keylen = i_le_size+i_tg_size+i_re_size;
    }  }  }

  db_leave_msg(proc,1); /* debug only */
    return;
   }
