/*------------------------------------------------------------\
|                                                             |
| Tool    :                     RDS                           |
|                                                             |
| File    :                  RdsAcces.c                       |
|                                                             |
| Authors :                Jacomme Ludovic                    |
|                                                             |
| Date    :                   01.08.93                        |
|                                                             |
\------------------------------------------------------------*/

/*------------------------------------------------------------\
|                                                             |
|                         Include Files                       |
|                                                             |
\------------------------------------------------------------*/

# include MUT_H
# include MPH_H
# include RDS_H

# include <stdio.h>
# include <malloc.h>
# include <memory.h>
# include <string.h>
# include "rdsacces.h"
# include "rdserror.h"

/*------------------------------------------------------------\
|                                                             |
|                           Constants                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                            Types                            |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Variables                          |
|                                                             |
\------------------------------------------------------------*/

  rdsfig_list *HEAD_RDSFIG = (rdsfig_list *)NULL;

  char RDS_LAYER_NAME [ RDS_MAX_LAYER ] [ 12 ] =

       {

         "RDS_NWELL  ",
         "RDS_PWELL  ",
         "RDS_NINP   ",
         "RDS_PINP   ",
         "RDS_ACTIV  ",
         "RDS_NDIF   ",
         "RDS_PDIF   ",
         "RDS_NTIE   ",
         "RDS_PTIE   ",
         "RDS_POLY   ",
         "RDS_GATE   ",
         "RDS_TPOLY  ",
         "RDS_CONT   ",
         "RDS_ALU1   ",
         "RDS_TALU1  ",
         "RDS_VIA1   ",
         "RDS_ALU2   ",
         "RDS_TALU2  ",
         "RDS_VIA2   ",
         "RDS_ALU3   ",
         "RDS_TALU3  ",
         "RDS_VIA3   ",
         "RDS_ALU4   ",
         "RDS_CPAS   ",
         "RDS_REF    ",
         "RDS_USER0  ",
         "RDS_USER1  ",
         "RDS_USER2  ",
         "RDS_ABOX   "
       };

  char RDS_TRANSF_NAME [ RDS_MAX_TRANSF ] [ 8 ] = 
 
       {
         "NOSYM",
         "ROT_P", 
         "SYMXY",
         "ROT_M",
         "SYM_X",
         "SY_RM",
         "SYM_Y",
         "SY_RP"
       };

  static char  *RdsHeapHeadArray[ 256 ];
  static char   InitRdsHeapHeadArray = 1;

/*------------------------------------------------------------\
|                                                             |
|                          Functions                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                       Alloc Functions                       |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Rds Alloc                          |
|                                                             |
\------------------------------------------------------------*/

  char *rdsalloc( Size, Heap )

        unsigned int Size; 
        char         Heap;
  {
    int           Counter;
    unsigned int  Index;
    char         *Pointer;
    char        **Prev;
    char         *Scan;

    if ( InitRdsHeapHeadArray == 1 )
    { 
      InitRdsHeapHeadArray = 0;

      for ( Counter = 0; Counter < 256 ; Counter++ )
      {
        RdsHeapHeadArray[ Counter ] = (char *)NULL;
      }
    }

    Index = ( Size + 3 ) >> 2;

    if ( ( Heap    == RDS_ALLOC_BLOCK ) ||
         ( Index   >  255             ) )
    {
      if ( !( Pointer = malloc( Size ) ) ) 
      {
        rdserror( RDS_ALLOC_ERROR, (char *)NULL );
      }

      bzero( Pointer, Size );
  
      return( Pointer );
    } 

    Size = Index << 2;

    if ( RdsHeapHeadArray[ Index ] == (char *)NULL )
    {
      if ( !( Pointer = malloc( Size << RDS_ALLOC_SHIFT ) ) ) 
      {
        rdserror( RDS_ALLOC_ERROR, (char *)NULL );
      }

      Scan = (char *)(Pointer + Size);

      Prev = &RdsHeapHeadArray[ Index ];

      for ( Counter = 1; Counter < RDS_ALLOC_SIZE; Counter++ )
      {
        *Prev = Scan; Prev = (char **)Scan; Scan = (char *)(Scan + Size);
      }

      *Prev = (char *)NULL;

      RdsHeapHeadArray[ Index ] = (char *)(Pointer + Size);

      bzero( Pointer, Size );

      return( Pointer );
    }

    Pointer = RdsHeapHeadArray[ Index ];

    RdsHeapHeadArray[ Index ] = *((char **)RdsHeapHeadArray[ Index ]);

    bzero( Pointer, Size );

    return( Pointer );
  }

