Example #1
0
/** Convert from a complex
	Converts a complex property to a string.  This function uses
	the global variable \p global_complex_format to perform the conversion.
	@return the number of character written to the string
 **/
int convert_from_complex(char *buffer, /**< pointer to the string buffer */
						int size, /**< size of the string buffer */
					    void *data, /**< a pointer to the data */
					    PROPERTY *prop) /**< a pointer to keywords that are supported */
{
	int count = 0;
	char temp[1025];
	complex *v = (complex*)data;

	double scale = 1.0;
	if ( prop->unit!=NULL )
	{

		/* only do conversion if the target unit differs from the class's unit for that property */
		PROPERTY *ptmp = (prop->oclass==NULL ? prop : class_find_property(prop->oclass, prop->name));
	
		if(prop->unit != ptmp->unit){
			if(0 == unit_convert_ex(ptmp->unit, prop->unit, &scale)){
				output_error("convert_from_complex(): unable to convert unit '%s' to '%s' for property '%s' (tape experiment error)", ptmp->unit->name, prop->unit->name, prop->name);
				/*	TROUBLESHOOT
					This is an error with the conversion of units from the complex property's units to the requested units.
					Please double check the units of the property and compare them to the units defined in the
					offending tape object.
				*/
				scale = 1.0;
			}
		}
	}

	if (v->Notation()==A)
	{
		double m = v->Mag()*scale;
		double a = v->Arg();
		if (a>PI) a-=(2*PI);
		count = sprintf(temp,global_complex_format,m,a*180/PI,A);
	} 
	else if (v->Notation()==R)
	{
		double m = v->Mag()*scale;
		double a = v->Arg();
		if (a>PI) a-=(2*PI);
		count = sprintf(temp,global_complex_format,m,a,R);
	} 
	else {
		count = sprintf(temp,global_complex_format,v->Re()*scale,v->Im()*scale,v->Notation()?v->Notation():'i');
	}
	if(count < size - 1){
		memcpy(buffer, temp, count);
		buffer[count] = 0;
		return count;
	} else {
		return 0;
	}
}
char *gld_loadHndl::start_element_object(char *buffer, size_t len, const Attributes& attributes){
	//	check generic props
	if(0 == strcmp(buffer, "parent")){
		strcpy(propname, "parent");
		stack_state = OBJECT_PROP;
	} else if(0 == strcmp(buffer, "root")){
		strcpy(propname, "root");
		stack_state = OBJECT_PROP;
	} else if(0 == strcmp(buffer, "rank")){
		strcpy(propname, "rank");
		stack_state = OBJECT_PROP;
	} else if(0 == strcmp(buffer, "clock")){
		strcpy(propname, "clock");
		stack_state = OBJECT_PROP;
	} else if(0 == strcmp(buffer, "latitude")){
		strcpy(propname, "latitude");
		stack_state = OBJECT_PROP;
	} else if(0 == strcmp(buffer, "longitude")){
		strcpy(propname, "longitude");
		stack_state = OBJECT_PROP;
	} else if(0 == strcmp(buffer, "in")){
		strcpy(propname, "in");
		stack_state = OBJECT_PROP;
	} else if(0 == strcmp(buffer, "out")){
		strcpy(propname, "out");
		stack_state = OBJECT_PROP;
	} else if(0 == strcmp(buffer, "library")){
		strcpy(propname, "library");	//	uhm?  an object library?
		stack_state = OBJECT_PROP;
	}	//	check specific props
	else if((prop = class_find_property(oclass, buffer)) != NULL){
		strcpy(propname, buffer);
		stack_state = OBJECT_PROP;
	} else {
		sprintf(errmsg, "Unrecognized property in start_element_object(%s)", buffer);
		return errmsg;
	}
	prop = class_find_property(obj->oclass, buffer);	//	prop = NULL is valid for hardcoded properties. -MH
	return NULL;
}
Example #3
0
/** Convert from a \e double
	Converts from a \e double property to the string.  This function uses
	the global variable \p global_double_format to perform the conversion.
	@return the number of characters written to the string
 **/
