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.