/***********************************
  (C) Copyright 1992-1993; dit/upm
  Distributed under the conditions stated in the
  TOPO General Public License (see file LICENSE)
  ***********************************/

/***********************************
  
  Santiago Pavon Gomez
  
  1 November 1990
  
  This module defines a type of dynamic trees. These trees are 
  formed by cells, which are linked between them, and attributes, 
  which are associated to the cells. 
  
  The memory used by both cells and attributes can be shared, 
  so there are some counters that indicates how many fathers has 
  any cell or attribute.
  These counter are called "copy" for the cells and "cont" for the 
  attributes.
  
  COMPILATION OPTIONS: The behaviour of this module can be modified
  by the following compilation flags:
  
  SDEBUG : activate debugging mode
  DEBUGMEM : activate control of deallocated memory
  
  TYPE DEFINITIONS:
  CellTypeTyp : cell types
  DescriptorTyp : cell names
  AttrValueTyp : attribute values
  AttrTypeTyp : attribute types
  PAttrsTyp : list of AttrTyp
  CellTyp, PCellTyp : cells
  AttrTyp, PAttrTyp : attributes
  
  FUNCTION DEFINITIONS:
  InitCell    : init module
  DeclareCell : declares a cell type
  DeclareAttr : declares an attribute type
  GetNameCell : returns the name of a cell
  GetNameAttr : returns the name of an attribute
  PutType     : sets the type of a cell
  LookType    : looks the type of a cell
  PutCopy     : sets the copy of a cell 
  LookCopy    : looks the copy field of a cell
  IncCopyC    : increments the copy field of a cell
  DecCopyC    : decrements the copy field of a cell
  PutName     : sets the name of a cell
  LookName    : looks the name of a cell
  PutAttr     : sets the attribute of a cell
  LookAttr    : looks the attribute field of a cell
  PutB1       : sets the first branch (b1) of a  cell
  LookB1      : returns the b1 field of a cell
  PutB2       : sets the second branch (b2) of a  cell
  LookB2      : returns the b2 field of a cell
  NewCell     : gets memory for a new cell
  DispCell    : disposes the memory used by a cell
  DrawCell    : prints a cell into a file
  CopyCell    : copies a cell
  GlueCellB1  : copies the tree "t->b1" in the memory used by "t".
  GlueCellB2  : copies the tree "t->b2" in the memory used by "t".
  ExchangeCell: exchanges the fields of two cells
  NewAttr     : gets memory for an AttrTyp
  DispAttr    : frees the memory used by an AttrTyp
  PutA        : adds an attribute to a cell
  LookA       : looks an attribute of a cell
  GetA        : gets an attribute of a cell
  FreeA       : frees the memory used by an the attribute
  CopyA       : copies an attribute
  UnshareA    : unshares an attribute
  MakeA       : makes an attribute
  PutAInfo    : puts a value into an attribute
  GetAInfo    : gets the value of an attribute
  LookAInfo   : looks the value of an attribute
  DecContA    : decrements the field "cont" of an attribute
  IncContA    : increments the field "cont" of an attribute
  WriteA      : prints an attribute in a file
  UnshareAS   : unshares all the attributes of a cell
  FreeAS      : frees the list of attributes of a cell
  CopyAS      : copies the list of attributes of a cell into another cell
  FreeTree    : deallocates the memory used by a tree
  FreeB1      : deallocates the memory used by the first branch of a tree
  FreeB2      : deallocates the memory used by the second branch of a tree
  GetTree     : returns a copy of a tree without shared cells
  CopyTree    : copies a tree
  GlueCell    : Copies a tree into the memory used by another tree
  UnshareAttrsOfTree : unshares the attributes of a tree
  DrawTree    : prints a tree into a file
  DrawLTree   : prints the cells of a tree like a list
  StatCell    : statistics about the module
  
  22-7-92 David
  Bug en IncCopyC y DecCopyC
  
  ************************************/


#ifndef LIcell_H
#define LIcell_H

#include "lilists.h"


/******************************************************************
 *
 *            Cell and attribute definitions.
 *
 *******************************************************************/