/*------------------------------------------------------------\
|                                                             |
|                        Rds Alloc Figure                     |
|                                                             |
\------------------------------------------------------------*/
 
  rdsfig_list *allocrdsfig()
  {
    return( (rdsfig_list *)(rdsalloc( sizeof( rdsfig_list), RDS_ALLOC_BLOCK)));
  }

/*------------------------------------------------------------\
|                                                             |
|                       Rds Alloc Instance                    |
|                                                             |
\------------------------------------------------------------*/

  rdsins_list *allocrdsins()
  {
    return( (rdsins_list *)(rdsalloc( sizeof( rdsins_list), RDS_ALLOC_BLOCK)));
  }

/*------------------------------------------------------------\
|                                                             |
|                     Rds Alloc Rectangle                     |
|                                                             |
\------------------------------------------------------------*/

  rdsrec_list *allocrdsrec( Size )

     unsigned int Size;
  {
    return( (rdsrec_list *)(rdsalloc( sizeof( rdsrec_list) + Size, RDS_ALLOC_HEAP )));
  }

/*------------------------------------------------------------\
|                                                             |
|                     Rds Free Functions                      |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Rds Free                           |
|                                                             |
\------------------------------------------------------------*/

  void  rdsfree( Pointer, Size )

        char         *Pointer;
        unsigned int  Size;
  {
    unsigned int Index;

    Index = ( Size + 3 ) >> 2;

    if ( ( Size  == 0              ) ||
         ( Index > 255             ) )
    {
      free( Pointer );
    }
    else
    {
      *((char **)Pointer) = RdsHeapHeadArray[ Index ];

      RdsHeapHeadArray[ Index ] = Pointer;
    }
  }
  
/*------------------------------------------------------------\
|                                                             |
|                      Rds Free Figure                        |
|                                                             |
\------------------------------------------------------------*/
 
  void freerdsfig( Figure )

       rdsfig_list *Figure;
  {
    rdsfree( (char *)Figure, sizeof( rdsfig_list ));
  }

/*------------------------------------------------------------\
|                                                             |
|                      Rds Free Instance                      |
|                                                             |
\------------------------------------------------------------*/

  void freerdsins( Instance )

       rdsins_list *Instance;
  {
    rdsfree( (char *)Instance, sizeof( rdsins_list ));
  }

/*------------------------------------------------------------\
|                                                             |
|                      Rds Free Rectangle                     |
|                                                             |
\------------------------------------------------------------*/

  void freerdsrec( Rectangle, Size )

       rdsrec_list  *Rectangle;
       unsigned int  Size;
  {
    rdsfree( (char *)Rectangle, sizeof( rdsrec_list ) + Size);
  }

/*------------------------------------------------------------\
|                                                             |
|                      Rds Add Functions                      |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                        Rds Add Figure                       |
|                                                             |
\------------------------------------------------------------*/

  rdsfig_list *addrdsfig( Name, Size )

     char        *Name;
     unsigned int Size; 
  {
    rdsfig_list *Figure;

    Figure = allocrdsfig();

    Figure->NAME  = namealloc( Name );
    Figure->SIZE  = Size;
    Figure->MODE  = 'A';
    Figure->NEXT  = HEAD_RDSFIG;

    HEAD_RDSFIG   = Figure;

    return( Figure );
  }

/*------------------------------------------------------------\
|                                                             |
|                        Rds Add Instance                     |
|                                                             |
\------------------------------------------------------------*/

  rdsins_list *addrdsins( Figure, Model, Name, Sym, X, Y )

     rdsfig_list *Figure;
     char        *Model;
     char        *Name;
     char         Sym;
     long         X; 
     long         Y; 
  {
    rdsins_list *Instance;

    Instance = allocrdsins();

    Instance->FIGNAME = namealloc( Model );
    Instance->INSNAME = namealloc( Name  );
    Instance->X       = X;
    Instance->Y       = Y;
    Instance->TRANSF  = Sym;
    Instance->SIZE    = Figure->SIZE;
    Instance->NEXT    = Figure->INSTANCE;

    Figure->INSTANCE  = Instance;

    return( Instance );
  }

/*------------------------------------------------------------\
|                                                             |
|                  Rds Add Rectangle in Instance              |
|                                                             |
\------------------------------------------------------------*/

  rdsrec_list *addrdsinsrec( Instance, Name, Layer, X, Y, Dx, Dy )

     rdsins_list *Instance;
     char        *Name;
     char         Layer;
     long         X;
     long         Y;
     long         Dx;
     long         Dy;
  {
    rdsrec_list *Rectangle;
 
    Rectangle = allocrdsrec( Instance->SIZE );
 
    Rectangle->NAME  = namealloc( Name );
    Rectangle->X     = X;
    Rectangle->Y     = Y;
    Rectangle->DX    = Dx;
    Rectangle->DY    = Dy;
    Rectangle->FLAGS = (unsigned char)(Layer);
    Rectangle->NEXT  = Instance->LAYERTAB[ Layer ];
  
    Instance->LAYERTAB[ Layer ] = Rectangle;

    ClearRdsFigRec( Rectangle );

    return( Rectangle );
  }

/*------------------------------------------------------------\
|                                                             |
|                  Rds Add Rectangle in Figure                |
|                                                             |
\------------------------------------------------------------*/

  rdsrec_list *addrdsfigrec( Figure, Name, Layer, X, Y, Dx, Dy )

     rdsfig_list *Figure;
     char        *Name;
     char         Layer;
     long         X;
     long         Y;
     long         Dx;
     long         Dy;
  {
    rdsrec_list *Rectangle;
 
    Rectangle = allocrdsrec( Figure->SIZE );
 
    Rectangle->NAME  = namealloc( Name );
    Rectangle->X     = X;
    Rectangle->Y     = Y;
    Rectangle->DX    = Dx;
    Rectangle->DY    = Dy;
    Rectangle->FLAGS = (unsigned char)(Layer);
    Rectangle->NEXT  = Figure->LAYERTAB[ Layer ];
  
    Figure->LAYERTAB[ Layer ] = Rectangle;

    SetRdsFigRec( Rectangle );

    return( Rectangle );
  }

/*------------------------------------------------------------\
|                                                             |
|                        Rds Del Functions                    |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                        Rds Del Figure                       |
|                                                             |
\------------------------------------------------------------*/

  int delrdsfig( Name )

     char *Name;
  {
    rdsfig_list  *Figure;
    rdsfig_list **Previous;
    rdsins_list  *Instance;
    rdsrec_list  *Rectangle;
    void         *Save;
    char          Layer;

    Name     = namealloc( Name );
    Previous = &HEAD_RDSFIG;

    for ( Figure  = HEAD_RDSFIG;
          Figure != (rdsfig_list *)NULL;
          Figure  = Figure->NEXT )
    {
      if ( Figure->NAME == Name ) break;

      Previous = &Figure->NEXT;
    }

    if ( Figure == (rdsfig_list *)NULL ) 
  
      return( 0 );

    *Previous = Figure->NEXT;

    for ( Layer = 0; Layer < RDS_MAX_LAYER; Layer++ )
    {
      Rectangle  = Figure->LAYERTAB[ Layer ];

      while ( Rectangle != (rdsrec_list *)NULL )
      {
        Save = (void *)(Rectangle->NEXT);

        freerdsrec( Rectangle, Figure->SIZE );

        Rectangle = (rdsrec_list *)Save;
      }
    }

    Instance = Figure->INSTANCE;

    while ( Instance != (rdsins_list *)NULL )
    {
      for ( Layer = 0; Layer < RDS_MAX_LAYER; Layer++ )
      {
        Rectangle  = Instance->LAYERTAB[ Layer ];
  
        while ( Rectangle != (rdsrec_list *)NULL )
        {
          Save = (void *)(Rectangle->NEXT);
  
          freerdsrec( Rectangle, Figure->SIZE );
  
          Rectangle = (rdsrec_list *)Save;
        }
      }

      Save = (void *)(Instance->NEXT);

      freerdsins( Instance );

      Instance = (rdsins_list *)Save;
    }
   
    freerdsfig( Figure );

    return( 1 );
  }

