ftp.nice.ch/pub/next/science/physics/gck.2.01.s.tar.gz#/gckc.2.0.1/gck_nodes.c

This is gck_nodes.c in view mode; [Download] [Up]

/* ******************************************************************** */
/* *                           GCK                                    * */
/* *               A Circuit Simulation Program                       * */
/* *                    by Tanju Cataltepe                            * */
/* *                    (c) Copyright 1989                            * */
/* ******************************************************************** */
/* (c) Copyright 1989, Tanju Cataltepe */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>			
#include <ctype.h>
#include <time.h>

#ifdef Macintosh
#include <console.h> 
#include <Files.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#endif

#include <math.h>
#include <float.h>
#include "gck.h"
#include "gck_vars.h"
#include "gck_protos.h"
#include "gck_errors.h"

long nodeRecordFromList(char *temp,unsigned char flag)

{
long counter;
long i;

/* reference */
  if (strcmp(temp,"GND") == 0)
    strcpy(temp,"0");

/* Find the record by string */
  for (counter = 0; counter < nodeNames.node_size; counter++) {
	if (strcmp(temp,nodeNames.node[counter].name) == 0)
	  break;
    }
  if (counter == nodeNames.node_size) {
    if (flag == REQUEST_NODE)
      errorReport(ERROR_NODE_REQUEST,temp,ERR_VOID,0);

    if ((flag == CREATE_NODE) && (nodeNames.node_size == nodeNames.max_nodes)) {
	  nodeNames.max_nodes += DYNAMIC_INCREMENTAL_SIZE;

      nodeNames.node = (nodeNameStruct *)
  	    realloc(nodeNames.node, sizeof(nodeNameStruct) * nodeNames.max_nodes);

	  if (nodeNames.node == NULL) 
	    errorReport(ERROR_REALLOC_NODE_MANAGER,0,ERR_VOID,0);
	    
	  for (i = nodeNames.node_size; i < nodeNames.max_nodes; i++)
        strcpy(nodeNames.node[i].name,"\0");
	  }
	/* add to list */
	strcpy(nodeNames.node[nodeNames.node_size++].name,temp);
    }
return(counter);

}



long nodeID(temp)
char *temp;
{
  long given_no;
  long i;
  long old_size;

  given_no = nodeRecordFromList(temp,CREATE_NODE);

  if (given_no >= ID_nindex_size) {
	old_size = ID_nindex_size;
    ID_nindex_size += DYNAMIC_INCREMENTAL_SIZE;
    ID_nindex = (long *)realloc(ID_nindex,(sizeof(long) * (ID_nindex_size + 1)));
	if (ID_nindex == NULL)
	  errorReport(ERROR_REALLOC_NODE_ID,0,ERR_VOID,0);
	  
	else {
	  for (i = old_size; i <= ID_nindex_size; i++)
	    ID_nindex[i] = 0;
      }
    }

  if (given_no != 0 && ID_nindex[given_no] == 0) {
    NoOfVars++;
    ID_nindex[given_no] = NoOfVars;
    }

  return (ID_nindex[given_no]);
}



void PushState()
{
  statusRec *presentState;
  long i;

  presentState = (statusRec *)c_malloc(sizeof(statusRec));
  presentState->next = baseOfStatus;
  baseOfStatus = presentState;

  baseOfStatus->NVar = NoOfVars;

  NoOfVars = 0;

  baseOfStatus->indexRecLength = ID_nindex_size;

  baseOfStatus->n_index = (long *)
  	c_malloc(sizeof(long) * (baseOfStatus->indexRecLength + 1));

  baseOfStatus->indexRecLength = ID_nindex_size;

  for (i = 0; i <= baseOfStatus->indexRecLength; i++) {
	baseOfStatus->n_index[i] = ID_nindex[i];
    ID_nindex[i] = 0;
    }

  baseOfStatus->base = baseOfBranch;
  baseOfBranch = NULL;
}


