Bill Swartz patch
This commit is contained in:
parent
625b3d14fc
commit
112261297d
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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() */
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ) ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(¶m_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(¶m_name) ;
|
||||
|
||||
for (i = old_stack_size + 1; i <= current_stack_size; i++)
|
||||
{
|
||||
spice_dstring_reinit(¶m_name) ;
|
||||
if( i < num_entries ){
|
||||
entry_p = entry_array[i] ;
|
||||
param_p = spice_dstring_print( ¶m_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(¶m_name) ;
|
||||
param_p = spice_dstring_print( ¶m_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(¶m_name) ;
|
||||
}
|
||||
tfree (inst_name);
|
||||
spice_dstring_free(¶m_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) ;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ noinst_HEADERS = \
|
|||
dllitf.h \
|
||||
domndefs.h \
|
||||
dopdefs.h \
|
||||
dstring.h \
|
||||
dvec.h \
|
||||
elctdefs.h \
|
||||
enh.h \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ libmisc_la_SOURCES = \
|
|||
alloc.c \
|
||||
alloc.h \
|
||||
dup2.c \
|
||||
dstring.c \
|
||||
dup2.h \
|
||||
hash.c \
|
||||
ivars.c \
|
||||
|
|
|
|||
|
|
@ -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() */
|
||||
|
|
@ -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 ){
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue