Fix of buffer overrun in interpolation at endpoint of interval. Made cfunc.mod for tables more modular. Prevented buffer overrun when building file name. Added error checking for allocation failures in many locations. Made binary search for interpolation more efficient.
This commit is contained in:
parent
b4757f934b
commit
1867f5b727
|
|
@ -7,17 +7,18 @@
|
|||
// Author: Arpad Buermen
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "ngspice/inpdefs.h"
|
||||
#include "ngspice/devdefs.h"
|
||||
#include "ngspice/evtudn.h"
|
||||
#include "ngspice/dllitf.h"
|
||||
#include "cmextrn.h"
|
||||
#include "udnextrn.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "ngspice/devdefs.h"
|
||||
#include "ngspice/dstring.h"
|
||||
#include "ngspice/dllitf.h"
|
||||
#include "ngspice/evtudn.h"
|
||||
#include "ngspice/inpdefs.h"
|
||||
#include "cmextrn.h"
|
||||
#include "udnextrn.h"
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -416,44 +417,76 @@ Infile_Path/<infile>
|
|||
NGSPICE_INPUT_DIR/<infile>, where the path is given by the environmental variable
|
||||
<infile>, where the path is the current directory
|
||||
*/
|
||||
|
||||
#define MAX_PATH_LEN 1024
|
||||
|
||||
#define DFLT_BUF_SIZE 256
|
||||
FILE *fopen_with_path(const char *path, const char *mode)
|
||||
{
|
||||
char buf[MAX_PATH_LEN+1];
|
||||
FILE *fp;
|
||||
|
||||
if((path[0] != '/') && (path[1] != ':')) {
|
||||
if((path[0] != '/') && (path[1] != ':')) { /* path absolue (probably) */
|
||||
// const char *x = getenv("ngspice_vpath");
|
||||
const char *x = cm_get_path();
|
||||
if(x) {
|
||||
strncpy(buf, x, MAX_PATH_LEN);
|
||||
strcat(buf, "/");
|
||||
strcat(buf, path);
|
||||
fp = fopen(buf, mode);
|
||||
if (fp)
|
||||
return fp;
|
||||
else {
|
||||
char *y = getenv( "NGSPICE_INPUT_DIR" );
|
||||
if (y && *y) {
|
||||
char *a;
|
||||
strncpy(buf, y, MAX_PATH_LEN);
|
||||
a = strrchr(buf, '/');
|
||||
if(a && a[1] == '\0')
|
||||
a[0] = '\0';
|
||||
strcat(buf, "/");
|
||||
strcat(buf, path);
|
||||
fp = fopen(buf, mode);
|
||||
if (fp)
|
||||
return fp;
|
||||
}
|
||||
if (x) {
|
||||
DS_CREATE(ds, DFLT_BUF_SIZE);
|
||||
|
||||
/* Build file <cm_get_path(()>/path> */
|
||||
if (ds_cat_printf(&ds, "%s/%s", x, path) != 0) {
|
||||
cm_message_printf(
|
||||
"Unable to build cm_get_path() path for opening file.");
|
||||
ds_free(&ds);
|
||||
return (FILE *) NULL;
|
||||
}
|
||||
|
||||
/* Try opening file. If fail, try using NGSPICE_INPUT_DIR
|
||||
* env variable location */
|
||||
if ((fp = fopen(ds_get_buf(&ds), mode)) == (FILE *) NULL) {
|
||||
char *y = getenv("NGSPICE_INPUT_DIR");
|
||||
if (y && *y) { /* have env var and not "" */
|
||||
int rc_ds = 0;
|
||||
/* Build <env var>/path and try opening. If the env var
|
||||
* ends with a slash, do not add a second slash */
|
||||
ds_clear(&ds);
|
||||
rc_ds |= ds_cat_str(&ds, y);
|
||||
|
||||
/* Add slash if not present. Note that check for
|
||||
* length > 0 is done on the remote chance that the
|
||||
* ds_cat_str() failed. */
|
||||
const size_t len = ds_get_length(&ds);
|
||||
if (len > 0 && ds_get_buf(&ds)[len - 1] != '/') {
|
||||
rc_ds |= ds_cat_char(&ds, '/'); /* add dir sep */
|
||||
}
|
||||
rc_ds |= ds_cat_str(&ds, path); /* add input path */
|
||||
|
||||
/* Ensure path built OK */
|
||||
if (rc_ds != 0) {
|
||||
cm_message_printf(
|
||||
"Unable to build NGSPICE_INPUT_DIR "
|
||||
"path for opening file.");
|
||||
ds_free(&ds);
|
||||
return (FILE *) NULL;
|
||||
}
|
||||
|
||||
/* Try opening file name that was built */
|
||||
if ((fp = fopen(ds_get_buf(&ds),
|
||||
mode)) != (FILE *) NULL) {
|
||||
ds_free(&ds);
|
||||
return fp;
|
||||
}
|
||||
}
|
||||
} /* end of open using prefix from cm_get_path() failed */
|
||||
else { /* Opened OK */
|
||||
ds_free(&ds);
|
||||
return fp;
|
||||
}
|
||||
ds_free(&ds); /* free dstring resources, if any */
|
||||
}
|
||||
}
|
||||
} /* end of case that path is not absolute */
|
||||
|
||||
/* If not opened yet, try opening exactly as given */
|
||||
fp = fopen(path, mode);
|
||||
|
||||
return fp;
|
||||
}
|
||||
} /* end of function fopen_with_path */
|
||||
|
||||
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -33,15 +33,19 @@ sf_alloc(int n /* number of elements */,
|
|||
{
|
||||
void *ptr;
|
||||
|
||||
size *= (size_t) n;
|
||||
if (n < 0) {
|
||||
cm_message_printf("%s: illegal allocation(%d X %zd bytes)",
|
||||
__FILE__, n, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (0 >= size)
|
||||
cm_message_printf("%s: illegal allocation(%d bytes)", __FILE__, (int) size);
|
||||
|
||||
ptr = malloc(size);
|
||||
|
||||
if (NULL == ptr)
|
||||
cm_message_printf("%s: cannot allocate %d bytes : ", __FILE__, (int) size);
|
||||
/* Use calloc so that any internal allocations will be set to NULL to
|
||||
* facilitate error recovery */
|
||||
if ((ptr = calloc(n, size)) == NULL) {
|
||||
cm_message_printf("%s: cannot allocate %zd bytes : ",
|
||||
__FILE__, n * size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@
|
|||
#include <float.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "eno.h"
|
||||
#include "../xspice/icm/dlmain.h"
|
||||
#include "alloc.h"
|
||||
#include "eno.h"
|
||||
|
||||
#define SF_MAX(a,b) ((a) < (b) ? (b) : (a))
|
||||
#define SF_MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
|
@ -39,16 +40,49 @@ sf_eno_init (int order, /* interpolation order */
|
|||
int n /* data size */)
|
||||
/*< Initialize interpolation object. >*/
|
||||
{
|
||||
sf_eno ent;
|
||||
int i;
|
||||
int xrc = 0;
|
||||
sf_eno ent = (sf_eno) NULL;
|
||||
|
||||
if ((ent = (sf_eno) sf_alloc(
|
||||
1, sizeof(*ent))) == (sf_eno) NULL) {
|
||||
cm_message_printf("Unable to allocate sf_eno structure "
|
||||
"in sf_eno_init");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
ent = (sf_eno) sf_alloc(1, sizeof(*ent));
|
||||
ent->order = order;
|
||||
ent->n = n;
|
||||
ent->diff = (double**) sf_alloc(order, sizeof(double*));
|
||||
for (i = 0; i < order; i++)
|
||||
ent->diff[i] = sf_doublealloc(n - i);
|
||||
|
||||
if ((ent->diff = (double **) sf_alloc(
|
||||
order, sizeof(double *))) == (double **) NULL) {
|
||||
cm_message_printf("Unable to allocate diff field "
|
||||
"in sf_eno_init");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < order; i++) {
|
||||
if ((ent->diff[i] = sf_doublealloc(
|
||||
n - i)) == (double *) NULL) {
|
||||
cm_message_printf("Unable to allocate in sf_eno_init "
|
||||
"at index %d.",
|
||||
i);
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXITPOINT:
|
||||
if (xrc != 0) {
|
||||
if (ent != (sf_eno) NULL) {
|
||||
sf_eno_close(ent);
|
||||
ent = (sf_eno) NULL;
|
||||
}
|
||||
}
|
||||
return ent;
|
||||
}
|
||||
|
||||
|
|
@ -56,10 +90,15 @@ void
|
|||
sf_eno_close (sf_eno ent)
|
||||
/*< Free internal storage >*/
|
||||
{
|
||||
int i;
|
||||
if (ent == (sf_eno) NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ent->order; i++)
|
||||
int i;
|
||||
const int n = ent->order;
|
||||
for (i = 0; i < n; i++) {
|
||||
free (ent->diff[i]);
|
||||
}
|
||||
free (ent->diff);
|
||||
free (ent);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,23 +36,74 @@ sf_eno2_init (int order, /* interpolation order */
|
|||
int n1, int n2 /* data dimensions */)
|
||||
/*< Initialize interpolation object >*/
|
||||
{
|
||||
sf_eno2 pnt;
|
||||
int i2;
|
||||
int xrc = 0;
|
||||
sf_eno2 pnt = (sf_eno2) NULL;
|
||||
|
||||
if ((pnt = (sf_eno2) sf_alloc(
|
||||
1, sizeof(*pnt))) == (sf_eno2) NULL) {
|
||||
cm_message_printf("Unable to allocate sf_eno2 structure "
|
||||
"in sf_eno2_init");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
pnt = (sf_eno2) sf_alloc(1, sizeof(*pnt));
|
||||
pnt->order = order;
|
||||
pnt->n1 = n1;
|
||||
pnt->n2 = n2;
|
||||
pnt->ng = 2 * order - 2;
|
||||
if (pnt->ng > pnt->n2)
|
||||
if (pnt->ng > pnt->n2) {
|
||||
cm_message_printf("%s: ng=%d is too big", __FILE__, pnt->ng);
|
||||
pnt->jnt = sf_eno_init (order, pnt->ng);
|
||||
pnt->f = sf_doublealloc (pnt->ng);
|
||||
pnt->f1 = sf_doublealloc (pnt->ng);
|
||||
pnt->ent = (sf_eno*) sf_alloc(n2, sizeof(sf_eno));
|
||||
for (i2 = 0; i2 < n2; i2++)
|
||||
pnt->ent[i2] = sf_eno_init (order, n1);
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
if ((pnt->jnt = sf_eno_init(order, pnt->ng)) == (sf_eno) NULL) {
|
||||
cm_message_printf("Unable to initialize field jnt "
|
||||
"in sf_eno2_init");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
if ((pnt->f = sf_doublealloc (pnt->ng)) == (double *) NULL) {
|
||||
cm_message_printf("Unable to allocate field f in sf_eno2_init()");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
if ((pnt->f1 = sf_doublealloc (pnt->ng)) == (double *) NULL) {
|
||||
cm_message_printf("Unable to allocate field f1 in sf_eno2_init()");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
if ((pnt->ent = (sf_eno *) sf_alloc(
|
||||
n2, sizeof(sf_eno))) == (sf_eno *) NULL) {
|
||||
cm_message_printf("Unable to allocate field ent in sf_eno2_init()");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
{
|
||||
int i2;
|
||||
for (i2 = 0; i2 < n2; i2++) {
|
||||
if ((pnt->ent[i2] = sf_eno_init(
|
||||
order, n1)) == (sf_eno) NULL) {
|
||||
cm_message_printf("Unable to initialize field ent[%d] "
|
||||
"in sf_eno3_init()",
|
||||
i2);
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXITPOINT:
|
||||
if (xrc != 0) {
|
||||
if (pnt != (sf_eno2) NULL) {
|
||||
sf_eno2_close(pnt);
|
||||
pnt = (sf_eno2) NULL;
|
||||
}
|
||||
}
|
||||
return pnt;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,27 +37,88 @@ sf_eno3_init(int order, /* interpolation order */
|
|||
int n1, int n2, int n3 /* data dimensions */)
|
||||
/*< Initialize interpolation object >*/
|
||||
{
|
||||
sf_eno3 pnt;
|
||||
int i2, i3;
|
||||
int xrc = 0;
|
||||
sf_eno3 pnt = (sf_eno3) NULL;
|
||||
|
||||
/* Allocate base structrue */
|
||||
if ((pnt = (sf_eno3) sf_alloc (1, sizeof *pnt)) == (sf_eno3) NULL) {
|
||||
cm_message_printf("Unable to allocate sf_eno3 structure "
|
||||
"in sf_eno3_init");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
pnt = (sf_eno3) sf_alloc (1, sizeof(*pnt));
|
||||
pnt->order = order;
|
||||
pnt->n1 = n1;
|
||||
pnt->n2 = n2;
|
||||
pnt->n3 = n3;
|
||||
pnt->ng = 2 * order - 2;
|
||||
if (pnt->ng > n2 || pnt->ng > n3)
|
||||
|
||||
if (pnt->ng > n2 || pnt->ng > n3) {
|
||||
cm_message_printf("%s: ng=%d is too big", __FILE__, pnt->ng);
|
||||
pnt->jnt = sf_eno2_init (order, pnt->ng, pnt->ng);
|
||||
pnt->f = sf_doublealloc2 (pnt->ng, pnt->ng);
|
||||
pnt->f1 = sf_doublealloc2 (pnt->ng, pnt->ng);
|
||||
pnt->ent = (sf_eno**) sf_alloc (n3, sizeof(sf_eno*));
|
||||
for (i3 = 0; i3 < n3; i3++) {
|
||||
pnt->ent[i3] = (sf_eno*) sf_alloc (n2, sizeof(sf_eno));
|
||||
for (i2 = 0; i2 < n2; i2++)
|
||||
pnt->ent[i3][i2] = sf_eno_init (order, n1);
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
if ((pnt->jnt = sf_eno2_init(
|
||||
order, pnt->ng, pnt->ng)) == (sf_eno2) NULL) {
|
||||
cm_message_printf("Unable to initialize field jnt "
|
||||
"in sf_eno3_init");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
if ((pnt->f = sf_doublealloc2(pnt->ng, pnt->ng)) == (double **) NULL) {
|
||||
cm_message_printf("Unable to allocate field f in sf_eno3_init()");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
if ((pnt->f1 = sf_doublealloc2(pnt->ng, pnt->ng)) == (double **) NULL) {
|
||||
cm_message_printf("Unable to allocate field f1 in sf_eno3_init()");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
if ((pnt->ent = (sf_eno **) sf_alloc(
|
||||
n3, sizeof(sf_eno*))) == (sf_eno **) NULL) {
|
||||
cm_message_printf("Unable to allocate field ent in sf_eno3_init()");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
{
|
||||
int i3;
|
||||
for (i3 = 0; i3 < n3; i3++) {
|
||||
if ((pnt->ent[i3] = (sf_eno*) sf_alloc(
|
||||
n2, sizeof(sf_eno))) == (sf_eno *) NULL) {
|
||||
cm_message_printf("Unable to allocate field ent[%d] "
|
||||
"in sf_eno3_init()", i3);
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
int i2;
|
||||
for (i2 = 0; i2 < n2; i2++) {
|
||||
if ((pnt->ent[i3][i2] = sf_eno_init(
|
||||
order, n1)) == (sf_eno) NULL) {
|
||||
cm_message_printf("Unable to initialize field "
|
||||
"ent[%d][%d] in sf_eno3_init()",
|
||||
i2, i3);
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXITPOINT:
|
||||
if (xrc != 0) {
|
||||
if (pnt != (sf_eno3) NULL) {
|
||||
sf_eno3_close(pnt);
|
||||
free(pnt);
|
||||
pnt = (sf_eno3) NULL;
|
||||
}
|
||||
}
|
||||
return pnt;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,33 +12,11 @@ is returned. The original input string is undisturbed.
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
/*=== CONSTANTS ========================*/
|
||||
|
||||
#define OK 0
|
||||
#define FAIL 1
|
||||
|
||||
/* Type definition for each possible token returned. */
|
||||
typedef enum token_type_s { CNV_NO_TOK, CNV_STRING_TOK } Cnv_Token_Type_t;
|
||||
|
||||
extern char *CNVget_token(char **s, Cnv_Token_Type_t *type);
|
||||
|
||||
/*=== MACROS ===========================*/
|
||||
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
#define DIR_PATHSEP "\\"
|
||||
#else
|
||||
#define DIR_PATHSEP "/"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define strdup _strdup
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#include "gettokens.h"
|
||||
|
||||
|
||||
|
||||
char *
|
||||
CNVgettok(char **s)
|
||||
char *CNVgettok(char **s)
|
||||
{
|
||||
char *buf; /* temporary storage to copy token into */
|
||||
/*char *temp;*/ /* temporary storage to copy token into */
|
||||
|
|
@ -52,7 +30,7 @@ CNVgettok(char **s)
|
|||
|
||||
/* skip over any white space */
|
||||
|
||||
while (isspace_c(**s) || (**s == '=') ||
|
||||
while (isspace(**s) || (**s == '=') ||
|
||||
(**s == '(') || (**s == ')') || (**s == ','))
|
||||
(*s)++;
|
||||
|
||||
|
|
@ -71,7 +49,7 @@ CNVgettok(char **s)
|
|||
/* or a mess o' characters. */
|
||||
i = 0;
|
||||
while ( (**s != '\0') &&
|
||||
(! ( isspace_c(**s) || (**s == '=') ||
|
||||
(! ( isspace(**s) || (**s == '=') ||
|
||||
(**s == '(') || (**s == ')') ||
|
||||
(**s == ',')
|
||||
) ) ) {
|
||||
|
|
@ -85,7 +63,7 @@ CNVgettok(char **s)
|
|||
|
||||
/* skip over white space up to next token */
|
||||
|
||||
while (isspace_c(**s) || (**s == '=') ||
|
||||
while (isspace(**s) || (**s == '=') ||
|
||||
(**s == '(') || (**s == ')') || (**s == ','))
|
||||
(*s)++;
|
||||
|
||||
|
|
@ -98,11 +76,10 @@ CNVgettok(char **s)
|
|||
if (buf) free(buf);
|
||||
|
||||
return ret_str;
|
||||
}
|
||||
} /* end of function CNVgettok */
|
||||
|
||||
|
||||
|
||||
/*=== Static CNVget_token ROUTINE =============*/
|
||||
/*
|
||||
Get the next token from the input string together with its type.
|
||||
The input string pointer
|
||||
|
|
@ -110,9 +87,7 @@ is advanced to the following token and the token from the input
|
|||
string is copied to malloced storage and a pointer to that storage
|
||||
is returned. The original input string is undisturbed.
|
||||
*/
|
||||
|
||||
char *
|
||||
CNVget_token(char **s, Cnv_Token_Type_t *type)
|
||||
char * CNVget_token(char **s, Cnv_Token_Type_t *type)
|
||||
{
|
||||
char *ret_str; /* storage for returned string */
|
||||
|
||||
|
|
@ -132,4 +107,126 @@ CNVget_token(char **s, Cnv_Token_Type_t *type)
|
|||
break;
|
||||
}
|
||||
return ret_str;
|
||||
}
|
||||
} /* end of function CNVget_token */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Function takes as input a string token from a SPICE
|
||||
deck and returns a floating point equivalent value.
|
||||
*/
|
||||
int cnv_get_spice_value(char *str, /* IN - The value text e.g. 1.2K */
|
||||
double *p_value) /* OUT - The numerical value */
|
||||
{
|
||||
/* the following were "int4" devices - jpm */
|
||||
size_t len;
|
||||
size_t i;
|
||||
int n_matched;
|
||||
|
||||
/* A SPICE size line. <= 80 characters plus '\n\0' */
|
||||
typedef char line_t[82];
|
||||
line_t val_str;
|
||||
|
||||
char c = ' ';
|
||||
char c1;
|
||||
|
||||
double scale_factor;
|
||||
double value;
|
||||
|
||||
/* Scan the input string looking for an alpha character that is not */
|
||||
/* 'e' or 'E'. Such a character is assumed to be an engineering */
|
||||
/* suffix as defined in the Spice 2G.6 user's manual. */
|
||||
|
||||
len = strlen(str);
|
||||
if (len > sizeof(val_str) - 1)
|
||||
len = sizeof(val_str) - 1;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
c = str[i];
|
||||
if (isalpha(c) && (c != 'E') && (c != 'e'))
|
||||
break;
|
||||
else if (isspace(c))
|
||||
break;
|
||||
else
|
||||
val_str[i] = c;
|
||||
}
|
||||
val_str[i] = '\0';
|
||||
|
||||
/* Determine the scale factor */
|
||||
|
||||
if ((i >= len) || (! isalpha(c)))
|
||||
scale_factor = 1.0;
|
||||
else {
|
||||
c = (char) tolower(c);
|
||||
|
||||
switch (c) {
|
||||
|
||||
case 't':
|
||||
scale_factor = 1.0e12;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
scale_factor = 1.0e9;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
scale_factor = 1.0e3;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
scale_factor = 1.0e-6;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
scale_factor = 1.0e-9;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
scale_factor = 1.0e-12;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
scale_factor = 1.0e-15;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
i++;
|
||||
if (i >= len) {
|
||||
scale_factor = 1.0e-3;
|
||||
break;
|
||||
}
|
||||
c1 = str[i];
|
||||
if (!isalpha(c1)) {
|
||||
scale_factor = 1.0e-3;
|
||||
break;
|
||||
}
|
||||
c1 = (char) toupper(c1);
|
||||
if (c1 == 'E')
|
||||
scale_factor = 1.0e6;
|
||||
else if (c1 == 'I')
|
||||
scale_factor = 25.4e-6;
|
||||
else
|
||||
scale_factor = 1.0e-3;
|
||||
break;
|
||||
|
||||
default:
|
||||
scale_factor = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert the numeric portion to a float and multiply by the */
|
||||
/* scale factor. */
|
||||
|
||||
n_matched = sscanf(val_str, "%le", &value);
|
||||
|
||||
if (n_matched < 1) {
|
||||
*p_value = 0.0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*p_value = value * scale_factor;
|
||||
return 0;
|
||||
} /* end of function cnv_get_spice_value */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -13,39 +13,33 @@ typedef struct Point3Struct { /* 3d point */
|
|||
} Point3;
|
||||
typedef Point3 Vector3;
|
||||
|
||||
//FIXME
|
||||
double BilinearInterpolation(double q11, double q12, double q21, double q22, double x1, double x2, double y1, double y2, double x, double y);
|
||||
|
||||
|
||||
/* Function to find the cross over point (the point before
|
||||
which elements are smaller than or equal to x and after
|
||||
which greater than x)
|
||||
http://www.geeksforgeeks.org/find-k-closest-elements-given-value/ */
|
||||
int
|
||||
findCrossOver(double arr[], int low, int high, double x)
|
||||
Returns the highest index of an element in arr whose value is less than
|
||||
or equal to x or 0 if all elements are greater than x. It is assumed that
|
||||
arr is sorted in order of increasing values. */
|
||||
int findCrossOver(double arr[], int n, double x)
|
||||
{
|
||||
int mid;
|
||||
// Base cases
|
||||
if (arr[high] <= x) // x is greater than all
|
||||
return high;
|
||||
if (arr[low] > x) // x is smaller than all
|
||||
return low;
|
||||
int low = 0;
|
||||
int high = n; /* 1 more than highest index */
|
||||
while (high - low > 1) {
|
||||
const int mid = (low + high) / 2;
|
||||
if (arr[mid] > x) { /* search lower */
|
||||
high = mid;
|
||||
}
|
||||
else { /* search higher */
|
||||
low = mid;
|
||||
}
|
||||
} /* end of bisecting loop */
|
||||
|
||||
// Find the middle point
|
||||
mid = (low + high)/2; /* low + (high - low)/2 */
|
||||
return low;
|
||||
} /* end of function findCrossOver */
|
||||
|
||||
/* If x is same as middle element, then return mid */
|
||||
if (arr[mid] <= x && arr[mid+1] > x)
|
||||
return mid;
|
||||
|
||||
/* If x is greater than arr[mid], then either arr[mid + 1]
|
||||
is ceiling of x or ceiling lies in arr[mid+1...high] */
|
||||
if (arr[mid] < x)
|
||||
return findCrossOver(arr, mid+1, high, x);
|
||||
|
||||
return findCrossOver(arr, low, mid - 1, x);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* https://helloacm.com/cc-function-to-compute-the-bilinear-interpolation/ */
|
||||
double
|
||||
BilinearInterpolation(double q11, double q12, double q21, double q22, double x1, double x2, double y1, double y2, double x, double y)
|
||||
|
|
@ -74,7 +68,6 @@ BilinearInterpolation(double q11, double q12, double q21, double q22, double x1,
|
|||
*
|
||||
*/
|
||||
|
||||
#if 0
|
||||
|
||||
double
|
||||
trilinear(Point3 *p, double *d, int xsize, int ysize, int zsize, double def)
|
||||
|
|
@ -152,13 +145,31 @@ trilinear(Point3 *p, double *d, int xsize, int ysize, int zsize, double def)
|
|||
#endif
|
||||
|
||||
|
||||
double BilinearInterpolation(double x, double y,
|
||||
int xind, int yind, double **td)
|
||||
{
|
||||
double V00, V10, V01, V11, Vxyz;
|
||||
|
||||
V00 = td[yind][xind];
|
||||
V10 = td[yind][xind+1];
|
||||
V01 = td[yind+1][xind];
|
||||
V11 = td[yind+1][xind+1];
|
||||
|
||||
Vxyz = V00 * (1 - x) * (1 - y) +
|
||||
V10 * x * (1 - y) +
|
||||
V01 * (1 - x) * y +
|
||||
V11 * x * y;
|
||||
return Vxyz;
|
||||
} /* end of function BilinearInterpolation */
|
||||
|
||||
|
||||
|
||||
/* trilinear interpolation
|
||||
Paul Bourke
|
||||
July 1997
|
||||
http://paulbourke.net/miscellaneous/interpolation/ */
|
||||
|
||||
double
|
||||
TrilinearInterpolation(double x, double y, double z, int xind, int yind, int zind, double ***td)
|
||||
double TrilinearInterpolation(double x, double y, double z,
|
||||
int xind, int yind, int zind, double ***td)
|
||||
{
|
||||
double V000, V100, V010, V001, V101, V011, V110, V111, Vxyz;
|
||||
|
||||
|
|
@ -172,12 +183,18 @@ TrilinearInterpolation(double x, double y, double z, int xind, int yind, int zin
|
|||
V111 = td[zind+1][yind+1][xind+1];
|
||||
|
||||
Vxyz = V000 * (1 - x) * (1 - y) * (1 - z) +
|
||||
V100 * x * (1 - y) * (1 - z) +
|
||||
V010 * (1 - x) * y * (1 - z) +
|
||||
V001 * (1 - x) * (1 - y) * z +
|
||||
V101 * x * (1 - y) * z +
|
||||
V011 * (1 - x) * y * z +
|
||||
V110 * x * y * (1 - z) +
|
||||
V111 * x * y * z;
|
||||
V100 * x * (1 - y) * (1 - z) +
|
||||
V010 * (1 - x) * y * (1 - z) +
|
||||
V001 * (1 - x) * (1 - y) * z +
|
||||
V101 * x * (1 - y) * z +
|
||||
V011 * (1 - x) * y * z +
|
||||
V110 * x * y * (1 - z) +
|
||||
V111 * x * y * z;
|
||||
return Vxyz;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -203,6 +203,7 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\misc\dstring.c" />
|
||||
<ClCompile Include="icm\analog\climit\climit-cfunc.c" />
|
||||
<ClCompile Include="icm\analog\climit\climit-ifspec.c" />
|
||||
<ClCompile Include="icm\analog\divide\divide-cfunc.c" />
|
||||
|
|
@ -291,7 +292,10 @@
|
|||
<None Include="..\..\src\xspice\icm\analog\file_source\cfunc.mod" />
|
||||
<None Include="..\..\src\xspice\icm\analog\file_source\ifspec.ifs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\include\ngspice\dstring.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\misc\dstring.c" />
|
||||
<ClCompile Include="icm\digital\adc_bridge\adc_bridge-cfunc.c">
|
||||
<AdditionalIncludeDirectories>..\..\src\xspice\%(RelativeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
|
|
@ -371,7 +372,10 @@
|
|||
<None Include="..\..\src\xspice\icm\digital\d_xor\cfunc.mod" />
|
||||
<None Include="..\..\src\xspice\icm\digital\d_xor\ifspec.ifs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\include\ngspice\dstring.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\misc\dstring.c" />
|
||||
<ClCompile Include="icm\spice2poly\icm_spice2poly\icm_spice2poly-cfunc.c" />
|
||||
<ClCompile Include="icm\spice2poly\icm_spice2poly\icm_spice2poly-ifspec.c" />
|
||||
<ClCompile Include="..\..\src\xspice\icm\dlmain.c" />
|
||||
|
|
@ -210,7 +211,10 @@
|
|||
<ItemGroup>
|
||||
<None Include="..\..\src\xspice\icm\spice2poly\icm_spice2poly\cfunc.mod" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\include\ngspice\dstring.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@
|
|||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;..\mada;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;CIDER;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>
|
||||
|
|
@ -124,7 +124,7 @@
|
|||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;..\mada;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>
|
||||
</ExceptionHandling>
|
||||
|
|
@ -151,7 +151,7 @@
|
|||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;..\mada;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;CIDER;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>
|
||||
|
|
@ -183,7 +183,7 @@
|
|||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;..\mada;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>
|
||||
</ExceptionHandling>
|
||||
|
|
@ -203,6 +203,7 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\misc\dstring.c" />
|
||||
<ClCompile Include="icm\table\table2D\table2D-cfunc.c">
|
||||
<AdditionalIncludeDirectories>..\..\src\xspice\icm\$(ProjectName);..\..\src\xspice\%(RelativeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
|
|
@ -219,7 +220,11 @@
|
|||
<None Include="..\..\src\xspice\icm\table\table3D\cfunc.mod" />
|
||||
<None Include="..\..\src\xspice\icm\table\table3D\ifspec.ifs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\include\ngspice\dstring.h" />
|
||||
<ClInclude Include="..\..\src\xspice\icm\dlmain.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\misc\dstring.c" />
|
||||
<ClCompile Include="icm\xtradev\aswitch\aswitch-cfunc.c">
|
||||
<AdditionalIncludeDirectories>..\..\src\xspice\%(RelativeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
|
|
@ -271,7 +272,10 @@
|
|||
<None Include="..\..\src\xspice\icm\xtradev\memristor\cfunc.mod" />
|
||||
<None Include="..\..\src\xspice\icm\xtradev\memristor\ifspec.ifs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\include\ngspice\dstring.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ call .\aux-udnfunc.bat $(ProjectName)</Command>
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\misc\dstring.c" />
|
||||
<ClCompile Include="icm\xtraevt\d_to_real\d_to_real-cfunc.c" />
|
||||
<ClCompile Include="icm\xtraevt\d_to_real\d_to_real-ifspec.c" />
|
||||
<ClCompile Include="icm\xtraevt\int\int-udnfunc.c" />
|
||||
|
|
@ -226,7 +227,10 @@ call .\aux-udnfunc.bat $(ProjectName)</Command>
|
|||
<None Include="..\..\src\xspice\icm\xtraevt\real_to_v\cfunc.mod" />
|
||||
<None Include="..\..\src\xspice\icm\xtraevt\real_to_v\ifspec.ifs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\include\ngspice\dstring.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
Loading…
Reference in New Issue