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.