diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 548456869..5ada38012 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -1968,14 +1968,28 @@ static char *get_model_type(char *line) return gettok_noparens(&beg_ptr); } +static inline char *skip_back_non_ws_nonc(const char *s, const char *start, char c) { while (s > start && !isspace_c(s[-1]) && (s[-1]!=c)) s--; return (char *) s; } + static char *get_adevice_model_name(char *line) { char *ptr_end, *ptr_beg; - - ptr_end = skip_back_ws(strchr(line, '\0'), line); - ptr_beg = skip_back_non_ws(ptr_end, line); - + char *prev; + /* F.B. added backward skipping param=val */ + for(ptr_end=strchr(line, '\0'); ptr_end>line; ) { + ptr_end = skip_back_ws(ptr_end, line); + ptr_beg = skip_back_non_ws_nonc(ptr_end, line, '='); + prev = skip_back_ws(ptr_beg, line); + if(prev>line && prev[-1]=='=') { + prev = skip_back_ws(prev-1, line); /* backskip \s*= */ + ptr_end=skip_back_non_ws(prev, line); /* backskip param= */ + } else + break; /* found model */ + } + if(ptr_beg == line) + return copy_substring(ptr_beg,ptr_beg); /* did not found the model */ + + printf("adev mod name: %s\n", ptr_beg); return copy_substring(ptr_beg, ptr_end); } @@ -8297,7 +8311,7 @@ static void inp_check_syntax(struct card *deck) } else { if (!check_ch) { - fprintf(stderr, "Warning: Unusal leading characters like '%c' or others out of '= [] ? () & %$§\"!:,'\n", *cut_line); + fprintf(stderr, "Warning: Unusal leading characters like '%c' or others out of '= [] ? () & %%$§\"!:,'\n", *cut_line); fprintf(stderr, " in netlist or included files, will be replaced with '*'\n"); check_ch = 1; /* just one warning */ } diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index 179e9abfb..1dc536696 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -97,6 +97,7 @@ static int numdevs(char *s); static wordlist *modtranslate(struct card *deck, char *subname, wordlist *new_modnames); static void devmodtranslate(struct card *deck, char *subname, wordlist * const orig_modnames); static int inp_numnodes(char c); +static char *search_adevice_model_name(char *line); #define N_GLOBAL_NODES 1005 @@ -1041,24 +1042,19 @@ translate(struct card *deck, char *formal, char *actual, char *scname, const cha translate_inst_name(&buffer, scname, name, NULL); bxx_putc(&buffer, ' '); + if(name) + tfree(name); + + /* search where the model name is and store in 'next_name' pointer */ + next_name = search_adevice_model_name(s); + if(next_name==NULL) + next_name=strchr(s,'\0'); /* not found, but process anyway */ - /* Now translate the nodes, looking ahead one token to recognize */ - /* when we reach the model name which should not be translated */ - /* here. */ - - next_name = MIFgettok(&s); - - for (;;) { - /* rotate the tokens and get the the next one */ - if (name) - tfree(name); - name = next_name; - next_name = MIFgettok(&s); - - /* if next token is NULL, name holds the model name, so exit */ - if (next_name == NULL) - break; - + /* Now translate the nodes */ + + while(s start && !isspace_c(s[-1]) && (s[-1]!=c)) s--; return (char *) s; } + +/* F.B: function to locate the model name in a A device (xspice coremodel) */ +/* a similar function is found in inpcomp.c */ +static char *search_adevice_model_name(char *line) +{ + char *ptr_end, *ptr_beg; + char *prev; + for(ptr_end=strchr(line, '\0'); ptr_end>line; ) { + ptr_end = skip_back_ws(ptr_end, line); + ptr_beg = skip_back_non_ws_nonc(ptr_end, line, '='); + prev = skip_back_ws(ptr_beg, line); + if(prev>line && prev[-1]=='=') { + prev = skip_back_ws(prev-1, line); /* backskip \s*= */ + ptr_end=skip_back_non_ws(prev, line); /* backskip param= */ + } else + break; /* found model */ + } + if(ptr_beg == line) + return NULL; + + return ptr_beg; +} +#endif + static void devmodtranslate(struct card *s, char *subname, wordlist * const orig_modnames) @@ -1658,42 +1678,24 @@ devmodtranslate(struct card *s, char *subname, wordlist * const orig_modnames) /* SDB debug statement */ printf("In devmodtranslate, found codemodel, line= %s\n", t); #endif - - /* first do refdes. */ - name = gettok(&t); /* get refdes */ - bxx_printf(&buffer, "%s ", name); - tfree(name); - - /* now do remainder of line. */ - next_name = gettok(&t); - for (;;) { - name = next_name; - next_name = gettok(&t); - - if (next_name == NULL) { - /* if next_name is NULL, we are at the line end. - * name holds the model name. Therefore, break */ - break; - - } else { - /* next_name holds something. Write name into the buffer and continue. */ - bxx_printf(&buffer, "%s ", name); - tfree(name); - } - } /* while */ - - translate_mod_name(&buffer, name, subname, orig_modnames); - tfree(name); - bxx_putc(&buffer, ' '); - -#ifdef TRACE - /* SDB debug statement */ - printf("In devmodtranslate, translated codemodel line= %s\n", buffer); -#endif - - bxx_put_cstring(&buffer, t); - tfree(s->line); - s->line = copy(bxx_buffer(&buffer)); + next_name = search_adevice_model_name(t); + if(next_name && *next_name!='!') { /* if start with !, will use a default model */ + bxx_put_substring(&buffer, t, next_name); /* put everything before model name */ + t = next_name; + name = gettok(&t); /* get modname */ + if(name==NULL) break; /* for safety but should not happen */ + translate_mod_name(&buffer, name, subname, orig_modnames); + tfree(name); + bxx_putc(&buffer, ' '); /* put a space after model name */ + bxx_put_cstring(&buffer, t); /* put the end of the line */ + #ifdef TRACE + /* SDB debug statement */ + printf("In devmodtranslate, translated codemodel line= %s\n", buffer); + #endif + /* replace the line in the card */ + tfree(s->line); + s->line = copy(bxx_buffer(&buffer)); + } break; #endif /* XSPICE */ diff --git a/src/include/ngspice/dllitf.h b/src/include/ngspice/dllitf.h index e4b19eb33..3bb86bfd0 100644 --- a/src/include/ngspice/dllitf.h +++ b/src/include/ngspice/dllitf.h @@ -79,6 +79,7 @@ struct coreInfo_t { /* added for instance parameters */ int ((*dllitf_MIFParam)(int, IFvalue *, GENinstance*, IFvalue *)); + void* nulltermination; /* For binary compatibility in future extensions */ }; #endif diff --git a/src/include/ngspice/mifcmdat.h b/src/include/ngspice/mifcmdat.h index 4a4b43f11..11ede6418 100644 --- a/src/include/ngspice/mifcmdat.h +++ b/src/include/ngspice/mifcmdat.h @@ -368,6 +368,7 @@ struct Mif_Private { int num_inst_var; /* Number of instance variables */ Mif_Inst_Var_Data_t **inst_var; /* Information about each inst variable */ Mif_Callback_t *callback; /* Callback function */ + /* new field for instance parameters - added to the end for binary compatibility */ Mif_Param_Data_t **iparam; /* Information about each inst parameter */ }; diff --git a/src/include/ngspice/mifparse.h b/src/include/ngspice/mifparse.h index 89be10120..f70a2cf68 100644 --- a/src/include/ngspice/mifparse.h +++ b/src/include/ngspice/mifparse.h @@ -115,9 +115,11 @@ struct Mif_Param_Info { Mif_Boolean_t has_upper_bound; /* True if there is an array size upper bound */ int upper_bound; /* Array size upper bound */ Mif_Boolean_t null_allowed; /* True if null is allowed for this parameter */ +#if 0 Mif_Boolean_t has_model_scope; /* True if the parameter is a model parameter */ Mif_Boolean_t has_inst_scope; /* True if the parameter is an instance parameter */ int inst_param_index; /* Index of instance parameter */ +#endif }; diff --git a/src/spicelib/analysis/cktparam.c b/src/spicelib/analysis/cktparam.c index e0f907180..6f769d5e1 100644 --- a/src/spicelib/analysis/cktparam.c +++ b/src/spicelib/analysis/cktparam.c @@ -25,7 +25,7 @@ CKTparam(CKTcircuit *ckt, GENinstance *fast, int param, IFvalue *val, IFvalue *s type = fast->GENmodPtr->GENmodType; if(DEVices[type]->DEVparam) { return(DEVices[type]->DEVparam (param, val, fast, selector)); - } else { + } else {printf("no DEVparam function for type %d %s\n",type,fast->GENmodPtr->GENmodName); return(E_BADPARM); } } diff --git a/src/spicelib/devices/dev.c b/src/spicelib/devices/dev.c index 9a5c4d2c1..26bd79d33 100644 --- a/src/spicelib/devices/dev.c +++ b/src/spicelib/devices/dev.c @@ -142,7 +142,7 @@ extern struct coreInfo_t coreInfo; /* cmexport.c */ #ifdef NDEV #include "ndev/ndevitf.h" #endif - +#define TRACE static SPICEdev *(*static_devices[])(void) = { /* URC device MUST precede both resistors and capacitors */ get_urc_info, @@ -415,7 +415,7 @@ int load_opus(const char *name) SPICEdev **devs; Evt_Udn_Info_t **udns; funptr_t fetch; - +printf("loading code model lib %s\n", name); lib = dlopen(name, RTLD_NOW); if (!lib) { msg = dlerror(); diff --git a/src/xspice/cm/cmexport.c b/src/xspice/cm/cmexport.c index fa8e9199c..b40436033 100644 --- a/src/xspice/cm/cmexport.c +++ b/src/xspice/cm/cmexport.c @@ -75,7 +75,7 @@ struct coreInfo_t coreInfo = txfree, tmalloc, trealloc, - txfree + txfree, #else GC_malloc, tcalloc, @@ -83,6 +83,8 @@ struct coreInfo_t coreInfo = no_free, GC_malloc, GC_realloc, - no_free + no_free, #endif + MIFParam, + NULL }; diff --git a/src/xspice/cmpp/mod_yacc.y b/src/xspice/cmpp/mod_yacc.y index 0b327602b..fd97bcb9e 100644 --- a/src/xspice/cmpp/mod_yacc.y +++ b/src/xspice/cmpp/mod_yacc.y @@ -113,6 +113,18 @@ static int buf_len; typedef enum {CONN, PARAM, STATIC_VAR} Id_Kind_t; + +static int inst_param_index(int param) +{ + int i, iparam; + for (i = 0; (i < param) && (i < mod_ifs_table->num_param); i++) + if(mod_ifs_table->param[i].scope != CMPP_MODEL) + iparam++; + if(iparam>=mod_ifs_table->num_param) + yyerror ("Internal error: Instance parameter not found"); + return iparam; +} + /*--------------------------------------------------------------------------*/ static char *subscript (Sub_Id_t sub_id) { @@ -452,8 +464,8 @@ macro : TOK_INIT fprintf (mod_yyout, "mif_private->param[%d]->element[%s]", i, subscript ($3)); else - fprintf (mod_yyout, "mif_private->iparam[mif_private->param[%d]->inst_param_index]->element[%s]", - i, subscript ($3)); + fprintf (mod_yyout, "mif_private->iparam[%d]->element[%s]", + inst_param_index(i), subscript ($3)); put_type (mod_yyout, mod_ifs_table->param[i].type); } | TOK_PARAM_SIZE TOK_LPAREN id TOK_RPAREN diff --git a/src/xspice/cmpp/writ_ifs.c b/src/xspice/cmpp/writ_ifs.c index c71d0ef0c..b207ffe9f 100644 --- a/src/xspice/cmpp/writ_ifs.c +++ b/src/xspice/cmpp/writ_ifs.c @@ -892,6 +892,7 @@ static int write_param_info( str = boolean_to_str(p_param_cur->null_allowed); rc |= fprintf(fp, " %s,\n", str); + #if 0 /* F.B. info about instance parameters */ str = boolean_to_str(p_param_cur->scope != CMPP_INSTANCE); rc |= fprintf(fp, " %s,\n", str); @@ -899,7 +900,8 @@ static int write_param_info( rc |= fprintf(fp, " %s,\n", str); str = integer_to_str(p_param_cur->scope == CMPP_MODEL ? -1 : inst_param_index); rc |= fprintf(fp, " %s,\n", str); - + #endif + if(p_param_cur->scope != CMPP_MODEL) inst_param_index++; @@ -1100,7 +1102,7 @@ static int write_SPICEdev( /* Write the names of the generic code model functions */ rc |= fprintf(fp, - " .DEVparam = NULL,\n" + " .DEVparam = MIFParam,\n" " .DEVmodParam = MIFmParam,\n" " .DEVload = MIFload,\n" " .DEVsetup = MIFsetup,\n" diff --git a/src/xspice/mif/mif_inp2.c b/src/xspice/mif/mif_inp2.c index 2f5851c15..3bb005cf4 100644 --- a/src/xspice/mif/mif_inp2.c +++ b/src/xspice/mif/mif_inp2.c @@ -110,6 +110,8 @@ static void gc_end(void); static char *alltokens[BSIZE_SP]; static int curtoknr = 0; +static int MIFinp2_params(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, GENinstance* inst, int type); + /* ********************************************************************* */ @@ -157,7 +159,8 @@ and error checks are performed. At this point, nothing should be left in 'line' -------------------------------------------------------------------------*/ - +extern INPmodel *modtab; +#define TRACE void MIF_INP2A ( CKTcircuit *ckt, /* circuit structure to put mod/inst structs in */ @@ -199,7 +202,8 @@ MIF_INP2A ( /* SDB debug statement */ printf("In MIF_INP2A, line to process = %s . . . \n", current->line); #endif - + printf("->modtab %p\n", modtab); + /* get the line text from the card struct */ line = current->line; @@ -209,18 +213,33 @@ MIF_INP2A ( /* get the name of the instance and add it to the symbol table */ name = copy(MIFgettok(&line)); INPinsert(&name, tab); - + + printf("->modtab %p\n", modtab); + /* locate the last token on the line (i.e. model name) and put it into "model" */ + /* locate the model name */ while(*line != '\0') { - model = MIFgettok(&line); + char* linetmp; + tmp_token = MIFgettok(&line); + linetmp=line; + do + linetmp--; + while(linetmp > current->line && isspace_c(*linetmp)); + if(*linetmp == '=') + break; + printf("model updated to %s, char %c, modtab %p\n", tmp_token, *linetmp,modtab); + model = tmp_token; } - + printf("->modtab %p\n", modtab); /* make sure the model name was there. */ if(model == NULL) { LITERR("Missing model on A type device"); gc_end(); return; } + + /* if model name starts with !, use or create a default model */ + /* TODO */ /* Locate model from pass 1. If it hasn't been processed yet, */ /* allocate a structure in ckt for it, process its parameters */ @@ -230,7 +249,7 @@ MIF_INP2A ( gc_end(); return; } - + printf("Device type %d\n", thismodel->INPmodType); /* get the integer index into the DEVices data array for this */ /* model */ type = thismodel->INPmodType; @@ -589,6 +608,10 @@ MIF_INP2A ( } } } + + /* parse the end of the line for reading instance parameters */ + MIFinp2_params(line, ckt, tab, current, (GENinstance*) fast[0], type); + gc_end(); } @@ -1028,6 +1051,48 @@ MIFget_port( } +static int +MIFinp2_params(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, GENinstance* inst, int type) +{ + int error; /* error code temporary */ + char *name; + int i; + IFvalue ptemp; /* a value structure */ + IFvalue *parm; + + while(*line) + { + INPgetTok(&line, &name, 0); + if(*line!='=') { + printf("Expect param=val format for %s, got %c\n", name, *line); + LITERR("Expect param=val format\n"); + return(0); + } + line++; /* skip '=' */ + for(i=0;i<*(DEVices[type]->DEVpublic.numInstanceParms);i++) + if(strcmp(name, DEVices[type]->DEVpublic.instanceParms[i].keyword)==0) + break; + if(0) tfree(name); /* don't it need anymore, we still know the keyword */ + if(i<*(DEVices[type]->DEVpublic.numInstanceParms)) + { + int dataType = DEVices[type]->DEVpublic.instanceParms[i].dataType; + if(0) printf("will set parameter %s to xspice instance\n", DEVices[type]->DEVpublic.instanceParms[i].keyword); + parm = INPgetValue(ckt, &line, dataType, tab); + printf("MIFinp2_params set %s id=%d i#%d\n", name, DEVices[type]->DEVpublic.instanceParms[i].id,i); + IFC(setInstanceParm, (ckt, (GENinstance*)inst, DEVices[type]->DEVpublic.instanceParms[i].id, parm, NULL)); + /*GCA(INPapName, (ckt, job->JOBtype, job, ana->analysisParms[i].keyword, parm)); */ + } + else + { + LITERR("Unrecognized parameter\n"); + return(0); + } + + } +} + + + #undef MIFgettok #undef MIFget_token diff --git a/src/xspice/mif/mifask.c b/src/xspice/mif/mifask.c index fccdba077..c49b4b5d9 100644 --- a/src/xspice/mif/mifask.c +++ b/src/xspice/mif/mifask.c @@ -291,7 +291,7 @@ int MIFaskInstParam( value_type &= IF_VARTYPES; /* get index into inst->iparam */ - inst_index = DEVices[mod_type]->DEVpublic.param[param_index].inst_param_index; + inst_index = i; if(inst_index <0) return(E_BADPARM); diff --git a/src/xspice/mif/mifgetmod.c b/src/xspice/mif/mifgetmod.c index b38c279dd..565a95475 100644 --- a/src/xspice/mif/mifgetmod.c +++ b/src/xspice/mif/mifgetmod.c @@ -79,6 +79,7 @@ the .model card are not filled in by this function. They are defaulted later by MIFsetup(). The function returns NULL when successful, and an error string on failure. */ +#define TRACE char *MIFgetMod( CKTcircuit *ckt, /* The circuit structure */ @@ -126,7 +127,6 @@ char *MIFgetMod( /* loop through modtable looking for this model (*name) */ for (modtmp = modtab; modtmp != NULL; modtmp = modtmp->INPnextModel) { - #ifdef TRACE /* SDB debug statement */ printf("In MIFgetMod, checking model against stored model = %s . . .\n", modtmp->INPmodName); diff --git a/src/xspice/mif/mifpara.c b/src/xspice/mif/mifpara.c index a14cd8e3a..8e0ab4ea7 100644 --- a/src/xspice/mif/mifpara.c +++ b/src/xspice/mif/mifpara.c @@ -57,7 +57,7 @@ MIFParam(int param_index, IFvalue *value, GENinstance *inst_in, IFvalue *select) /* Arrange for access to MIF specific data in the model */ inst = (MIFinstance*) inst_in; model = MIFmodPtr(inst); - +printf("Mif param %d\n", param_index); /* Get model type */ mod_type = model->MIFmodType; if((mod_type < 0) || (mod_type >= DEVmaxnum)) @@ -68,25 +68,14 @@ MIFParam(int param_index, IFvalue *value, GENinstance *inst_in, IFvalue *select) if((param_index < 0) || (param_index >= model->num_param)) return(E_BADPARM); - if(!DEVices[mod_type]->DEVpublic.param[param_index].has_inst_scope) + /* search the instance parameter index */ + for(iparam=0;iparam<*(DEVices[mod_type]->DEVpublic.numInstanceParms);iparam++) + if(DEVices[mod_type]->DEVpublic.instanceParms[iparam].id == param_index) + break; + + if((iparam < 0) || (iparam >= *(DEVices[mod_type]->DEVpublic.numInstanceParms))) return(E_BADPARM); - iparam = DEVices[mod_type]->DEVpublic.param[param_index].inst_param_index; - if((iparam < 0) || (iparam >= inst->num_iparam)) - return(E_BADPARM); - - /* find param_index */ - /* - param_index=-1; - for(i=0;iDEVpublic.num_param;i++) - if(DEVices[mod_type]->DEVpublic.param[i].inst_param_index == iparam) - { - param_index=i; - break; - } - if(param_index<0) - return(E_BADPARM); */ - /* get value type to know which members of unions to access */ value_type = DEVices[mod_type]->DEVpublic.modelParms[param_index].dataType; value_type &= IF_VARTYPES; diff --git a/src/xspice/mif/mifsetup.c b/src/xspice/mif/mifsetup.c index b5aaff90c..22be753d3 100644 --- a/src/xspice/mif/mifsetup.c +++ b/src/xspice/mif/mifsetup.c @@ -140,9 +140,13 @@ MIFsetup( /* For each parameter not given explicitly on the .model */ /* card, default it */ - for(i = 0; i < model->num_param; i++) { - - if(model->param[i]->is_null && DEVices[mod_type]->DEVpublic.param[i].has_model_scope) { + for(int imp=0; imp<*(DEVices[mod_type]->DEVpublic.numModelParms);imp++) + { + i = DEVices[mod_type]->DEVpublic.modelParms[imp].id; + if(i<0 || i>= model->num_param) + continue; + + if(model->param[i]->is_null) { /* setup a pointer for quick access */ param_info = &(DEVices[mod_type]->DEVpublic.param[i]); @@ -201,7 +205,87 @@ MIFsetup( } /* end for number of parameters */ - /* For each instance, initialize stuff used by cm_... functions */ + /* For each instance, set default value for instance parameter */ + /* if parameter is both for instance and model, copy model value */ + + for(here = MIFinstances(model); here != NULL; here = MIFnextInstance(here)) { + for(int ip=0; ip<*(DEVices[mod_type]->DEVpublic.numInstanceParms);ip++) + { + i = DEVices[mod_type]->DEVpublic.instanceParms[ip].id; + if(i<0 || i>= model->num_param) + break; /* not an instance parameter from ifspec.ifs */ + if(here->iparam[ip]->is_null) { + int alsomodidx; + /* setup a pointer for quick access */ + param_info = &(DEVices[mod_type]->DEVpublic.param[i]); + + /* look if it is also a model parameter */ + for(alsomodidx=0; alsomodidx<*(DEVices[mod_type]->DEVpublic.numModelParms);alsomodidx++) + if(DEVices[mod_type]->DEVpublic.modelParms[alsomodidx].id == i) + break; + if(alsomodidx<*(DEVices[mod_type]->DEVpublic.numModelParms)) + { + /* copy from model */ + size = model->param[i]->size; + here->iparam[ip]->is_null = 0; + here->iparam[ip]->size = size; + here->iparam[ip]->element = TMALLOC(Mif_Value_t, size); + for(j = 0; j < size; j++) + here->iparam[ip]->element[j] = model->param[i]->element[j]; + } + else + { + /* copy default value from ifspec.ifs */ + + /* determine the size and allocate the parameter element(s) */ + if(! param_info->is_array) { + here->iparam[ip]->size = 1; + here->iparam[ip]->element = TMALLOC(Mif_Value_t, 1); + } else { /* parameter is an array */ + /* MIF_INP2A() parser assures that there is an associated array connection */ + size = here->conn[param_info->conn_ref]->size; + here->iparam[ip]->size = size; + here->iparam[ip]->element = TMALLOC(Mif_Value_t, size); + } /* end if parameter is an array */ + + /* set the parameter element(s) to default value */ + for(j = 0; j < here->iparam[ip]->size; j++) { + + switch(param_info->type) { + + case MIF_BOOLEAN: + here->iparam[ip]->element[j].bvalue = param_info->default_value.bvalue; + break; + + case MIF_INTEGER: + here->iparam[ip]->element[j].ivalue = param_info->default_value.ivalue; + break; + + case MIF_REAL: + here->iparam[ip]->element[j].rvalue = param_info->default_value.rvalue; + break; + + case MIF_COMPLEX: + here->iparam[ip]->element[j].cvalue = param_info->default_value.cvalue; + break; + + case MIF_STRING: + here->iparam[ip]->element[j].svalue = param_info->default_value.svalue; + break; + + default: + return(E_BADPARM); + } + + } /* end for number of elements in param array */ + } /* end copy from default */ + + } /* end param is null */ + } /* end for ip instance parameter */ + } /* end for instance here */ + + + /* For each instance, initialize stuff used by cm_... functions */ for(here = MIFinstances(model); here != NULL; here = MIFnextInstance(here)) { diff --git a/src/xspice/xspice.c b/src/xspice/xspice.c index 5f94d0557..ee8fe149d 100644 --- a/src/xspice/xspice.c +++ b/src/xspice/xspice.c @@ -84,4 +84,5 @@ struct coreInfo_t coreInfo = no_free, #endif MIFParam, + NULL };