typedef int     CellTypeTyp;   /* Cell type */   
typedef int     DescriptorTyp; /* Cell name */
typedef void*   AttrValueTyp;  /* Elements stored in the attributes */
typedef int     AttrTypeTyp;   /* Attribute type */
typedef ListTyp PAttrsTyp;     /* Attribute list(Elements are AttrTyp) */


/* 
 *  Cell definition.
 */
typedef struct cellTyp { CellTypeTyp         type;
                         DescriptorTyp       name;
                         int                 copy;
                         struct cellTyp      *b1, *b2;
                         PAttrsTyp           attrlist;
                       } CellTyp,*PCellTyp;


/* 
 *  Attribute definition.
 */
typedef struct { int          cont;
                 AttrTypeTyp  type;
                 AttrValueTyp attr;
               } AttrTyp, *PAttrTyp;


/******************************************************************
 *
 *  Initiation functions
 *
 *******************************************************************/


/* InitCell
 * Initiation of this module.
 * This function must only be called when the application start.
 */
extern void InitCell();


/* DeclareCell
 * Declares a cell type.
 * Parameters:
 *    type: a number for each cell type.
 *    name: a string name for each cell type.
 *    d2n:  a function that returns a name for a given cell name.
 */
extern void DeclareCell( /* type,name,d2n */ );
/* CellTypeTyp   type;
   char *        name;
   char *        (*d2n)(); */


/* DeclareAttr
 * Declares an attribute type.
 * Parameters:
 *   type: a number for each attribute type.
 *   name: a string name for each attribute type.
 *   print: function to print attributes of a given type.
 *   deall: function to deallocate the memory used by attributes of
 *         a given type.
 *   copy: function to copy attributes of a given type.
 *   unshare: function to unshare attributes of a given type.
 */
extern void DeclareAttr( /* type,name,print,deall,copy,unshare */ );
/* AttrTypeTyp   type;
   char *        name;
   void          (*print)();    
   void          (*deall)();    
   AttrValueTyp  (*copy)(); 
   AttrValueTyp  (*unshare)();  */


/* GetNameCell
 * Returns the name of the cell which type is "t".
 */
extern char * GetNameCell( /* t */ );
/* CellTypeTyp   t; */


/* GetNameAttr
 * Returns the name of the attribute which type is "t".
 */
extern char * GetNameAttr( /* t */ );
/* AttrTypeTyp   t; */


/******************************************************************
 *
 * Functions to manage cells.
 *
 *******************************************************************/


/* PutType
 * Sets the type of the cell "c" to "t".
 */
#define PutType(c,t) {LASSERT(c!=NULL) ; (c)->type = t;}


/* LookType
 * Returns the type of the cell "c".
 */
#define LookType(c) ((c)->type) 


/* PutCopy
 * Sets the copy of the cell "c" to "n".
 */
#define PutCopy(c,n)   {(c)->copy = n;}


/* LookCopy
 * Returns the copy field of the cell "c".
 */
#define LookCopy(c)  ((c)->copy)


/* IncCopyC
 * Increments the copy field of the cell "c".
 */
#define IncCopyC(c) {(c)->copy += ((c)->copy)>=0  ? 1 : -1;}


/* DecCopyC
 * Decrements the copy field of the cell "c".
 */
#define DecCopyC(c)  {(c)->copy -= ((c)->copy)>=0  ? 1 : -1;}


/* PutName
 * Sets the name of the cell "c" to "n".
 */
#define PutName(c,n)  {(c)->name = n;}


/* LookName
 * Returns the name of the cell "c".
 */
#define LookName(c) ((c)->name)


/* PutAttr
 * sets the attribute of the cell "c" to "a".
 */
#define PutAttr( c, a ) {(c)->attrlist = a;}


/* LookAttr
 * Returns the attribute field of the cell "c".
 */
#define LookAttr( c )  ((c)->attrlist)


/* PutB1
 * Sets the first branch (b1) of the cell "c" to "b_1".
 */
#define PutB1(c,b_1) {(c)->b1 = b_1;}


/* LookB1
 * Returns the b1 field of the cell "c".
 */
#define LookB1(c) ((c)->b1)


/* PutB2
 * Sets the second branch (b2) of the cell "c" to "b_2".
 */
#define PutB2(c,b_2) {(c)->b2 = b_2;}


/* LookB2
 * Returns the b2 field of the cell "c".
 */
