EXPORT MODULE *subload(char *modname, MODULE **pMod, CLASS **cptr, int argc, char **argv) { MODULE *mod = (MODULE *)malloc(sizeof(MODULE)); CLASS *c = NULL; memset(mod, 0, sizeof(MODULE)); gl_output("glmjava: trying to subload \"%s\"", modname); java_init(callback, (JAVACALLBACKS *)getvar("jcallback", NULL, NULL), mod, modname, argc, argv); c = *cptr; while(c != NULL) { c->create = (FUNCTIONADDR)create_java; c->init = (FUNCTIONADDR)init_java; c->isa = (FUNCTIONADDR)isa_java; c->notify = (FUNCTIONADDR)notify_java; c->plc = (FUNCTIONADDR)plc_java; c->recalc = (FUNCTIONADDR)recalc_java; c->sync = (FUNCTIONADDR)sync_java; c->commit = (FUNCTIONADDR)commit_java; c = c->next; } return mod; }
EXPORT int check() { /* check each link to make sure it has a node at either end */ FINDLIST *list = gl_find_objects(FL_NEW,FT_MODULE,SAME,"powerflow",NULL); OBJECT *obj=NULL; int *nodemap, /* nodemap marks where nodes are */ *linkmap, /* linkmap counts the number of links to/from a given node */ *tomap; /* counts the number of references to any given node */ int errcount = 0; int objct = 0; int queuef = 0, queueb = 0, queuect = 0; int islandct = 0; int i, j; GLOBALVAR *gvroot = NULL; PFLIST anchor, *tlist = NULL; link **linklist = NULL, **linkqueue = NULL; objct = gl_get_object_count(); anchor.ptr = NULL; anchor.next = NULL; nodemap = (int *)malloc((size_t)(objct*sizeof(int))); linkmap = (int *)malloc((size_t)(objct*sizeof(int))); tomap = (int *)malloc((size_t)(objct*sizeof(int))); linkqueue = (link **)malloc((size_t)(objct*sizeof(link *))); linklist = (link **)malloc((size_t)(objct*sizeof(link *))); memset(nodemap, 0, objct*sizeof(int)); memset(linkmap, 0, objct*sizeof(int)); memset(tomap, 0, objct*sizeof(int)); memset(linkqueue, 0, objct*sizeof(link *)); memset(linklist, 0, objct*sizeof(link *)); /* per-object checks */ /* check from/to info on links */ while (obj=gl_find_next(list,obj)) { if (gl_object_isa(obj,"node")) { /* add to node map */ nodemap[obj->id]+=1; /* if no parent, then add to anchor list */ if(obj->parent == NULL){ tlist = (PFLIST *)malloc(sizeof(PFLIST)); tlist->ptr = obj; tlist->next = anchor.next; anchor.next = tlist; tlist = NULL; } } else if (gl_object_isa(obj,"link")) { link *pLink = OBJECTDATA(obj,link); OBJECT *from = pLink->from; OBJECT *to = pLink->to; node *tNode = OBJECTDATA(to, node); node *fNode = OBJECTDATA(from, node); /* count 'to' reference */ tomap[to->id]++; /* check link connections */ if (from==NULL){ gl_error("link %s (%s:%d) from object is not specified", pLink->get_name(), pLink->oclass->name, pLink->get_id()); ++errcount; } else if (!gl_object_isa(from,"node")){ gl_error("link %s (%s:%d) from object is not a node", pLink->get_name(), pLink->oclass->name, pLink->get_id()); ++errcount; } else { /* is a "from" and it isa(node) */ linkmap[from->id]++; /* mark that this node has a link from it */ } if (to==NULL){ gl_error("link %s (%s:%d) to object is not specified", pLink->get_name(), pLink->oclass->name, pLink->get_id()); ++errcount; } else if (!gl_object_isa(to,"node")){ gl_error("link %s (%s:%d) to object is not a node", pLink->get_name(), pLink->oclass->name, pLink->get_id()); ++errcount; } else { /* is a "to" and it isa(node) */ linkmap[to->id]++; /* mark that this node has links to it */ } /* add link to heap? */ if((from != NULL) && (to != NULL) && (linkmap[from->id] > 0) && (linkmap[to->id] > 0)){ linklist[queuect] = pLink; queuect++; } // check phases /* this isn't cooperating with me. -MH */ /* if(tNode->get_phases(PHASE_A) == fNode->get_phases(PHASE_A)){ gl_error("link:%i: to, from nodes have mismatched A phase (%i vs %i)", obj->id, tNode->get_phases(PHASE_A), fNode->get_phases(PHASE_A)); ++errcount; } if(tNode->get_phases(PHASE_B) == fNode->get_phases(PHASE_B)){ gl_error("link:%i: to, from nodes have mismatched B phase (%i vs %i)", obj->id, tNode->get_phases(PHASE_B), fNode->get_phases(PHASE_B)); ++errcount; } if(tNode->get_phases(PHASE_C) == fNode->get_phases(PHASE_C)){ gl_error("link:%i: to, from nodes have mismatched C phase (%i vs %i)", obj->id, tNode->get_phases(PHASE_C), fNode->get_phases(PHASE_C)); ++errcount; } if(tNode->get_phases(PHASE_D) == fNode->get_phases(PHASE_D)){ gl_error("link:%i: to, from nodes have mismatched D phase (%i vs %i)", obj->id, tNode->get_phases(PHASE_D), fNode->get_phases(PHASE_D)); ++errcount; } if(tNode->get_phases(PHASE_N) == fNode->get_phases(PHASE_N)){ gl_error("link:%i: to, from nodes have mismatched N phase (%i vs %i)", obj->id, tNode->get_phases(PHASE_N), fNode->get_phases(PHASE_N)); ++errcount; }*/ } } for(i = 0; i < objct; ++i){ /* locate unlinked nodes */ if(nodemap[i] != 0){ if(linkmap[i] * nodemap[i] > 0){ /* there is a node at [i] and links to it*/ ; } else if(linkmap[i] == 1){ /* either a feeder or an endpoint */ ; } else { /* unattached node */ gl_error("node:%i: node with no links to or from it", i); nodemap[i] *= -1; /* mark as unlinked */ ++errcount; } } } for(i = 0; i < objct; ++i){ /* mark by islands*/ if(nodemap[i] > 0){ /* has linked node */ linkmap[i] = i; /* island until proven otherwise */ } else { linkmap[i] = -1; /* just making sure... */ } } queueb = 0; for(i = 0; i < queuect; ++i){ if(linklist[i] != NULL){ /* consume the next item */ linkqueue[queueb] = linklist[i]; linklist[i] = NULL; queueb++; } while(queuef < queueb){ /* expand this island */ linkmap[linkqueue[queuef]->to->id] = linkmap[linkqueue[queuef]->from->id]; /* capture the adjacent nodes */ for(j = 0; j < queuect; ++j){ if(linklist[j] != NULL){ if(linklist[j]->from->id == linkqueue[queuef]->to->id){ linkqueue[queueb] = linklist[j]; linklist[j] = NULL; ++queueb; } } } ++queuef; } /* we've consumed one island, grab another */ } for(i = 0; i < objct; ++i){ if(nodemap[i] != 0){ gl_testmsg("node:%i on island %i", i, linkmap[i]); if(linkmap[i] == i){ ++islandct; } } if(tomap[i] > 1){ FINDLIST *cow = gl_find_objects(FL_NEW,FT_ID,SAME,i,NULL); OBJECT *moo = gl_find_next(cow, NULL); char grass[64]; gl_output("object #%i, \'%s\', has more than one link feeding to it (this will diverge)", i, gl_name(moo, grass, 64)); } } gl_output("Found %i islands", islandct); tlist = anchor.next; while(tlist != NULL){ PFLIST *tptr = tlist; tlist = tptr->next; free(tptr); } /* An extra something to check link directionality, * if the root node has been defined on the command line. * -d3p988 */ gvroot = gl_global_find("powerflow::rootnode"); if(gvroot != NULL){ PFLIST *front=NULL, *back=NULL, *del=NULL; /* node queue */ OBJECT *_node = gl_get_object((char *)gvroot->prop->addr); OBJECT *_link = NULL; int *rankmap = (int *)malloc((size_t)(objct*sizeof(int))); int bct = 0; if(_node == NULL){ gl_error("powerflow check(): Unable to do directionality check, root node name not found."); } else { gl_testmsg("Powerflow Check ~ Backward Links:"); } for(int i = 0; i < objct; ++i){ rankmap[i] = objct; } rankmap[_node->id] = 0; front = (PFLIST *)malloc(sizeof(PFLIST)); front->next = NULL; front->ptr = _node; back = front; while(front != NULL){ // find all links from the node for(OBJECT *now=gl_find_next(list, NULL); now != NULL; now = gl_find_next(list, now)){ link *l; if(!gl_object_isa(now, "link")) continue; l = OBJECTDATA(now, link); if((l->from != front->ptr) && (l->to != front->ptr)){ continue; } else if(rankmap[l->from->id]<objct && rankmap[l->to->id]<objct){ continue; } else if(rankmap[l->from->id] < rankmap[l->to->id]){ /* mark */ rankmap[l->to->id] = rankmap[l->from->id]+1; } else if(rankmap[l->from->id] > rankmap[l->to->id]){ /* swap & mark */ OBJECT *t = l->from; gl_testmsg("reversed link: %s goes from %s to %s", now->name, l->from->name, l->to->name); l->from = l->to; l->to = t; rankmap[l->to->id] = rankmap[l->from->id]+1;; } // enqueue the "to" node back->next = (PFLIST *)malloc(sizeof(PFLIST)); back->next->next = NULL; //back->next->ptr = l->to; back = back->next; back->ptr = l->to; } del = front; front = front->next; free(del); } } free(nodemap); free(linkmap); free(linklist); free(linkqueue); return 0; }
//EXPORT for object-level call (as opposed to module-level) EXPORT SIMULATIONMODE update_double_assert(OBJECT *obj, TIMESTAMP t0, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val) { char buff[64]; char dateformat[8]=""; char error_output_buff[1024]; char datebuff[64]; double_assert *da = OBJECTDATA(obj,double_assert); DATETIME delta_dt_val; double del_clock; TIMESTAMP del_clock_int; int del_microseconds; double *x; if(da->get_once() == da->ONCE_TRUE){ da->set_once_value(da->get_value()); da->set_once(da->ONCE_DONE); } else if (da->get_once() == da->ONCE_DONE){ if(da->get_once_value() == da->get_value()){ gl_verbose("Assert skipped with ONCE logic"); return SM_EVENT; } else { da->set_once_value(da->get_value()); } } // get the within range double range = 0.0; if ( da->get_within_mode() == da->IN_RATIO ) { range = da->get_value() * da->get_within(); //if ( range<0.001 ) //minimum bounds removed since many deltamode items are small //{ // minimum bounds // range = 0.001; //} } else if ( da->get_within_mode()== da->IN_ABS ) { range = da->get_within(); } //Iteration checker - assert only valid on the first timestep if (iteration_count_val == 0) { //Skip first timestep of any delta iteration -- nature of delta means it really isn't checking the right one if (delta_time>=dt) { //Get value x = (double*)gl_get_double_by_name(obj->parent,da->get_target()); if (x==NULL) { gl_error("Specified target %s for %s is not valid.",da->get_target(),gl_name(obj->parent,buff,64)); /* TROUBLESHOOT Check to make sure the target you are specifying is a published variable for the object that you are pointing to. Refer to the documentation of the command flag --modhelp, or check the wiki page to determine which variables can be published within the object you are pointing to with the assert function. */ return SM_ERROR; } else if (da->get_status() == da->ASSERT_TRUE) { double m = fabs(*x-da->get_value()); if (_isnan(m) || m>range) { //Calculate time if (delta_time>=dt) //After first iteration del_clock = (double)t0 + (double)(delta_time-dt)/(double)DT_SECOND; else //First second different, don't back out del_clock = (double)t0 + (double)(delta_time)/(double)DT_SECOND; del_clock_int = (TIMESTAMP)del_clock; /* Whole seconds - update from global clock because we could be in delta for over 1 second */ del_microseconds = (int)((del_clock-(int)(del_clock))*1000000+0.5); /* microseconds roll-over - biased upward (by 0.5) */ //Convert out gl_localtime(del_clock_int,&delta_dt_val); //Determine output format gl_global_getvar("dateformat",dateformat,sizeof(dateformat)); //Output date appropriately if ( strcmp(dateformat,"ISO")==0) sprintf(datebuff,"ERROR [%04d-%02d-%02d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.year,delta_dt_val.month,delta_dt_val.day,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz); else if ( strcmp(dateformat,"US")==0) sprintf(datebuff,"ERROR [%02d-%02d-%04d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.month,delta_dt_val.day,delta_dt_val.year,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz); else if ( strcmp(dateformat,"EURO")==0) sprintf(datebuff,"ERROR [%02d-%02d-%04d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.day,delta_dt_val.month,delta_dt_val.year,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz); else sprintf(datebuff,"ERROR .09f : ",del_clock); //Actual error part sprintf(error_output_buff,"Assert failed on %s - %s (%g) not within %f of given value %g",gl_name(obj->parent, buff, 64),da->get_target(), *x, da->get_within(), da->get_value()); //Send it out gl_output("%s%s",datebuff,error_output_buff); return SM_ERROR; } gl_verbose("Assert passed on %s", gl_name(obj->parent, buff, 64)); return SM_EVENT; } else if (da->get_status() == da->ASSERT_FALSE) { double m = fabs(*x-da->get_value()); if (_isnan(m) || m<range) { //Calculate time if (delta_time>=dt) //After first iteration del_clock = (double)t0 + (double)(delta_time-dt)/(double)DT_SECOND; else //First second different, don't back out del_clock = (double)t0 + (double)(delta_time)/(double)DT_SECOND; del_clock_int = (TIMESTAMP)del_clock; /* Whole seconds - update from global clock because we could be in delta for over 1 second */ del_microseconds = (int)((del_clock-(int)(del_clock))*1000000+0.5); /* microseconds roll-over - biased upward (by 0.5) */ //Convert out gl_localtime(del_clock_int,&delta_dt_val); //Determine output format gl_global_getvar("dateformat",dateformat,sizeof(dateformat)); //Output date appropriately if ( strcmp(dateformat,"ISO")==0) sprintf(datebuff,"ERROR [%04d-%02d-%02d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.year,delta_dt_val.month,delta_dt_val.day,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz); else if ( strcmp(dateformat,"US")==0) sprintf(datebuff,"ERROR [%02d-%02d-%04d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.month,delta_dt_val.day,delta_dt_val.year,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz); else if ( strcmp(dateformat,"EURO")==0) sprintf(datebuff,"ERROR [%02d-%02d-%04d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.day,delta_dt_val.month,delta_dt_val.year,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz); else sprintf(datebuff,"ERROR .09f : ",del_clock); //Actual error part sprintf(error_output_buff,"Assert failed on %s - %s (%g) not within %f of given value %g",gl_name(obj->parent, buff, 64),da->get_target(), *x, da->get_within(), da->get_value()); //Send it out gl_output("%s%s",datebuff,error_output_buff); return SM_ERROR; } gl_verbose("Assert passed on %s", gl_name(obj->parent, buff, 64)); return SM_EVENT; } else { gl_verbose("Assert test is not being run on %s", gl_name(obj->parent, buff, 64)); return SM_EVENT; } } else //First pass, just proceed return SM_EVENT; } else //Iteration, so don't care return SM_EVENT; }
CLASS *java_init(CALLBACKS *fntable, JAVACALLBACKS *jfntable, MODULE *module, char *modulename, int argc, char *argv[]) { JavaVM *jvm = NULL; JNIEnv *jnienv = NULL; if (!set_callback(fntable)) { errno = EINVAL; return NULL; } JAVACALLBACKS *jcallback = jfntable; if(jcallback == NULL) { gl_error("%s:java_init() - unable to find jcallback", modulename); return NULL; } if(jvm == NULL) jvm = get_jvm(); if(jnienv == NULL) jnienv = get_env(); jstring *jargv = new jstring[argc]; int i = 0; gl_output("javamod init entered\n"); jclass cls = jnienv->FindClass(modulename); if(cls == NULL) { gl_error("javamod:init.cpp: unable to find %s.class", modulename); return NULL; } jmethodID init_mid = jnienv->GetStaticMethodID(cls, "init", "(JLjava/lang/String;I[Ljava/lang/String;)J"); if(init_mid == NULL) { gl_error("javamod:init.cpp: unable to find \"int %s.init(long, string, int, string[])\"", modulename); return NULL; } jobjectArray args = jnienv->NewObjectArray(argc, jnienv->FindClass("[Ljava/lang/String;"), NULL); if(args == NULL) { gl_error("javamod:init.cpp: unable to allocate args[] for %s.init()", modulename); return NULL; } for(i = 0; i < argc; ++i) { jargv[i] = jnienv->NewStringUTF(argv[i]); jnienv->SetObjectArrayElement(args, i, jargv[i]); } jstring jmodname = jnienv->NewStringUTF(modulename); if(jmodname == NULL) { gl_error("javamod:init.cpp: unable to allocate jmodname for %s.init()", modulename); } gl_output("javamod:init.cpp(): moduleaddr = %x", module); int64 rv = jnienv->CallStaticLongMethod(cls, init_mid, (int64)module, jmodname, argc, jargv); if (jnienv->ExceptionOccurred()) { jnienv->ExceptionDescribe(); } // JNI cleanup jnienv->DeleteLocalRef(args); for(i = 0; i < argc; ++i) ; /* delete the strings */ gl_output("finished javamod init\n"); return (CLASS *)rv; }
EXPORT bool glx_settag(glxlink *mod, char *tag, char *data) { MATLABLINK *matlab = (MATLABLINK*)mod->get_data(); if ( strcmp(tag,"command")==0 ) { matlab->command = (char*)malloc(strlen(data)+1); strcpy(matlab->command,data); } else if ( strcmp(tag,"window")==0 ) { if ( strcmp(data,"show")==0 ) matlab->window = MWD_SHOW; else if ( strcmp(data,"hide")==0 ) matlab->window = MWD_HIDE; else if ( strcmp(data,"onerror")==0 ) matlab->window = MWD_ONERROR; else if ( strcmp(data,"ondebug")==0 ) matlab->window = MWD_ONDEBUG; else if ( strcmp(data,"keep")==0 ) matlab->window = MWD_KEEP; else gl_error("'%s' is not a valid matlab window disposition", data); } else if ( strcmp(tag,"output")==0 ) { matlab->output_size = atoi(data); if ( matlab->output_size>0 ) matlab->output_buffer = (char*)malloc(matlab->output_size); else gl_error("'%s' is not a valid output buffer size", data); } else if ( strcmp(tag,"workdir")==0 ) { strcpy(matlab->workdir,data); } else if ( strcmp(tag,"root")==0 ) { if ( strcmp(data,"")==0 ) // no root matlab->rootname=NULL; else { matlab->rootname = (char*)malloc(strlen(data)+1); sscanf(data,"%s",matlab->rootname); // use scanf to avoid spaces in root name } } else if ( strcmp(tag,"on_init")==0 ) { size_t data_len = strlen(data); char *data_new = (char*)malloc(error_handling_begin_len+error_handling_end_len+data_len+1); strcpy (data_new,error_handling_begin); strcat (data_new,data); strcat (data_new,error_handling_end); if ( (error_handling_begin_len+error_handling_end_len+data_len)>0 ) { matlab->init = (char*)malloc(error_handling_begin_len+error_handling_end_len+data_len+1); strcpy(matlab->init,data_new); free(data_new); } } else if ( strcmp(tag,"on_sync")==0 ) { size_t data_len = strlen(data); char *data_new = (char*)malloc(error_handling_begin_len+error_handling_end_len+data_len+1); strcpy (data_new,error_handling_begin); strcat (data_new,data); strcat (data_new,error_handling_end); if ( (error_handling_begin_len+error_handling_end_len+data_len)>0 ) { matlab->sync = (char*)malloc(error_handling_begin_len+error_handling_end_len+data_len+1); strcpy(matlab->sync,data_new); free(data_new); } } else if ( strcmp(tag,"on_term")==0 ) { size_t data_len = strlen(data); char *data_new = (char*)malloc(error_handling_begin_len+error_handling_end_len+data_len+1); strcpy (data_new,error_handling_begin); strcat (data_new,data); strcat (data_new,error_handling_end); if ( (error_handling_begin_len+error_handling_end_len+data_len)>0 ) { matlab->term = (char*)malloc(error_handling_begin_len+error_handling_end_len+data_len+1); strcpy(matlab->term,data_new); free(data_new); } } else if( strcmp(tag, "skipsafe")==0 ) { if( strcmp(data, "yes")==0 ) { mod->glxflags |= LF_SKIPSAFE; } else if( strcmp(data, "no")==0 ) { mod->glxflags &= ~LF_SKIPSAFE; } else { gl_error("glxmatlab::glx_settag ~ skipsafe value '%s' is not valid", data); return false; } } else { gl_output("tag '%s' not valid for matlab target", tag); return false; } return true; }