void PopState()
{
  statusRec *pastState;
  statusRec *tmpPtr;
  long i;
  
  if (baseOfStatus == NULL)
    return;

  NoOfVars = baseOfStatus->NVar;

  baseOfBranch = baseOfStatus->base;

  for (i = 0; i <= baseOfStatus->indexRecLength; i++) {
	ID_nindex[i] = baseOfStatus->n_index[i];
	}

  free(baseOfStatus->n_index);

  pastState = baseOfStatus;
  baseOfStatus = baseOfStatus->next;

  free(pastState);
}


void openSubckt(l)
char *l;
{
  /*.SUBCKT NAME N1 N2 ...*/
  subcktRec *tmpS;
  long i;
  aWord tmp;

  PushState();
  tmpS = (subcktRec *)c_malloc(sizeof(subcktRec));
  GetWORD(tmpS->name,2L);
  i = 3;
  tmpS->NConn = 0;
  GetWORD(tmp,i);
  while (tmp[0] != NULL_CHAR) {
    tmpS->NConn = nodeID(tmp);
    i++;
    GetWORD(tmp,i);
  }
  tmpS->next = baseOfSubckt;
  baseOfSubckt = tmpS;
}


void closeSubckt(l)
char *l;
{
  /*.ENDSUB NAME*/
  subcktRec *tmpS;
  aWord tmp;
  nameString SName;
  long i;

  GetWORD(SName,2L);
  GetSubcktByName(&tmpS, SName);
  tmpS->NVar = NoOfVars;
  tmpS->base = baseOfBranch;
  PopState();
}



void readSymbolDef()			/* from card */
{
/* .DEFINE SYMBOL VALUE */
/* .SYMBOL SYMBOL [=] VALUE */

/* Symbol is case insensitive, value must be absolute */

char symbol[WORD_LEN];
char value[WORD_LEN];
char *breakpos;

GetWORD(symbol,2L);
GetWORD(value,3L);

createSymbol(symbol,value);

}



double parseSymbol(b,index,word_position)
branchRec **b;
long index;							/* which indexed value within "b" */
long word_position;					/* which word to grab on card */
{
char symbol[WORD_LEN];
char value[WORD_LEN];

GetWORD(symbol,word_position);
GetWORD(value,word_position+1);	/* the '=' character is a valid delimiter */

/* make sure the manager knows about him */
createSymbol(symbol,value);

/* register the symbol with the guy that declared it! */
(*b)->value.sv[index].is_symbol = TRUE;
strcpy((*b)->value.sv[index].sName,symbol);

if (strlen(value) == 0)
  return(1.0);
else
  return(gck_atod(value));

}

/* same as parseSymbol above, yet works for models */
double parseSymbolModel(m,index,word_position)
modelRec **m;
long index;							/* which indexed value within "b" */
long word_position;					/* which word to grab on card */
{
char symbol[WORD_LEN];
char value[WORD_LEN];

GetWORD(symbol,word_position);
GetWORD(value,word_position+1);	/* the '=' character is a valid delimiter */

/* make sure the manager knows about him */
createSymbol(symbol,value);

/* register the symbol with the guy that declared it! */
(*m)->value.sv[index].is_symbol = TRUE;
strcpy((*m)->value.sv[index].sName,symbol);

if (strlen(value) == 0)
  return(1.0);
else
  return(gck_atod(value));

}

