Support use of vector defaults for XSPICE vector parameters.
This answers Feature Request 60 - "Array as default value for parameter".
This commit is contained in:
parent
f37a292c82
commit
7ff4ad0b32
|
|
@ -101,8 +101,8 @@ struct Mif_Param_Info {
|
||||||
char *name; /* Name of this parameter */
|
char *name; /* Name of this parameter */
|
||||||
char *description; /* Description of this parameter */
|
char *description; /* Description of this parameter */
|
||||||
Mif_Data_Type_t type; /* Is this a real, boolean, string, ... */
|
Mif_Data_Type_t type; /* Is this a real, boolean, string, ... */
|
||||||
Mif_Boolean_t has_default; /* True if there is a default value */
|
int default_value_siz;/* Size of default_values array. */
|
||||||
Mif_Parse_Value_t default_value; /* The default value */
|
Mif_Parse_Value_t *default_values; /* The default values (array). */
|
||||||
Mif_Boolean_t has_lower_limit; /* True if there is a lower limit */
|
Mif_Boolean_t has_lower_limit; /* True if there is a lower limit */
|
||||||
Mif_Parse_Value_t lower_limit; /* The lower limit for this parameter */
|
Mif_Parse_Value_t lower_limit; /* The lower limit for this parameter */
|
||||||
Mif_Boolean_t has_upper_limit; /* True if there is a upper limit */
|
Mif_Boolean_t has_upper_limit; /* True if there is a upper limit */
|
||||||
|
|
|
||||||
|
|
@ -208,8 +208,8 @@ typedef struct {
|
||||||
char *name; /* Name of this parameter */
|
char *name; /* Name of this parameter */
|
||||||
char *description; /* Description of this parameter */
|
char *description; /* Description of this parameter */
|
||||||
Data_Type_t type; /* Data type, e.g. REAL, INTEGER, ... */
|
Data_Type_t type; /* Data type, e.g. REAL, INTEGER, ... */
|
||||||
bool has_default; /* True if there is a default value */
|
int default_value_idx;/* Start of default_values.. */
|
||||||
Value_t default_value; /* The default value */
|
int default_value_cnt;/* Number of default_values.. */
|
||||||
bool has_lower_limit; /* True if there is a lower limit */
|
bool has_lower_limit; /* True if there is a lower limit */
|
||||||
Value_t lower_limit; /* The lower limit for this parameter */
|
Value_t lower_limit; /* The lower limit for this parameter */
|
||||||
bool has_upper_limit; /* True if there is a upper limit */
|
bool has_upper_limit; /* True if there is a upper limit */
|
||||||
|
|
@ -239,7 +239,14 @@ typedef struct {
|
||||||
|
|
||||||
} Inst_Var_Info_t;
|
} Inst_Var_Info_t;
|
||||||
|
|
||||||
|
/* Structure used when parsing default values from the IFS file, used below. */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool has_value;
|
||||||
|
bool advance; // Used for vector default values.
|
||||||
|
Data_Type_t kind;
|
||||||
|
Value_t u; // Union holding the value.
|
||||||
|
} My_Value_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The all encompassing structure for the ifs table information
|
* The all encompassing structure for the ifs table information
|
||||||
|
|
@ -254,7 +261,8 @@ typedef struct {
|
||||||
Param_Info_t *param; /* Array of parameter info structs */
|
Param_Info_t *param; /* Array of parameter info structs */
|
||||||
int num_inst_var; /* Number of entries in the instance var table(s) */
|
int num_inst_var; /* Number of entries in the instance var table(s) */
|
||||||
Inst_Var_Info_t *inst_var; /* Array of instance variable info structs */
|
Inst_Var_Info_t *inst_var; /* Array of instance variable info structs */
|
||||||
|
int num_default_values;
|
||||||
|
My_Value_t *defaults_var; /* Array of annotated values. */
|
||||||
} Ifs_Table_t;
|
} Ifs_Table_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,16 +115,14 @@ Ifs_Table_t *parser_ifs_table;
|
||||||
|
|
||||||
int ifs_num_errors;
|
int ifs_num_errors;
|
||||||
|
|
||||||
static size_t alloced_size [4];
|
/* Allocated and initial sizes of tables for parse results. */
|
||||||
|
|
||||||
/*
|
static size_t alloced_size [5];
|
||||||
* !!!!! Make sure these are large enough so that they never get realloced
|
|
||||||
* !!!!! since that will cause garbage uninitialized data...
|
#define DEFAULT_SIZE_CONN 10
|
||||||
* !!!!! (FIX THIS!)
|
#define DEFAULT_SIZE_PARAM 10
|
||||||
*/
|
#define DEFAULT_SIZE_INST_VAR 10
|
||||||
#define DEFAULT_SIZE_CONN 100
|
#define DEFAULT_SIZE_DEFAULTS 100
|
||||||
#define DEFAULT_SIZE_PARAM 100
|
|
||||||
#define DEFAULT_SIZE_INST_VAR 100
|
|
||||||
#define GROW_SIZE 10
|
#define GROW_SIZE 10
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
@ -132,6 +130,7 @@ typedef enum {
|
||||||
TBL_PORT,
|
TBL_PORT,
|
||||||
TBL_PARAMETER,
|
TBL_PARAMETER,
|
||||||
TBL_STATIC_VAR,
|
TBL_STATIC_VAR,
|
||||||
|
TBL_DEFAULTS,
|
||||||
} Table_t;
|
} Table_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -368,15 +367,19 @@ assign_limits (Data_Type_t type, Param_Info_t *param, Range_t range)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Advance the item variable, checking for table overflow. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_item_num (void)
|
check_item_num (void)
|
||||||
{
|
{
|
||||||
|
item++;
|
||||||
if (item-item_offset >= ITEM_BUFFER_SIZE) {
|
if (item-item_offset >= ITEM_BUFFER_SIZE) {
|
||||||
fatal ("Too many items in table - split into sub-tables");
|
fatal("Too many items in table - split into sub-tables");
|
||||||
}
|
}
|
||||||
if (item > (int) alloced_size [context.table] ) {
|
if (item >= (int) alloced_size [context.table] ) {
|
||||||
switch (context.table) {
|
switch (context.table) {
|
||||||
case TBL_NAME:
|
case TBL_NAME: // Fixed size.
|
||||||
|
case TBL_DEFAULTS: // Handled in store_default_value().
|
||||||
break;
|
break;
|
||||||
case TBL_PORT:
|
case TBL_PORT:
|
||||||
alloced_size[context.table] += GROW_SIZE;
|
alloced_size[context.table] += GROW_SIZE;
|
||||||
|
|
@ -407,7 +410,6 @@ check_item_num (void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
@ -429,6 +431,7 @@ check_end_item_num (void)
|
||||||
num_items_fixed = true;
|
num_items_fixed = true;
|
||||||
switch (context.table) {
|
switch (context.table) {
|
||||||
case TBL_NAME:
|
case TBL_NAME:
|
||||||
|
case TBL_DEFAULTS:
|
||||||
break;
|
break;
|
||||||
case TBL_PORT:
|
case TBL_PORT:
|
||||||
TBL->num_conn = num_items;
|
TBL->num_conn = num_items;
|
||||||
|
|
@ -445,11 +448,38 @@ check_end_item_num (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INIT(n) item = (n); item_offset = (n); num_items = (n); num_items_fixed = false
|
#define INIT(n) item = (n); item_offset = (n); num_items = (n); num_items_fixed = false
|
||||||
#define ITEM check_item_num()
|
#define ITEM check_item_num() // Advances the item_buffer index.
|
||||||
#define END check_end_item_num()
|
#define END check_end_item_num() // Check for excessive values in later row.
|
||||||
|
|
||||||
|
/* Store a default value for a parameter. */
|
||||||
|
|
||||||
|
static void store_default_value(My_Value_t *vp)
|
||||||
|
{
|
||||||
|
if (TBL->num_default_values >= alloced_size[TBL_DEFAULTS]) {
|
||||||
|
/* Expand table. */
|
||||||
|
|
||||||
|
alloced_size [TBL_DEFAULTS] += GROW_SIZE * 5;
|
||||||
|
TBL->defaults_var = (My_Value_t *) realloc(TBL->defaults_var,
|
||||||
|
alloced_size[TBL_DEFAULTS] * sizeof (My_Value_t));
|
||||||
|
if (!TBL->defaults_var) {
|
||||||
|
fatal ("Error allocating memory for default parameter values");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TBL->defaults_var[TBL->num_default_values++] = *vp;
|
||||||
|
if (vp->advance)
|
||||||
|
ITEM; // Count another parameter sub-table.
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
/* The parser perfoms a double scan for each row (labelled line), with the
|
||||||
|
* row spanning multiple sub-tables (individual connection definitions etc.).
|
||||||
|
* Values and other information are copied into the item_buffer[]
|
||||||
|
* array as they are recognised and then moved to their destination stucture
|
||||||
|
* TBL->xxxx[index] when the whole row has been parsed. Default parameter
|
||||||
|
* values are hndled differently and copied directly to TBL->defaults_var.
|
||||||
|
*/
|
||||||
|
|
||||||
%token TOK_ALLOWED_TYPES
|
%token TOK_ALLOWED_TYPES
|
||||||
%token TOK_ARRAY
|
%token TOK_ARRAY
|
||||||
%token TOK_ARRAY_BOUNDS
|
%token TOK_ARRAY_BOUNDS
|
||||||
|
|
@ -501,6 +531,10 @@ check_end_item_num (void)
|
||||||
%token TOK_SPICE_MODEL_NAME
|
%token TOK_SPICE_MODEL_NAME
|
||||||
%token TOK_STRING_LITERAL
|
%token TOK_STRING_LITERAL
|
||||||
|
|
||||||
|
/* This declares the type of Bison's "semantic values" (the value associated
|
||||||
|
* with an instance of a symbol of the grammer, $$), defining YYSTYPE.
|
||||||
|
*/
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
Ctype_List_t *ctype_list;
|
Ctype_List_t *ctype_list;
|
||||||
Dir_t dir;
|
Dir_t dir;
|
||||||
|
|
@ -549,6 +583,7 @@ YYSTYPE item_buffer [ITEM_BUFFER_SIZE];
|
||||||
ifs_file : {TBL->num_conn = 0;
|
ifs_file : {TBL->num_conn = 0;
|
||||||
TBL->num_param = 0;
|
TBL->num_param = 0;
|
||||||
TBL->num_inst_var = 0;
|
TBL->num_inst_var = 0;
|
||||||
|
TBL->num_default_values = 0;
|
||||||
|
|
||||||
saw_function_name = false;
|
saw_function_name = false;
|
||||||
saw_model_name = false;
|
saw_model_name = false;
|
||||||
|
|
@ -556,6 +591,7 @@ ifs_file : {TBL->num_conn = 0;
|
||||||
alloced_size [TBL_PORT] = DEFAULT_SIZE_CONN;
|
alloced_size [TBL_PORT] = DEFAULT_SIZE_CONN;
|
||||||
alloced_size [TBL_PARAMETER] = DEFAULT_SIZE_PARAM;
|
alloced_size [TBL_PARAMETER] = DEFAULT_SIZE_PARAM;
|
||||||
alloced_size [TBL_STATIC_VAR] = DEFAULT_SIZE_INST_VAR;
|
alloced_size [TBL_STATIC_VAR] = DEFAULT_SIZE_INST_VAR;
|
||||||
|
alloced_size [TBL_DEFAULTS] = DEFAULT_SIZE_DEFAULTS;
|
||||||
|
|
||||||
TBL->conn = (Conn_Info_t*)
|
TBL->conn = (Conn_Info_t*)
|
||||||
calloc(DEFAULT_SIZE_CONN, sizeof (Conn_Info_t));
|
calloc(DEFAULT_SIZE_CONN, sizeof (Conn_Info_t));
|
||||||
|
|
@ -563,7 +599,10 @@ ifs_file : {TBL->num_conn = 0;
|
||||||
calloc (DEFAULT_SIZE_PARAM, sizeof (Param_Info_t));
|
calloc (DEFAULT_SIZE_PARAM, sizeof (Param_Info_t));
|
||||||
TBL->inst_var = (Inst_Var_Info_t*)
|
TBL->inst_var = (Inst_Var_Info_t*)
|
||||||
calloc (DEFAULT_SIZE_INST_VAR, sizeof (Inst_Var_Info_t));
|
calloc (DEFAULT_SIZE_INST_VAR, sizeof (Inst_Var_Info_t));
|
||||||
if (! (TBL->conn && TBL->param && TBL->inst_var) ) {
|
TBL->defaults_var = (My_Value_t *)
|
||||||
|
calloc(DEFAULT_SIZE_DEFAULTS, sizeof (My_Value_t));
|
||||||
|
if (! (TBL->conn && TBL->param &&
|
||||||
|
TBL->inst_var && TBL->defaults_var) ) {
|
||||||
fatal ("Could not allocate enough memory");
|
fatal ("Could not allocate enough memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -701,18 +740,8 @@ parameter_table_item : TOK_PARAMETER_NAME list_of_ids
|
||||||
check_dtype_not_pointer (ITEM_BUF(i).dtype);
|
check_dtype_not_pointer (ITEM_BUF(i).dtype);
|
||||||
TBL->param[i].type = ITEM_BUF(i).dtype;
|
TBL->param[i].type = ITEM_BUF(i).dtype;
|
||||||
}}
|
}}
|
||||||
| TOK_DEFAULT_VALUE list_of_values
|
| TOK_DEFAULT_VALUE list_of_default_values
|
||||||
{int i;
|
{END; } // Check against current sub-table count.
|
||||||
END;
|
|
||||||
FOR_ITEM (i) {
|
|
||||||
TBL->param[i].has_default =
|
|
||||||
ITEM_BUF(i).value.has_value;
|
|
||||||
if (TBL->param[i].has_default) {
|
|
||||||
assign_value (TBL->param[i].type,
|
|
||||||
&TBL->param[i].default_value,
|
|
||||||
ITEM_BUF(i).value);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
| TOK_LIMITS list_of_ranges
|
| TOK_LIMITS list_of_ranges
|
||||||
{int i;
|
{int i;
|
||||||
END;
|
END;
|
||||||
|
|
@ -870,10 +899,17 @@ number_or_dash : TOK_DASH {$$.has_bound = false;}
|
||||||
$$.bound = $1;}
|
$$.bound = $1;}
|
||||||
;
|
;
|
||||||
|
|
||||||
list_of_values : /* empty */
|
list_of_pure_values : value { $1.advance = 1; store_default_value(&$1); }
|
||||||
| list_of_values value_or_dash {ITEM; BUF.value = $2;}
|
| list_of_pure_values value
|
||||||
|
{ $2.advance = 0; store_default_value(&$2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
list_of_default_values : /* empty */
|
||||||
|
| list_of_default_values value_or_dash
|
||||||
|
{ $2.advance = 1; store_default_value(&$2); }
|
||||||
|
| list_of_default_values
|
||||||
|
TOK_LBRACKET list_of_pure_values TOK_RBRACKET
|
||||||
|
|
||||||
value_or_dash : TOK_DASH {$$.has_value = false;}
|
value_or_dash : TOK_DASH {$$.has_value = false;}
|
||||||
| value
|
| value
|
||||||
;
|
;
|
||||||
|
|
|
||||||
|
|
@ -39,18 +39,6 @@ NON-STANDARD FEATURES
|
||||||
|
|
||||||
#include "cmpp.h"
|
#include "cmpp.h"
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool has_value;
|
|
||||||
Data_Type_t kind;
|
|
||||||
union {
|
|
||||||
bool bvalue;
|
|
||||||
int ivalue;
|
|
||||||
double rvalue;
|
|
||||||
Complex_t cvalue;
|
|
||||||
char *svalue;
|
|
||||||
} u;
|
|
||||||
} My_Value_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool has_bound;
|
bool has_bound;
|
||||||
My_Value_t bound;
|
My_Value_t bound;
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,10 @@ NON-STANDARD FEATURES
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "cmpp.h"
|
#include "cmpp.h"
|
||||||
|
|
||||||
/* Local function prototypes */
|
/* Local function prototypes */
|
||||||
|
|
@ -183,6 +187,8 @@ EXITPOINT:
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
xrc = -1;
|
xrc = -1;
|
||||||
}
|
}
|
||||||
|
if (xrc < 0 && filename)
|
||||||
|
unlink(filename); // So "make" will not see it.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filename != (char *) NULL) {
|
if (filename != (char *) NULL) {
|
||||||
|
|
@ -680,29 +686,91 @@ static int write_param_info(
|
||||||
FILE *fp, /* File to write to */
|
FILE *fp, /* File to write to */
|
||||||
Ifs_Table_t *ifs_table) /* Table of Interface Specification data */
|
Ifs_Table_t *ifs_table) /* Table of Interface Specification data */
|
||||||
{
|
{
|
||||||
int xrc = 0;
|
Param_Info_t * const param = ifs_table->param;
|
||||||
int i;
|
const int num_param = ifs_table->num_param;
|
||||||
|
int rc, xrc = 0;
|
||||||
|
int i, dv_idx;
|
||||||
const char *str;
|
const char *str;
|
||||||
|
|
||||||
|
|
||||||
/* Only write the paramTable if there is something to put in it. */
|
/* Only write the paramTable if there is something to put in it. */
|
||||||
/* Otherwise, we will put NULL in the SPICEdev structure in its slot */
|
/* Otherwise, we will put NULL in the SPICEdev structure in its slot */
|
||||||
|
|
||||||
if (ifs_table->num_param == 0) {
|
if (num_param <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write the default values for each parameter. */
|
||||||
|
|
||||||
/* Write the structure beginning */
|
for (i = 0, dv_idx = 0, rc = 0; i < num_param; i++) {
|
||||||
int rc = 0;
|
Param_Info_t * p_param_cur = param + i;
|
||||||
|
My_Value_t * p_val = ifs_table->defaults_var + dv_idx;
|
||||||
|
int start_index = dv_idx;
|
||||||
|
|
||||||
|
if (dv_idx >= ifs_table->num_default_values) {
|
||||||
|
fprintf(stderr, "Not enough default values for parameter: %s.\n",
|
||||||
|
p_param_cur->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p_val->has_value) {
|
||||||
|
/* Dummy entry, no default values. */
|
||||||
|
|
||||||
|
++dv_idx;
|
||||||
|
p_param_cur->default_value_cnt = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rc |= fprintf(fp, "static struct Mif_Parse_Value %s_default[] = {\n",
|
||||||
|
p_param_cur->name);
|
||||||
|
|
||||||
|
do { // Write the default values for this parameter.
|
||||||
|
if (!p_val->advance && !p_param_cur->is_array) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Vector initialisation of default values "
|
||||||
|
"for non-vector parameter: %s.\n",
|
||||||
|
p_param_cur->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_val->kind != p_param_cur->type) {
|
||||||
|
if (p_val->kind == CMPP_INTEGER &&
|
||||||
|
p_param_cur->type == CMPP_REAL) {
|
||||||
|
/* Promote it. */
|
||||||
|
|
||||||
|
p_val->u.rvalue = p_val->u.ivalue;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Data type of default value does not match for "
|
||||||
|
"parameter: %s.\n",
|
||||||
|
p_param_cur->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str = value_to_str(p_param_cur->type, p_val->u);
|
||||||
|
rc |= fprintf(fp, " %s,\n", str);
|
||||||
|
++dv_idx; ++p_val;
|
||||||
|
} while (dv_idx < ifs_table->num_default_values && !p_val->advance);
|
||||||
|
|
||||||
|
rc |= fprintf(fp, "};\n\n");
|
||||||
|
p_param_cur->default_value_cnt = dv_idx - start_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check outputs */
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
print_error("Writing of default param values failed.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the main parameter structure beginning. */
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
rc |= fprintf(fp,
|
rc |= fprintf(fp,
|
||||||
"\n"
|
"\n"
|
||||||
"static Mif_Param_Info_t MIFparamTable[] = {\n");
|
"static Mif_Param_Info_t MIFparamTable[] = {\n");
|
||||||
|
|
||||||
|
|
||||||
/* Write out an entry for each parameter in the table */
|
/* Write out an entry for each parameter in the table */
|
||||||
const Param_Info_t * const param = ifs_table->param;
|
|
||||||
const int num_param = ifs_table->num_param;
|
|
||||||
for (i = 0; i < num_param; i++) {
|
for (i = 0; i < num_param; i++) {
|
||||||
const Param_Info_t * const p_param_cur = param + i;
|
const Param_Info_t * const p_param_cur = param + i;
|
||||||
|
|
||||||
|
|
@ -713,14 +781,11 @@ static int write_param_info(
|
||||||
rc |= fprintf(fp, " %s,\n",
|
rc |= fprintf(fp, " %s,\n",
|
||||||
data_type_to_str(p_param_cur->type));
|
data_type_to_str(p_param_cur->type));
|
||||||
|
|
||||||
str = boolean_to_str(p_param_cur->has_default);
|
rc |= fprintf(fp, " %d,\n", p_param_cur->default_value_cnt);
|
||||||
rc |= fprintf(fp, " %s,\n", str);
|
if (p_param_cur->default_value_cnt)
|
||||||
|
rc |= fprintf(fp, " %s_default,\n", p_param_cur->name);
|
||||||
if (p_param_cur->has_default == true)
|
|
||||||
str = value_to_str(p_param_cur->type, p_param_cur->default_value);
|
|
||||||
else
|
else
|
||||||
str = no_value_to_str();
|
rc |= fprintf(fp, " NULL,\n");
|
||||||
rc |= fprintf(fp, " %s,\n", str);
|
|
||||||
|
|
||||||
str = boolean_to_str(p_param_cur->has_lower_limit);
|
str = boolean_to_str(p_param_cur->has_lower_limit);
|
||||||
rc |= fprintf(fp, " %s,\n", str);
|
rc |= fprintf(fp, " %s,\n", str);
|
||||||
|
|
|
||||||
|
|
@ -570,7 +570,7 @@ MIF_INP2A (
|
||||||
if(mdfast->param[i]->is_null) {
|
if(mdfast->param[i]->is_null) {
|
||||||
char* emessage;
|
char* emessage;
|
||||||
|
|
||||||
if(! param_info->has_default) {
|
if(param_info->default_value_siz == 0) {
|
||||||
if (param_info->type == MIF_STRING)
|
if (param_info->type == MIF_STRING)
|
||||||
continue; // Allow NULL
|
continue; // Allow NULL
|
||||||
emessage = tprintf("Parameter %s on model %s has no default",
|
emessage = tprintf("Parameter %s on model %s has no default",
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,6 @@ MIFsetup(
|
||||||
|
|
||||||
for( ; model != NULL; model = MIFnextModel(model)) {
|
for( ; model != NULL; model = MIFnextModel(model)) {
|
||||||
|
|
||||||
|
|
||||||
/* For each parameter not given explicitly on the .model */
|
/* For each parameter not given explicitly on the .model */
|
||||||
/* card, default it */
|
/* card, default it */
|
||||||
|
|
||||||
|
|
@ -151,42 +150,66 @@ MIFsetup(
|
||||||
model->param[i]->size = 1;
|
model->param[i]->size = 1;
|
||||||
model->param[i]->element = TMALLOC(Mif_Value_t, 1);
|
model->param[i]->element = TMALLOC(Mif_Value_t, 1);
|
||||||
} else { /* parameter is an array */
|
} else { /* parameter is an array */
|
||||||
/* MIF_INP2A() parser assures that there is an associated array connection */
|
/* If there is an associated array connection, take the
|
||||||
/* Since several instances may share this model, we have to create an array */
|
* size from there. Since several instances may share
|
||||||
/* big enough for the instance with the biggest connection array */
|
* this model, create an array big enough for the
|
||||||
max_size = 0;
|
* instance with the biggest connection array.
|
||||||
for(here = MIFinstances(model); here != NULL; here = MIFnextInstance(here)) {
|
* Otherwise, use the size of the default.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (param_info->has_conn_ref) {
|
||||||
|
for (here = MIFinstances(model), max_size = 0;
|
||||||
|
here != NULL;
|
||||||
|
here = MIFnextInstance(here)) {
|
||||||
size = here->conn[param_info->conn_ref]->size;
|
size = here->conn[param_info->conn_ref]->size;
|
||||||
if(size > max_size)
|
if (size > max_size)
|
||||||
max_size = size;
|
max_size = size;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
max_size = param_info->default_value_siz;
|
||||||
|
if (param_info->has_lower_bound &&
|
||||||
|
param_info->lower_bound > max_size) {
|
||||||
|
max_size = param_info->lower_bound;
|
||||||
|
}
|
||||||
|
}
|
||||||
model->param[i]->size = max_size;
|
model->param[i]->size = max_size;
|
||||||
model->param[i]->element = TMALLOC(Mif_Value_t, max_size);
|
model->param[i]->element = TMALLOC(Mif_Value_t, max_size);
|
||||||
} /* end if parameter is an array */
|
} /* end if parameter is an array */
|
||||||
|
|
||||||
/* set the parameter element(s) to default value */
|
if (param_info->default_value_siz == 0)
|
||||||
for(j = 0; j < model->param[i]->size; j++) {
|
continue;
|
||||||
|
|
||||||
|
/* Set the parameter element(s) to default value(s). */
|
||||||
|
|
||||||
|
for(j = 0; j < model->param[i]->size; j++) {
|
||||||
|
Mif_Parse_Value_t *dvp;
|
||||||
|
|
||||||
|
if (j >= param_info->default_value_siz) {
|
||||||
|
dvp = param_info->default_values +
|
||||||
|
param_info->default_value_siz - 1;
|
||||||
|
} else {
|
||||||
|
dvp = param_info->default_values + j;
|
||||||
|
}
|
||||||
switch(param_info->type) {
|
switch(param_info->type) {
|
||||||
|
|
||||||
case MIF_BOOLEAN:
|
case MIF_BOOLEAN:
|
||||||
model->param[i]->element[j].bvalue = param_info->default_value.bvalue;
|
model->param[i]->element[j].bvalue = dvp->bvalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIF_INTEGER:
|
case MIF_INTEGER:
|
||||||
model->param[i]->element[j].ivalue = param_info->default_value.ivalue;
|
model->param[i]->element[j].ivalue = dvp->ivalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIF_REAL:
|
case MIF_REAL:
|
||||||
model->param[i]->element[j].rvalue = param_info->default_value.rvalue;
|
model->param[i]->element[j].rvalue = dvp->rvalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIF_COMPLEX:
|
case MIF_COMPLEX:
|
||||||
model->param[i]->element[j].cvalue = param_info->default_value.cvalue;
|
model->param[i]->element[j].cvalue = dvp->cvalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIF_STRING:
|
case MIF_STRING:
|
||||||
model->param[i]->element[j].svalue = param_info->default_value.svalue;
|
model->param[i]->element[j].svalue = dvp->svalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue