double* module_getvar_addr(MODULE *mod, char *varname) { char modvarname[1024]; GLOBALVAR *var; sprintf(modvarname,"%s::%s",mod->name,varname); var = global_find(modvarname); if (var!=NULL) return var->prop->addr; else return NULL; }
char *gld_loadHndl::start_element_module_prop(char *buffer, size_t len, const Attributes& attributes){ char pname[323]; sprintf(pname, "%s::%s", this->module->name, buffer); if(global_find(pname)){ strcpy(propname, pname); } else { output_warning("XML: start_element_module_prop: property \"\" not found, initializing"); strcpy(propname, pname); } return NULL; }
/** Load and process the command-line arguments @return a STATUS value Arguments are processed immediately as they are seen. This means that models are loaded when they are encountered, and in relation to the other flags. Thus @code gridlabd --warn model1 --warn model2 @endcode will load \p model1 with warnings on, and \p model2 with warnings off. **/ STATUS cmdarg_load(int argc, /**< the number of arguments in \p argv */ char *argv[]) /**< a list pointers to the argument string */ { int test_mod_num = 1; unsigned int pos=0; int i; char *pd1, *pd2; /* capture the execdir */ strcpy(global_execname,argv[0]); strcpy(global_execdir,argv[0]); pd1 = strrchr(global_execdir,'/'); pd2 = strrchr(global_execdir,'\\'); if (pd1>pd2) *pd1='\0'; else if (pd2>pd1) *pd2='\0'; /* capture the command line */ for (i=0; i<argc; i++) { if (pos<sizeof(global_command_line)-strlen(argv[i])) pos += sprintf(global_command_line+pos,"%s%s",pos>0?" ":"",argv[i]); } while (argv++,--argc>0) { if (strcmp(*argv,"--copyright")==0) legal_notice(); else if (strcmp(*argv,"-w")==0 || strcmp(*argv,"--warn")==0) global_warn_mode=!global_warn_mode; else if (strcmp(*argv,"--bothstdout")==0) output_both_stdout(); else if (strcmp(*argv,"-c")==0 || strcmp(*argv,"--check")==0) global_runchecks=!global_runchecks; else if (strcmp(*argv,"--debug")==0) global_debug_output=!global_debug_output; else if (strcmp(*argv,"--debugger")==0){ global_debug_mode=1; global_debug_output=!global_debug_output; } else if (strcmp(*argv,"--dumpall")==0) global_dumpall=!global_dumpall; else if (strcmp(*argv,"-q")==0 || strcmp(*argv,"--quiet")==0) global_quiet_mode=!global_quiet_mode; else if (strcmp(*argv,"-v")==0 || strcmp(*argv,"--verbose")==0){ global_verbose_mode=!global_verbose_mode; } else if (strcmp(*argv,"--profile")==0) global_profiler=!global_profiler; else if (strcmp(*argv,"--pause")==0) global_pauseatexit=!global_pauseatexit; else if (strcmp(*argv,"--compile")==0) global_compileonly = !global_compileonly; else if (strcmp(*argv,"--license")==0) legal_license(); else if (strcmp(*argv,"--server_portnum")==0 || strcmp(*argv,"-P")==0) { if (argc-1>0) global_server_portnum = (argc--,atoi(*++argv)); else { output_fatal("missing server port number"); /* TROUBLESHOOT The <b>-P</b> or <b>--server_portnum</b> command line directive was not followed by a valid number. The correct syntax is <b>-P <i>number</i></b> or <b>--server_portnum <i>number</i></b>. */ } } else if (strcmp(*argv, "-V")==0 ||strcmp(*argv, "--version")==0) { char *buildinfo = strstr(BUILD,":"); int build = buildinfo ? atoi(strstr(BUILD,":")+1) : 0; output_message("Revision major: %d", REV_MAJOR); output_message("Revision minor: %d", REV_MINOR); output_message("Patch number : %d", REV_PATCH); output_message("Branch name : %s", BRANCH); if (build>0) output_message("Build number : %d", build); else output_message("Build number : %s", #ifdef WIN32 #ifdef _DEBUG #ifdef _M_X64 "WIN64-DEBUG" #else "WIN32-DEBUG" #endif #else #ifdef _M_X64 "WIN64-RELEASE" #else "WIN32-RELEASE" #endif #endif #else "DEV" #endif ); } else if (strcmp(*argv,"--dsttest")==0) timestamp_test(); else if (strcmp(*argv,"--randtest")==0) random_test(); else if (strcmp(*argv,"--unitstest")==0) unit_test(); else if (strcmp(*argv,"--scheduletest")==0) schedule_test(); else if (strcmp(*argv,"--loadshapetest")==0) loadshape_test(); else if (strcmp(*argv,"--endusetest")==0) enduse_test(); else if (strcmp(*argv,"--xmlstrict")==0) global_xmlstrict = !global_xmlstrict; else if (strcmp(*argv,"--globaldump")==0) { global_dump(); exit(0); } else if (strcmp(*argv,"--relax")==0) global_strictnames = FALSE; else if (strncmp(*argv,"--pidfile",9)==0) { char *filename = strchr(*argv,'='); if (filename==NULL) strcpy(global_pidfile,"gridlabd.pid"); else strcpy(global_pidfile,filename+1); } else if (strncmp(*argv,"--kml",5)==0) { char *filename = strchr(*argv,'='); if (filename) strcpy(global_kmlfile,filename+1); else strcpy(global_kmlfile,"gridlabd.kml"); } else if (strcmp(*argv, "--avlbalance") == 0){ global_no_balance = !global_no_balance; } else if (strcmp(*argv,"--testall")==0){ FILE *fd = NULL; if(*++argv != NULL) fd = fopen(*argv,"r"); else { output_fatal("no filename for testall"); /* TROUBLESHOOT The --testall parameter was found on the command line, but if was not followed by a filename containing the test description file. */ return FAILED; } argc--; global_test_mode=TRUE; if(fd == NULL) { output_fatal("incorrect module list file name"); /* TROUBLESHOOT The --testall parameter was found on the command line, but if was not followed by a valid filename containing the test description file. */ return FAILED; } if(load_module_list(fd,&test_mod_num) == FAILED) return FAILED; } else if (strcmp(*argv,"--modhelp")==0) { if(argc-1 > 0){ MODULE *mod = NULL; CLASS *oclass = NULL; argv++; argc--; if(strchr(argv[0], ':') == 0){ // no class mod = module_load(argv[0],0,NULL); } else { GLOBALVAR *var=NULL; char *cname; cname = strchr(argv[0], ':')+1; mod = module_load(strtok(argv[0],":"),0,NULL); oclass = class_get_class_from_classname(cname); if(oclass == NULL){ output_fatal("Unable to find class '%s' in module '%s'", cname, argv[0]); /* TROUBLESHOOT The <b>--modhelp</b> parameter was found on the command line, but if was followed by a class specification that isn't valid. Verify that the class exists in the module you specified. */ return FAILED; } /* dump module globals */ printf("module %s {\n", mod->name); while ((var=global_getnext(var))!=NULL) { PROPERTY *prop = var->prop; char *proptype = class_get_property_typename(prop->ptype); if (strncmp(var->prop->name,mod->name,strlen(mod->name))!=0) continue; if (proptype!=NULL){ if(prop->unit != NULL) { printf("\t%s %s[%s];", proptype, strrchr(prop->name,':')+1, prop->unit->name); } else if (prop->ptype==PT_set || prop->ptype==PT_enumeration) { KEYWORD *key; printf("\t%s {", proptype); for (key=prop->keywords; key!=NULL; key=key->next) printf("%s=%"FMT_INT64"u%s", key->name, (int64)key->value, key->next==NULL?"":", "); printf("} %s;", strrchr(prop->name,':')+1); } else { printf("\t%s %s;", proptype, strrchr(prop->name,':')+1); } if (prop->description!=NULL) printf(" // %s%s",prop->flags&PF_DEPRECATED?"(DEPRECATED) ":"",prop->description); printf("\n"); } } printf("}\n"); } if(mod == NULL){ output_fatal("module %s is not found",*argv); /* TROUBLESHOOT The <b>--modhelp</b> parameter was found on the command line, but if was followed by a module specification that isn't valid. Verify that the module exists in GridLAB-D's <b>lib</b> folder. */ return FAILED; } if(oclass != NULL) { print_class(oclass); } else { CLASS *oclass; pntree *ctree; /* lexographically sort all elements from class_get_first_class & oclass->next */ oclass=class_get_first_class(); ctree = (pntree *)malloc(sizeof(pntree)); if(ctree == NULL){ throw_exception("--modhelp: malloc failure"); /* TROUBLESHOOT The memory allocation needed for module help to function has failed. Try freeing up system memory and try again. */ } ctree->name = oclass->name; ctree->oclass = oclass; ctree->left = ctree->right = 0; for(; oclass != NULL; oclass = oclass->next){ modhelp_alpha(&ctree, oclass); //print_class(oclass); } /* flatten tree */ print_modhelp_tree(ctree); } } } else if (strcmp(*argv,"--modtest")==0) { if (argc-1>0) { MODULE *mod = module_load(argv[1],0,NULL); if (mod==NULL) output_fatal("module %s is not found",argv[1]); /* TROUBLESHOOT The <b>--modtest</b> parameter was found on the command line, but if was followed by a module specification that isn't valid. Verify that the module exists in GridLAB-D's <b>lib</b> folder. */ else { argv++;argc--; if (mod->test==NULL) output_fatal("module %s does not implement a test routine", argv[0]); /* TROUBLESHOOT The <b>--modtest</b> parameter was found on the command line, but if was followed by a specification for a module that doesn't implement any test procedures. See the <b>--libinfo</b> command line parameter for information on which procedures the module supports. */ else { output_test("*** modtest of %s beginning ***", argv[0]); mod->test(0,NULL); output_test("*** modtest of %s ended ***", argv[0]); } } } else { output_fatal("definition is missing"); /* TROUBLESHOOT The <b>--modtest</b> parameter was found on the command line, but if was not followed by a module specification. The correct syntax is <b>gridlabd --modtest <i>module_name</i></b>. */ return FAILED; } } else if (strcmp(*argv,"--test")==0){ global_test_mode=TRUE; global_strictnames = FALSE; output_debug("disabling strict naming for tests"); if (argc-1>0) { char mod_test[100]; sprintf(mod_test,"mod_test%d=%s",test_mod_num++,*++argv); if (global_setvar(mod_test)==SUCCESS) argc--; } else { output_fatal("test module name is missing"); /* TROUBLESHOOT The <b>--test</b> parameter was found on the command line, but if was not followed by a module specification that is valid. The correct syntax is <b>gridlabd --test <i>module_name</i></b>. */ return FAILED; } } else if (strcmp(*argv,"-D")==0 || strcmp(*argv,"--define")==0) { if (argc-1>0) { bool namestate = global_strictnames; global_strictnames = FALSE; if (global_setvar(*++argv,NULL)==SUCCESS){ argc--; } global_strictnames = namestate; } else { output_fatal("definition is missing"); /* TROUBLESHOOT The <b>-D</b> or <b>--define</b> command line parameters was given, but it was not followed by a variable definition. The correct syntax <b>-D </i>variable</i>=<i>value</i></b> or <b>--define </i>variable</i>=<i>value</i></b> */ return FAILED; } } else if (strcmp(*argv,"--globals")==0) { char *list[65536]; int i, n=0; GLOBALVAR *var = NULL; /* load the list into the array */ while ((var=global_getnext(var))!=NULL) { if (n<sizeof(list)/sizeof(list[0])) list[n++] = var->prop->name; else { output_fatal("--globals has insufficient buffer space to sort globals list"); return FAILED; } } /* sort the array */ qsort(list,n,sizeof(list[0]),compare); /* output sorted array */ for (i=0; i<n; i++) { char buffer[1024]; var = global_find(list[i]); printf("%s=%s;",var->prop->name,global_getvar(var->prop->name,buffer,sizeof(buffer))?buffer:"(error)"); if (var->prop->description || var->prop->flags&PF_DEPRECATED) printf(" // %s%s", (var->prop->flags&PF_DEPRECATED)?"DEPRECATED ":"", var->prop->description?var->prop->description:""); printf("\n"); } } else if (strcmp(*argv,"--redirect")==0) { if (argc-1>0) { char buffer[1024]; char *p; strcpy(buffer,*++argv); argc--; if (strcmp(buffer,"all")==0) { if (output_redirect("output",NULL)==NULL || output_redirect("error",NULL)==NULL || output_redirect("warning",NULL)==NULL || output_redirect("debug",NULL)==NULL || output_redirect("verbose",NULL)==NULL || output_redirect("profile",NULL)==NULL || output_redirect("progress",NULL)==NULL) { output_fatal("redirection of all failed"); /* TROUBLESHOOT An attempt to close all standard stream from the command line using <b>--redirect all</b> has failed. One of the streams cannot be closed. Try redirecting each stream separately until the problem stream is identified and the correct the problem with that stream. */ return FAILED; } } else if ((p=strchr(buffer,':'))!=NULL) { *p++='\0'; if (output_redirect(buffer,p)==NULL) { output_fatal("redirection of %s to '%s' failed: %s",buffer,p, strerror(errno)); /* TROUBLESHOOT An attempt to redirect a standard stream from the command line using <b>--redirect <i>stream</i>:<i>destination</i></b> has failed. The message should provide an indication of why the attempt failed. The remedy will depend on the nature of the problem. */ return FAILED; } } else if (output_redirect(buffer,NULL)==NULL) { output_fatal("default redirection of %s failed: %s",buffer, strerror(errno)); /* TROUBLESHOOT An attempt to close a standard stream from the command line using <b>--redirect <i>stream</i></b> has failed. The message should provide an indication of why the attempt failed. The remedy will depend on the nature of the problem. */ return FAILED; } } else { output_fatal("redirection is missing"); /* TROUBLESHOOT A <b>--redirect</b> directive on the command line is missing its redirection specification. The correct syntax is <b>--redirect <i>stream</i>[:<i>destination</i>]</b>. */ return FAILED; } } else if (strcmp(*argv,"-L")==0 || strcmp(*argv,"--libinfo")==0) { if (argc-1>0) { argc--; module_libinfo(*++argv); exit(0); } else { output_fatal("missing library name"); /* TROUBLESHOOT The <b>-L</b> or <b>--libinfo</b> command line directive was not followed by a module name. The correct syntax is <b>-L <i>module_name</i></b> or <b>--libinfo <i>module_name</i></b>. */ return FAILED; } } else if (strcmp(*argv,"-T")==0 || strcmp(*argv,"--threadcount")==0) { if (argc-1>0) global_threadcount = (argc--,atoi(*++argv)); else { output_fatal("missing thread count"); /* TROUBLESHOOT The <b>-T</b> or <b>--threadcount</b> command line directive was not followed by a valid number. The correct syntax is <b>-T <i>number</i></b> or <b>--threadcount <i>number</i></b>. */ return FAILED; } } else if (strcmp(*argv,"-o")==0 || strcmp(*argv,"--output")==0) { if (argc-1>0) strcpy(global_savefile,(argc--,*++argv)); else { output_fatal("missing output file"); /* TROUBLESHOOT The <b>-o</b> or <b>--output</b> command line directive was not followed by a valid filename. The correct syntax is <b>-o <i>file</i></b> or <b>--output <i>file</i></b>. */ return FAILED; } } else if (strcmp(*argv,"-e")==0 || strcmp(*argv,"--environment")==0) { if (argc-1>0) strcpy(global_environment,(argc--,*++argv)); else { output_fatal("environment not specified"); /* TROUBLESHOOT The <b>-e</b> or <b>--environment</b> command line directive was not followed by a valid environment specification. The correct syntax is <b>-e <i>keyword</i></b> or <b>--environment <i>keyword</i></b>. */ return FAILED; } } else if (strcmp(*argv,"--xmlencoding")==0) { if (argc-1>0) { global_xml_encoding = atoi(*++argv); argc--; } else { output_fatal("xml encoding not specified"); /* TROUBLESHOOT The <b>--xmlencoding</b> command line directive was not followed by a encoding specification. The correct syntax is <b>--xmlencoding <i>keyword</i></b>. */ return FAILED; } } else if (strcmp(*argv,"--xsd")==0) { if (argc-1>0) { argc--; exit(output_xsd(*++argv)); } else { MODULE *mod; for (mod=module_get_first(); mod!=NULL; mod=mod->next) output_xsd(mod->name); return SUCCESS; } } else if (strcmp(*argv,"--xsl")==0) { if (argc-1>0) { char fname[1024]; char *p_arg = *++argv; char n_args=1; char **p_args; argc--; while (*p_arg++!='\0') if (*p_arg==',') n_args++; p_args = (char**)malloc(sizeof(char*)*n_args); p_arg = strtok(*argv,","); n_args=0; while (p_arg!=NULL) { p_args[n_args++] = p_arg; p_arg = strtok(NULL,","); } sprintf(fname,"gridlabd-%d_%d.xsl",global_version_major,global_version_minor); exit(output_xsl(fname,n_args,p_args)); } else { output_fatal("module list not specified"); /* TROUBLESHOOT The <b>--xsl</b> command line directive was not followed by a validlist of modules. The correct syntax is <b>--xsl <i>module1</i>[,<i>module2</i>[,...]]</b>. */ return FAILED; } } else if (strcmp(*argv,"--stream")==0) global_streaming_io_enabled = !global_streaming_io_enabled; else if (strcmp(*argv,"--server")==0) strcpy(global_environment,"server"); else if (strcmp(*argv,"-h")==0 || strcmp(*argv,"--help")==0) { printf("Syntax: gridlabd [OPTIONS ...] <file> ... \nOptions:\n" " --avlbalance toggles AVL tree balancing\n" " -c|--check toggles module checks after model loads\n" " -D|--define <def> defines a macro value\n" " --debug toggles debug output (prints internal messages)\n" " --debugger toggles debugger mode (generates internal messages)\n" " --dumpall toggles module data dump after run completes\n" " -e|--environment <name> specifies user environment (default none)\n" " --license print license information\n" " -L|--libinfo <module> print module library information\n" " -o|--output <file> specifies model should be output after run\n" " --profile toggles profilers\n" " -q|--quiet toggles quiet mode (suppresses startup banner)\n" " --test toggles test mode (activate testing procedures)\n" " -T|--threadcount <n> specifies the number of processor threads to use\n" " -v|--verbose toggles verbose mode (active verbose messages)\n" " -V|--version prints the GridlabD version information\n" " -w|--warn toggles warning mode (generates warning messages)\n" " --xmlencoding <num> set the XML encoding (8, 16, or 32)\n" " --xmlstrict toggles XML encoding to be strict\n" " --xsd <module>[:<object>] prints the xsd of an object\n" " --xsl <modlist> prints the xsl for the modules listed\n" ); exit(0); } else if (**argv!='-') { if (global_test_mode) output_warning("file '%s' ignored in test mode", *argv); /* TROUBLESHOOT This warning is caused by an attempt to read an input file in self-test mode. The use of self-test model precludes reading model files. Try running the system in normal more or leaving off the model file name. */ else { if (!loadall(*argv)) return FAILED; /* preserve name of first model only */ if (strcmp(global_modelname,"")==0) strcpy(global_modelname,*argv); } } else { int n = module_cmdargs(argc,argv); if (n==0) { output_error("command line option '%s' is not recognized",*argv); /* TROUBLESHOOT The command line option given is not valid where it was found. Check the command line for correct syntax and order of options. */ return FAILED; } } } /*debug_traverse_tree(NULL);*/ /* for checking the name tree & getting a test file. -mh */ return SUCCESS; }
/** Convert to a \e double_array data type Converts a string to a \e double_array data type property. @return 1 on success, 0 on failure, -1 if conversion was incomplete **/ int convert_to_double_array(const char *buffer, void *data, PROPERTY *prop) { double_array *a=(double_array*)data; a->set_name(prop->name); unsigned row=0, col=0; const char *p = buffer; /* new array */ /* parse input */ for ( p=buffer ; *p!='\0' ; ) { char value[256]; char objectname[64], propertyname[64]; while ( *p!='\0' && isspace(*p) ) p++; /* skip spaces */ if ( *p!='\0' && sscanf(p,"%s",value)==1 ) { if ( *p==';' ) /* end row */ { row++; col=0; p++; continue; } else if ( strnicmp(p,"NAN",3)==0 ) /* NULL value */ { a->grow_to(row,col); a->clr_at(row,col); col++; } else if ( isdigit(*p) || *p=='.' || *p=='-' || *p=='+' ) /* probably real value */ { a->grow_to(row+1,col+1); a->set_at(row,col,atof(p)); col++; } else if ( sscanf(value,"%[^.].%[^; \t]",objectname,propertyname)==2 ) /* object property */ { OBJECT *obj = load_get_current_object(); if ( obj!=NULL && strcmp(objectname,"parent")==0 ) obj = obj->parent; else if ( strcmp(objectname,"this")!=0 ) obj = object_find_name(objectname); if ( obj==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - object property '%s' not found", buffer,row,col,objectname); return 0; } PROPERTY *prop = object_get_property(obj,propertyname,NULL); if ( prop==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - property '%s' not found in object '%s'", buffer,row,col,propertyname,objectname); return 0; } a->grow_to(row+1,col+1); a->set_at(row,col,object_get_double(obj,prop)); if ( a->is_nan(row,col) ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname); return 0; } col++; } else if ( sscanf(value,"%[^; \t]",propertyname)==1 ) /* current object/global property */ { OBJECT *obj; PROPERTY *target = NULL; obj = (OBJECT*)((char*)data - (char*)prop->addr)-1; object_name(obj,objectname,sizeof(objectname)); target = object_get_property(obj,propertyname,NULL); if ( target!=NULL ) { if ( target->ptype!=PT_double && target->ptype!=PT_random && target->ptype!=PT_enduse && target->ptype!=PT_loadshape && target->ptype!=PT_enduse ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' refers to property '%s', which is not an underlying double", buffer,row,col,propertyname,objectname,target->name); return 0; } a->grow_to(row+1,col+1); a->set_at(row,col,object_get_double(obj,target)); if ( a->is_nan(row,col) ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname); return 0; } col++; } else { GLOBALVAR *var = global_find(propertyname); if ( var==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d global '%s' not found", buffer,row,col,propertyname); return 0; } if ( var->prop->ptype!=PT_double ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' refers to a global '%s', which is not an underlying double", buffer,row,col,propertyname,objectname,propertyname); return 0; } a->grow_to(row+1,col+1); a->set_at(row,col,(double*)var->prop->addr); if ( a->is_nan(row,col) ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname); return 0; } col++; } } else /* not a valid entry */ { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d is not valid (value='%10s')", buffer,row,col,p); return 0; } while ( *p!='\0' && !isspace(*p) && *p!=';' ) p++; /* skip characters just parsed */ } } return 1; }
/** Convert to a \e complex_array data type Converts a string to a \e complex_array data type property. @return 1 on success, 0 on failure, -1 if conversion was incomplete **/ int convert_to_complex_array(const char *buffer, void *data, PROPERTY *prop) { complex_array *a=(complex_array*)data; unsigned row=0, col=0; const char *p = buffer; /* new array */ /* parse input */ for ( p=buffer ; *p!='\0' ; ) { char value[256]; char objectname[64], propertyname[64]; complex c; while ( *p!='\0' && isspace(*p) ) p++; /* skip spaces */ if ( *p!='\0' && sscanf(p,"%s",value)==1 ) { if ( *p==';' ) /* end row */ { row++; col=0; p++; continue; } else if ( strnicmp(p,"NAN",3)==0 ) /* NULL value */ { a->grow_to(row,col); a->clr_at(row,col); col++; } else if ( convert_to_complex(value,(void*)&c,prop) ) /* probably real value */ { a->grow_to(row,col); a->set_at(row,col,c); col++; } else if ( sscanf(value,"%[^.].%[^; \t]",objectname,propertyname)==2 ) /* object property */ { OBJECT *obj = object_find_name(objectname); PROPERTY *prop; if ( obj==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - object '%s' not found", buffer,row,col,objectname); return 0; } prop = object_get_property(obj,propertyname,NULL); if ( prop==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - property '%s' not found in object '%s'", buffer,row,col,propertyname,objectname); return 0; } a->grow_to(row,col); a->set_at(row,col,object_get_complex(obj,prop)); if ( a->is_nan(row,col) ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname); return 0; } col++; } else if ( sscanf(value,"%[^; \t]",propertyname)==1 ) /* object property */ { GLOBALVAR *var = global_find(propertyname); if ( var==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d global '%s' not found", buffer,row,col,propertyname); return 0; } a->grow_to(row,col); a->set_at(row,col,(complex*)var->prop->addr); if ( a->is_nan(row,col) ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname); return 0; } col++; } else /* not a valid entry */ { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d is not valid (value='%10s')", buffer,row,col,p); return 0; } while ( *p!='\0' && !isspace(*p) && *p!=';' ) p++; /* skip characters just parsed */ } } return 1; }
/* initialize modules */ int link_initall(void) { output_debug("link_initall(): link startup in progress..."); glxlink *mod; for ( mod=glxlink::get_first() ; mod!=NULL ; mod=mod->get_next() ) { LINKLIST *item; output_debug("link_initall(): setting up %s link", mod->get_target()); // set default global list (if needed) if ( mod->get_globals()==NULL ) { GLOBALVAR *var = NULL; while ( (var=global_getnext(var))!=NULL ) { if ( var->prop!=NULL && var->prop->name!=NULL ) { LINKLIST *item = mod->add_global(var->prop->name); if ( item!=NULL ) item->data = (void*)var; else output_error("link_initall(): unable to link %s", var->prop->name); } else output_warning("link_initall(): a variable property definition is null"); } } else { // link global variables for ( item=mod->get_globals() ; item!=NULL ; item=mod->get_next(item) ) { if ( strcmp(item->name,"")==0 ) continue; item->data = (void*)global_find(item->name); if ( item->data==NULL ) output_error("link_initall(target='%s'): global '%s' is not found", mod->get_target(), item->name); } } // link objects if ( mod->get_objects()==NULL ) { // set default object list OBJECT *obj = NULL; for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) ) { // add named objects LINKLIST *item = NULL; if ( obj->name!=NULL ) item = mod->add_object(obj->name); else { char id[256]; sprintf(id,"%s:%d",obj->oclass->name,obj->id); item = mod->add_object(id); } item->data = (void*)obj; } } else { LINKLIST *item; // link global variables for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) ) { if ( strcmp(item->name,"")==0 ) continue; OBJECT *obj = NULL; item->data = (void*)object_find_name(item->name); if ( item->data==NULL) output_error("link_initall(target='%s'): object '%s' is not found", mod->get_target(), item->name); } } // link exports for ( item=mod->get_exports() ; item!=NULL ; item=mod->get_next(item) ) { char objname[64], propname[64], varname[64]; if ( sscanf(item->name,"%[^.].%s %s",objname,propname,varname)==3 ) { OBJECTPROPERTY *objprop = (OBJECTPROPERTY*)malloc(sizeof(OBJECTPROPERTY)); objprop->obj = object_find_name(objname); if ( objprop->obj ) { objprop->prop = class_find_property(objprop->obj->oclass,propname); if ( objprop->prop==NULL ) output_error("link_initall(target='%s'): export '%s' property not found", mod->get_target(), item->name); else { item->data = objprop; strcpy(item->name,varname); } } else output_error("link_initall(target='%s'): export '%s' object not found", mod->get_target(), item->name); } else output_error("link_initall(target='%s'): '%s' is not a valid export specification", mod->get_target(), item->name); } // link imports for ( item=mod->get_imports() ; item!=NULL ; item=mod->get_next(item) ) { char objname[64], propname[64], varname[64]; if ( sscanf(item->name,"%[^.].%s %s",objname,propname,varname)==3 ) { OBJECTPROPERTY *objprop = (OBJECTPROPERTY*)malloc(sizeof(OBJECTPROPERTY)); objprop->obj = object_find_name(objname); if ( objprop->obj ) { objprop->prop = class_find_property(objprop->obj->oclass,propname); if ( objprop->prop==NULL ) output_error("link_initall(target='%s'): import '%s' property not found", mod->get_target(), item->name); else { item->data = objprop; strcpy(item->name,varname); } } else output_error("link_initall(target='%s'): import '%s' object not found", mod->get_target(), item->name); } else output_error("link_initall(target='%s'): '%s' is not a valid import specification", mod->get_target(), item->name); } // initialize link module if ( !mod->do_init() ) { output_error("link_initall(): link startup failed"); link_termall(); return 0; } } output_debug("link_initall(): link startup done ok"); atexit((void(*)(void))link_termall); return 1; }
/** Get a value (object, clock, or global) \verbatim gl('get',name) \endverbatim **/ void cmex_get(int nlhs, mxArray *plhs[], /**< {data} */ int nrhs, const mxArray *prhs[] ) /**< (name) */ { if (nrhs>0) { char name[1024]; OBJECT *obj=NULL; if (!mxIsChar(prhs[0])) output_error("entity name (arg 1) is not a string"); else if (nlhs>1) output_error("only one return value is possible"); else if (mxGetString(prhs[0],name,sizeof(name))!=0) output_error("object name too long"); else if (strcmp(name,"clock")==0) { char *fnames[] = {"timestamp","timestring","timezone"}; char buffer[256]; mxArray *pTimestamp = mxCreateDoubleMatrix(1,1,mxREAL); mxArray *pTimestring = mxCreateString(convert_from_timestamp(global_clock,buffer,sizeof(buffer))?buffer:"(error)"); mxArray *pTimezone = mxCreateString(timestamp_current_timezone()); *(double*)mxGetPr(pTimestamp) = ((double)global_clock)/TS_SECOND; plhs[0] = mxCreateStructMatrix(1,1,sizeof(fnames)/sizeof(fnames[0]),fnames); mxSetFieldByNumber(plhs[0],0,0,pTimestamp); mxSetFieldByNumber(plhs[0],0,1,pTimestring); mxSetFieldByNumber(plhs[0],0,2,pTimezone); } else if (strcmp(name,"property")==0 && nrhs>1) { if (mxGetString(prhs[1],name,sizeof(name))!=0) output_error("missing property name"); else { char classname[256]; char propname[256]; if (sscanf(name,"%[^.].%s",classname,propname)==2) { CLASS *pClass = class_get_class_from_classname(classname); if (pClass) { PROPERTY *pProp = class_find_property(pClass,propname); if (pProp) { char *fields[] = {"class","name","type","size","access","unit","delegation","keywords"}; int fn = 0; mxArray *oclass = mxCreateString(classname); mxArray *prop = mxCreateString(pProp->name); mxArray *type = mxCreateString(class_get_property_typename(pProp->ptype)); mxArray *size = mxCreateDoubleMatrix(1,1,mxREAL); mxArray *access = mxCreateString("(na)"); /** @todo implement get_property access info (ticket #187) */ mxArray *unit = mxCreateString(pProp->unit->name); mxArray *delegation = mxCreateString(pProp->delegation?pProp->delegation->oclass->name:"(none)"); mxArray *keywords = mxCreateString("(na)"); /** @todo implement get_property keywords (ticket #188) */ *(mxGetPr(size)) = pProp->size==0?1:pProp->size; plhs[0] = mxCreateStructMatrix(1,1,sizeof(fields)/sizeof(fields[0]),fields); mxSetFieldByNumber(plhs[0],0,fn++,oclass); mxSetFieldByNumber(plhs[0],0,fn++,prop); mxSetFieldByNumber(plhs[0],0,fn++,type); mxSetFieldByNumber(plhs[0],0,fn++,size); mxSetFieldByNumber(plhs[0],0,fn++,access); mxSetFieldByNumber(plhs[0],0,fn++,unit); mxSetFieldByNumber(plhs[0],0,fn++,delegation); mxSetFieldByNumber(plhs[0],0,fn++,keywords); } else output_error("property %s is not found in class %s", propname,classname); } else output_error("class %s is not found"); } else output_error("property name not in class.name format"); } } else if ((convert_to_object(name,&obj,NULL))==0) { GLOBALVAR *var = global_find(name); if (var==NULL) output_error("entity '%s' not found", name); else if (var->prop->ptype==PT_double) { size_t size = var->prop->size?var->prop->size:1; plhs[0] = mxCreateDoubleMatrix(size,1,mxREAL); memcpy(mxGetPr(plhs[0]),(void*)var->prop->addr,sizeof(double)*size); } else if (var->prop->ptype==PT_int32) { size_t size = var->prop->size?var->prop->size:1; plhs[0] = mxCreateDoubleMatrix(size,1,mxREAL); memcpy(mxGetPr(plhs[0]),(void*)var->prop->addr,sizeof(double)*size); } else if (var->prop->ptype!=PT_double) output_error("cannot retrieve globals that are of type %s",class_get_property_typename(var->prop->ptype)); } else if ((plhs[0]=get_object_data(obj))==NULL) output_error("unable to extract %s data", name); } else output_error("object not specified"); return; }