void expandSymbols(b)
branchRec **b;
{
long depth;
long i,j;
aWord holder;
aWord cn;
boolean flag;


depth = (*b)->depth;

if (depth > (MAX_SUBCKT_DEPTH - 1))
  errorReport(ERROR_SUBCKT_DEPTH,0,ERR_VOID,0);

strcpy(sd[depth],(*b)->cktname);
strcpy(sd[depth+1],"\0");

for (j = depth+1; j > 0; j--) {
  strcpy(holder,"\0");
  for (i = j; i <= (depth + 1); i++) {
    strcat(holder,sd[i]);
    if (i != (depth + 1))
      strcat(holder,".");
    }
  if ((*b)->element != subckt) {
    if (j == depth + 1)
      flag = TRUE;
    else
      flag = FALSE;
    switch ((*b)->element) {
      case adder:
        if ((*b)->value.sv[0].is_symbol) {
          strcpy(cn,holder);
          strcat(cn,(*b)->value.sv[0].sName);
          if ((flag == TRUE) || (doesSymbolExist(cn)))
            (*b)->value.UU.x[0] = getSymbolValueByName(cn);
          }
        if ((*b)->value.sv[1].is_symbol) {
          strcpy(cn,holder);
          strcat(cn,(*b)->value.sv[1].sName);
          if ((flag == TRUE) || (doesSymbolExist(cn)))
            (*b)->value.UU.x[1] = getSymbolValueByName(cn);
          }
        break;
      case resistor:
      case capacitor:
      case inductor:
      case vcvs:
      case vccs:
      case ccvs:
      case cccs:
        if ((*b)->value.sv[0].is_symbol) {
          strcpy(cn,holder);
          strcat(cn,(*b)->value.sv[0].sName);
          if ((flag == TRUE) || (doesSymbolExist(cn)))
            (*b)->value.UU.x[0] = getSymbolValueByName(cn);
          }
        break;
      case delay:
        if ((*b)->value.sv[0].is_symbol) {
          strcpy(cn,holder);
          strcat(cn,(*b)->value.sv[0].sName);
          if ((flag == TRUE) || (doesSymbolExist(cn))) {
            (*b)->value.sv[0].delay = (long) getSymbolValueByName(cn);
            }
          }
        break;
      case vs:
      case cs:
        /* this will be the wrong place to do the checking for each type...the type
        isn't assigned until the function setupSources() ... RdH March 17, 1992 */
        break;
      default:
        break;
      }
    }
  }
}



double getSymbolValueByName(char *symbol)
{
long counter;
long i;

if (symbol[0] == NULL_CHAR) 
  errorReport(ERROR_GET_SYMBOL_VALUE,0,ERR_VOID,0);  

/* find the symbol from within the list */
for (counter = 0; counter < symbolNames.symbol_size; counter++) {
  if (strcmp(symbol,symbolNames.symbol[counter].name) == 0)
    break;
  }

if (counter >= symbolNames.symbol_size)
  errorReport(ERROR_SYMBOL_UNRESOLVED,0,ERR_VOID,0);
  
if (symbolNames.symbol[counter].assigned == FALSE)
  errorReport(ERROR_SYMBOL_NOT_ASSIGNED,symbol,ERR_VOID,0);

return(symbolNames.symbol[counter].value);
  
}



boolean doesSymbolExist(char *symbol)
{
long counter;
long i;

if (symbol[0] == NULL_CHAR) 
  errorReport(ERROR_SYMBOL_CHECK,0,ERR_VOID,0);

/* find the symbol from within the list */
for (counter = 0; counter < symbolNames.symbol_size; counter++) {
  if (strcmp(symbol,symbolNames.symbol[counter].name) == 0)
    break;
  }

if (counter >= symbolNames.symbol_size)
  return(FALSE);
else
  return(TRUE);

}



void createSymbol(symbol,value)
char *symbol;
char *value;

