@ -15,12 +15,14 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
# include "typesdef.h"
# define NUMTYPES 128+4 /* If this is too little we can use a list. */
# define NUMTYPES (128 + 4) /* If this is too little we can use a list. */
# define NUMPLOTTYPES 512 /* Since there may be more than 1 pat/type. */
struct type {
char * t_name ;
char * t_abbrev ;
bool f_name_is_alloc ; /* Flag that name was allocated */
bool f_abbrev_is_alloc ; /* Flag that abbrev was allocated */
} ;
/* The stuff for plot names. */
@ -28,61 +30,63 @@ struct type {
struct plotab {
char * p_name ;
char * p_pattern ;
bool f_name_is_alloc ; /* Flag that name was allocated */
bool f_pattern_is_alloc ; /* Flag that pattern was allocated */
} ;
/* note: This should correspond to SV_ defined in sim.h */
static struct type types [ NUMTYPES ] = {
{ " notype " , NULL } ,
{ " time " , " s " } ,
{ " frequency " , " Hz " } ,
{ " voltage " , " V " } ,
{ " current " , " A " } ,
{ " voltage-density " , " V/sqrt(Hz) " } ,
{ " current-density " , " A/sqrt(Hz) " } ,
{ " voltage^2-density " , " (V^2)/Hz " } ,
{ " current^2-density " , " (A^2)/Hz " } ,
{ " voltage^2 " , " (V^2) " } ,
{ " current^2 " , " (A^2) " } ,
{ " pole " , NULL } ,
{ " zero " , NULL } ,
{ " s-param " , NULL } ,
{ " temp-sweep " , " Celsius " } , /* Added by HT */
{ " res-sweep " , " Ohms " } , /* Added by HT */
{ " impedance " , " Ohms " } , /* Added by A.Roldan */
{ " admittance " , " Mhos " } , /* Added by A.Roldan */
{ " power " , " W " } , /* Added by A.Roldan */
{ " phase " , " Degree " } , /* Added by A.Roldan */
{ " decibel " , " dB " } , /* Added by A.Roldan */
{ " capacitance " , " F " } ,
{ " charge " , " C " } ,
{ " temperature " , " Celsius " } ,
{ " notype " , NULL , FALSE , FALSE } ,
{ " time " , " s " , FALSE , FALSE } ,
{ " frequency " , " Hz " , FALSE , FALSE } ,
{ " voltage " , " V " , FALSE , FALSE } ,
{ " current " , " A " , FALSE , FALSE } ,
{ " voltage-density " , " V/sqrt(Hz) " , FALSE , FALSE } ,
{ " current-density " , " A/sqrt(Hz) " , FALSE , FALSE } ,
{ " voltage^2-density " , " (V^2)/Hz " , FALSE , FALSE } ,
{ " current^2-density " , " (A^2)/Hz " , FALSE , FALSE } ,
{ " voltage^2 " , " (V^2) " , FALSE , FALSE } ,
{ " current^2 " , " (A^2) " , FALSE , FALSE } ,
{ " pole " , NULL , FALSE , FALSE } ,
{ " zero " , NULL , FALSE , FALSE } ,
{ " s-param " , NULL , FALSE , FALSE } ,
{ " temp-sweep " , " Celsius " , FALSE , FALSE } , /* Added by HT */
{ " res-sweep " , " Ohms " , FALSE , FALSE } , /* Added by HT */
{ " impedance " , " Ohms " , FALSE , FALSE } , /* Added by A.Roldan */
{ " admittance " , " Mhos " , FALSE , FALSE } , /* Added by A.Roldan */
{ " power " , " W " , FALSE , FALSE } , /* Added by A.Roldan */
{ " phase " , " Degree " , FALSE , FALSE } , /* Added by A.Roldan */
{ " decibel " , " dB " , FALSE , FALSE } , /* Added by A.Roldan */
{ " capacitance " , " F " , FALSE , FALSE } ,
{ " charge " , " C " , FALSE , FALSE } ,
{ " temperature " , " Celsius " , FALSE , FALSE }
} ;
/* The stuff for plot names. */
static struct plotab plotabs [ NUMPLOTTYPES ] = {
{ " tran " , " transient " } ,
{ " op " , " op " } ,
{ " tf " , " function " } ,
{ " dc " , " d.c. " } ,
{ " dc " , " dc " } ,
{ " dc " , " transfer " } ,
{ " ac " , " a.c. " } ,
{ " ac " , " ac " } ,
{ " pz " , " pz " } ,
{ " pz " , " p.z. " } ,
{ " pz " , " pole-zero " } ,
{ " disto " , " disto " } ,
{ " dist " , " dist " } ,
{ " noise " , " noise " } ,
{ " sens " , " sens " } ,
{ " sens " , " sensitivity " } ,
{ " sens2 " , " sens2 " } ,
{ " sp " , " s.p. " } ,
{ " sp " , " sp " } ,
{ " harm " , " harm " } ,
{ " spect " , " spect " } ,
{ " pss " , " periodic " } ,
{ " tran " , " transient " , FALSE , FALSE } ,
{ " op " , " op " , FALSE , FALSE } ,
{ " tf " , " function " , FALSE , FALSE } ,
{ " dc " , " d.c. " , FALSE , FALSE } ,
{ " dc " , " dc " , FALSE , FALSE } ,
{ " dc " , " transfer " , FALSE , FALSE } ,
{ " ac " , " a.c. " , FALSE , FALSE } ,
{ " ac " , " ac " , FALSE , FALSE } ,
{ " pz " , " pz " , FALSE , FALSE } ,
{ " pz " , " p.z. " , FALSE , FALSE } ,
{ " pz " , " pole-zero " , FALSE } ,
{ " disto " , " disto " , FALSE , FALSE } ,
{ " dist " , " dist " , FALSE , FALSE } ,
{ " noise " , " noise " , FALSE , FALSE } ,
{ " sens " , " sens " , FALSE , FALSE } ,
{ " sens " , " sensitivity " , FALSE , FALSE } ,
{ " sens2 " , " sens2 " , FALSE , FALSE } ,
{ " sp " , " s.p. " , FALSE , FALSE } ,
{ " sp " , " sp " , FALSE , FALSE } ,
{ " harm " , " harm " , FALSE , FALSE } ,
{ " spect " , " spect " , FALSE , FALSE } ,
{ " pss " , " periodic " , FALSE , FALSE }
} ;
@ -92,59 +96,173 @@ static struct plotab plotabs[NUMPLOTTYPES] = {
* parse things like abbrev ( name ) and to label axes with M < abbrev > , instead
* of numbers . It may be ommitted .
* Also , the command " deftype p plottype pattern ... " will assign plottype as
* the name to any plot with one of the patterns in its Name : field .
* the name to any plot with one of the patterns as its p_name field .
*
* Parameter
* wl : A linked list of strings of words providing arguments to the
* deftype command .
*
* Remarks
* The caller must ensure that there are 3 words in the linked
* list with the v subcommand or the function will cause access violations
* as it tries to access the required arguments . With the p subcommand ,
* only 2 arguments are strictly required , but the function will not
* do anything useful unless at least 3 are provided .
*/
void
com_dftype ( wordlist * wl )
{
char * name , * abb ;
int i ;
/* Identify the subcommand and partially validate it */
const char * const subcmd_word = wl - > wl_word ;
const char subcmd_char = * subcmd_word ;
if ( subcmd_char = = ' \0 ' | | subcmd_word [ 1 ] ! = ' \0 ' ) {
( void ) fprintf ( cp_err , " Error: invalid subcommand \" %s \" . \n " ,
subcmd_word ) ;
return ;
}
switch ( * wl - > wl_word ) {
switch ( subcmd_char ) {
case ' v ' :
case ' V ' :
case ' V ' : {
wl = wl - > wl_next ;
name = wl - > wl_word ;
const char * const name = wl - > wl_word ; /* type name */
wl = wl - > wl_next ;
abb = wl - > wl_word ;
const char * const abb = wl - > wl_word ; /* abbreviation */
/* Test for invalid arguments */
if ( ( wl = wl - > wl_next ) ! = ( wordlist * ) NULL ) {
( void ) fprintf ( cp_err , " Error: extraneous argument%s supplied "
" with the v subcommand: \" %s \" " ,
wl - > wl_next = = ( wordlist * ) NULL ? " " : " s " ,
wl - > wl_word ) ;
wl = wl - > wl_next ;
for ( ; wl ! = ( wordlist * ) NULL ; wl = wl - > wl_next ) {
( void ) fprintf ( cp_err , " , \" %s \" " , wl - > wl_word ) ;
}
( void ) fprintf ( cp_err , " \n " ) ;
return ;
}
int i ;
/* Sequentially scan :( the defined types until the desired type
* name is found or all names have been checked . */
for ( i = 0 ; i < NUMTYPES & & types [ i ] . t_name ; i + + )
if ( cieq ( types [ i ] . t_name , name ) )
break ;
if ( i > = NUMTYPES ) {
fprintf ( cp_err , " Error: too many types defined \n " ) ;
if ( cieq ( types [ i ] . t_name , name ) )
break ; /* match found at index i */
if ( i = = NUMTYPES ) { /* array is full */
fprintf ( cp_err , " Error: too many types (%d) defined \n " ,
NUMTYPES ) ;
return ;
}
if ( ! types [ i ] . t_name )
types [ i ] . t_name = copy ( name ) ;
types [ i ] . t_abbrev = copy ( abb ) ;
break ;
{
struct type * const type_cur = types + i ;
/* If reached the end of the list of defined types,
* define a new type */
if ( type_cur - > t_name = = ( char * ) NULL ) {
type_cur - > t_name = copy ( name ) ;
type_cur - > f_name_is_alloc = TRUE ;
}
else { /* already exists, so may be abbrev to free */
/* If the abbreviation has already been defined via an
* allocated buffer , free the allocation */
if ( type_cur - > t_abbrev ! = ( char * ) NULL & &
type_cur - > f_abbrev_is_alloc ) {
txfree ( ( void * ) type_cur - > t_abbrev ) ;
}
}
/* Set the new abbreviation */
type_cur - > t_abbrev = copy ( abb ) ;
type_cur - > f_abbrev_is_alloc = TRUE ;
}
break ;
}
case ' p ' :
case ' P ' :
case ' P ' : {
wl = wl - > wl_next ;
name = copy ( wl - > wl_word ) ;
wl = wl - > wl_next ;
for ( ; wl ; wl = wl - > wl_next ) {
char * const name = copy ( wl - > wl_word ) ; /* plot type name */
bool f_name_used = FALSE ; /* flag that name copy alloc is used */
/* For each pattern supplied in the command, locate it in the
* list of known patterns or add it if it does not exist and
* the list is not full . */
for ( wl = wl - > wl_next ; wl ; wl = wl - > wl_next ) {
char * pattern = wl - > wl_word ;
int i ;
for ( i = 0 ; i < NUMPLOTTYPES & & plotabs [ i ] . p_pattern ; i + + )
if ( cieq ( plotabs [ i ] . p_pattern , pattern ) )
break ;
if ( i > = NUMPLOTTYPES ) {
fprintf ( cp_err , " Error: too many plot abs \n " ) ;
break ; /* match found at index i */
if ( i = = NUMPLOTTYPES ) { /* array is full */
if ( ! f_name_used ) {
/* Free the name copy that was never used */
txfree ( ( void * ) name ) ;
}
fprintf ( cp_err , " Error: too many plot abs (%d) defined. \n " ,
NUMPLOTTYPES ) ;
return ;
}
if ( ! plotabs [ i ] . p_pattern )
plotabs [ i ] . p_pattern = copy ( pattern ) ;
plotabs [ i ] . p_name = name ;
}
break ;
default :
fprintf ( cp_err , " Error: missing 'p' or 'v' argument \n " ) ;
{
struct plotab * const plotab_cur = plotabs + i ;
/* If reached the end of the list of defined patterns,
* define a new one */
if ( plotab_cur - > p_pattern = = ( char * ) NULL ) {
plotab_cur - > p_pattern = copy ( pattern ) ;
plotab_cur - > f_pattern_is_alloc = TRUE ;
}
/* Assign the name for the pattern. Freeing the old
* name , if present , is complicated by the fact that
* the same name allocation is used for all matching
* patterns . */
else {
char * const p_name_old = plotab_cur - > p_name ;
if ( p_name_old ! = ( char * ) NULL & &
plotab_cur - > f_name_is_alloc ) {
/* Alloc exists. Must free if this is the only use.
* Find usage count to make this decision . */
int j ;
int n_use = 0 ;
for ( j = 0 ; j < NUMPLOTTYPES ; j + + ) {
const char * const p_name_cur = plotabs [ j ] . p_name ;
/* Test for end of list */
if ( p_name_cur = = ( char * ) NULL ) { /* end */
break ;
}
/* More entries, so check for the allocation of
* the old name */
if ( p_name_cur = = p_name_old ) { /* match */
n_use + + ;
}
} /* end of loop over plot types */
/* Now can free if the usage count is exactly one,
* that use being the current one */
if ( n_use = = 1 ) {
txfree ( ( void * ) p_name_old ) ;
}
} /* end of case that there was an existing name here */
} /* end of case that there was an old pattern */
/* Assign the (new) name */
plotab_cur - > p_name = name ;
plotab_cur - > f_name_is_alloc = TRUE ;
} /* end of block for assigning pattern and abbrev */
f_name_used = TRUE ; /* flag that the allocated name was used */
} /* end of loop over patterns */
break ;
}
}
default :
fprintf ( cp_err , " Error: invalid subcommand '%c'. "
" Expecting 'p' or 'v'. \n " , subcmd_char ) ;
break ;
} /* end of switch over subcommands */
} /* end of function com_dftype */
/* Return the abbreviation associated with a number. */