/*------------------------------------------------------------\
|                                                             |
|                        Rds Del Instance                     |
|                                                             |
\------------------------------------------------------------*/

 int delrdsins( Figure, Name )

     rdsfig_list *Figure;
     char        *Name;
  {
    rdsins_list **Previous;
    rdsins_list  *Instance;
    rdsrec_list  *Rectangle;
    void         *Save;
    char          Layer;

    Name     = namealloc( Name );
    Previous = &Figure->INSTANCE;

    for ( Instance  = Figure->INSTANCE;
          Instance != (rdsins_list *)NULL;
          Instance  = Instance->NEXT )
    {
      if ( Instance->INSNAME == Name ) break;

      Previous = &Instance->NEXT;
    }

    if ( Instance == (rdsins_list *)NULL ) 
  
      return( 0 );

    *Previous = Instance->NEXT;

    for ( Layer = 0; Layer < RDS_MAX_LAYER; Layer++ )
    {
      Rectangle  = Instance->LAYERTAB[ Layer ];

      while ( Rectangle != (rdsrec_list *)NULL )
      {
        Save = (void *)(Rectangle->NEXT);

        freerdsrec( Rectangle, Figure->SIZE );

        Rectangle = (rdsrec_list *)Save;
      }
    }

    freerdsins( Instance );

    return( 1 );
  }
 
/*------------------------------------------------------------\
|                                                             |
|                   Rds Del Rectangle In Instance             |
|                                                             |
\------------------------------------------------------------*/

  int delrdsinsrec( Instance, Rectangle )

     rdsins_list *Instance;
     rdsrec_list *Rectangle;
  {
    rdsrec_list **Previous;
    rdsrec_list  *Scan;

    Previous = &Instance->LAYERTAB[ GetRdsLayer( Rectangle ) ];

    for ( Scan  = Instance->LAYERTAB[ GetRdsLayer( Rectangle ) ];
          Scan != (rdsrec_list *)NULL;
          Scan  = Scan->NEXT )
    {
      if ( Scan == Rectangle ) break;

      Previous = &Scan->NEXT;
    }

    if ( Scan == (rdsrec_list *)NULL ) 
  
      return( 0 );

    *Previous = Rectangle->NEXT;

    freerdsrec( Rectangle, Instance->SIZE );

    return( 1 );
  }
 
/*------------------------------------------------------------\
|                                                             |
|                   Rds Del Rectangle In Figure               |
|                                                             |
\------------------------------------------------------------*/

  int delrdsfigrec( Figure, Rectangle )

     rdsfig_list *Figure;
     rdsrec_list *Rectangle;
  {
    rdsrec_list **Previous;
    rdsrec_list  *Scan;

    Previous = &Figure->LAYERTAB[ GetRdsLayer( Rectangle ) ];

    for ( Scan  = Figure->LAYERTAB[ GetRdsLayer( Rectangle ) ];
          Scan != (rdsrec_list *)NULL;
          Scan  = Scan->NEXT )
    {
      if ( Scan == Rectangle ) break;

      Previous = &Scan->NEXT;
    }

    if ( Scan == (rdsrec_list *)NULL ) 
  
      return( 0 );

    *Previous = Rectangle->NEXT;

    freerdsrec( Rectangle, Figure->SIZE );

    return( 1 );
  }

