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;
}
Example #3
0
/** 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;
}
Example #4
0
/** 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;
}
Example #5
0
/** 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;
}
Example #6
0
/* 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;
}
Example #7
0
/** 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;
}