#define LookB2(c) ((c)->b2)


/* NewCell
 * Gets memory for a new cell
 */
extern PCellTyp NewCell( /* t */ );
/*  CellTypeTyp   t; */   


/* DispCell
 * Disposes the memory used by the cell "c".
 */
extern void DispCell( /* c */ );
/* PCellTyp  c; */


/* DrawCell
 * Prints the cell "c" with indentation "i".
 * "pstr" is the function used to print strings.
 */
extern void DrawCell( /* c, i, pstr */ );
/* PCellTyp  c;
   int       i; 
   void      (*pstr)(); */


/* CopyCell
 * Copies the cell "t".
 * Attributes are shared (not copied).
 * Links b1 and b2 are set to NULL.
 * The "copy" fields is set to 0.
 */
extern PCellTyp  CopyCell( /* t */ );
/* PCellTyp t;  */    


/* GlueCellB1
 * The tree "t->b1" is copied in the memory used by "t".
 * This function is equal to moving all the pointer to "t" to "t->b1"
 * and deleting "t".
 */
extern void GlueCellB1( /* t */ );
/*  PCellTyp  t; */


/* GlueCellB2
 * The tree "t->b2" is copied in the memory used by "t".
 * This function is equal to moving all the pointer to "t" to "t->b2"
 * and deleting "t".
 */
extern void GlueCellB2( /* t */ );
/*  PCellTyp  t; */


/* ExchangeCell
 * Exchanges the fields of the cells pointed by b1p and b2p, except the
 * copy field.
 */
extern void ExchangeCell(/*b1p,b2p*/);
/* PCellTyp *b1p,*b2p; */


/******************************************************************
 *
 * Functions to manage attributes.
 *
 *******************************************************************/


/* NewAttr
 * Gets memory for an AttrTyp
 */
extern PAttrTyp NewAttr();


/* DispAttr
 * Frees the memory used by the AttrTyp "p".
 */
extern void DispAttr( /* p */ );
/*  PAttrTyp  p;  */


/* PutA
 * Adds the attribute "a" to the cell "c".
 * If the attribute already exists, it produces a error.
 */
extern void PutA( /* c,a */ );
/* PCellTyp  c;
   PAttrTyp a; */


/* LookA
 * Returns the attribute of type "t" of the cell "c"
 * If it is not found then it returns NULL.
 */
extern PAttrTyp LookA( /* c,t */ );
/* PCellTyp  c;
   AttrTypeTyp t; */


/* GetA
 * Returns the attribute of type "t" of the cell "c"
 * and removes it from the cell.
 * If it is not found then it returns NULL.
 */
extern PAttrTyp GetA( /* c,t */ );
/* PCellTyp  c; 
   AttrTypeTyp t; */


/* FreeA
 * Frees the memory used by the attribute "a" if "a->cont" is 0.
 */
extern void FreeA( /* a */ );
/*  PAttrTyp a; */


/* CopyA
 * Returns a copy of the the attribute "a".
 * Note: the value stored in the attribute is copied.
 */
extern PAttrTyp CopyA( /* a */ );
/* PAttrTyp a; */


/* UnshareA
 * Unshares the attribute of type "t" of the cell "c".
 * Then the cont field of the attribute will be 1.
 */
extern void UnshareA( /* c,t */ );
/* PCellTyp  c;
   AttrTypeTyp t;  */


/* MakeA
 * Makes a new attribute of type "t" with the value "v" stored in it.
 */
extern PAttrTyp MakeA( /* v,t */ );
/* AttrValueTyp  v;
   AttrTypeTyp   t;  */


/* PutAInfo
 * Puts the value "v" into the attribute "a", which must not have a value.
 */
extern void PutAInfo( /* a,v */ );
/* PAttrTyp   a;
   AttrValueTyp  v; */


/* GetAInfo
 * Extracts the value stored in the attribute "a".
 * Then "a" will not have value  after applying this function.
 * Use PutAInfo to put another value in "a".
 */
extern AttrValueTyp GetAInfo( /* a */ );
/* PAttrTyp a; */


/* LookAInfo
 * Returns the value stored in the attribute "a", but it is not
 * extracted from the attribute. So, it must not be modified, i.e.
 * it must only be examined.
 */
