Bill Swartz patch

This commit is contained in:
dwarning 2010-03-25 22:44:37 +00:00
parent 625b3d14fc
commit 112261297d
16 changed files with 700 additions and 597 deletions

View File

@ -1,3 +1,9 @@
2010-03-25 Dietmar Warning
* Bill Swartz patch:
* numparam/*.c, *.h, *.txt, misc/hash.c, string.c: local and global hash lists for subckts
* misc/dstring.c, include/dstring.h, Makefile.am: dynamic string feature
* analysis/cktop.c: remove the CR in some printf's
2010-03-20 Holger Vogt
* variable.c:450 prevent ngspice from crashing after command 'unset zzz',
when zzz is not defined

View File

@ -1,4 +1,4 @@
@set UPDATED 25 November 2008
@set UPDATED-MONTH November 2008
@set EDITION 18
@set VERSION 18
@set EDITION 20
@set VERSION 20

View File

@ -5,43 +5,12 @@
#include <stdlib.h>
the function code is in 'mystring.c' .
*/
#include "dstring.h"
#define Use(x) x=0;x=x
#define Uses(s) s=s
#define Usep(x) x=x
/* -----------------------------------------------------------------
* This structure is modified from Tcl. We do this to avoid a
* conflict and later add a conditional compile to just use the Tcl
* code if desired.
----------------------------------------------------------------- */
#define SPICE_DSTRING_STATIC_SIZE 200
typedef struct spice_dstring {
char *string ; /* Points to beginning of string: either
* staticSpace below or a malloced array. */
int length ; /* Number of non-NULL characters in the
* string. */
int spaceAvl ; /* Total number of bytes available for the
* string and its terminating NULL char. */
char staticSpace[SPICE_DSTRING_STATIC_SIZE] ;
/* Space to use in common case where string
* is small. */
} SPICE_DSTRING, *SPICE_DSTRINGPTR ;
/* -----------------------------------------------------------------
* spice_dstring_xxxx routines. Used to manipulate dynamic strings.
----------------------------------------------------------------- */
extern void spice_dstring_init(SPICE_DSTRINGPTR dsPtr) ;
extern char *spice_dstring_append(SPICE_DSTRINGPTR dsPtr,char *string,int length) ;
extern char *spice_dstring_print(SPICE_DSTRINGPTR dsPtr,char *format, ... ) ;
extern char *spice_dstring_setlength(SPICE_DSTRINGPTR dsPtr,int length) ;
extern char *_spice_dstring_setlength(SPICE_DSTRINGPTR dsPtr,int length) ;
extern void spice_dstring_free(SPICE_DSTRINGPTR dsPtr) ;
#define spice_dstring_reinit(x_xz) spice_dstring_setlength(x_xz,0) ;
#define spice_dstring_value(x_xz) ((x_xz)->string)
#define spice_dstring_space(x_xz) ((x_xz)->spaceAvl)
#define spice_dstring_length(x_xz) ((x_xz)->length)
typedef enum {Esc=27} _nEsc;
typedef enum {Tab=9} _nTab;
typedef enum {Bs=8} _nBs;

View File

@ -1119,328 +1119,3 @@ intp (double x) /* integral part */
}
#endif
/* -----------------------------------------------------------------
* Dynamic string utilities.
* ----------------------------------------------------------------- */
/*
*----------------------------------------------------------------------
*
* spice_dstring_init --
*
* Initializes a dynamic string, discarding any previous contents
* of the string (spice_dstring_free should have been called already
* if the dynamic string was previously in use).
*
* Results:
* None.
*
* Side effects:
* The dynamic string is initialized to be empty.
*
*----------------------------------------------------------------------
*/
void spice_dstring_init(SPICE_DSTRINGPTR dsPtr)
{
dsPtr->string = dsPtr->staticSpace ;
dsPtr->length = 0 ;
dsPtr->spaceAvl = SPICE_DSTRING_STATIC_SIZE ;
dsPtr->staticSpace[0] = EOS;
} /* end spice_dstring_init() */
/*
*----------------------------------------------------------------------
*
* spice_dstring_append --
*
* Append more characters to the current value of a dynamic string.
*
* Results:
* The return value is a pointer to the dynamic string's new value.
*
* Side effects:
* Length bytes from string (or all of string if length is less
* than zero) are added to the current value of the string. Memory
* gets reallocated if needed to accomodate the string's new size.
*
* Notes: char *string; String to append. If length is -1 then
* this must be null-terminated.
* INT length; Number of characters from string to append.
* If < 0, then append all of string, up to null at end.
*
*----------------------------------------------------------------------
*/
char *spice_dstring_append(SPICE_DSTRINGPTR dsPtr,char *string,int length)
{
int newSize ; /* needed size */
char *newString ; /* newly allocated string buffer */
char *dst ; /* destination */
char *end ; /* end of string */
if( length < 0){
length = strlen(string) ;
}
newSize = length + dsPtr->length ;
/* -----------------------------------------------------------------
* Allocate a larger buffer for the string if the current one isn't
* large enough. Allocate extra space in the new buffer so that there
* will be room to grow before we have to allocate again.
----------------------------------------------------------------- */
if (newSize >= dsPtr->spaceAvl) {
dsPtr->spaceAvl = 2 * newSize ;
newString = new( dsPtr->spaceAvl * sizeof(char) ) ;
memcpy((void *) newString, (void *) dsPtr->string, (size_t) dsPtr->length) ;
if (dsPtr->string != dsPtr->staticSpace) {
dispose(dsPtr->string) ;
}
dsPtr->string = newString;
}
/* -----------------------------------------------------------------
* Copy the new string into the buffer at the end of the old
* one.
----------------------------------------------------------------- */
for( dst = dsPtr->string + dsPtr->length, end = string+length;
string < end; string++, dst++) {
*dst = *string ;
}
*dst = EOS ;
dsPtr->length += length ;
return(dsPtr->string) ;
} /* end spice_dstring_append() */
static int spice_format_length( va_list args, char *fmt )
{
int i ; /* integer */
int len ; /* length of format */
int size_format ; /* width of field */
int found_special ; /* look for special characters */
char *s ; /* string */
char c ; /* character */
/* -----------------------------------------------------------------
* First find length of buffer.
----------------------------------------------------------------- */
len = 0 ;
while(fmt && *fmt){
if( *fmt == '%' ){
fmt++ ;
if( *fmt == '%' ){
len++ ;
} else {
/* -----------------------------------------------------------------
* We have a real formatting character, loop until we get a special
* character.
----------------------------------------------------------------- */
if( *fmt == '.' || *fmt == '-' ){
fmt++ ; /* skip over these characters */
}
size_format = atoi(fmt) ;
if( size_format > 0 ){
len += size_format ;
}
found_special = FALSE ;
for( ; fmt && *fmt ; fmt++ ){
switch( *fmt ){
case 's':
s = va_arg(args, char *) ;
if( s ){
len += strlen(s) ;
}
found_special = TRUE ;
break ;
case 'i':
case 'd':
case 'o':
case 'x':
case 'X':
case 'u':
i = va_arg(args, int) ;
len += 10 ;
found_special = TRUE ;
break ;
case 'c':
c = va_arg(args, int) ;
len++ ;
found_special = TRUE ;
break ;
case 'f':
case 'e':
case 'F':
case 'g':
case 'G':
c = va_arg(args, double) ;
len += 35 ;
found_special = TRUE ;
break ;
default:
;
} /* end switch() */
if( found_special ){
break ;
}
}
}
} else {
len++ ;
}
fmt++ ;
} /* end while() */
va_end(args) ;
return(len) ;
} /* end Ymessage_format_length() */
char *spice_dstring_print( SPICE_DSTRINGPTR dsPtr,char *format, ... )
{
va_list args ;
int format_len ; /* length of format */
int length ; /* new length */
int orig_length ; /* original length of buffer */
char *buffer ; /* proper length of buffer */
/* -----------------------------------------------------------------
* First get the length of the buffer needed.
----------------------------------------------------------------- */
va_start( args, format ) ;
format_len = spice_format_length(args,format) ;
/* -----------------------------------------------------------------
* Next allocate the proper buffer size.
----------------------------------------------------------------- */
orig_length = dsPtr->length ;
length = orig_length + format_len + 1 ;
buffer = spice_dstring_setlength( dsPtr, length) ;
/* -----------------------------------------------------------------
* Convert the format.
----------------------------------------------------------------- */
va_start( args, format ) ;
if( format ){
vsprintf( buffer + orig_length, format, args ) ;
dsPtr->length = strlen( buffer ) ;
} else {
buffer = NULL ;
}
va_end(args) ;
return( buffer ) ;
} /* end spice_dstring_print() */
/*
*----------------------------------------------------------------------
*
* _spice_dstring_setlength --
*
* Change the length of a dynamic string. This can cause the
* string to either grow or shrink, depending on the value of
* length.
*
* Results:
* Returns the current string buffer.
*
* Side effects:
* The length of dsPtr is changed to length but a null byte is not
* stored at that position in the string. Use spice_dstring_setlength
* for that function. If length is larger
* than the space allocated for dsPtr, then a panic occurs.
*
*----------------------------------------------------------------------
*/
char *_spice_dstring_setlength(SPICE_DSTRINGPTR dsPtr,int length)
{
char *newString ;
if (length < 0) {
length = 0 ;
}
if (length >= dsPtr->spaceAvl) {
dsPtr->spaceAvl = length+1;
newString = new( dsPtr->spaceAvl * sizeof(char) ) ;
/* -----------------------------------------------------------------
* SPECIAL NOTE: must use memcpy, not strcpy, to copy the string
* to a larger buffer, since there may be embedded NULLs in the
* string in some cases.
----------------------------------------------------------------- */
memcpy((void *) newString, (void *) dsPtr->string, (size_t) dsPtr->length) ;
if( dsPtr->string != dsPtr->staticSpace ) {
dispose(dsPtr->string) ;
}
dsPtr->string = newString ;
}
dsPtr->length = length ;
return(dsPtr->string) ;
} /* end _spice_dstring_setlength() */
/*
*----------------------------------------------------------------------
*
* spice_dstring_setlength --
*
* Change the length of a dynamic string. This can cause the
* string to either grow or shrink, depending on the value of
* length.
*
* Results:
* Returns the current string buffer.
*
* Side effects:
* The length of dsPtr is changed to length and a null byte is
* stored at that position in the string. If length is larger
* than the space allocated for dsPtr, then a panic occurs.
*
*----------------------------------------------------------------------
*/
char *spice_dstring_setlength(SPICE_DSTRINGPTR dsPtr,int length)
{
char *str_p ; /* newly create string */
str_p = _spice_dstring_setlength( dsPtr,length) ;
str_p[length] = EOS ;
return( str_p ) ;
} /* end spice_dstring_setlength() */
/*
*----------------------------------------------------------------------
*
* spice_dstring_free --
*
* Frees up any memory allocated for the dynamic string and
* reinitializes the string to an empty state.
*
* Results:
* None.
*
* Side effects:
* The previous contents of the dynamic string are lost, and
* the new value is an empty string.
*
*----------------------------------------------------------------------
*/
void spice_dstring_free(SPICE_DSTRINGPTR dsPtr)
{
if (dsPtr->string != dsPtr->staticSpace) {
dispose(dsPtr->string) ;
}
dsPtr->string = dsPtr->staticSpace ;
dsPtr->length = 0 ;
dsPtr->spaceAvl = SPICE_DSTRING_STATIC_SIZE;
dsPtr->staticSpace[0] = EOS ;
} /* end spice_dstring_free() */

