VIS

src/hrc/hrcMisc.c File Reference

#include "hrcInt.h"
Include dependency graph for hrcMisc.c:

Go to the source code of this file.

Functions

static void NodeObtainComponentModels (Hrc_Node_t *node, st_table *models)
Hrc_Node_t * Hrc_ManagerFindNodeByPathName (Hrc_Manager_t *manager, char *path, boolean pathFlag)
Var_Variable_t * Hrc_VariableFindActualFromFormal (Hrc_Node_t *node, Var_Variable_t *formalVar, Hrc_Node_t *referenceNode)
array_t * Hrc_ManagerObtainComponentModels (Hrc_Manager_t *manager)
char * Hrc_NodeFindHierarchicalName (Hrc_Node_t *node, boolean pathFlag)
boolean Hrc_TreeReplace (Hrc_Node_t *oldNode, Hrc_Node_t *newNode)
boolean Hrc_NodeTestIsInTree (Hrc_Node_t *node1, Hrc_Node_t *node2)
boolean Hrc_NodeTestIsUninterpreted (Hrc_Node_t *node)
boolean Hrc_ModelTestIsUninterpreted (Hrc_Model_t *model)
boolean Hrc_NodeTestRecursivelyIsUninterpreted (Hrc_Node_t *parent)
boolean Hrc_NodeTestIsUninterpretedNodeInHierarchy (Hrc_Manager_t *hmgr)
boolean Hrc_NodeCheckVariableConsistency (Hrc_Node_t *node)

Variables

static char rcsid[] UNUSED = "$Id: hrcMisc.c,v 1.4 2005/04/27 00:10:58 fabio Exp $"

Function Documentation

Hrc_Node_t* Hrc_ManagerFindNodeByPathName ( Hrc_Manager_t *  manager,
char *  path,
boolean  pathFlag 
)

AutomaticEnd Function********************************************************************

Synopsis [Returns pointer to the node corresponding to a path name.]

Description [The function returns a pointer to the node corresponding to a path name. If pathFlag is TRUE it is assumed that the name begins from the current node otherwise the name is assumed to begin from the root node. If the pathname is correct, the corresponding node is returned otherwise NULL is returned. Note that the pathname should start with instance name of the child of the current node or the root node as the case may be. The individual instance names are separated by ".".]

SideEffects []

SeeAlso []

Definition at line 97 of file hrcMisc.c.

{
  int position, count;
  int i = 0;
  Hrc_Node_t *presentNode;
  char *name;
  
  /* Check whether the pathname begins from the root node or the current node
     and initialize presentNode accordingly. */
  if(pathFlag == FALSE) {  
    /* Hierarchy will be traversed beginning from root node. */
    presentNode = manager->rootNode;
  }
  else {
    /* Hierarchy will be traversed beginning from current node. */
    presentNode = manager->currentNode;
  }

  position = i;
/* The name of a particular node in the pathname begins at position.
   position is updated every time presentNode is updated to a child from
   the parent. */
  
  count = 0;
  while(path[i] != '\0') {
    if(path[i] == '.') {
      name = ALLOC(char, count+1);
      strncpy(name, path+position, count);
      name[count] = '\0';
      if((presentNode = Hrc_NodeFindChildByName(presentNode, name)) ==
         NIL(Hrc_Node_t)) {
        FREE(name);
        return NIL(Hrc_Node_t);
      }
      position += count + 1;
      count = 0;
      FREE(name);
    }
    else {
      count++;
    }
    i++;
  }
  name = ALLOC(char, count+1);
  strncpy(name, path+position, count);
  name[count] = '\0';
  if((presentNode = Hrc_NodeFindChildByName(presentNode, name)) ==
     NIL(Hrc_Node_t)) {
    FREE(name);
    return NIL(Hrc_Node_t);
  }
  FREE(name);
  return presentNode;
}

Here is the call graph for this function:

Here is the caller graph for this function:

array_t* Hrc_ManagerObtainComponentModels ( Hrc_Manager_t *  manager)

Function********************************************************************

Synopsis [Returns an array of models being used in the hierarchy below the current node.]

SideEffects []

SeeAlso []

Definition at line 257 of file hrcMisc.c.