{
long counter;
long i;

if (symbol[0] == NULL_CHAR)
  errorReport(ERROR_SYMBOL_CREATION_NULL,0,ERR_VOID,0);
  
for (counter = 0; counter < symbolNames.symbol_size; counter++) {
  if (strcmp(symbol,symbolNames.symbol[counter].name) == 0)
    break;
  }

if (counter < symbolNames.symbol_size) {
  if (strlen(value) != 0) {
    symbolNames.symbol[counter].value = gck_atod(value);
    symbolNames.symbol[counter].assigned = TRUE;
    }
  }
else {
  if (symbolNames.max_symbols <= (symbolNames.symbol_size + 1)) {
    symbolNames.max_symbols += DYNAMIC_INCREMENTAL_SIZE;
    symbolNames.symbol =
    	realloc(symbolNames.symbol,
    		sizeof(symbolNameStruct) * symbolNames.max_symbols);
    if (symbolNames.symbol == NULL)
	  errorReport(ERROR_REALLOC_SYMBOL,0,ERR_VOID,0);

    for (i = (counter - 1); i < symbolNames.max_symbols; i++) {
	  symbolNames.symbol[i].name[0] = NULL_CHAR;
	  symbolNames.symbol[i].value = 1.0;
      }
    }
  /* creating ... */ 
  strcpy(symbolNames.symbol[symbolNames.symbol_size].name,symbol);
  
  if (strlen(value) == 0) {			/* reference, not an assignment */
	symbolNames.symbol[symbolNames.symbol_size].value = 1.0; /* stub */
	symbolNames.symbol[symbolNames.symbol_size].assigned = FALSE;
    }
  else {
    symbolNames.symbol[symbolNames.symbol_size].value = gck_atod(value);
    symbolNames.symbol[symbolNames.symbol_size].assigned = TRUE;
    }
  symbolNames.symbol_size++;
  }

}


/* command line symbols stored in separate table until later. */
void createCommandSymbol(symbol,value)
char *symbol;
char *value;

{
long counter;
long i;

if (symbol[0] == NULL_CHAR)
  errorReport(ERROR_SYMBOL_CREATION_NULL,0,ERR_VOID,0);
  
for (counter = 0; counter < commandNames.symbol_size; counter++) {
  if (strcmp(symbol,commandNames.symbol[counter].name) == 0)
    break;
  }

if (counter < commandNames.symbol_size) {
  if (strlen(value) != 0) {
    commandNames.symbol[counter].value = gck_atod(value);
    commandNames.symbol[counter].assigned = TRUE;
    }
  }
else {
  if (commandNames.max_symbols <= (commandNames.symbol_size + 1)) {
    commandNames.max_symbols += DYNAMIC_INCREMENTAL_SIZE;
    commandNames.symbol =
    	realloc(commandNames.symbol,
    		sizeof(symbolNameStruct) * commandNames.max_symbols);
    if (commandNames.symbol == NULL)
	  errorReport(ERROR_REALLOC_SYMBOL,0,ERR_VOID,0);

    for (i = (counter - 1); i < commandNames.max_symbols; i++) {
	  commandNames.symbol[i].name[0] = NULL_CHAR;
	  commandNames.symbol[i].value = 1.0;
      }
    }
  /* creating ... */ 
  strcpy(commandNames.symbol[commandNames.symbol_size].name,symbol);
  
  if (strlen(value) == 0) {			/* reference, not an assignment */
	commandNames.symbol[commandNames.symbol_size].value = 1.0; /* stub */
	commandNames.symbol[commandNames.symbol_size].assigned = FALSE;
    }
  else {
    commandNames.symbol[commandNames.symbol_size].value = gck_atod(value);
    commandNames.symbol[commandNames.symbol_size].assigned = TRUE;
    }
  commandNames.symbol_size++;
  }

}




void MakeSymbolList(base, n) /* RdH March 12, 1992 */
flex *base;
long n;
{
long i;

  base->sv = c_malloc(sizeof(symbol_value) * n);
  for (i = 0; i < n; i++) {
    base->sv[i].is_symbol = FALSE;
    base->sv[i].sName[0] = NULL_CHAR;
    }

}



void dsymbol_base()
{
branchRec *b;

b = baseOfBranch;
while (b != NULL) {
  b->depth = 0;
  strcpy(b->cktname,"ROOT");
  b = b->next;
  }


}



void updateSymbols()
{
long counter;
aWord symbol;
aWord value;
long i;

for (counter = 0; counter < commandNames.symbol_size; counter++) {
  strcpy(symbol,commandNames.symbol[counter].name);
  sprintf(value,"%g",commandNames.symbol[counter].value);
  createSymbol(symbol,value);
  }

}	

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.