Gxxx n1 n2 TABLE {expression} = (x0, y0) (x1, y1) (x2, y2)
This commit is contained in:
parent
d6e616a310
commit
94e9f07b90
|
|
@ -1,3 +1,10 @@
|
||||||
|
2011-12-21 Holger Vogt
|
||||||
|
* src/misc/string.c ,
|
||||||
|
src/frontend/inpcom.c ,
|
||||||
|
src/include/ngspice/stringutil.h:
|
||||||
|
allow syntax Gxxx n1 n2 TABLE {expression} = (x0, y0) (x1, y1) (x2, y2)
|
||||||
|
or Exxx n1 n2 TABLE {expression} = (x0, y0) (x1, y1) (x2, y2)
|
||||||
|
|
||||||
2011-12-17 Robert Larice
|
2011-12-17 Robert Larice
|
||||||
* src/xspice/cmpp/ifs_lex.l ,
|
* src/xspice/cmpp/ifs_lex.l ,
|
||||||
* src/xspice/cmpp/ifs_yacc.y ,
|
* src/xspice/cmpp/ifs_yacc.y ,
|
||||||
|
|
|
||||||
|
|
@ -3780,52 +3780,11 @@ inp_split_multi_param_lines( struct line *deck, int line_num )
|
||||||
return line_num;
|
return line_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ps compatibility:
|
/* ps compatibility:
|
||||||
ECOMP 3 0 TABLE {V(1,2)} = (-1MV 0V) (1MV, 10V)
|
ECOMP 3 0 TABLE {V(1,2)} = (-1 0V) (1, 10V)
|
||||||
-->
|
-->
|
||||||
ECOMP 3 0 int3 int0 1
|
ECOMP 3 0 int3 int0 1
|
||||||
BECOMP int3 int0 V = pwl(V(1,2), -1MV, 0 , 1MV, 10V)
|
BECOMP int3 int0 V = pwl(V(1,2), -2, 0, -1, 0 , 1, 10V, 2, 10V)
|
||||||
|
|
||||||
GD16 16 1 TABLE {V(16,1)} ((-100V,-1pV)(0,0)(1m,1u)(2m,1m))
|
GD16 16 1 TABLE {V(16,1)} ((-100V,-1pV)(0,0)(1m,1u)(2m,1m))
|
||||||
-->
|
-->
|
||||||
|
|
@ -3925,7 +3884,114 @@ static void inp_compat(struct line *deck)
|
||||||
*(str_ptr + 3) = 'o';
|
*(str_ptr + 3) = 'o';
|
||||||
*(str_ptr + 4) = 'l';
|
*(str_ptr + 4) = 'l';
|
||||||
}
|
}
|
||||||
|
/* Exxx n1 n2 TABLE {expression} = (x0, y0) (x1, y1) (x2, y2)
|
||||||
|
-->
|
||||||
|
Exxx n1 n2 int1 0 1
|
||||||
|
BExxx int1 0 V = pwl (expression, x0-(x2-x0)/2, y0, x0, y0, x1, y1, x2, y2, x2+(x2-x0)/2, y2)
|
||||||
|
*/
|
||||||
|
if ((str_ptr = strstr( curr_line, "table" )) != NULL) {
|
||||||
|
char *expression, *firstno, *ffirstno, *secondno, *midline, *lastno, *lastlastno;
|
||||||
|
double fnumber, lnumber, delta;
|
||||||
|
int nerror;
|
||||||
|
cut_line = curr_line;
|
||||||
|
/* title and nodes */
|
||||||
|
title_tok = gettok(&cut_line);
|
||||||
|
node1 = gettok(&cut_line);
|
||||||
|
node2 = gettok(&cut_line);
|
||||||
|
// Exxx n1 n2 int1 0 1
|
||||||
|
xlen = 2*strlen(title_tok) + strlen(node1) + strlen(node2)
|
||||||
|
+ 20 - 4*2 + 1;
|
||||||
|
ckt_array[0] = TMALLOC(char, xlen);
|
||||||
|
sprintf(ckt_array[0], "%s %s %s %s_int1 0 1",
|
||||||
|
title_tok, node1, node2, title_tok);
|
||||||
|
// get the expression
|
||||||
|
str_ptr = gettok(&cut_line); /* ignore 'table' */
|
||||||
|
tfree(str_ptr);
|
||||||
|
expression = gettok_char(&cut_line, '}', TRUE); /* expression */
|
||||||
|
if (!expression) {
|
||||||
|
fprintf(stderr, "Error: bad sytax in line %d\n %s\n",
|
||||||
|
card->li_linenum_orig, card->li_line);
|
||||||
|
controlled_exit(EXIT_BAD);
|
||||||
|
}
|
||||||
|
/* remove '{' and '}' from expression */
|
||||||
|
if ((str_ptr = strstr( expression, "{" )) != NULL)
|
||||||
|
*str_ptr = ' ';
|
||||||
|
if ((str_ptr = strstr( expression, "}" )) != NULL)
|
||||||
|
*str_ptr = ' ';
|
||||||
|
/* cut_line may now have a '=', if yes, it will have '{' and '}'
|
||||||
|
(braces around token after '=') */
|
||||||
|
if ((str_ptr = strstr( cut_line, "=" )) != NULL)
|
||||||
|
*str_ptr = ' ';
|
||||||
|
if ((str_ptr = strstr( cut_line, "{" )) != NULL)
|
||||||
|
*str_ptr = ' ';
|
||||||
|
if ((str_ptr = strstr( cut_line, "}" )) != NULL)
|
||||||
|
*str_ptr = ' ';
|
||||||
|
/* get first two numbers to establish extrapolation */
|
||||||
|
str_ptr = cut_line;
|
||||||
|
ffirstno = gettok_node(&cut_line);
|
||||||
|
firstno = copy(ffirstno);
|
||||||
|
fnumber = INPevaluate(&ffirstno, &nerror, TRUE);
|
||||||
|
secondno = gettok_node(&cut_line);
|
||||||
|
midline = cut_line;
|
||||||
|
cut_line = strrchr(str_ptr, '(');
|
||||||
|
/* replace '(' with ',' and ')' with ' ' */
|
||||||
|
while(*str_ptr) {
|
||||||
|
if (*str_ptr == '(')
|
||||||
|
*str_ptr = ',';
|
||||||
|
else if (*str_ptr == ')')
|
||||||
|
*str_ptr = ' ';
|
||||||
|
*str_ptr++;
|
||||||
|
}
|
||||||
|
/* scan for last two numbers */
|
||||||
|
lastno = gettok_node(&cut_line);
|
||||||
|
lnumber = INPevaluate(&lastno, &nerror, FALSE);
|
||||||
|
/* check for max-min and take half the difference for delta */
|
||||||
|
delta = (lnumber-fnumber)/2.;
|
||||||
|
lastlastno = gettok_node(&cut_line);
|
||||||
|
if (!secondno || (*midline == 0) || (delta <= 0.) || !lastlastno) {
|
||||||
|
fprintf(stderr, "Error: bad sytax in line %d\n %s\n",
|
||||||
|
card->li_linenum_orig, card->li_line);
|
||||||
|
controlled_exit(EXIT_BAD);
|
||||||
|
}
|
||||||
|
xlen = 2*strlen(title_tok) + strlen(expression) + 14 + strlen(firstno) +
|
||||||
|
2*strlen(secondno) + strlen(midline) + 14 +
|
||||||
|
strlen(lastlastno) + 50;
|
||||||
|
ckt_array[1] = TMALLOC(char, xlen);
|
||||||
|
sprintf(ckt_array[1], "b%s %s_int1 0 v = pwl(%s, %e, %s, %s, %s, %s, %e, %s)",
|
||||||
|
title_tok, title_tok, expression, fnumber-delta, secondno, firstno, secondno,
|
||||||
|
midline, lnumber + delta, lastlastno);
|
||||||
|
|
||||||
|
// insert new B source line immediately after current line
|
||||||
|
tmp_ptr = card->li_next;
|
||||||
|
for ( i = 0; i < 2; i++ ) {
|
||||||
|
if ( param_end ) {
|
||||||
|
param_end->li_next = alloc(struct line);
|
||||||
|
param_end = param_end->li_next;
|
||||||
|
} else {
|
||||||
|
param_end = param_beg = alloc(struct line);
|
||||||
|
}
|
||||||
|
param_end->li_next = NULL;
|
||||||
|
param_end->li_error = NULL;
|
||||||
|
param_end->li_actual = NULL;
|
||||||
|
param_end->li_line = ckt_array[i];
|
||||||
|
param_end->li_linenum = 0;
|
||||||
|
}
|
||||||
|
// comment out current variable e line
|
||||||
|
*(card->li_line) = '*';
|
||||||
|
// insert new param lines immediately after current line
|
||||||
|
tmp_ptr = card->li_next;
|
||||||
|
card->li_next = param_beg;
|
||||||
|
param_end->li_next = tmp_ptr;
|
||||||
|
// point 'card' pointer to last in scalar list
|
||||||
|
card = param_end;
|
||||||
|
|
||||||
|
param_beg = param_end = NULL;
|
||||||
|
tfree(firstno);
|
||||||
|
tfree(lastlastno);
|
||||||
|
tfree(title_tok);
|
||||||
|
tfree(node1);
|
||||||
|
tfree(node2);
|
||||||
|
}
|
||||||
/* Exxx n1 n2 VOL = {equation}
|
/* Exxx n1 n2 VOL = {equation}
|
||||||
-->
|
-->
|
||||||
Exxx n1 n2 int1 0 1
|
Exxx n1 n2 int1 0 1
|
||||||
|
|
@ -4003,6 +4069,116 @@ static void inp_compat(struct line *deck)
|
||||||
*(str_ptr + 3) = 'u';
|
*(str_ptr + 3) = 'u';
|
||||||
*(str_ptr + 4) = 'r';
|
*(str_ptr + 4) = 'r';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Gxxx n1 n2 TABLE {expression} = (x0, y0) (x1, y1) (x2, y2)
|
||||||
|
-->
|
||||||
|
Gxxx n1 n2 int1 0 1
|
||||||
|
BGxxx int1 0 V = pwl (expression, x0-(x2-x0)/2, y0, x0, y0, x1, y1, x2, y2, x2+(x2-x0)/2, y2)
|
||||||
|
*/
|
||||||
|
if ((str_ptr = strstr( curr_line, "table" )) != NULL) {
|
||||||
|
char *expression, *firstno, *ffirstno, *secondno, *midline, *lastno, *lastlastno;
|
||||||
|
double fnumber, lnumber, delta;
|
||||||
|
int nerror;
|
||||||
|
cut_line = curr_line;
|
||||||
|
/* title and nodes */
|
||||||
|
title_tok = gettok(&cut_line);
|
||||||
|
node1 = gettok(&cut_line);
|
||||||
|
node2 = gettok(&cut_line);
|
||||||
|
// Gxxx n1 n2 int1 0 1
|
||||||
|
xlen = 2*strlen(title_tok) + strlen(node1) + strlen(node2)
|
||||||
|
+ 20 - 4*2 + 1;
|
||||||
|
ckt_array[0] = TMALLOC(char, xlen);
|
||||||
|
sprintf(ckt_array[0], "%s %s %s %s_int1 0 1",
|
||||||
|
title_tok, node1, node2, title_tok);
|
||||||
|
// get the expression
|
||||||
|
str_ptr = gettok(&cut_line); /* ignore 'table' */
|
||||||
|
tfree(str_ptr);
|
||||||
|
expression = gettok_char(&cut_line, '}', TRUE); /* expression */
|
||||||
|
if (!expression) {
|
||||||
|
fprintf(stderr, "Error: bad sytax in line %d\n %s\n",
|
||||||
|
card->li_linenum_orig, card->li_line);
|
||||||
|
controlled_exit(EXIT_BAD);
|
||||||
|
}
|
||||||
|
/* remove '{' and '}' from expression */
|
||||||
|
if ((str_ptr = strstr( expression, "{" )) != NULL)
|
||||||
|
*str_ptr = ' ';
|
||||||
|
if ((str_ptr = strstr( expression, "}" )) != NULL)
|
||||||
|
*str_ptr = ' ';
|
||||||
|
/* cut_line may now have a '=', if yes, it will have '{' and '}'
|
||||||
|
(braces around token after '=') */
|
||||||
|
if ((str_ptr = strstr( cut_line, "=" )) != NULL)
|
||||||
|
*str_ptr = ' ';
|
||||||
|
if ((str_ptr = strstr( cut_line, "{" )) != NULL)
|
||||||
|
*str_ptr = ' ';
|
||||||
|
if ((str_ptr = strstr( cut_line, "}" )) != NULL)
|
||||||
|
*str_ptr = ' ';
|
||||||
|
/* get first two numbers to establish extrapolation */
|
||||||
|
str_ptr = cut_line;
|
||||||
|
ffirstno = gettok_node(&cut_line);
|
||||||
|
firstno = copy(ffirstno);
|
||||||
|
fnumber = INPevaluate(&ffirstno, &nerror, TRUE);
|
||||||
|
secondno = gettok_node(&cut_line);
|
||||||
|
midline = cut_line;
|
||||||
|
cut_line = strrchr(str_ptr, '(');
|
||||||
|
/* replace '(' with ',' and ')' with ' ' */
|
||||||
|
while(*str_ptr) {
|
||||||
|
if (*str_ptr == '(')
|
||||||
|
*str_ptr = ',';
|
||||||
|
else if (*str_ptr == ')')
|
||||||
|
*str_ptr = ' ';
|
||||||
|
*str_ptr++;
|
||||||
|
}
|
||||||
|
/* scan for last two numbers */
|
||||||
|
lastno = gettok_node(&cut_line);
|
||||||
|
lnumber = INPevaluate(&lastno, &nerror, FALSE);
|
||||||
|
/* check for max-min and take half the difference for delta */
|
||||||
|
delta = (lnumber-fnumber)/2.;
|
||||||
|
lastlastno = gettok_node(&cut_line);
|
||||||
|
if (!secondno || (*midline == 0) || (delta <= 0.) || !lastlastno) {
|
||||||
|
fprintf(stderr, "Error: bad sytax in line %d\n %s\n",
|
||||||
|
card->li_linenum_orig, card->li_line);
|
||||||
|
controlled_exit(EXIT_BAD);
|
||||||
|
}
|
||||||
|
/* BGxxx int1 0 V = pwl (expression, x0-(x2-x0)/2, y0, x0, y0, x1, y1, x2, y2, x2+(x2-x0)/2, y2) */
|
||||||
|
xlen = 2*strlen(title_tok) + strlen(expression) + 14 + strlen(firstno) +
|
||||||
|
2*strlen(secondno) + strlen(midline) + 14 +
|
||||||
|
strlen(lastlastno) + 50;
|
||||||
|
ckt_array[1] = TMALLOC(char, xlen);
|
||||||
|
sprintf(ckt_array[1], "b%s %s_int1 0 v = pwl(%s, %e, %s, %s, %s, %s, %e, %s)",
|
||||||
|
title_tok, title_tok, expression, fnumber-delta, secondno, firstno, secondno,
|
||||||
|
midline, lnumber + delta, lastlastno);
|
||||||
|
|
||||||
|
// insert new B source line immediately after current line
|
||||||
|
tmp_ptr = card->li_next;
|
||||||
|
for ( i = 0; i < 2; i++ ) {
|
||||||
|
if ( param_end ) {
|
||||||
|
param_end->li_next = alloc(struct line);
|
||||||
|
param_end = param_end->li_next;
|
||||||
|
} else {
|
||||||
|
param_end = param_beg = alloc(struct line);
|
||||||
|
}
|
||||||
|
param_end->li_next = NULL;
|
||||||
|
param_end->li_error = NULL;
|
||||||
|
param_end->li_actual = NULL;
|
||||||
|
param_end->li_line = ckt_array[i];
|
||||||
|
param_end->li_linenum = 0;
|
||||||
|
}
|
||||||
|
// comment out current variable e line
|
||||||
|
*(card->li_line) = '*';
|
||||||
|
// insert new param lines immediately after current line
|
||||||
|
tmp_ptr = card->li_next;
|
||||||
|
card->li_next = param_beg;
|
||||||
|
param_end->li_next = tmp_ptr;
|
||||||
|
// point 'card' pointer to last in scalar list
|
||||||
|
card = param_end;
|
||||||
|
|
||||||
|
param_beg = param_end = NULL;
|
||||||
|
tfree(firstno);
|
||||||
|
tfree(lastlastno);
|
||||||
|
tfree(title_tok);
|
||||||
|
tfree(node1);
|
||||||
|
tfree(node2);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Gxxx n1 n2 CUR = {equation}
|
Gxxx n1 n2 CUR = {equation}
|
||||||
-->
|
-->
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ void strtoupper(char *str);
|
||||||
char * stripWhiteSpacesInsideParens(char *str);
|
char * stripWhiteSpacesInsideParens(char *str);
|
||||||
char * gettok(char **s);
|
char * gettok(char **s);
|
||||||
char * gettok_instance(char **);
|
char * gettok_instance(char **);
|
||||||
|
char * gettok_char(char **s, char p, bool inc_p);
|
||||||
|
|
||||||
|
|
||||||
#ifdef CIDER
|
#ifdef CIDER
|
||||||
|
|
|
||||||
|
|
@ -360,6 +360,40 @@ gettok_instance(char **s)
|
||||||
return ( token ) ;
|
return ( token ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get the next token starting at next non white spice, stopping
|
||||||
|
at p, if inc_p is true, then including p, else excluding p
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
gettok_char(char **s, char p, bool inc_p)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
char *token ; /* return token */
|
||||||
|
SPICE_DSTRING buf ; /* allow any length string */
|
||||||
|
|
||||||
|
while ( isspace(**s) )
|
||||||
|
(*s)++; /* iterate over whitespace */
|
||||||
|
|
||||||
|
if (!**s)
|
||||||
|
return (NULL); /* return NULL if we come to end of line */
|
||||||
|
|
||||||
|
spice_dstring_init(&buf) ;
|
||||||
|
while ((c = **s) != '\0' &&
|
||||||
|
( **s != p )
|
||||||
|
) {
|
||||||
|
spice_dstring_append_char( &buf, *(*s)++ ) ;
|
||||||
|
}
|
||||||
|
if (inc_p)
|
||||||
|
spice_dstring_append_char( &buf, *(*s)++ ) ;
|
||||||
|
|
||||||
|
/* Now iterate up to next non-whitespace char */
|
||||||
|
while ( isspace(**s) )
|
||||||
|
(*s)++;
|
||||||
|
|
||||||
|
token = copy( spice_dstring_value(&buf) ) ;
|
||||||
|
spice_dstring_free(&buf) ;
|
||||||
|
return ( token ) ;
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*
|
/*-------------------------------------------------------------------------*
|
||||||
* gettok_node was added by SDB on 12.3.2003
|
* gettok_node was added by SDB on 12.3.2003
|
||||||
* It acts like gettok, except that it treats parens and commas like
|
* It acts like gettok, except that it treats parens and commas like
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue