/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : DESB  v2.n                                                  */
/*    Fichier : driver.c                                                    */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) : Marc LAURENTIN                        le : 06/09/1991     */
/*                                                                          */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/

#include "declar.h"


/******************************************************************************
*                       fonction savedesa()                                   *
******************************************************************************/


void                     savedesa(pt_desafig)
desafig_list            *pt_desafig;
{
locon_list              *ptcon;
trans_list              *pttrans;
cone_list               *ptcone0, *ptcone1;
list_list               *ptlist;
link_list               *ptlink;
ptype_list              *pttype;
chain_list              *ptchain0, *ptchain1;
FILE                    *ptfile;
char                     filename[120];
char                     cone_type[16], path_type[8], trans_type[8];
long                     counter = 1;
short                    error = 0;


if((ptfile = mbkfopen(pt_desafig->NAME,"deb",WRITE_TEXT)) == NULL)
  {
  char buff[80] ;
  sprintf(buff,"%s.deb",pt_desafig->NAME);
  dsbFatalError(7,"savedesa",buff,0);
  }
  
/*---------------------------------------------------------------------------+
|                        HEADER                                              |
+---------------------------------------------------------------------------*/
time(&counter);
fprintf(ptfile, "(DESB V%s %s %s %s",DESB_VERSION, IN_LO,pt_desafig->NAME, getenv("USER"));
fprintf(ptfile, " %s\n", ctime(&counter));

/*---------------------------------------------------------------------------+
|                        DESB CONNECTOR LIST                                 |
+---------------------------------------------------------------------------*/
counter = 0;
fprintf(ptfile, "\n(CONNECTOR");
for(ptcon = pt_desafig->LOCON; ptcon; ptcon = ptcon->NEXT)
  {
  counter++;
  ptcon->ROOT = (void*)counter;
  fprintf(ptfile, "\n(%ld %s", (long)ptcon->ROOT,GetVectName(ptcon->NAME));
  if((ptcon->DIRECTION == 'I') || (ptcon->DIRECTION == 'O')
     || (ptcon->DIRECTION == 'X') || (ptcon->DIRECTION == 'T')
     || (ptcon->DIRECTION == 'A') || (ptcon->DIRECTION == 'B')
     || (ptcon->DIRECTION == 'Z'))
    { fprintf(ptfile, " %c", ptcon->DIRECTION); }
  else
    { fprintf(ptfile, " ?"); }

     if(ptcon->DIRECTION == 'X')
     {
     long capa ;
     ptype_list * conxUser = getptype(ptcon->USER,CAPA_TSP);
     capa = (long) conxUser->DATA ;
     fprintf(ptfile," %4.1f ",(float)capa);
     }
  fprintf(ptfile,")");
  }
fprintf(ptfile, ")\n");

/*---------------------------------------------------------------------------+
|                        DESB TRANSISTOR LIST                                |
+---------------------------------------------------------------------------*/
counter = 0;
fprintf(ptfile, "\n(TRANSISTOR");
for(pttrans = pt_desafig->TRANS; pttrans; pttrans = pttrans->NEXT)
  {
  counter++;
  pttrans->USER = (ptype_list*)counter;
  fprintf(ptfile, "\n(%ld", (long)pttrans->USER);
  if( pttrans->GRID != NULL)
    { fprintf(ptfile, " %ld", ((cone_list *)pttrans->GRID)->INDEX); }
  else
    { fprintf(ptfile, " ?"); error=1; }
  fprintf(ptfile, " %u %u", pttrans->WIDTH, pttrans->LENGTH);
  fprintf(ptfile, " %u %u", pttrans->PS, pttrans->PD);
  fprintf(ptfile, " %u %u", pttrans->XS, pttrans->XD);
  strcpy(trans_type, "");
  if((pttrans->TYPE & TN) == TN) strcat(trans_type, "N");
  if((pttrans->TYPE & TP) == TP) strcat(trans_type, "P");
  if((pttrans->TYPE & CAPACITE) == CAPACITE) strcat(trans_type, "C");
  if((pttrans->TYPE & DIODE) == DIODE) strcat(trans_type, "D");
  if((pttrans->TYPE & RESIST) == RESIST) strcat(trans_type, "R");
  if((pttrans->TYPE & PRECHARGE) == PRECHARGE) strcat(trans_type, "p");
  if(strlen(trans_type) == 0) { error = 1; strcat(trans_type, "?"); }
  fprintf(ptfile, " %s", trans_type);
  fprintf(ptfile, " %ld %ld)", pttrans->X, pttrans->Y);
  }
fprintf(ptfile, ")\n");

/*---------------------------------------------------------------------------+
|                        DESB REGISTER LIST                                  |
+---------------------------------------------------------------------------*/
if((ptchain0 = pt_desafig->REG) != NULL)
  {
  fprintf(ptfile, "\n(REGISTER");
  if(ptchain0->DATA != NULL)
    {
    fprintf(ptfile, "\n(%ld", ((cone_list*)ptchain0->DATA)->INDEX);
    counter = 1;
    for(ptchain0 = pt_desafig->REG->NEXT; ptchain0; ptchain0 = ptchain0->NEXT)
      {
      if(counter++ == 5) { fprintf(ptfile, "\n"); counter = 0; }
      fprintf(ptfile, " %ld", ((cone_list*)ptchain0->DATA)->INDEX);
      }
    }
  else
    { fprintf(ptfile, "\n(?"); }
  fprintf(ptfile, "))\n");
  }

/*---------------------------------------------------------------------------+
|                        DESB CONE LIST                                      |
+---------------------------------------------------------------------------*/
fprintf(ptfile, "\n(CONE");
for(ptcone0 = pt_desafig->CONE; ptcone0; ptcone0 = ptcone0->NEXT)
  {
  fprintf(ptfile, "\n\n(%ld %s", ptcone0->INDEX, GetVectName(ptcone0->NAME));
  fprintf(ptfile, " %ld %ld", ptcone0->X1, ptcone0->Y1);
  fprintf(ptfile, " %ld %ld", ptcone0->X2, ptcone0->Y2);
  strcpy(cone_type, " ");
  if((ptcone0->TYPE & VDD) == VDD) strcat(cone_type, "U");
  if((ptcone0->TYPE & VSS) == VSS) strcat(cone_type, "D");
  if((ptcone0->TYPE & EXT) == EXT) strcat(cone_type, "E");
  if((ptcone0->TYPE & TNINVDD) == TNINVDD) strcat(cone_type, "G");
  if((ptcone0->TYPE & TPINVSS) == TPINVSS) strcat(cone_type, "g");
  if((ptcone0->TYPE & BLEEDER) == BLEEDER) strcat(cone_type, "B");
  if((ptcone0->TYPE & PATH_PARA) == PATH_PARA) strcat(cone_type, "P");
  if((ptcone0->TYPE & PRECHARGE) == PRECHARGE) strcat(cone_type, "p");
  if((ptcone0->TYPE & SWITCH) == SWITCH) strcat(cone_type, "S");
  if((ptcone0->TYPE & CONFLICT) == CONFLICT) strcat(cone_type, "C");
  if((ptcone0->TYPE & HZ) == HZ) strcat(cone_type, "H");
  if((ptcone0->TYPE & DUAL) == DUAL) strcat(cone_type, "d");
  if((ptcone0->TYPE & AUTRE) == AUTRE) strcat(cone_type, "A");
  if((ptcone0->TYPE & LATCH) == LATCH) strcat(cone_type, "L");
  if((ptcone0->TYPE & MEMORY) == MEMORY) strcat(cone_type, "M");
  if((ptcone0->TYPE & MAST) == MAST) strcat(cone_type, "m");
  if((ptcone0->TYPE & SLAVE) == SLAVE) strcat(cone_type, "s");
  if(strlen(cone_type) == 1) { error = 1; strcat(cone_type, "?"); } 
  fprintf(ptfile, "%s", cone_type);
    
/*---------------------------------------------------------------------------+
|                       CONE_INPUT LIST                                      |
+---------------------------------------------------------------------------*/
  if(ptcone0->INCONE != NULL)
    { 
    fprintf(ptfile, "\n(INPUT");
    for(ptlist = ptcone0->INCONE; ptlist; ptlist = ptlist->NEXT)
      {
      if((ptlist->TYPE & CONE_TYPE) ==  CONE_TYPE)
        {
        fprintf(ptfile, "\n(C");
        if((ptlist->TYPE & LOOP) ==  LOOP)
          { fprintf(ptfile, "L"); }
        if((ptlist->TYPE & COMMAND) ==  COMMAND)
          { fprintf(ptfile, "c"); }
        ptcone1 = (cone_list*)ptlist->DATA;
        if(ptcone1 != NULL)
          { fprintf(ptfile, " %ld)", ptcone1->INDEX); }
        else
          { fprintf(ptfile, " ?)"); error=1; }
        }
      else if((ptlist->TYPE & VDD) ==  VDD)
        {
        fprintf(ptfile, "\n(U");
        ptcone1 = (cone_list*)ptlist->DATA;
        if(ptcone1 != NULL)
          { fprintf(ptfile, " %ld)", ptcone1->INDEX); }
        else
          { fprintf(ptfile, " ?)"); error=1; }
        }
      else if((ptlist->TYPE & VSS) ==  VSS)
        {
        fprintf(ptfile, "\n(D");
        ptcone1 = (cone_list*)ptlist->DATA;
        if(ptcone1 != NULL)
          { fprintf(ptfile, " %ld)", ptcone1->INDEX); }
        else
          { fprintf(ptfile, " ?)"); error=1; }
        }
      else if((ptlist->TYPE & EXT) == EXT)
        {
        fprintf(ptfile, "\n(E");
           if((ptlist->TYPE & LOOP) ==  LOOP)
           { fprintf(ptfile, "L"); }
        ptcon = (locon_list*)ptlist->DATA;
        if(ptcon != NULL)
          { fprintf(ptfile, " %ld)", (long)ptcon->ROOT); }
        else
          { fprintf(ptfile, " ?)"); error=1; }
        }
      else
        { fprintf(ptfile, "\n(? ?)"); error=1; }
      }
    fprintf(ptfile, ")");
    }

/*---------------------------------------------------------------------------+
|                       CONE_OUPUT LIST                                      |
+---------------------------------------------------------------------------*/
  if(ptcone0->OUTCONE != NULL)
    { 
    fprintf(ptfile, "\n(OUTPUT");
    for(ptlist = ptcone0->OUTCONE; ptlist; ptlist = ptlist->NEXT)
      {
      if((ptlist->TYPE & CONE_TYPE) ==  CONE_TYPE)
        {
        fprintf(ptfile, "\n(C");
        if((ptlist->TYPE & LOOP) ==  LOOP)
          { fprintf(ptfile, "L"); }
        ptcone1 = (cone_list*)ptlist->DATA;
        if(ptcone1 != NULL)
          { fprintf(ptfile, " %ld)", ptcone1->INDEX); }
        else
          { fprintf(ptfile, " ?)"); error=1; }
        }
      else if((ptlist->TYPE & EXT) == EXT)
        {
        fprintf(ptfile, "\n(E");
        ptcon = (locon_list*)ptlist->DATA;
        if(ptcon != NULL)
          { fprintf(ptfile, " %ld)", (long)ptcon->ROOT); }
        else
          { fprintf(ptfile, " ?)"); error=1; }
        }
      else
        { fprintf(ptfile, "\n(? ?)"); error=1; }
      }
    fprintf(ptfile, ")");
    }

/*---------------------------------------------------------------------------+
|                       CONE_PATHS LIST                                      |
+---------------------------------------------------------------------------*/
  if(ptcone0->PATH != NULL)
    {
    counter = 0;
    fprintf(ptfile, "\n(PATH");
    for(ptlist = ptcone0->PATH; ptlist; ptlist = ptlist->NEXT)
      {
      if((link_list*)ptlist->DATA != NULL)
        {
        strcpy(path_type, "");
        if((ptlist->TYPE & VDD) == VDD) strcat(path_type, "U");
        if((ptlist->TYPE & VSS) == VSS) strcat(path_type, "D");
        if((ptlist->TYPE & EXT) == EXT) strcat(path_type, "E");
        if((ptlist->TYPE & TNINVDD) == TNINVDD) strcat(path_type, "G");
        if((ptlist->TYPE & TPINVSS) == TPINVSS) strcat(path_type, "g");
        if((ptlist->TYPE & BLEEDER) == BLEEDER) strcat(path_type, "B");
        if((ptlist->TYPE & CONFLICT) == CONFLICT) strcat(path_type, "C");
        if(strlen(path_type) == 0) { error = 1; strcat(path_type, "?"); } 
        fprintf(ptfile, "\n(%s", path_type);
        counter++;
        ptlist->USER = (ptype_list*)counter;
        fprintf(ptfile, " %ld", ptlist->USER);
        for(ptlink = (link_list*)ptlist->DATA; ptlink; ptlink = ptlink->NEXT)
          {
          if(((ptlink->TYPE & TN) == TN) || ((ptlink->TYPE & TP) == TP))
            {
            strcpy(trans_type, "");
            if((ptlink->TYPE & TN) == TN) strcat(trans_type, "N");
            if((ptlink->TYPE & TP) == TP) strcat(trans_type, "P");
            if((ptlink->TYPE & CAPACITE) == CAPACITE) strcat(trans_type, "C");
            if((ptlink->TYPE & DIODE) == DIODE) strcat(trans_type, "D");
            if((ptlink->TYPE & RESIST) == RESIST) strcat(trans_type, "R");
            if((ptlink->TYPE & PRECHARGE) == PRECHARGE) strcat(trans_type, "p");
            if((ptlink->TYPE & SWITCH) == SWITCH) strcat(trans_type, "S");
            if(strlen(trans_type) == 0) { error = 1; strcat(trans_type, "?"); } 
            fprintf(ptfile, "\n(%s", trans_type);
            pttrans=(trans_list*)(ptlink->TRANS);
            if(pttrans != NULL)
              { fprintf(ptfile, " %ld", (long)(pttrans->USER)); }
            else
              { fprintf(ptfile, " ?"); error=1; }
            }
          else if(((ptlink->TYPE & IN) == IN)
                  || ((ptlink->TYPE & INOUT) == INOUT))
            {
            if((ptlink->TYPE & IN) == IN)
              { fprintf(ptfile, "\n(I"); }
            else
              { fprintf(ptfile, "\n(X"); }
            ptcon=(locon_list*)ptlink->TRANS;
            if(ptcon != NULL)
              { fprintf(ptfile, " %ld", (long)ptcon->ROOT); }
            else
              { fprintf(ptfile, " ?"); error=1; }
            }
          else
            { fprintf(ptfile, "\n(? ?"); error=1; }
          fprintf(ptfile, " %3.2f", ptlink->CAPA);
          fprintf(ptfile, ")");
          }
        fprintf(ptfile, ")");
        }
      }
    fprintf(ptfile, ")");
    }

/*---------------------------------------------------------------------------+
|                       CONE_USERS LIST                                      |
+---------------------------------------------------------------------------*/
  if(((getptype(ptcone0->USER, (long)SWITCH)) != NULL)
     || ((getptype(ptcone0->USER, (long)PATH_PARA)) != NULL)
     || ((getptype(ptcone0->USER, (long)MEMORY)) != NULL)
     || ((getptype(ptcone0->USER, (long)BLEEDER)) != NULL))
    { 
    fprintf(ptfile, "\n(USER");

                /*      cone switchs         */

    if((pttype = getptype(ptcone0->USER, (long)SWITCH)) != NULL)
      {
      if(pttype->DATA != NULL)
        {
        fprintf(ptfile, "\n(SWITCH");
        for(ptchain0 = (chain_list*)pttype->DATA; ptchain0;
              ptchain0 = ptchain0->NEXT)
          {
          if ((ptchain1 = (chain_list*)ptchain0->DATA) != NULL)
            {
            fprintf(ptfile, "\n(%ld",
                      (long)((trans_list*)ptchain1->DATA)->USER);
            if (ptchain1->NEXT != NULL)
              {
              fprintf(ptfile, " %ld)",
                        (long)((trans_list*)ptchain1->NEXT->DATA)->USER);
              }
            else
              { fprintf(ptfile, " ?)"); }
            }
          else
            { fprintf(ptfile, " ? ?)"); }
          }
        fprintf(ptfile, ")");
        }
      }

                /*      cone path//          */

    if((pttype = getptype(ptcone0->USER, (long)PATH_PARA)) != NULL)
      {
      if(pttype->DATA != NULL)
        {
        fprintf(ptfile, "\n(PATH//");
        for(ptchain0 = (chain_list*)pttype->DATA; ptchain0;
              ptchain0 = ptchain0->NEXT)
          {
          if(ptchain0->DATA != NULL)
            {
            ptchain1 = (chain_list*)ptchain0->DATA;
            fprintf(ptfile, "\n(%ld", (long)((list_list*)ptchain1->DATA)->USER);
            for(ptchain1 = ((chain_list*)ptchain0->DATA)->NEXT; ptchain1;
                  ptchain1 = ptchain1->NEXT)
              {
              fprintf(ptfile, " %ld", (long)((list_list*)ptchain1->DATA)->USER);
              }
            fprintf(ptfile, ")");
            }
          }
        fprintf(ptfile, ")");
        }
      }


                /*      cone BLEEDER, LATCH, et MEMORY        */

    if((pttype = getptype(ptcone0->USER, (long)BLEEDER)) != NULL)
      {
      if((ptchain0 = (chain_list*)pttype->DATA) != NULL)
        {
        fprintf(ptfile, "\n(BLEEDER");
        fprintf(ptfile, "\n(%ld", (long)((list_list*)ptchain0->DATA)->USER);
        for(ptchain1 = ptchain0->NEXT; ptchain1; ptchain1 = ptchain1->NEXT)
          { fprintf(ptfile, " %ld", (long)((list_list*)ptchain1->DATA)->USER); }
        fprintf(ptfile, "))");
        }
      }
    if((pttype = getptype(ptcone0->USER,(long)MEMORY))!=NULL)
      {
      cone_list * cone;
      cone=(cone_list*)pttype->DATA;
      fprintf(ptfile,"\n(MEMORY");
      fprintf(ptfile,"\n(%ld))",(long)cone->INDEX);
      }                       /* end of user fields    */
    fprintf(ptfile, ")");
    }                         /* end of cone          */
  fprintf(ptfile, ")");
  }                           /*      end of cones      */
fprintf(ptfile, ")");         /*      end of desa       */
fprintf(ptfile, ")\n");       /*      close file        */

if(error == 1)
  {
  if(DESB_TRACE_MODE >= WARNING_2)
    {
    printf("WAR_dsb savedesa : unknown fields found (marked by '?') \n");
    }
  }

if(fclose(ptfile)!=0)
  {
  char buff[80] ;
  sprintf(buff,"%s.deb",pt_desafig->NAME);
  dsbFatalError(8,"savedesa",buff,0);
  }
}