{
  st_generator *gen;
  char *modelName;
  char *dummy;
  Hrc_Model_t *model;
  st_table *modelTable = st_init_table(strcmp, st_strhash);
  array_t *modelArray = array_alloc(Hrc_Model_t *, 0);
  
  NodeObtainComponentModels(manager->currentNode, modelTable);
  st_foreach_item(modelTable, gen, &modelName, &dummy) {
    st_lookup(manager->modelTable, modelName, &model);
    array_insert_last(Hrc_Model_t *, modelArray, model);
  }
  st_free_table(modelTable);
  return modelArray;
}

Here is the call graph for this function:

Here is the caller graph for this function:

boolean Hrc_ModelTestIsUninterpreted ( Hrc_Model_t *  model)

Function********************************************************************

Synopsis [Checks if a model is uninterpreted.]

Description []

SideEffects []

SeeAlso [Hrc_NodeTestIsUninterpreted]

Definition at line 694 of file hrcMisc.c.

{
  Hrc_Node_t* node;

  node = Hrc_ModelReadMasterNode( model );

  if( st_count( Hrc_NodeReadLatchTable( node ) ) ||
      array_n(  Hrc_NodeReadNameTables( node ) ) ||
      st_count( Hrc_ModelReadSubcktTable( model ) ) ) return FALSE;
  
  return TRUE;
}

Here is the call graph for this function:

boolean Hrc_NodeCheckVariableConsistency ( Hrc_Node_t *  node)

Function********************************************************************

Synopsis [Returns 1 if all the variables of a given node are consistent. Otherwise 0 is returned.]

Description [Checks if all the variables in a given node are consistent in terms of labeling of six attributes (PI,PO,PS,NS,SI,SO) and the numFanoutTables field. Returns 1 if consistent. Otherwise 0 is returned. The function can be used for a sanity check after restructuring the hrc data structure.]

SideEffects [None]

SeeAlso []

Definition at line 784 of file hrcMisc.c.