View File

@ -60,15 +60,14 @@ typedef struct _ttdico {
int srcline;
int oldline;
int errcount;
int num_symbols ; /* number of symbols in entry array */
entry **symbol_array ; /* symbol entries in array format for stack ops */
NGHASHPTR symbol_table ; /* hash table of symbols for quick lookup */
int nbd; /* number of data entries */
int symbol_stack_alloc ; /* stack allocation */
int stack_depth ; /* current depth of the symbol stack */
NGHASHPTR global_symbols ; /* hash table of globally defined symbols for quick lookup */
NGHASHPTR *local_symbols ; /* stack of locally defined symbols */
NGHASHPTR inst_symbols ; /* instance qualified symbols - after a pop */
char **inst_name ; /* name of subcircuit */
fumas fms[101];
int nfms; /* number of functions & macros */
int stack[20];
char *inst_name[20];
int tos; /* top of stack index for symbol mark/release mechanics */
auxtable nodetab;
// char * refptr[Maxline]; /* pointers to source code lines */
char **dynrefptr;
@ -79,6 +78,7 @@ typedef struct _ttdico {
void initdico(tdico * dico);
int donedico(tdico * dico);
void dico_free_entry( entry *entry_p ) ;
unsigned char defsubckt( tdico *dico, char * s, int w, char categ);
int findsubckt( tdico *dico, char * s, SPICE_DSTRINGPTR subname);
unsigned char nupa_substitute( tdico *dico, char * s, char * r, unsigned char err);
@ -87,4 +87,4 @@ unsigned char nupa_subcktcall( tdico *dico, char * s, char * x, unsigned char er
void nupa_subcktexit( tdico *dico);
tdico * nupa_fetchinstance(void);
char getidtype( tdico *d, char * s);
entry *attrib( tdico *dico, char * t, char op );
entry *attrib( tdico *d, NGHASHPTR htable, char * t, char op );

View File

@ -295,7 +295,7 @@ In the syntax description,
symbols and any .param assignments are considered local: they mask any
global identical names, until the .ends line is encountered.
You cannot reassign to a global number inside a .subckt, a local copy is
created instead. Scope nesting works up to a level of 10. For example,
created instead. Scope nesting now works up to any level. For example,
if the main circuit calls A which has a formal parameter xx, A calls B
which has a param. xx, and B calls C which also has a formal param. xx,
there will be three versions of 'xx' in the symbol table but only the most

View File

@ -32,7 +32,6 @@ Todo:
extern void txfree (void *ptr);
char *nupa_inst_name;
static tdico *inst_dicoS ;
/* number of parameter substitutions, available only after the substitution */
extern long dynsubst; /* spicenum.c:144 */
@ -166,7 +165,7 @@ findsubname (tdico * dico, SPICE_DSTRINGPTR dstr_p)
SPICE_DSTRING name ; /* extract a name */
char *s ; /* current dstring */
int h, j, k, nest, ls;
unsigned char found;
int found ;
h = 0;
ls = spice_dstring_length (dstr_p) ;
@ -310,7 +309,7 @@ transform (tdico * dico, SPICE_DSTRINGPTR dstr_p, unsigned char nostripping,
* 'B' netlist (or .model ?) line that had Braces killed
*/
{
int i, k, a, n;
int k, a, n;
char *s ; /* dstring value of dstr_p */
char *t ; /* dstring value of tstr */
char category;
@ -367,7 +366,7 @@ transform (tdico * dico, SPICE_DSTRINGPTR dstr_p, unsigned char nostripping,
}
else if (upcase (s[0]) == 'X')
{ /* strip actual parameters */
i = findsubname (dico, dstr_p) ; /* i= index following last identifier in s */
findsubname (dico, dstr_p) ;/* i= index following last identifier in s */
category = 'X';
}
else if (s[0] == '+') /* continuation line */
@ -454,9 +453,7 @@ nupa_init (char *srcfile)
incontrolS = 0;
placeholder = 0;
dicoS = (tdico *)new(sizeof(tdico));
inst_dicoS = (tdico *)new(sizeof(tdico));
initdico (dicoS);
initdico (inst_dicoS);
dicoS->dynrefptr = (char**)tmalloc((dynmaxline + 1)*sizeof(char*));
dicoS->dyncategory = (char*)tmalloc((dynmaxline + 1)*sizeof(char));
@ -545,21 +542,19 @@ nupa_scan (char *s, int linenum, int is_subckt)
}
/* -----------------------------------------------------------------
* Dump the contents of the symbol table.
* Dump the contents of a symbol table.
* ----------------------------------------------------------------- */
void
nupa_list_params (FILE * cp_out)
static void
dump_symbol_table( tdico *dico_p, NGHASHPTR htable_p, FILE * cp_out)
{
char *name; /* current symbol */
entry *entry_p ; /* current entry */
tdico *dico_p ; /* local copy for speed */
NGHASHITER iter ; /* hash iterator - thread safe */
dico_p = dicoS ;
fprintf (cp_out, "\n\n");
for (entry_p = nghash_enumerateRE(dico_p->symbol_table,NGHASH_FIRST(&iter)) ;
NGHASH_FIRST(&iter) ;
for (entry_p = nghash_enumerateRE( htable_p,&iter) ;
entry_p ;
entry_p = nghash_enumerateRE(dico_p->symbol_table,&iter))
entry_p = nghash_enumerateRE( htable_p,&iter))
{
if (entry_p->tp == 'R')
{
@ -570,17 +565,58 @@ nupa_list_params (FILE * cp_out)
spice_dstring_free( & dico_p->lookup_buf ) ;
}
}
} /* end dump_symbol_table() */
/* -----------------------------------------------------------------
* Dump the contents of the symbol table.
* ----------------------------------------------------------------- */
void
nupa_list_params (FILE * cp_out)
{
int depth ; /* nested subcircit depth */
tdico *dico_p ; /* local copy for speed */
NGHASHPTR htable_p ; /* current hash table */
dico_p = dicoS ;
fprintf (cp_out, "\n\n");
/* -----------------------------------------------------------------
* Print out the locally defined symbols from highest to lowest priority.
* If there are no parameters, the hash table will not be allocated as
* we use lazy allocation to save memory.
* ----------------------------------------------------------------- */
for( depth = dico_p->stack_depth ; depth > 0 ; depth-- ){
htable_p = dico_p->local_symbols[depth] ;
if( htable_p ){
fprintf (cp_out, " local symbol definitions for:%s\n", dico_p->inst_name[depth]) ;
dump_symbol_table( dico_p, htable_p, cp_out ) ;
}
}
/* -----------------------------------------------------------------
* Finally dump the global symbols.
* ----------------------------------------------------------------- */
fprintf (cp_out, " global symbol definitions:\n") ;
dump_symbol_table( dico_p, dico_p->global_symbols, cp_out ) ;
}
/* -----------------------------------------------------------------
* Lookup a parameter value in the symbol table.
* Lookup a parameter value in the symbol tables. This involves
* multiple lookups in various hash tables in order to get the scope
* correct. Each subcircuit instance will have its own local hash
* table if it has parameters. We can return whenever we get a hit.
* Otherwise, we have to exhaust all of the tables including the global
* table.
* ----------------------------------------------------------------- */
double
nupa_get_param (char *param_name, int *found)
{
int depth ; /* nested subcircit depth */
char *up_name; /* current parameter upper case */
entry *entry_p ; /* current entry */
tdico *dico_p ; /* local copy for speed */
NGHASHPTR htable_p ; /* current hash table */
double result = 0; /* parameter value */
dico_p = dicoS ;
@ -589,11 +625,27 @@ nupa_get_param (char *param_name, int *found)
up_name = spice_dstring_value( & dico_p->lookup_buf ) ;
*found = 0;
entry_p = nghash_find( dico_p->symbol_table, up_name ) ;
if( entry_p ){
result = entry_p->vl ;
*found = 1;
for( depth = dico_p->stack_depth ; depth > 0 ; depth-- ){
htable_p = dico_p->local_symbols[depth] ;
if( htable_p ){
entry_p = nghash_find( htable_p, up_name ) ;
if( entry_p ){
result = entry_p->vl ;
*found = 1;
break ;
}
}
}
if(!(*found)){
/* No luck. Try the global table. */
entry_p = nghash_find( dico_p->global_symbols, up_name ) ;
if( entry_p ){
result = entry_p->vl ;
*found = 1;
}
}
spice_dstring_free( & dico_p->lookup_buf ) ;
return result;
}
@ -604,6 +656,7 @@ nupa_add_param (char *param_name, double value)
char *up_name; /* current parameter upper case */
entry *entry_p ; /* current entry */
tdico *dico_p ; /* local copy for speed */
NGHASHPTR htable_p ; /* hash table of interest */
dico_p = dicoS ;
/* -----------------------------------------------------------------
@ -614,7 +667,18 @@ nupa_add_param (char *param_name, double value)
scopy_up( & dico_p->lookup_buf, param_name ) ;
up_name = spice_dstring_value( & dico_p->lookup_buf ) ;
entry_p = attrib (dicoS, up_name, 'N');
if( dico_p->stack_depth > 0 ){
/* can't be lazy anymore */
if(!(dico_p->local_symbols[dico_p->stack_depth])){
dico_p->local_symbols[dico_p->stack_depth] = nghash_init( NGHASH_MIN_SIZE ) ;
}
htable_p = dico_p->local_symbols[dico_p->stack_depth] ;
} else {
/* global symbol */
htable_p = dico_p->global_symbols ;
}
entry_p = attrib ( dico_p, htable_p, up_name, 'N');
if( entry_p ){
entry_p->vl = value;
entry_p->tp = 'R';
@ -631,12 +695,16 @@ nupa_add_inst_param (char *param_name, double value)
entry *entry_p ; /* current entry */
tdico *dico_p ; /* local copy for speed */
dico_p = inst_dicoS ;
dico_p = dicoS ;
spice_dstring_reinit( & dico_p->lookup_buf ) ;
scopy_up( & dico_p->lookup_buf, param_name ) ;
up_name = spice_dstring_value( & dico_p->lookup_buf ) ;
entry_p = attrib (dicoS, up_name, 'N');
if(!(dico_p->inst_symbols)){
dico_p->inst_symbols = nghash_init( NGHASH_MIN_SIZE ) ;
}
entry_p = attrib ( dico_p, dico_p->inst_symbols, up_name, 'N');
if( entry_p ){
entry_p->vl = value;
entry_p->tp = 'R';
@ -646,18 +714,35 @@ nupa_add_inst_param (char *param_name, double value)
spice_dstring_free( & dico_p->lookup_buf ) ;
}
/* -----------------------------------------------------------------
* This function copies any definitions in the inst_symbols hash
* table which are qualified symbols and makes them available at
* the global level. Afterwards, the inst_symbols table is freed.
* ----------------------------------------------------------------- */
void
nupa_copy_inst_dico ()
{
tdico *idico_p ; /* local copy for speed */
entry *entry_p ; /* current entry */
tdico *dico_p ; /* local copy for speed */
NGHASHITER iter ; /* hash iterator - thread safe */
idico_p = inst_dicoS ;
for (entry_p = nghash_enumerateRE(idico_p->symbol_table,NGHASH_FIRST(&iter)) ;
entry_p ;
entry_p = nghash_enumerateRE(idico_p->symbol_table,&iter))
nupa_add_param ( entry_p->symbol, entry_p->vl) ;
dico_p = dicoS ;
if( dico_p->inst_symbols ){
/* We we perform this operation we should be in global scope */
if( dico_p->stack_depth > 0 ){
fprintf( stderr, "stack depth should be zero.\n" ) ;
}
NGHASH_FIRST(&iter) ;
for (entry_p = nghash_enumerateRE(dico_p->inst_symbols,&iter ) ;
entry_p ;
entry_p = nghash_enumerateRE(dico_p->inst_symbols,&iter)){
nupa_add_param ( entry_p->symbol, entry_p->vl) ;
dico_free_entry( entry_p ) ;
}
nghash_free( dico_p->inst_symbols, NULL, NULL ) ;
dico_p->inst_symbols = NULL ;
}
}
char *
@ -840,18 +925,9 @@ nupa_fetchinstance (void)
}
#endif /* USING_NUPATEST */
static void dump_symbols( tdico *dico_p )
void dump_symbols( tdico *dico_p )
{
char *name_p ; /* current symbol */
entry *entry_p ; /* current entry */
void *key ; /* return key */
NGHASHITER iter ; /* hash iterator - thread safe */
fprintf (stderr, "Symbol table\n");
for (entry_p = nghash_enumeratekRE(dico_p->symbol_table,&key,NGHASH_FIRST(&iter)) ;
entry_p ;
entry_p = nghash_enumeratekRE(dico_p->symbol_table,&key,&iter)) {
name_p = (char *) key ;
fprintf (stderr, " ---> %s = %g\n", name_p, entry_p->vl) ;
}
nupa_list_params ( stderr ) ;
}

View File

@ -177,21 +177,26 @@ debugwarn (tdico * d, char *s)
void
initdico (tdico * dico)
{
int asize ; /* default allocation size */
COMPATMODE_T compat_mode;
dico->nbd = 0;
spice_dstring_init( &(dico->option) ) ;
spice_dstring_init( &(dico->srcfile) ) ;
dico->srcline = -1;
dico->errcount = 0;
dico->symbol_table = nghash_init( NGHASH_MIN_SIZE ) ;
nghash_unique( dico->symbol_table, FALSE ) ;
dico->global_symbols = nghash_init( NGHASH_MIN_SIZE ) ;
nghash_unique( dico->global_symbols, TRUE ) ; /* no rewrite of global symbols */
spice_dstring_init( &(dico->lookup_buf) ) ;
dico->tos = 0;
dico->stack[dico->tos] = 0; /* global data beneath */
dico->stack_depth = 0 ; /* top of the stack */
asize = dico->symbol_stack_alloc = 10 ;/* expected stack depth - no longer limited */
asize++ ; /* account for zero */
dico->local_symbols = tmalloc( asize * sizeof(NGHASHPTR) ) ;
dico->inst_name = tmalloc( asize * sizeof(char *) ) ;
dico->inst_symbols = NULL ; /* instance qualified are lazily allocated */
initkeys ();
compat_mode = ngspice_compat_mode() ;
@ -202,7 +207,7 @@ initdico (tdico * dico)
dico->hspice_compatibility = 0 ;
}
static void dico_free_entry( entry *entry_p )
void dico_free_entry( entry *entry_p )
{
if( entry_p->symbol ){
txfree(entry_p->symbol ) ;
@ -210,32 +215,6 @@ static void dico_free_entry( entry *entry_p )
txfree(entry_p) ;
} /* end dico_free_entry() */
static
entry **dico_rebuild_symbol_array( tdico * dico, int *num_entries_ret )
{
int i ; /* counter */
int size ; /* number of entries in symbol table */
entry *entry_p ; /* current entry */
NGHASHITER iter ; /* hash iterator - thread safe */
size = *num_entries_ret = nghash_get_size( dico->symbol_table ) ;
if( dico->num_symbols == size ){
/* no work to do up to date */
return( dico->symbol_array ) ;
}
if( size <= 0 ){
size = 1 ;
}
dico->symbol_array = trealloc( dico->symbol_array, (size+1) * sizeof(entry *) ) ;
i = 0 ;
for (entry_p = nghash_enumerateRE(dico->symbol_table,NGHASH_FIRST(&iter)) ;
entry_p ;
entry_p = nghash_enumerateRE(dico->symbol_table,&iter)){
dico->symbol_array[i++] = entry_p ;
}
dico->num_symbols = *num_entries_ret ;
return dico->symbol_array ;
}
/* local semantics for parameters inside a subckt */
/* arguments as wll as .param expressions */
@ -251,52 +230,61 @@ static void
dicostack (tdico * dico, char op)
/* push or pop operation for nested subcircuit locals */
{
char *param_p, *inst_name;
int i, current_stack_size, old_stack_size;
int num_entries ; /* number of entries */
entry **entry_array ; /* entry array */
int asize ; /* allocation size */
char *inst_name ; /* name of subcircuit instance */
char *param_p ; /* qualified inst parameter name */
entry *entry_p ; /* current entry */
SPICE_DSTRING param_name ;
NGHASHPTR htable_p ; /* current hash table */
NGHASHITER iter ; /* hash iterator - thread safe */
if (op == Push)
{
if (dico->tos < (20 - 1))
dico->tos++;
else
message (dico, " Subckt Stack overflow");
dico->stack[dico->tos] = dico->nbd;
dico->inst_name[dico->tos] = nupa_inst_name;
dico->stack_depth++;
if ( dico->stack_depth > dico->symbol_stack_alloc ){
/* Just double the stack alloc */
dico->symbol_stack_alloc *= 2 ;
asize = dico->symbol_stack_alloc + 1 ; /* account for zero */
dico->local_symbols = trealloc( dico->local_symbols, asize * sizeof(NGHASHPTR) ) ;
dico->inst_name = trealloc( dico->inst_name, asize * sizeof(char *) ) ;
}
/* lazy allocation - don't allocate space if we can help it */
dico->local_symbols[dico->stack_depth] = NULL ;
dico->inst_name[dico->stack_depth] = nupa_inst_name ;
}
else if (op == Pop)
{
if (dico->tos > 0)
if (dico->stack_depth > 0)
{
/* keep instance parameters around */
current_stack_size = dico->nbd;
old_stack_size = dico->stack[dico->tos];
inst_name = dico->inst_name[dico->tos];
spice_dstring_init(&param_name) ;
entry_array = dico_rebuild_symbol_array( dico, &num_entries ) ;
/* -----------------------------------------------------------------
* Keep instance parameters around by transferring current local
* scope variables to an instance qualified hash table.
* ----------------------------------------------------------------- */
inst_name = dico->inst_name[dico->stack_depth] ;
htable_p = dico->local_symbols[dico->stack_depth] ;
if( htable_p ){
SPICE_DSTRING param_name ; /* build a qualified name */
spice_dstring_init(&param_name) ;
for (i = old_stack_size + 1; i <= current_stack_size; i++)
{
spice_dstring_reinit(&param_name) ;
if( i < num_entries ){
entry_p = entry_array[i] ;
param_p = spice_dstring_print( &param_name, "%s.%s",
inst_name,
entry_p->symbol ) ;
NGHASH_FIRST(&iter) ;
for (entry_p = nghash_enumerateRE( htable_p,&iter ) ;
entry_p ;
entry_p = nghash_enumerateRE( htable_p,&iter))
{
spice_dstring_reinit(&param_name) ;
param_p = spice_dstring_print( &param_name, "%s.%s",
inst_name,
entry_p->symbol ) ;
nupa_add_inst_param (param_p, entry_p->vl);
/* nghash_deleteItem( dico->symbol_table, entry_p->symbol, entry_p ) ;
dico_free_entry( entry_p ) ; */
dico_free_entry( entry_p ) ;
}
nghash_free( htable_p, NULL, NULL ) ;
spice_dstring_free(&param_name) ;
}
tfree (inst_name);
spice_dstring_free(&param_name) ;
dico->nbd = dico->stack[dico->tos]; /* simply kill all local items */
dico->tos--;
dico->inst_name[dico->stack_depth] = NULL ;
dico->local_symbols[dico->stack_depth] = NULL ;
dico->stack_depth--;
}
else
{
@ -308,21 +296,37 @@ dicostack (tdico * dico, char op)
int
donedico (tdico * dico)
{
int sze = dico->nbd;
int sze = nghash_get_size( dico->global_symbols ) ;
return sze;
}
/* FIXME : WPS this should be a hash table */
/* -----------------------------------------------------------------
* Now entryb works on the given hash table hierarchy. First
* look thru the stack of local symbols and then look at the global
* symbols in that order.
* ----------------------------------------------------------------- */
static entry *
entrynb (tdico * d, char *s)
/* symbol lookup from end to start, for stacked local symbols .*/
/* bug: sometimes we need access to same-name symbol, at lower level? */
entrynb ( tdico *d, char *s)
{
int depth ; /* stack depth */
entry *entry_p ; /* search hash table */
NGHASHPTR htable_p ; /* hash table */
entry_p = nghash_find( d->symbol_table, s ) ;
return( entry_p ) ;
}
/* look at the current scope and then backup the stack */
for( depth = d->stack_depth ; depth > 0 ; depth-- ){
htable_p = d->local_symbols[depth] ;
if( htable_p ){
entry_p = nghash_find( htable_p, s ) ;
if( entry_p ){
return( entry_p ) ;
}
}
}
/* No local symbols - try the global table */
entry_p = nghash_find( d->global_symbols, s ) ;
return( entry_p ) ;
} /* end entrynb() */
char
getidtype (tdico * d, char *s)
@ -331,11 +335,11 @@ getidtype (tdico * d, char *s)
entry *entry_p ; /* hash table entry */
char itp = '?'; /* assume unknown */
entry_p = entrynb (d, s) ;
if( entry_p ){
itp = entry_p->tp ;
}
return (itp) ;
entry_p = entrynb( d, s ) ;
if( entry_p )
itp = entry_p->tp ;
return (itp) ;
}
static double
@ -379,30 +383,27 @@ fetchnumentry (tdico * dico, char *t, unsigned char *perr)
/******* writing dictionary entries *********/
entry *
attrib (tdico * dico, char *t, char op)
attrib (tdico *dico_p, NGHASHPTR htable_p, char *t, char op)
{
/* seek or attribute dico entry number for string t.
Option op='N' : force a new entry, if tos>level and old is valid.
*/
int i;
entry *entry_p ; /* symbol table entry */
entry_p = nghash_find( dico->symbol_table, t ) ;
entry_p = nghash_find( htable_p, t ) ;
if ( entry_p && (op == 'N')
&& ( entry_p->level < dico->tos) && ( entry_p->tp != '?'))
&& ( entry_p->level < dico_p->stack_depth) && ( entry_p->tp != '?'))
{
entry_p = NULL ;
}
if (!(entry_p))
{
dico->nbd++;
i = dico->nbd;
entry_p = tmalloc( sizeof(entry) ) ;
entry_p->symbol = strdup( t ) ;
entry_p->tp = '?'; /* signal Unknown */
entry_p->level = dico->tos ;
nghash_insert( dico->symbol_table, t, entry_p ) ;
entry_p->level = dico_p->stack_depth ;
nghash_insert( htable_p, t, entry_p ) ;
}
return entry_p ;
}
@ -429,9 +430,21 @@ define (tdico * dico,
unsigned char err, warn;
entry *entry_p ; /* spice table entry */
SPICE_DSTRING vartemp ; /* vairable temp */
NGHASHPTR htable_p ; /* hash table */
spice_dstring_init(&vartemp) ;
entry_p = attrib (dico, t, op);
if( dico->stack_depth > 0 ){
/* can't be lazy anymore */
if(!(dico->local_symbols[dico->stack_depth])){
dico->local_symbols[dico->stack_depth] = nghash_init( NGHASH_MIN_SIZE ) ;
}
htable_p = dico->local_symbols[dico->stack_depth] ;
} else {
/* global symbol */
htable_p = dico->global_symbols ;
}
entry_p = attrib (dico, htable_p, t, op);
err = 0;
if (!(entry_p))
err = message (dico, " Symbol table overflow");
@ -453,9 +466,9 @@ define (tdico * dico,
entry_p->sbbase = base ;
/* if ( (c !='?') && (i<= dico->stack[dico->tos]) ) { */
if (c == '?')
entry_p->level = dico->tos; /* promote! */
entry_p->level = dico->stack_depth ; /* promote! */
if ( entry_p->level < dico->tos)
if ( entry_p->level < dico->stack_depth)
{
/* warn about re-write to a global scope! */
scopys(&vartemp, t) ;

View File

@ -28,6 +28,7 @@ noinst_HEADERS = \
dllitf.h \
domndefs.h \
dopdefs.h \
dstring.h \
dvec.h \
elctdefs.h \
enh.h \

View File

@ -39,11 +39,11 @@ typedef struct nghashbox {
NGTABLEPTR searchPtr ; /* used for find again mechanism */
void *compare_func ; /* the comparison function */
void *hash_func ; /* the hash function */
double growth_factor ; /* how much to grow table by */
int size ; /* the size of the table */
int max_density ; /* maximum number of entries before growth */
int num_entries ; /* current number of entries in table */
int need_resize ; /* amount before we need a resize */
float growth_factor ; /* how much to grow table by */
long access ; /* used for statistics */
long collision ; /* collision times */
unsigned int power_of_two : 8 ; /* build table as a power of two */
@ -51,29 +51,40 @@ typedef struct nghashbox {
unsigned int unique : 16 ; /* true if only one unique item in col. list */
} NGHASHBOX, *NGHASHPTR ;
/* -----------------------------------------------------------------
* This enumerated type is used to control the base hash function types
* as well as hash table attributes such as uniqueness and power of 2.
* The negative definitions for the function are used so we catch a
* segfault immediately if the hash table is used incorrectly. Notice
* that the default function string is zero. Because there definitions
* can be cast into functions, they are defined as longs so it will work
* on all architecture types include 64bits.
* ----------------------------------------------------------------- */
typedef enum {
NGHASH_NONUNIQUE = 0,
NGHASH_UNIQUE = 1L,
NGHASH_POWER_OF_TWO = (1L<<1)
NGHASH_FUNC_NUM = -2L,
NGHASH_FUNC_PTR = -1L,
NGHASH_FUNC_STR = 0L,
NGHASH_UNIQUE = 1L,
NGHASH_POWER_OF_TWO = (1L<<1),
NGHASH_UNIQUE_TWO = NGHASH_UNIQUE | NGHASH_POWER_OF_TWO
} NGHASHFLAGS_T ;
typedef unsigned int (*nghash_func)(NGHASHPTR,void *) ;
/* the default hashing functions */
typedef enum {
NGHASH_FUNC_STR = 0,
NGHASH_FUNC_PTR = -1,
NGHASH_FUNC_NUM = -2
} NGHASH_FUNC_T ;
typedef struct nghash_iter_rec {
struct ngtable_rec *position ;
} NGHASHITER, *NGHASHITERPTR ;
/* -----------------------------------------------------------------
* macro definition for enumeration. Strange looking but compiler
* will optimize. x_yz->position = 0 and x_yz will be returned.
----------------------------------------------------------------- */
#define NGHASH_FIRST(x_yz) ( ((x_yz)->position = NULL) ? (x_yz) : (x_yz) )
No longer use this trick and now explicitly write out both lines because
some compilers complain about unintentional assignment. Unfortunately,
we want to intentionally assign it. The compiler is warning unnecessarily.
----------------------------------------------------------------- */
#define NGHASH_FIRST(x_yz) ( (x_yz)->position = NULL ) ;
#define NGHASH_ITER_EQUAL(x_yz,y_yz) ( (x_yz)->position == (y_yz)->position )
#define NGHASH_DEF_HASH_STR NGHASH_FUNC_STR

View File

@ -10,6 +10,7 @@ libmisc_la_SOURCES = \
alloc.c \
alloc.h \
dup2.c \
dstring.c \
dup2.h \
hash.c \
ivars.c \

352
src/misc/dstring.c Normal file
View File

@ -0,0 +1,352 @@
/* -----------------------------------------------------------------
FILE: dstring.c
DESCRIPTION:This file contains the routines for manipulating dynamic strings.
CONTENTS:
DATE: Wed Mar 24 18:38:28 CDT 2010
REVISIONS: $Log$
REVISIONS: Revision 1.1 2010-03-25 22:44:38 dwarning
REVISIONS: Bill Swartz patch
REVISIONS:
----------------------------------------------------------------- */
#include "ngspice.h"
#include <stdarg.h>
#include "dstring.h"
/* definitions local to this file only */
/* ********************** TYPE DEFINITIONS ************************* */
/* ********************** STATIC DEFINITIONS ************************* */
/*
*----------------------------------------------------------------------
*
* spice_dstring_init --
*
* Initializes a dynamic string, discarding any previous contents
* of the string (spice_dstring_free should have been called already
* if the dynamic string was previously in use).
*
* Results:
* None.
*
* Side effects:
* The dynamic string is initialized to be empty.
*
*----------------------------------------------------------------------
*/
void spice_dstring_init(SPICE_DSTRINGPTR dsPtr)
{
dsPtr->string = dsPtr->staticSpace ;
dsPtr->length = 0 ;
dsPtr->spaceAvl = SPICE_DSTRING_STATIC_SIZE ;
dsPtr->staticSpace[0] = EOS;
} /* end spice_dstring_init() */
/*
*----------------------------------------------------------------------
*
* spice_dstring_append --
*
* Append more characters to the current value of a dynamic string.
*
* Results:
* The return value is a pointer to the dynamic string's new value.
*
* Side effects:
* Length bytes from string (or all of string if length is less
* than zero) are added to the current value of the string. Memory
* gets reallocated if needed to accomodate the string's new size.
*
* Notes: char *string; String to append. If length is -1 then
* this must be null-terminated.
* INT length; Number of characters from string to append.
* If < 0, then append all of string, up to null at end.
*
*----------------------------------------------------------------------
*/
char *spice_dstring_append(SPICE_DSTRINGPTR dsPtr,char *string,int length)
{
int newSize ; /* needed size */
char *newString ; /* newly allocated string buffer */
char *dst ; /* destination */
char *end ; /* end of string */
if( length < 0){
length = strlen(string) ;
}
newSize = length + dsPtr->length ;
/* -----------------------------------------------------------------
* Allocate a larger buffer for the string if the current one isn't
* large enough. Allocate extra space in the new buffer so that there
* will be room to grow before we have to allocate again.
----------------------------------------------------------------- */
if (newSize >= dsPtr->spaceAvl) {
dsPtr->spaceAvl = 2 * newSize ;
newString = tmalloc( dsPtr->spaceAvl * sizeof(char) ) ;
memcpy((void *) newString, (void *) dsPtr->string, (size_t) dsPtr->length) ;
if (dsPtr->string != dsPtr->staticSpace) {
txfree(dsPtr->string) ;
}
dsPtr->string = newString;
}
/* -----------------------------------------------------------------
* Copy the new string into the buffer at the end of the old
* one.
----------------------------------------------------------------- */
for( dst = dsPtr->string + dsPtr->length, end = string+length;
string < end; string++, dst++) {
*dst = *string ;
}
*dst = EOS ;
dsPtr->length += length ;
return(dsPtr->string) ;
} /* end spice_dstring_append() */
/* -----------------------------------------------------------------
* Function: add character c to dynamic string dstr_p.
* ----------------------------------------------------------------- */
char *spice_dstring_append_char( SPICE_DSTRINGPTR dstr_p, char c)
{
char tmp_str[2] ; /* temporary string for append */
char *val_p ; /* return value */
tmp_str[0] = c ;
tmp_str[1] = EOS ;
val_p = spice_dstring_append( dstr_p, tmp_str, -1 ) ;
return(val_p) ;
} /* end spice_dstring_append_char() */
static int spice_format_length( va_list args, char *fmt )
{
int i ; /* integer */
int len ; /* length of format */
int size_format ; /* width of field */
int found_special ; /* look for special characters */
char *s ; /* string */
char c ; /* character */
/* -----------------------------------------------------------------
* First find length of buffer.
----------------------------------------------------------------- */
len = 0 ;
while(fmt && *fmt){
if( *fmt == '%' ){
fmt++ ;
if( *fmt == '%' ){
len++ ;
} else {
/* -----------------------------------------------------------------
* We have a real formatting character, loop until we get a special
* character.
----------------------------------------------------------------- */
if( *fmt == '.' || *fmt == '-' ){
fmt++ ; /* skip over these characters */
}
size_format = atoi(fmt) ;
if( size_format > 0 ){
len += size_format ;
}
found_special = FALSE ;
for( ; fmt && *fmt ; fmt++ ){
switch( *fmt ){
case 's':
s = va_arg(args, char *) ;
if( s ){
len += strlen(s) ;
}
found_special = TRUE ;
break ;
case 'i':
case 'd':
case 'o':
case 'x':
case 'X':
case 'u':
i = va_arg(args, int) ;
len += 10 ;
found_special = TRUE ;
break ;
case 'c':
c = va_arg(args, int) ;
len++ ;
found_special = TRUE ;
break ;
case 'f':
case 'e':
case 'F':
case 'g':
case 'G':
c = va_arg(args, double) ;
len += 35 ;
found_special = TRUE ;
break ;
default:
;
} /* end switch() */
if( found_special ){
break ;
}
}
}
} else {
len++ ;
}
fmt++ ;
} /* end while() */
va_end(args) ;
return(len) ;
} /* end Ymessage_format_length() */
char *spice_dstring_print( SPICE_DSTRINGPTR dsPtr,char *format, ... )
{
va_list args ;
int format_len ; /* length of format */
int length ; /* new length */
int orig_length ; /* original length of buffer */
char *buffer ; /* proper length of buffer */
/* -----------------------------------------------------------------
* First get the length of the buffer needed.
----------------------------------------------------------------- */
va_start( args, format ) ;
format_len = spice_format_length(args,format) ;
/* -----------------------------------------------------------------
* Next allocate the proper buffer size.
----------------------------------------------------------------- */
orig_length = dsPtr->length ;
length = orig_length + format_len + 1 ;
buffer = spice_dstring_setlength( dsPtr, length) ;
/* -----------------------------------------------------------------
* Convert the format.
----------------------------------------------------------------- */
va_start( args, format ) ;
if( format ){
vsprintf( buffer + orig_length, format, args ) ;
dsPtr->length = strlen( buffer ) ;
} else {
buffer = NULL ;
}
va_end(args) ;
return( buffer ) ;
} /* end spice_dstring_print() */
/*
*----------------------------------------------------------------------
*
* _spice_dstring_setlength --
*
* Change the length of a dynamic string. This can cause the
* string to either grow or shrink, depending on the value of
* length.
*
* Results:
* Returns the current string buffer.
*
* Side effects:
* The length of dsPtr is changed to length but a null byte is not
* stored at that position in the string. Use spice_dstring_setlength
* for that function. If length is larger
* than the space allocated for dsPtr, then a panic occurs.
*
*----------------------------------------------------------------------
*/
char *_spice_dstring_setlength(SPICE_DSTRINGPTR dsPtr,int length)
{
char *newString ;
if (length < 0) {
length = 0 ;
}
if (length >= dsPtr->spaceAvl) {
dsPtr->spaceAvl = length+1;
newString = tmalloc( dsPtr->spaceAvl * sizeof(char) ) ;
/* -----------------------------------------------------------------
* SPECIAL NOTE: must use memcpy, not strcpy, to copy the string
* to a larger buffer, since there may be embedded NULLs in the
* string in some cases.
----------------------------------------------------------------- */
memcpy((void *) newString, (void *) dsPtr->string, (size_t) dsPtr->length) ;
if( dsPtr->string != dsPtr->staticSpace ) {
txfree(dsPtr->string) ;
}
dsPtr->string = newString ;
}
dsPtr->length = length ;
return(dsPtr->string) ;
} /* end _spice_dstring_setlength() */
/*
*----------------------------------------------------------------------
*
* spice_dstring_setlength --
*
* Change the length of a dynamic string. This can cause the
* string to either grow or shrink, depending on the value of
* length.
*
* Results:
* Returns the current string buffer.
*
* Side effects:
* The length of dsPtr is changed to length and a null byte is
* stored at that position in the string. If length is larger
* than the space allocated for dsPtr, then a panic occurs.
*
*----------------------------------------------------------------------
*/
char *spice_dstring_setlength(SPICE_DSTRINGPTR dsPtr,int length)
{
char *str_p ; /* newly create string */
str_p = _spice_dstring_setlength( dsPtr,length) ;
str_p[length] = EOS ;
return( str_p ) ;
} /* end spice_dstring_setlength() */
/*
*----------------------------------------------------------------------
*
* spice_dstring_free --
*
* Frees up any memory allocated for the dynamic string and
* reinitializes the string to an empty state.
*
* Results:
* None.
*
* Side effects:
* The previous contents of the dynamic string are lost, and
* the new value is an empty string.
*
*----------------------------------------------------------------------
*/
void spice_dstring_free(SPICE_DSTRINGPTR dsPtr)
{
if (dsPtr->string != dsPtr->staticSpace) {
txfree(dsPtr->string) ;
}
dsPtr->string = dsPtr->staticSpace ;
dsPtr->length = 0 ;
dsPtr->spaceAvl = SPICE_DSTRING_STATIC_SIZE;
dsPtr->staticSpace[0] = EOS ;
} /* end spice_dstring_free() */

View File

@ -138,7 +138,7 @@ NGHASHPTR nghash_init_pointer(int num_entries)
return( nghash_init_with_parms( NGHASH_DEF_CMP_PTR, NGHASH_DEF_HASH_PTR,
num_entries, NGHASH_DEF_MAX_DENSITY,
NGHASH_DEF_GROW_FACTOR,
NGHASH_UNIQUE|NGHASH_POWER_OF_TWO) ) ;
NGHASH_UNIQUE_TWO) ) ;
} /* end nghash_init_pointer() */
NGHASHPTR nghash_init_integer(int num_entries)
@ -146,7 +146,7 @@ NGHASHPTR nghash_init_integer(int num_entries)
return( nghash_init_with_parms( NGHASH_DEF_CMP_NUM, NGHASH_DEF_HASH_NUM,
num_entries, NGHASH_DEF_MAX_DENSITY,
NGHASH_DEF_GROW_FACTOR,
NGHASH_UNIQUE|NGHASH_POWER_OF_TWO) ) ;
NGHASH_UNIQUE_TWO) ) ;
} /* end nghash_init_integer() */
int nghash_table_get(NGHASHPTR hashtable)
@ -166,20 +166,10 @@ int nghash_max_density(NGHASHPTR hashtable,int max_density)
void nghash_empty(NGHASHPTR hashtable, void (*delete_data) (void *),
void (*delete_key) (void *))
{
long old_size ; /* old size of hash table */
long new_size ; /* new size of hash table */
NGTABLEPTR *table, hptr , zapptr ;
nghash_reset_stat(hashtable);
old_size = MAX( NGHASH_MIN_SIZE, hashtable->num_entries ) ;
if( hashtable->power_of_two ){
new_size = nghash_table_size2( old_size ) ;
} else {
/* prime size */
new_size = nghash_table_size( old_size ) ;
}
table = hashtable->hash_table ;
if( table ){
for( hptr = hashtable->thread ; hptr ; ){
@ -316,10 +306,8 @@ void * _nghash_find_again(NGHASHPTR hashtable, void * user_key,BOOL *status)
int ret_code ; /* comparison return code */
NGTABLEPTR curPtr ; /* current hashtable entry */
COMPARE_FUNC compare_func ; /* user defined comparison function */
NGTABLEPTR *table ; /* hash table array */
/* initialization */
table = hashtable->hash_table ;
DS(hashtable->access++;) ;
if( hashtable->searchPtr ){

View File

@ -8,6 +8,7 @@ Copyright 1990 Regents of the University of California. All rights reserved.
#include "ngspice.h"
#include "stringutil.h"
#include "dstring.h"
int
prefix(register char *p, register char *s)
@ -195,16 +196,17 @@ register char *p, register char *s)
char *
gettok(char **s)
{
char buf[BSIZE_SP];
int i = 0;
char c;
int paren;
char *token ; /* return token */
SPICE_DSTRING buf ; /* allow any length string */
paren = 0;
while (isspace(**s))
(*s)++;
if (!**s)
return (NULL);
spice_dstring_init(&buf) ;
while ((c = **s) && !isspace(c)) {
if (c == '('/*)*/)
paren += 1;
@ -212,12 +214,13 @@ gettok(char **s)
paren -= 1;
else if (c == ',' && paren < 1)
break;
buf[i++] = *(*s)++;
spice_dstring_append_char( &buf, *(*s)++ ) ;
}
buf[i] = '\0';
while (isspace(**s) || **s == ',')
(*s)++;
return (copy(buf));
token = copy( spice_dstring_value(&buf) ) ;
spice_dstring_free(&buf) ;
return ( token ) ;
}
/*-------------------------------------------------------------------------*
@ -230,9 +233,9 @@ gettok(char **s)
char *
gettok_noparens(char **s)
{
char buf[BSIZE_SP];
int i = 0;
char c;
char *token ; /* return token */
SPICE_DSTRING buf ; /* allow any length string */
while ( isspace(**s) )
(*s)++; /* iterate over whitespace */
@ -240,29 +243,31 @@ gettok_noparens(char **s)
if (!**s)
return (NULL); /* return NULL if we come to end of line */
spice_dstring_init(&buf) ;
while ((c = **s) &&
!isspace(c) &&
( **s != '(' ) &&
( **s != ')' ) &&
( **s != ',')
) {
buf[i++] = *(*s)++;
spice_dstring_append_char( &buf, *(*s)++ ) ;
}
buf[i] = '\0';
/* Now iterate up to next non-whitespace char */
while ( isspace(**s) )
(*s)++;
return (copy(buf));
token = copy( spice_dstring_value(&buf) ) ;
spice_dstring_free(&buf) ;
return ( token ) ;
}
char *
gettok_instance(char **s)
{
char buf[BSIZE_SP];
int i = 0;
char c;
char *token ; /* return token */
SPICE_DSTRING buf ; /* allow any length string */
while ( isspace(**s) )
(*s)++; /* iterate over whitespace */
@ -270,20 +275,22 @@ gettok_instance(char **s)
if (!**s)
return (NULL); /* return NULL if we come to end of line */
spice_dstring_init(&buf) ;
while ((c = **s) &&
!isspace(c) &&
( **s != '(' ) &&
( **s != ')' )
) {
buf[i++] = *(*s)++;
spice_dstring_append_char( &buf, *(*s)++ ) ;
}
buf[i] = '\0';
/* Now iterate up to next non-whitespace char */
while ( isspace(**s) )
(*s)++;
return (copy(buf));
token = copy( spice_dstring_value(&buf) ) ;
spice_dstring_free(&buf) ;
return ( token ) ;
}
/*-------------------------------------------------------------------------*
@ -295,9 +302,9 @@ gettok_instance(char **s)
char *
gettok_node(char **s)
{
char buf[BSIZE_SP];
int i = 0;
char c;
char *token ; /* return token */
SPICE_DSTRING buf ; /* allow any length string */
while (isspace(**s) ||
( **s == '(' ) ||
@ -309,15 +316,15 @@ gettok_node(char **s)
if (!**s)
return (NULL); /* return NULL if we come to end of line */
spice_dstring_init(&buf) ;
while ((c = **s) &&
!isspace(c) &&
( **s != '(' ) &&
( **s != ')' ) &&
( **s != ',')
) { /* collect chars until whitespace or ( , ) */
buf[i++] = *(*s)++;
spice_dstring_append_char( &buf, *(*s)++ ) ;
}
buf[i] = '\0';
/* Now iterate up to next non-whitespace char */
while (isspace(**s) ||
@ -327,7 +334,9 @@ gettok_node(char **s)
)
(*s)++; /* iterate over whitespace and ( , ) */
return (copy(buf));
token = copy( spice_dstring_value(&buf) ) ;
spice_dstring_free(&buf) ;
return ( token ) ;
}
/*-------------------------------------------------------------------------*
@ -383,26 +392,29 @@ get_r_paren(char **s)
char *
stripWhiteSpacesInsideParens(char *str)
{
char buf[BSIZE_SP];
int i = 0, j = 0;
char *token ; /* return token */
SPICE_DSTRING buf ; /* allow any length string */
int i = 0 ; /* index into string */
while ( (str[i] == ' ') || (str[i] == '\t') )
i++;
spice_dstring_init(&buf) ;
for(i=i; str[i]!='\0'; i++)
{
if ( str[i] != '(' ) {
buf[j++] = str[i];
spice_dstring_append_char( &buf, str[i] ) ;
} else {
buf[j++] = str[i];
spice_dstring_append_char( &buf, str[i] ) ;
while ( (str[i++] != ')') ) {
if ( str[i] != ' ' ) buf[j++] = str[i];
if ( str[i] != ' ' ) spice_dstring_append_char( &buf, str[i] ) ;
}
i--;
}
}
buf[j] = '\0';
return copy(buf);
token = copy( spice_dstring_value(&buf) ) ;
spice_dstring_free(&buf) ;
return ( token ) ;
}
@ -477,4 +489,3 @@ get_comma_separated_values( char *values[], char *str ) {
values[count++] = strdup(str);
return count;
}

View File

@ -419,7 +419,7 @@ gillespie_src (CKTcircuit * ckt, long int firstmode,
/* First, try a straight solution with all sources at zero */
fprintf (stderr, "\rSupplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
fprintf (stderr, "Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
/* If this doesn't work, try gmin stepping as well for the first solution */
@ -490,7 +490,7 @@ gillespie_src (CKTcircuit * ckt, long int firstmode,
if (converged == 0)
do {
fprintf (stderr,
"\rSupplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
"Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
iters = ckt->CKTstat->STATnumIter;

View File

@ -1,47 +1,47 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vngspice", "vngspice.vcproj", "{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
console_debug|Win32 = console_debug|Win32
console_debug|x64 = console_debug|x64
console_release|Win32 = console_release|Win32
console_release|x64 = console_release|x64
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
release64|Win32 = release64|Win32
release64|x64 = release64|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_debug|Win32.ActiveCfg = console_debug|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_debug|Win32.Build.0 = console_debug|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_debug|x64.ActiveCfg = console_debug|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_debug|x64.Build.0 = console_debug|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_release|Win32.ActiveCfg = console_release|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_release|Win32.Build.0 = console_release|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_release|x64.ActiveCfg = console_release|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_release|x64.Build.0 = console_release|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Debug|Win32.ActiveCfg = Debug|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Debug|Win32.Build.0 = Debug|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Debug|x64.ActiveCfg = Debug|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Debug|x64.Build.0 = Debug|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Release|Win32.ActiveCfg = Debug|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Release|Win32.Build.0 = Debug|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Release|x64.ActiveCfg = Release|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Release|x64.Build.0 = Release|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.release64|Win32.ActiveCfg = release64|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.release64|Win32.Build.0 = release64|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.release64|x64.ActiveCfg = release64|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.release64|x64.Build.0 = release64|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
AMDCaProjectFile = D:\Spice_general\ng-spice-rework\visualc\CodeAnalyst\vngspice.caw
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vngspice", "vngspice.vcproj", "{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
console_debug|Win32 = console_debug|Win32
console_debug|x64 = console_debug|x64
console_release|Win32 = console_release|Win32
console_release|x64 = console_release|x64
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
release64|Win32 = release64|Win32
release64|x64 = release64|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_debug|Win32.ActiveCfg = console_debug|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_debug|Win32.Build.0 = console_debug|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_debug|x64.ActiveCfg = console_debug|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_debug|x64.Build.0 = console_debug|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_release|Win32.ActiveCfg = console_release|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_release|Win32.Build.0 = console_release|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_release|x64.ActiveCfg = console_release|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.console_release|x64.Build.0 = console_release|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Debug|Win32.ActiveCfg = Debug|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Debug|Win32.Build.0 = Debug|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Debug|x64.ActiveCfg = Debug|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Debug|x64.Build.0 = Debug|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Release|Win32.ActiveCfg = Release|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Release|Win32.Build.0 = Release|Win32
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Release|x64.ActiveCfg = Release|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.Release|x64.Build.0 = Release|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.release64|Win32.ActiveCfg = release64|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.release64|Win32.Build.0 = release64|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.release64|x64.ActiveCfg = release64|x64
{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}.release64|x64.Build.0 = release64|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
AMDCaProjectFile = D:\Spice_general\ng-spice-rework\visualc\CodeAnalyst\vngspice.caw
EndGlobalSection
EndGlobal