extern AttrValueTyp LookAInfo( /* a */ );
/* PAttrTyp a; */


/* DecContA
 * Decrements the field "cont" of the attribute "a".
 */
#define DecContA(a)  {a->cont -= 1}


/* IncContA
 * Increments the field "cont" of the attribute "a".
 */
#define IncContA(a)  {a->cont += 1}


/* WriteA
 * Prints the attribute "a".
 * "pstr" is the function used to print strings.
 */
extern void WriteA( /* a,pstr */ );
/* PAttrTyp  a; 
   void      (*pstr)(); */


/* UnshareAS
 * Unshares all the attributes of the attribute list of the cell "c".
 */
extern void UnshareAS( /* c */ );
/* PCellTyp c; */


/* FreeAS
 * Frees the list of attributes of the cell "c".
 */
extern void FreeAS( /* c */ );
/* PCellTyp c; */


/* CopyAS
 * Copies the list of attributes of the cell "c1" into the cell "c2". 
 * The attribute values are not copied, they are shared by "c1" and "c2".
 */
extern void CopyAS( /* c1 , c2 */ );
/* PCellTyp c1,c2; */


/******************************************************************
 *
 *   Functions to manage trees.
 *
 *******************************************************************/


/* FreeTree
 * Deallocates the memory used by the cells and the attributes of 
 * the tree "t" if the "copy" field of the cell in the root of the 
 * tree is equal to 0, i.e. if this cell has not got any other father.
 */
extern void FreeTree( /* t */ );
/* PCellTyp t;  */    


/* FreeB1
 * Deallocates the memory used by the tree "t->b1" and sets "t->b1" 
 * to NULL.
 * If the tree "t->b1" has got any other father then the memory is 
 * not dealoocated.
 */
extern void FreeB1( /* t */ );
/* PCellTyp t;  */    


/* FreeB2
 * Deallocates the memory used by the tree "t->b2" and sets "t->b2" 
 * to NULL.
 * If the tree "t->b2" has got any other father then the memory is 
 * not dealoocated.
 */
extern void FreeB2( /* t */ );
/* PCellTyp t;  */    


/* GetTree
 * Returns a copy of the tree "t" where all the shared sub-tree has 
 * been unshered. Note that if the whole tree has not got any sub-tree 
 * shared, then nothing is done.
 * Only the cells are copied. The attributes are always shared.
 */
extern PCellTyp  GetTree( /* t */ );
/* PCellTyp t;  */    


/* CopyTree
 * Returns a unshared copy of the tree "t".
 * Only the cells are copied. The attributes are always shared.
 */
extern PCellTyp  CopyTree( /* t */ );
/* PCellTyp t;  */    


/* GlueCell
 * Copies the tree "t2" into the memory used by "t1".
 * This function is equal to moving all the pointer to "t1" to "t2"
 * and deleting "t1".
 */
extern void GlueCell( /* t1,t2 */ );
/*  PCellTyp  t1,t2;  */


/* UnshareAttrsOfTree
 * Unshare the attributes of the tree t until the end of the tree.
 * t must have been thoroughly unshared previously.
 */
extern void UnshareAttrsOfTree( /* t */ );
/*  PCellTyp  t;  */


/* DrawTree
 * Prints the tree "t" until a depth of cells.
 * "pstr" is the function used to print strings.
 */
extern void DrawTree(/* t, depth, pstr */);
/*     PCellTyp  t;
       int       depth;
       void      (*pstr)(); */

/* DrawLTree
 * Prints the tree "t" without the attributes in a list format. 
 * "pstr" is the function used to print strings.
 */
extern void DrawLTree( /* t, pstr */ );
/* PCellTyp  t;
   void      (*pstr)(); */


/* StatCell
 * Gives some statistics about the cell and attr used, etc...
 * uc: number of cell queries the system has granted this module with.
 * rc: number of cell releases.
 * mc: max number of cells hold on by this module till now.
 * ua: attrs queries.
 * ra: attrs releases.
 * ma: max number of attrs hold on by this module till now.
 */
extern void StatCell( /* uc, rc, mc, ua, ra, ma  */ );
/* int *uc, *rc, *mc, *ua, *ra, *ma; */

#endif