int convert_from_double(char *buffer, /**< pointer to the string buffer */
						int size, /**< size of the string buffer */
					    void *data, /**< a pointer to the data */
					    PROPERTY *prop) /**< a pointer to keywords that are supported */
{
	char temp[1025];
	int count = 0;

	double scale = 1.0;
	if(prop->unit != NULL){

		/* only do conversion if the target unit differs from the class's unit for that property */
		PROPERTY *ptmp = (prop->oclass==NULL ? prop : class_find_property(prop->oclass, prop->name));
		scale = *(double *)data;
		if(prop->unit != ptmp->unit && ptmp->unit != NULL){
			if(0 == unit_convert_ex(ptmp->unit, prop->unit, &scale)){
				output_error("convert_from_double(): unable to convert unit '%s' to '%s' for property '%s' (tape experiment error)", ptmp->unit->name, prop->unit->name, prop->name);
				return 0;
			} else {
				count = sprintf(temp, global_double_format, scale);
			}
		} else {
			count = sprintf(temp, global_double_format, *(double *)data);
		}
	} else {
		count = sprintf(temp, global_double_format, *(double *)data);
	}


	if(count < size+1){
		memcpy(buffer, temp, count);
		buffer[count] = 0;
		return count;
	} else {
		return 0;
	}
}
Example #4
0
/** This function builds an collection of objects into an aggregation.  
	The aggregation can be run using aggregate_value(AGGREGATION*)
 **/