/*------------------------------------------------------------\
|                                                             |
|                         View Functions                      |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                       View Rds Rectangle                    |
|                                                             |
\------------------------------------------------------------*/

  void viewrdsrec( Rectangle )

       rdsrec_list *Rectangle;
  {
    char *LayerName;

    LayerName = RDS_LAYER_NAME[ GetRdsLayer( Rectangle ) ];

    fprintf( stdout, "\n\t--> Rectangle" );

    if ( Rectangle->NAME != (char *)NULL )
    {
      fprintf( stdout, "\n\t\tNAME  : %s" , Rectangle->NAME  );
    }
    else
    {   
      fprintf( stdout, "\n\t\tNAME  : NO NAME" );
    }

    fprintf( stdout, "\n\t\tX     : %ld" , Rectangle->X     );
    fprintf( stdout, "\n\t\tY     : %ld" , Rectangle->Y     );
    fprintf( stdout, "\n\t\tDX    : %ld" , Rectangle->DX    );
    fprintf( stdout, "\n\t\tDY    : %ld" , Rectangle->DY    );
    fprintf( stdout, "\n\t\tFLAGS : %l0X", Rectangle->FLAGS );
    fprintf( stdout, "\n\t\tLAYER : %s"  , LayerName        );
  }

/*------------------------------------------------------------\
|                                                             |
|                       View Rds Instance                     |
|                                                             |
\------------------------------------------------------------*/

  void viewrdsins( Instance )

       rdsins_list *Instance;
  {
    char         Layer;
    rdsrec_list *Rectangle;
    char        *TransfName;

    TransfName = RDS_TRANSF_NAME[ Instance->TRANSF ];

    fprintf( stdout, "\n--> Instance" );

    fprintf( stdout, "\n\tINSNAME : %s" , Instance->INSNAME );
    fprintf( stdout, "\n\tFIGNAME : %s" , Instance->FIGNAME );
    fprintf( stdout, "\n\tX       : %ld", Instance->X       );
    fprintf( stdout, "\n\tY       : %ld", Instance->Y       );
    fprintf( stdout, "\n\tTRANSF  : %s" , TransfName        );
    fprintf( stdout, "\n\tSIZE    : %d" , Instance->SIZE    );
    fprintf( stdout, "\n\tFLAGS   : %x" , Instance->FLAGS   );

    for ( Layer = 0; Layer < RDS_MAX_LAYER; Layer++ )
    {
      for ( Rectangle  = Instance->LAYERTAB[ Layer ];
            Rectangle != (rdsrec_list *)NULL;
            Rectangle  = Rectangle->NEXT )
      {
        viewrdsrec( Rectangle );
      }
    }
  }

/*------------------------------------------------------------\
|                                                             |
|                       View Rds Figure                       |
|                                                             |
\------------------------------------------------------------*/

  void viewrdsfig( Figure )

       rdsfig_list *Figure;
  {
    char         Layer;
    rdsins_list *Instance;
    rdsrec_list *Rectangle;

    fprintf( stdout, "\n--> Figure" );

    fprintf( stdout, "\n\tNAME  : %s", Figure->NAME  );
    fprintf( stdout, "\n\tMODE  : %c", Figure->MODE  );
    fprintf( stdout, "\n\tSIZE  : %d", Figure->SIZE  );
    fprintf( stdout, "\n\tFLAGS : %x", Figure->FLAGS );

    for ( Layer = 0; Layer < RDS_MAX_LAYER; Layer++ )
    {
      for ( Rectangle  = Figure->LAYERTAB[ Layer ];
            Rectangle != (rdsrec_list *)NULL;
            Rectangle  = Rectangle->NEXT )
      {
        viewrdsrec( Rectangle );
      }
    }

    for ( Instance  = Figure->INSTANCE;
          Instance != (rdsins_list *)NULL;
          Instance  = Instance->NEXT )
    {
      viewrdsins( Instance );
    }
  }