{
  boolean success = TRUE;
  int i, j;
  st_generator *gen;
  Var_Variable_t *var;
  Hrc_Latch_t *latch;
  char *latchName, *varName;
  st_table *varToNumFanoutTables;
  Tbl_Table_t *table;
  long num;

  Hrc_NodeForEachFormalInput(node,i,var){
    if (Var_VariableTestIsPI(var) == 0){
      fprintf(vis_stderr, "Input variable %s is not labeled as PI.\n",
        Var_VariableReadName(var));
      success = FALSE;
    }
  }
  Hrc_NodeForEachFormalOutput(node,i,var){
    if (Var_VariableTestIsPO(var) == 0){
      fprintf(vis_stderr, "Output variable %s is not labeled as PO.\n",
        Var_VariableReadName(var));
      success = FALSE;
    }
  }
  /* if the node is not the root node, check consistency of actual variables */
  if (Hrc_NodeReadParentNode(node) != NIL(Hrc_Node_t)){
    Hrc_NodeForEachActualInput(node,i,var){
      if (Var_VariableTestIsSI(var) == 0){
        fprintf(vis_stderr, "Subcircuit input variable %s is not labeled as SI.\n",
          Var_VariableReadName(var));
        success = FALSE;
      }
    }
    Hrc_NodeForEachActualOutput(node,i,var){
      if (Var_VariableTestIsSO(var) == 0){
        fprintf(vis_stderr, "Subcircuit output variable %s is not labeled as SO.\n",
          Var_VariableReadName(var));
        success = FALSE;
      }
    }
  }

  Hrc_NodeForEachLatch(node,gen,latchName,latch){
    var = Hrc_LatchReadOutput(latch);
    if (Var_VariableTestIsPS(var) == 0){
      fprintf(vis_stderr, "Latch output variable %s is not labeled as PS.\n",
        Var_VariableReadName(var));
      success = FALSE;
    }
    var = Hrc_LatchReadInput(latch);
    if (Var_VariableTestIsNS(var) == 0){
      fprintf(vis_stderr, "Latch input variable %s is not labeled as NS.\n",
        Var_VariableReadName(var));
      success = FALSE;
    }
  }

  varToNumFanoutTables = st_init_table(st_ptrcmp,st_ptrhash);
  Hrc_NodeForEachVariable(node,gen,varName,var){
    if (Var_VariableTestTypeConsistency(var) == 0){
      success = FALSE;
    }
    (void)st_insert(varToNumFanoutTables, (char *)var, (char *)((long)0));
  }

  Hrc_NodeForEachNameTable(node,i,table){
    Tbl_TableForEachInputVar(table,j,var){
      (void)st_lookup(varToNumFanoutTables,var,&num);
      st_insert(varToNumFanoutTables,var,(char *) ++num);
    }  
  }

  Hrc_NodeForEachVariable(node,gen,varName,var){
    (void)st_lookup(varToNumFanoutTables,var,&num);
    if (num != (long)Var_VariableReadNumFanoutTables(var)){
      fprintf(vis_stderr,"numFanoutTables field of variable %s is inconsistent.  (True value = %d, Registered value = %d)\n", 
        Var_VariableReadName(var), (int)num, Var_VariableReadNumFanoutTables(var));
      success = FALSE;
    }
  }

  st_free_table(varToNumFanoutTables);
  return success;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* Hrc_NodeFindHierarchicalName ( Hrc_Node_t *  node,
boolean  pathFlag 
)

Function********************************************************************

Synopsis [Returns the hierarchical name of a node.]

Description [A pointer to a string containing the hierarchical name is returned. The user is responsible for freeing this string. If pathFlag is set to TRUE the name is found relative to the current node otherwise the name is found relative to the root node. The path name of root node relative to the root node and the current node relative to the current node is "". If there is any error NULL is returned. Note that for each level of hierarchy that is traversed there is an instance name and these are separated by ".".]

SideEffects []

SeeAlso [Hrc_ManagerFindNodeByPathName()]

Definition at line 296 of file hrcMisc.c.

{
  Hrc_Manager_t *manager = Hrc_NodeReadManager(node);
  Hrc_Node_t *currentNode, *rootNode, *tempNode;
  char *name;
  char *parentName;
  char *temp;

  rootNode = Hrc_ManagerReadRootNode(manager);
  currentNode = Hrc_ManagerReadCurrentNode(manager);
  
  if(pathFlag == FALSE) {
    if(node == rootNode) {
      name = util_strsav("");
    }
    else {
      tempNode = node;
      name = util_strsav(Hrc_NodeReadInstanceName(tempNode));
      while((tempNode = Hrc_NodeReadParentNode(tempNode)) != rootNode) {
        parentName = util_strsav(Hrc_NodeReadInstanceName(tempNode));
        temp = util_strcat3(parentName, ".", name);
        FREE(parentName);
        FREE(name);
        name = temp;      
      }
    }
  }
  else {
    if(node == currentNode) {
    name = util_strsav("");
    }
    else {
      tempNode = node;
      name = util_strsav(Hrc_NodeReadInstanceName(tempNode));
      if(tempNode == rootNode) {
        /* return NULL. In this case, the function is being asked to find the
           pathname of root node relative to the current node, when the
           current node is not the root node */
        FREE(name);
        return NIL(char);
      }
      while((tempNode = Hrc_NodeReadParentNode(tempNode)) != currentNode) {
        if(tempNode == rootNode) {
          FREE(name);
          return NIL(char);
        }
        parentName = util_strsav(Hrc_NodeReadInstanceName(tempNode));
        temp = util_strcat3(parentName, ".", name);
        FREE(parentName);
        FREE(name);
        name = temp;      
      }
    }
  }
  return name;
}

Here is the call graph for this function:

Here is the caller graph for this function:

boolean Hrc_NodeTestIsInTree ( Hrc_Node_t *  node1,
Hrc_Node_t *  node2 
)

Function********************************************************************

Synopsis [Checks whether node1 is part of the tree whose root is node2.]

Description [The function returns TRUE if node1 is part of the sub-tree whose root is node2. Otherwise, it returns FALSE.]

SideEffects []

SeeAlso [Hrc_TreeReplace()]

Definition at line 610 of file hrcMisc.c.

{
/* node1 is the node whose membership is to be tested */
/* node2 is the root of the tree which is to be searched */
  st_generator *gen;
  char *name;
  Hrc_Node_t *childNode;
  
  if(node1 == node2) {
    return TRUE;
  }
  else {
    Hrc_NodeForEachChild(node2, gen, name, childNode) {
      if(Hrc_NodeTestIsInTree(node1, childNode)) {
        return TRUE;
      }
    }
    return FALSE;
  }
}

Here is the caller graph for this function:

boolean Hrc_NodeTestIsUninterpreted ( Hrc_Node_t *  node)

Function********************************************************************

Synopsis [ Test whether a hnode is uninterpreted]

Description [ An uninterpreted node does not have tables, latches or children. This type of node is defined in BLIF-MV as follows:

syntax/example:

.subckt f1 t1 a <= x c => z b <= y

this represents an instance of the uninterpreted function z = f1( x, y ).

a <= b denotes formal variable a and actual variable b. Where a is a subckt input.

a => b denotes formal variable a and actual variable b. Where a is a subckt output.

All subckts, with the same model name, should have identical formal parameters.

Note: previous .subckt syntax is still be supported. There is no model definition for uninterpreted subckt. ]

SideEffects []

SeeAlso [Hrc_ModelTestIsUninterpreted]

Definition at line 669 of file hrcMisc.c.

{
  if( st_count( Hrc_NodeReadLatchTable( node ) ) ||
      array_n(  Hrc_NodeReadNameTables( node ) ) ||
      st_count( Hrc_NodeReadChildTable( node ) ) ) return FALSE;

  return TRUE;

}

Here is the call graph for this function:

Here is the caller graph for this function:

boolean Hrc_NodeTestIsUninterpretedNodeInHierarchy ( Hrc_Manager_t *  hmgr)

Function********************************************************************

Synopsis [ Checks for an uninterpreted node in hierarchy.]

Description [ Determines if there is a node in the hierarchy that is uninterpreted.]

SideEffects []

SeeAlso []

Definition at line 757 of file hrcMisc.c.

Here is the call graph for this function:

boolean Hrc_NodeTestRecursivelyIsUninterpreted ( Hrc_Node_t *  parent)

Function********************************************************************

Synopsis [ Checks for the existence of an uninterpreted node in the hierarchy below the parent.]

Description [ Determines if there is a child hnode below the parent is uninterpreted.]

SideEffects []

SeeAlso []

Definition at line 724 of file hrcMisc.c.

{
  st_generator* gen;
  char*         childName;
  Hrc_Node_t*   child;
  
  if( Hrc_NodeTestIsUninterpreted( parent )) return TRUE;
  
  Hrc_NodeForEachChild( parent, gen, childName, child) {

    if( Hrc_NodeTestRecursivelyIsUninterpreted( child ) ) return TRUE;

  }

  return FALSE;

}

Here is the call graph for this function:

Here is the caller graph for this function:

boolean Hrc_TreeReplace ( Hrc_Node_t *  oldNode,
Hrc_Node_t *  newNode 
)

Function********************************************************************

Synopsis [Returns pointer to a hash table from global path name of a formal variable to actual variable]

Description [The hash table returned is from the global path name of a formal variable to the global path name of its corresponding actual variable. While traversing up the hierarchy, the function will not go beyond rootNode.]

SideEffects [None]

SeeAlso [optional]Function********************************************************************

Synopsis [Replaces a sub-tree in the hierarchy with a another tree.]

Description [The function replaces a sub-tree in the hierarchy whose root is oldNode by another tree whose root node is specified by newNode. It is illegal for newNode to be NULL. If oldNode is NULL, the tree hanging from newNode is freed recursively and TRUE is returned. Otherwise, it is checked whether newNode is a part of the existing hierarchy. If it is, FALSE is returned and nothing is done. If it is not, oldNode is replaced by newNode in the hierarchy and TRUE is returned. To effect the replacement, the applInfoTable of newNode is freed and a copy of applInfoTable of oldNode is stored in its place. Then changeFn is called for each entry in the table. The hierarchy is traversed towards the root node starting from the parent of oldNode. At each step, a new model is created and registered with the hierarchy manager. The new model names are obtained by appending a '~' to the name of the model which was modified. Finally, oldNode is freed recursively.]

SideEffects [The hierarchy tree is modified and new models are added.]

SeeAlso []

Definition at line 405 of file hrcMisc.c.

{
  Hrc_Node_t *tempNode, *presentNode;
  char *newName, *instanceName;
  char *newInstanceName;
  int i, num, index;
  Hrc_Model_t *prevOldModel, *prevNewModel;
  Hrc_Model_t *oldModel, *newModel;
  Hrc_Model_t *calleeModel;
  Hrc_Subckt_t *subckt;
  st_table *varToDupVar;
  Tbl_Table_t *table, *dupTable;
  Var_Variable_t *var, *dupVar;
  char *name, *dupName;
  st_generator *gen;
  Hrc_Latch_t *latch, *dupLatch;
  array_t *newActualInputVars, *newActualOutputVars;
  char *key;
  ApplInfo_t *applInfo;
  
  /* It is illegal to pass NULL as newNode. */
  assert(newNode != NIL(Hrc_Node_t));
  
  if(oldNode == NIL(Hrc_Node_t)) {
    HrcNodeFreeRecursively(newNode);
    return TRUE;
  }
  
  if(Hrc_NodeTestIsInTree(newNode, oldNode->manager->rootNode)) {
    return FALSE;
  }

  /* free applInfo strutures all the way to the root since
     flattened networks get invalidated with this tree-replace. */
  presentNode = oldNode;
  while(presentNode != NIL(Hrc_Node_t)) {
    st_foreach_item(presentNode->applInfoTable, gen, &key, &applInfo) {
      (*applInfo->freeFn)(applInfo->data);
      FREE(key);
      FREE(applInfo);
    }
    st_free_table(presentNode->applInfoTable);
    presentNode->applInfoTable = st_init_table(strcmp, st_strhash);
    presentNode = Hrc_NodeReadParentNode(presentNode);
  }

  /* If oldNode is the root node of the hierarchy, simply set the root node
     and current node of the hierarchy to newNode. */

  if(oldNode->parentNode == NIL(Hrc_Node_t)) {
    Hrc_ManagerSetRootNode(oldNode->manager, newNode);
    Hrc_ManagerSetCurrentNode(oldNode->manager, newNode);
  }
  else {
    /* First, remove the connection between oldNode and its parent and
       establish connection between newNode and oldNode's parent. */
    tempNode = HrcNodeDeleteChild(oldNode->parentNode, oldNode->instanceName);
    assert(oldNode == tempNode);
    FREE(newNode->instanceName);
    newNode->instanceName = util_strsav(oldNode->instanceName);
    newNode->parentNode = oldNode->parentNode;
    st_insert(newNode->parentNode->childTable, newNode->instanceName,
              (char *) newNode);
    newNode->actualInputs = array_dup(oldNode->actualInputs);
    newNode->actualOutputs = array_dup(oldNode->actualOutputs);

    /* Starting from the parent of oldNode (now the parent of newNode), go
       up the hierarchy and at each node generate a new model by modifying
       the model corresponding to the node appropriately. The new model name
       is obtained from the old one by appending a '~' to it. The model names
       in the nodes traversed have to be modified.
       
       The three variables newInstanceName, prevOldModel and prevNewModel
       keep information needed to generate new models by modifying already
       existing ones. */
    newInstanceName = newNode->instanceName;
    presentNode = newNode->parentNode;
    st_lookup(presentNode->manager->modelTable, oldNode->modelName,
              &prevOldModel);
    st_lookup(presentNode->manager->modelTable, newNode->modelName,
              &prevNewModel);
    while(presentNode != NIL(Hrc_Node_t)) {
      oldModel = Hrc_ManagerFindModelByName(presentNode->manager,
                                            presentNode->modelName);
      newName = ALLOC(char, strlen(presentNode->modelName) + 2);
      strcpy(newName, presentNode->modelName);
      strcat(newName, "~");
      FREE(presentNode->modelName);
      presentNode->modelName = newName;

      /* Allocate a new model and fill up its fields by copying and
         modifying appropriately the fields from the old model */
      newModel = Hrc_ModelAlloc(presentNode->manager, presentNode->modelName);

      /* Fill in the entries of the master node of newModel. I couldn't
         use Hrc_NodeDup() to duplicate the master node of the oldModel here
         because that function does some other things too. All the variables
         of the masterNode of oldModel are duplicated. Note that masterNode
         and the nodes in the hierarchy corresponding to the model do not
         share variables. */

      varToDupVar = st_init_table(st_ptrcmp, st_ptrhash);
      Hrc_NodeForEachVariable(oldModel->masterNode, gen, name, var) {
        dupVar = Var_VariableDup(var, newModel->masterNode);
        dupName = Var_VariableReadName(dupVar);
        st_insert(newModel->masterNode->varTable, dupName, dupVar);
        st_insert(varToDupVar, var, dupVar);
      }
      Hrc_NodeForEachFormalInput(oldModel->masterNode, i, var) {
        st_lookup(varToDupVar, var, &dupVar);
        array_insert_last(Var_Variable_t *,
                          newModel->masterNode->formalInputs, dupVar);
      }
      Hrc_NodeForEachFormalOutput(oldModel->masterNode, i, var) {
        st_lookup(varToDupVar, var, &dupVar);
        array_insert_last(Var_Variable_t *,
                          newModel->masterNode->formalOutputs, dupVar);
      }
      Hrc_NodeForEachNameTable(oldModel->masterNode, i, table) {
        dupTable = Tbl_TableSoftDup(table);
        Tbl_TableForEachInputVar(dupTable, index, var) {
          st_lookup(varToDupVar, var, &dupVar);
          Tbl_TableSubstituteVar(dupTable, var, dupVar);
        }
        Tbl_TableForEachOutputVar(dupTable, index, var) {
          st_lookup(varToDupVar, var, &dupVar);
          Tbl_TableSubstituteVar(dupTable, var, dupVar);
        }
        array_insert_last(Tbl_Table_t *, newModel->masterNode->nameTables,
                          dupTable);
      }
      Hrc_NodeForEachLatch(oldModel->masterNode, gen, name, latch) {
        dupLatch = ALLOC(Hrc_Latch_t, 1);
        st_lookup(varToDupVar, latch->latchInput, &(dupLatch->latchInput));
        st_lookup(varToDupVar, latch->latchOutput, &(dupLatch->latchOutput));
        dupLatch->resetTable = Tbl_TableSoftDup(latch->resetTable);
        Tbl_TableForEachInputVar(dupLatch->resetTable, index, var) {
          st_lookup(varToDupVar, var, &dupVar);
          Tbl_TableSubstituteVar(dupLatch->resetTable, var, dupVar);
        }
        Tbl_TableForEachOutputVar(dupLatch->resetTable, index, var) {
          st_lookup(varToDupVar, var, &dupVar);
          Tbl_TableSubstituteVar(dupLatch->resetTable, var, dupVar);
        }
        dupLatch->undef = latch->undef;
        st_insert(newModel->masterNode->latchTable, Var_VariableReadName(dupLatch->latchOutput), dupLatch);
      }

      /* For each subckt entry in oldModel, add a corresponding entry to
         newModel except for the entry corresponding to the modified child
         of presentNode. This particular subckt is recognized by its
         instanceName. */
      Hrc_ModelForEachSubckt(oldModel, gen, name, subckt) {
        if(!strcmp(subckt->instanceName, newInstanceName)) {
          calleeModel = prevNewModel;
        }
        else {
          calleeModel = subckt->model;
        }
        instanceName = subckt->instanceName;
        newActualInputVars = array_alloc(Var_Variable_t *, 0);
        num = array_n(subckt->actualInputVars);
        for(i =0; i < num; ++i) {
          var = array_fetch(Var_Variable_t *, subckt->actualInputVars, i);
          st_lookup(varToDupVar, var, &dupVar);
          array_insert_last(Var_Variable_t *, newActualInputVars, dupVar);
        }
        newActualOutputVars = array_alloc(Var_Variable_t *, 0);
        num = array_n(subckt->actualOutputVars);
        for(i =0; i < num; ++i) {
          var = array_fetch(Var_Variable_t *, subckt->actualOutputVars, i);
          st_lookup(varToDupVar, var, &dupVar);
          array_insert_last(Var_Variable_t *, newActualOutputVars, dupVar);
        }
        Hrc_ModelAddSubckt(newModel, calleeModel, instanceName,
                           newActualInputVars, newActualOutputVars);
      }
      
      st_free_table(varToDupVar);
      
      newInstanceName = presentNode->instanceName;
      /* Right now, I am not modifying the instance names. */
      prevOldModel = oldModel;
      prevNewModel = newModel;
      presentNode = presentNode->parentNode;
    }
  }
  HrcNodeFreeRecursively(oldNode);
  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Var_Variable_t* Hrc_VariableFindActualFromFormal ( Hrc_Node_t *  node,
Var_Variable_t *  formalVar,
Hrc_Node_t *  referenceNode 
)

Function********************************************************************

Synopsis [Returns pointer to the actual variable corresponding to a formal variable of a node.]

Description [The function tracks a formal variable up in the hierarchy until that variable becomes an internal variable of a node. While traversing the hierarchy upwards it does not go beyond the specified reference node. If node is identical to reference node, formalVar is returned. If any error occurs a NULL pointer is returned]

SideEffects []

SeeAlso []

Definition at line 173 of file hrcMisc.c.

{
  int position = -1;
  int i;
  Var_Variable_t *var;
  Hrc_Node_t *presentNode;
  Var_Variable_t *presentVar;
  char *varName;
  
  if(node == referenceNode) {
    return formalVar;
  }
  else {
    presentNode = node;
    presentVar = formalVar;
  }
  
  /* A variable at position i in formalInputs corresponds to a varible at
     position i in actualInputs. The variables in actualInputs in a node
     are actually formal variables (could be I/O or internal) of the parent
     of the node. Given a formal variable and a node, search for the
     variable in formalInputs and formalOutputs. If it is not present in
     either then check if it is an internal variable of the node. If it is
     present, get the corresponding variable from actualInputs or
     actualOutputs as the case may be. Update presentVar to this variable
     and presentNode to the parent of the node. Repeat the process until
     presentVar is an internal variable of presentNode or presentNode
     becomes the same as referenceNode. */

  while(presentNode != referenceNode) {
    Hrc_NodeForEachFormalInput(presentNode, i, var) {
      if(var == presentVar) {
        position = i;
      }
    }
    if(position != -1) {
      presentVar = array_fetch(Var_Variable_t *,
                               presentNode->actualInputs, position);
    }
    else {
      Hrc_NodeForEachFormalOutput(presentNode, i, var) {
        if(var == presentVar) {
          position = i;
        }
      }
      if(position != -1) {
        presentVar = array_fetch(Var_Variable_t *,
                                 presentNode->actualOutputs, position);
      }
      else {
        varName = Var_VariableReadName(presentVar);
        if(st_is_member(presentNode->varTable, varName)) {
          return presentVar;
        }
        else {
          return NIL(Var_Variable_t);
        }
      }
    }
    presentNode = presentNode->parentNode;
/* The following check is just to make sure that the function does not try
   to access the parent of the root node. */
    if(presentNode == NIL(Hrc_Node_t )) {
      return NIL(Var_Variable_t);
    }
    position = -1;
  }
  return presentVar;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void NodeObtainComponentModels ( Hrc_Node_t *  node,
st_table *  models 
) [static]

AutomaticStart

Function********************************************************************

Synopsis [A recursive function which inserts the names of all models used in the construction of a node into the hash table models.]

SideEffects []

SeeAlso [Hrc_ManagerObtainComponentModels()]

Definition at line 892 of file hrcMisc.c.

{
    char *name;
    Hrc_Node_t *child;
    st_generator *gen;
    
    st_insert(models, node->modelName, (char *) 0);
    Hrc_NodeForEachChild(node, gen, name, child){
        NodeObtainComponentModels(child, models);
    }
}

Here is the caller graph for this function:


Variable Documentation

char rcsid [] UNUSED = "$Id: hrcMisc.c,v 1.4 2005/04/27 00:10:58 fabio Exp $" [static]

CFile***********************************************************************

FileName [hrcMisc.c]

PackageName [hrc]

Synopsis [This file provides some miscellaneous functions.]

SeeAlso []

Author [Shaz Qadeer]

Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of California. All rights reserved.

Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software.

IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]

Definition at line 36 of file hrcMisc.c.