AGGREGATION *aggregate_mkgroup(char *aggregator, /**< aggregator (min,max,avg,std,sum,prod,mbe,mean,var,skew,kur,count,gamma) */
							   char *group_expression) /**< grouping rule; see find_mkpgm(char *)*/
{
	AGGREGATOR op = AGGR_NOP;
	AGGREGATION *result=NULL;
	char aggrop[9], aggrval[257], *aggrpart;
	char aggrprop[33], aggrunit[9];
	unsigned char flags=0x00;

	//Change made for collector to handle propeties of objects
	OBJECT *obj;
	PROPERTY *pinfo=NULL;
	FINDPGM *pgm = NULL;
	FINDLIST *list=NULL;	
	//Change ends here

	UNIT *from_unit = NULL, *to_unit = NULL;
	double scale = 1.0;

	if (sscanf(aggregator,"%8[A-Za-z0-9_](%256[][A-Za-z0-9_.^])",aggrop,aggrval)!=2 &&
		(flags|=AF_ABS,
		sscanf(aggregator,"%8[A-Za-z0-9_]|%256[][A-Za-z0-9_.^]|",aggrop,aggrval)!=2 
		))
	{
		output_error("aggregate group '%s' is not valid", aggregator);
		/* TROUBLESHOOT
			An aggregation expression does not have the required syntax, e.g., <i>aggregation</i>(<i>value</i>[.<i>part</i>]).
			Check the aggregation's syntax and make sure it conforms to the required syntax.
		 */
		errno = EINVAL;
		return NULL;
	}

	//Change made for collector to handle propeties of objects
	pgm = find_mkpgm(group_expression);
	if(pgm != NULL){
		list = find_runpgm(NULL,pgm);
		if(list != NULL){
			obj = find_first(list);
			if(obj != NULL){
				pinfo = class_find_property(obj->oclass,aggrval);
				if (pinfo==NULL)
				{
					aggrpart = strrchr(aggrval,'.');
					/* if an aggregate part is found */
					if (aggrpart!=NULL)
						*aggrpart++ = '\0';	// split the value and the part
					else
						aggrpart=""; // no part given
				}
					else
				{
					aggrpart=""; // no part given
				}
			}
		}
	}
	//Change ends here

	if(sscanf(aggrval, "%32[A-Za-z0-9_][%[A-Za-z0-9_^]]", aggrprop, aggrunit) == 2){
		to_unit = unit_find(aggrunit);
		if(to_unit == NULL){
			output_error("aggregate group '%s' has invalid units (%s)", aggrval, aggrunit);
			/* TROUBLESHOOT
				An aggregation expression include a unit specification in the value expression, but the unit is not found.
				Check your aggregations and make sure all the units are defined.
			 */
			errno = EINVAL;
			return NULL;
		}
		strcpy(aggrval, aggrprop); // write property back into value, sans unit
	}

	if (stricmp(aggrop,"min")==0) op=AGGR_MIN;
	else if (stricmp(aggrop,"max")==0) op=AGGR_MAX;
	else if (stricmp(aggrop,"avg")==0) op=AGGR_AVG;
	else if (stricmp(aggrop,"std")==0) op=AGGR_STD;
	else if (stricmp(aggrop,"sum")==0) op=AGGR_SUM;
	else if (stricmp(aggrop,"prod")==0) op=AGGR_SUM;
	else if (stricmp(aggrop,"mbe")==0) op=AGGR_MBE;
	else if (stricmp(aggrop,"mean")==0) op=AGGR_MEAN;
	else if (stricmp(aggrop,"var")==0) op=AGGR_VAR;
	else if (stricmp(aggrop,"skew")==0) op=AGGR_SKEW;
	else if (stricmp(aggrop,"kur")==0) op=AGGR_KUR;
	else if (stricmp(aggrop,"count")==0) op=AGGR_COUNT;
	else if (stricmp(aggrop,"gamma")==0) op=AGGR_GAMMA;
	else
	{
		output_error("aggregate group '%s' does not use a known aggregator", aggregator);
		/* TROUBLESHOOT
			An aggregation expression uses an aggregator that is not defined.  
			Check that all your aggregators used allowed functions (e.g., min, max, avg, std, sum, count, etc.).
		 */
		errno = EINVAL;
		return NULL;
	}
	if (op!=AGGR_NOP)
	{		
		AGGRPART part=AP_NONE;	
		
		if (pgm==NULL)
		{
			output_error("aggregate group expression '%s' failed", group_expression);
			/* TROUBLESHOOT
				A group expression failed to generate a useful group.  
				Check that all your groups are correctly defined.
			 */
			errno = EINVAL;
			return NULL;
		}
		else
		{
			PGMCONSTFLAGS flags = find_pgmconstants(pgm); 
			
			/* the search must be over the same class so that the property offset is known in advance */
			if ((flags&CF_CLASS)!=CF_CLASS)
			{
				output_error("aggregate group expression '%s' does not result in a set with a fixed class", group_expression);
				/* TROUBLESHOOT
					A group expression generated a group whose members vary over time.  
					This is not allowed.  
					Check that all your groups are defined such that the group membership is constant.
				 */
				errno = EINVAL;
				free(pgm);
				pgm = NULL;
				return NULL;
			}
			else
			{				
				if (list==NULL)
				{
					output_error("aggregate group expression '%s' does not result is a usable object list", group_expression);
					/* TROUBLESHOOT
						A group expression failed to generate a useful group.  
						Check that all your groups are correctly defined.
					 */
					free(pgm);
					pgm = NULL;
					errno=EINVAL;
					return NULL;
				}
				
				if (obj==NULL)
				{
					output_error("aggregate group expression '%s' results is an empty object list", group_expression);
					/* TROUBLESHOOT
						A group expression generated an empty group.  
						Check that all your groups are correctly defined.
					 */
					free(pgm);
					pgm = NULL;
					free(list);
					list = NULL;
					errno=EINVAL;
					return NULL;
				}
				pinfo = class_find_property(obj->oclass,aggrval);
				if (pinfo==NULL)
				{
					output_error("aggregate group property '%s' is not found in the objects satisfying search criteria '%s'", aggrval, group_expression);
					/* TROUBLESHOOT
						A group expression failed to generate a group that contains objects that meet the required criteria.  
						Check that all your groups are correctly defined.
					 */
					errno = EINVAL;
					free(pgm);
					pgm = NULL;
					free(list);
					list = NULL;
					return NULL;
				}
				else if (pinfo->ptype==PT_double || pinfo->ptype==PT_random || pinfo->ptype==PT_loadshape )
				{
					if (strcmp(aggrpart,"")!=0)
					{	/* doubles cannot have parts */
						output_error("aggregate group property '%s' cannot have part '%s'", aggrval, aggrpart);
						/* TROUBLESHOOT
							An aggregate part refers to a property that is a real number and does not have any parts.  
							Check that all your aggregate parts refer a property with parts, e.g., a complex value.
						 */
						errno = EINVAL;
						free(pgm);
						pgm = NULL;
						free(list);
						list = NULL;
						return NULL;
					}
					part = AP_NONE;
				}
				else if (pinfo->ptype==PT_complex || pinfo->ptype==PT_enduse)
				{	/* complex must have parts */
					if (strcmp(aggrpart,"real")==0)
						part = AP_REAL;
					else if (strcmp(aggrpart,"imag")==0)
						part = AP_IMAG;
					else if (strcmp(aggrpart,"mag")==0)
						part = AP_MAG;
					else if (strcmp(aggrpart,"ang")==0)
						part = AP_ANG;
					else if (strcmp(aggrpart,"arg")==0)
						part = AP_ARG;
					else
					{
						output_error("aggregate group property '%s' cannot have part '%s'", aggrval, aggrpart);
						/* TROUBLESHOOT
							The aggregate part requested is not recognized for the property given.  
							Check that your aggregate part is defined for a complex value.
						 */
						errno = EINVAL;
						free(pgm);
						pgm = NULL;
						free(list);
						list = NULL;
						return NULL;
					}
				}
				else
				{
					output_error("aggregate group property '%s' cannot be aggregated", aggrval);
					/* TROUBLESHOOT
						The aggregate referred to a type of property that cannot be aggregated.  
						Check that your aggregate part refers to a numeric value.
					 */
					errno = EINVAL;
					free(pgm);
					pgm = NULL;
					free(list);
					list = NULL;
					return NULL;
				}
				from_unit = pinfo->unit;
				if(to_unit != NULL && from_unit == NULL){
					output_error("aggregate group property '%s' is unitless and cannot be converted", aggrval);
					/* TROUBLESHOOT
						The aggregate attempted to convert the units of a property that is unitless.  
						Check that your aggregate part does not include a unit specification.
					 */
					errno = EINVAL;
					free(pgm);
					pgm = NULL;
					free(list);
					list = NULL;
					return NULL;
				}
				if (from_unit != NULL && to_unit != NULL && unit_convert_ex(from_unit, to_unit, &scale) == 0){
					output_error("aggregate group property '%s' cannot use units '%s'", aggrval, aggrunit);
					/* TROUBLESHOOT
						The aggregate attempted to convert a property to a unit that is not compatible with the
						property's original unit.  Check that your aggregate uses a unit that is fundamentally 
						compatible.
					 */
					errno = EINVAL;
					free(pgm);
					pgm = NULL;
					free(list);
					list = NULL;
					return NULL;
				}
			}
		}

		/* build aggregation unit */
		result = (AGGREGATION*)malloc(sizeof(AGGREGATION));
		if (result!=NULL)
		{
			result->op = op;
			result->group = pgm;
			result->pinfo = pinfo;
			result->part = part;
			result->last = list;
			result->next = NULL;
			result->flags = flags;
			result->punit = to_unit;
			result->scale = scale;
		}
		else
		{
			errno=ENOMEM;
			free(pgm);
			pgm = NULL;
			free(list);
			list = NULL;
			return NULL;
		}
	}

	return result;
}
int convert_to_enduse(char *string, void *data, PROPERTY *prop)
{
	enduse *e = (enduse*)data;
	char buffer[1024];
	char *token = NULL;

	/* check string length before copying to buffer */
	if (strlen(string)>sizeof(buffer)-1)
	{
		output_error("convert_to_enduse(string='%-.64s...', ...) input string is too long (max is 1023)",string);
		return 0;
	}
	strcpy(buffer,string);

	/* parse tuples separate by semicolon*/
	while ((token=strtok(token==NULL?buffer:NULL,";"))!=NULL)
	{
		/* colon separate tuple parts */
		char *param = token;
		char *value = strchr(token,':');

		/* isolate param and token and eliminte leading whitespaces */
		while (isspace(*param) || iscntrl(*param)) param++;
		if (value==NULL)
			value="1";
		else
			*value++ = '\0'; /* separate value from param */
		while (isspace(*value) || iscntrl(*value)) value++;

		// parse params
		if (strcmp(param,"current_fraction")==0)
			e->current_fraction = atof(value);
		else if (strcmp(param,"impedance_fraction")==0)
			e->impedance_fraction = atof(value);
		else if (strcmp(param,"power_fraction")==0)
			e->power_fraction = atof(value);
		else if (strcmp(param,"power_factor")==0)
			e->power_factor = atof(value);
		else if (strcmp(param,"loadshape")==0)
		{
			PROPERTY *pref = class_find_property(prop->oclass,value);
			if (pref==NULL)
			{
				output_warning("convert_to_enduse(string='%-.64s...', ...) loadshape '%s' not found in class '%s'",string,value,prop->oclass->name);
				return 0;
			}
			e->shape = (loadshape*)((char*)e - (int64)(prop->addr) + (int64)(pref->addr));
		}
		else
		{
			output_error("convert_to_enduse(string='%-.64s...', ...) parameter '%s' is not valid",string,param);
			return 0;
		}
	}

	/* reinitialize the loadshape */
	if (enduse_init((enduse*)data))
		return 0;

	/* everything converted ok */
	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;
}