示例#1
0
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[])
{
	if (set_callback(fntable)==NULL)
	{
		errno = EINVAL;
		return NULL;
	}
	pGlobalClock = fntable->global_clock;
	gl_global_getvar("execdir",libpath,sizeof(libpath));
	strcat(libpath,"/plc/lib");
	gl_global_create("plc::libpath",PT_char1024,libpath,NULL);

	gl_global_getvar("execdir",incpath,sizeof(incpath));
	strcat(incpath,"/plc/include");
	gl_global_create("plc::incpath",PT_char1024,incpath,NULL);

	new plc(module);
	new comm(module);

	/* always return the first class registered */
	return plc::oclass;
}
示例#2
0
int read_aggregates(AGGREGATION *aggr, char *buffer, int size)
{
	AGGREGATION *p;
	int offset=0;
	int count=0;
	char32 fmt;

	gl_global_getvar("double_format", fmt, 32);
	for (p=aggr; p!=NULL && offset<size-33; p=p->next)
	{
		if (offset>0) strcpy(buffer+offset++,",");
		offset+=sprintf(buffer+offset,fmt,gl_run_aggregate(p));
		buffer[offset]='\0';
		count++;
	}
	return count;
}
示例#3
0
/* Object initialization is called once after all object have been created */
int metrics::init(OBJECT *parent)
{
	OBJECT *hdr = OBJECTHDR(this);
	int index, indexa, indexb, returnval;
	char work_metrics[1025];
	char *startVal, *endVal, *workVal;
	char workbuffer[1025];
	char metricbuffer[257];
	FILE *FPVal;
	FINDLIST *CandidateObjs;
	OBJECT *temp_obj;
	bool *temp_bool;
	FUNCTIONADDR funadd = NULL;

	//Ensure our "module metrics" object is populated
	if (module_metrics_obj == NULL)
	{
		GL_THROW("Please specify a module metrics object for metrics:%s",hdr->name);
		/*  TROUBLESHOOT
		To operate properly, the metrics object must have the corresponding module's
		metrics calculator linked.  If this object is missing, metrics has no idea
		what to calculate and will not proceed.
		*/
	}

	//It's not null, map up the init function and call it (this must exist, even if it does nothing)
	funadd = (FUNCTIONADDR)(gl_get_function(module_metrics_obj,"init_reliability"));
					
	//Make sure it was found
	if (funadd == NULL)
	{
		GL_THROW("Unable to map reliability init function on %s in %s",module_metrics_obj->name,hdr->name);
		/*  TROUBLESHOOT
		While attempting to initialize the reliability module in the "module of interest" metrics device,
		a error was encountered.  Ensure this object fully supports reliability and try again.  If the bug
		persists, please submit your code and a bug report to the trac website.
		*/
	}

	Extra_Data = ((void *(*)(OBJECT *, OBJECT *))(*funadd))(module_metrics_obj,hdr);

	//Make sure it worked
	if (Extra_Data==NULL)
	{
		GL_THROW("Unable to map reliability init function on %s in %s",module_metrics_obj->name,hdr->name);
		//defined above
	}

	//Figure out how many indices we should be finding
	index = 0;

	while ((metrics_oi[index] != '\0') && (index < 1024))
	{
		if (metrics_oi[index] == ',')
		{
			num_indices++;	//Increment counter
		}

		index++;	//Increment pointer
	}

	//Make sure we didn't blow the top off
	if (index == 1024)
	{
		GL_THROW("Maximum length exceeded on metrics_of_interest in metrics:%s",hdr->name);
		/*  TROUBLESHOOT
		While parsing the metrics_of_interest list, the maximum length (1024 characters) was
		reached.  This can cause undesired behavior.  Ensure the metrics list is within this
		character count.  If it is, please try again.  If the error persists, please submit
		your code and a bug report via the trac website.
		*/
	}

	//See if at least one was found.  If it was, that means there are 2 (it counts commas)
	if (num_indices >= 1)
		num_indices++;
	
	//See if we were a solitary one - if so, increment accordingly
	if ((num_indices == 0) && (index > 1))
		num_indices = 1;

	//Make sure at least one was found
	if (num_indices == 0)
	{
		GL_THROW("No indices of interest specified for metrics:%s",hdr->name);
		/*  TROUBLESHOOT
		No indices were found to read.  Please specify the proper indices and try again.
		*/
	}

	//Malloc us up!
	CalcIndices = (INDEXARRAY*)gl_malloc(num_indices * sizeof(INDEXARRAY));

	//Make sure it worked
	if (CalcIndices == NULL)
	{
		GL_THROW("Failure to allocate indices memory in metrics:%s",hdr->name);
		/*  TROUBLESHOOT
		While allocating the storage matrix for the indices to calculate, an error occurred.
		Please try again.  If the error persists, please submit you code and a bug report
		using the trac website.
		*/
	}

	//Initialize these, just in case
	for (index=0; index<num_indices; index++)
	{
		CalcIndices[index].MetricLoc = NULL;	//No address by default
		
		for (indexa=0; indexa<257; indexa++)	//+1 due to end \0
			CalcIndices[index].MetricName[indexa]='\0';
	}

	//Populate it up - copy it first so we don't destroy the original
	metrics_oi.copy_to(work_metrics);

	//Set initial pointers
	startVal = work_metrics;
	endVal = work_metrics;

	//Loop through and find them
	for (index=0; index<num_indices; index++)	//Loop through
	{
		//Find the next comma or end point
		while ((*endVal != ',') && (*endVal != '\0'))
		{
			endVal++;
		}

		//Replace us (comma) with EOS (\0)
		*endVal='\0';

		//Copy us into the structure
		workVal = startVal;
		indexa = 0;
		while ((workVal<=endVal) && (indexa < 256))
		{
			//Copy the value in
			CalcIndices[index].MetricName[indexa] = *workVal;

			//Copy into secondary
			metricbuffer[indexa] = *workVal;

			//Increment pointers
			indexa++;
			workVal++;
		}

		//apply the "_int" portion for the interval search
		indexb = indexa-1;

		//Now update pointers appropriately and proceed
		endVal++;
		startVal = endVal;
		
		//Now try to find this variable
		CalcIndices[index].MetricLoc = get_metric(module_metrics_obj,CalcIndices[index].MetricName);

		//Make sure it worked
		if (CalcIndices[index].MetricLoc == NULL)
		{
			GL_THROW("Unable to find metric %s in object %s for metric:%s",CalcIndices[index].MetricName.get_string(),module_metrics_obj->name,hdr->name);
			/*  TROUBLESHOOT
			While attempting to map out a reliability metric, the desired metric was not found.  Please check the variable
			name and ensure the metric is being published in the module metrics object and try again.  If the error persists,
			please submit your code and a bug report to the trac website.
			*/
		}

		//Get the interval metric - if it exists - and there is room
		if ((indexb+4) <= 256)
		{
			metricbuffer[indexb] = '_';
			metricbuffer[(indexb+1)] = 'i';
			metricbuffer[(indexb+2)] = 'n';
			metricbuffer[(indexb+3)] = 't';
			metricbuffer[(indexb+4)] = '\0';

			//Try to map it
			CalcIndices[index].MetricLocInterval = get_metric(module_metrics_obj,metricbuffer);

			//No NULL check - if it wasn't found, we won't deal with it
		}
	}//end metric traversion
	
	//Map our reset functions for ease
	reset_interval_func = (FUNCTIONADDR)(gl_get_function(module_metrics_obj,"reset_interval_metrics"));
	
	//Make sure it worked
	if (reset_interval_func == NULL)
	{
		GL_THROW("Failed to map interval reset in metrics object %s for metrics:%s",module_metrics_obj->name,hdr->name);
		/*  TROUBLESHOOT
		While attempting to map the interval statistics reset function, the metrics object encountered a problem.
		Please make sure the module metrics object supports a "reset_interval_metrics" function.  If so, please try again.
		If the error persists, please submit your code and a bug report using the trac website.
		*/
	}

	reset_annual_func = (FUNCTIONADDR)(gl_get_function(module_metrics_obj,"reset_annual_metrics"));

	//Make sure it worked
	if (reset_annual_func == NULL)
	{
		GL_THROW("Failed to map annual reset in metrics object %s for metrics:%s",module_metrics_obj->name,hdr->name);
		/*  TROUBLESHOOT
		While attempting to map the annual statistics reset function, the metrics object encountered a problem.
		Please make sure the module metrics object supports a "reset_interval_metrics" function.  If so, please try again.
		If the error persists, please submit your code and a bug report using the trac website.
		*/
	}

	compute_metrics = (FUNCTIONADDR)(gl_get_function(module_metrics_obj,"calc_metrics"));

	//Make sure it worked
	if (compute_metrics == NULL)
	{
		GL_THROW("Failed to map metric computation function in metrics object %s for metrics:%s",module_metrics_obj->name,hdr->name);
		/*  TROUBLESHOOT
		While attempting to map the function to compute the desired metrics, the metrics object encountered a problem.
		Please make sure the module metrics object supports a "calc_metrics" function.  If so, please try again.
		If the error persists, please submit your code and a bug report using the trac website.
		*/
	}

	//Call the resets - interval
	returnval = ((int (*)(OBJECT *, OBJECT *))(*reset_interval_func))(hdr,module_metrics_obj);

	if (returnval != 1)	//See if it failed
	{
		GL_THROW("Failed to reset interval metrics for %s by metrics:%s",module_metrics_obj->name,hdr->name);
		/*  TROUBLESHOOT
		The metrics object encountered an error while attempting to reset the interval statistics variables.
		Please try again.  If the error persists, submit your code and a bug report via the trac website.
		*/
	}

	//Call the resets - annual
	returnval = ((int (*)(OBJECT *, OBJECT *))(*reset_annual_func))(hdr,module_metrics_obj);

	if (returnval != 1)	//See if it failed
	{
		GL_THROW("Failed to reset annual metrics for %s by metrics:%s",module_metrics_obj->name,hdr->name);
		/*  TROUBLESHOOT
		The metrics object encountered an error while attempting to reset the annual statistics variables.
		Please try again.  If the error persists, submit your code and a bug report via the trac website.
		*/
	}

	//Convert our calculation interval to a timestamp
	metric_interval = (TIMESTAMP)metric_interval_dbl;
	report_interval = (TIMESTAMP)report_interval_dbl;

	//See if it is a year - flag appropriately
	if (metric_interval == 31536000)
		metric_equal_annual = true;

	//Make sure we have a file name provided
	if (report_file[0] == '\0')	//None specified
	{
		GL_THROW("Please specify a proper report file name if you would like an output file from metrics:%s",hdr->name);
		/*  TROUBLESHOOT
		While attempting to write the report file, an invalid file name was provided.  Please provide a valid file name
		and try again.
		*/
	}

	//Open the file to clear it
	FPVal = fopen(report_file,"wt");

	//Make sure it worked
	if (FPVal == NULL)
	{
		GL_THROW("Unable to create the report file '%s' for metrics:%s",report_file,hdr->name);
		/*  TROUBLESHOOT
		While attempting to write the metrics output file, an error occurred.  Please make sure you
		have write permissions at that location and try again.  If the error persists, please submit
		your code and a bug report using the trac website.
		*/
	}

	//It must exist - write the typical header nonsense
	fprintf(FPVal,"Reliability report for %s\n", gl_global_getvar("modelname",workbuffer,(1025*sizeof(char))));

	//Find our lucky candidate objects
	CandidateObjs = gl_find_objects(FL_GROUP,customer_group.get_string());
	if (CandidateObjs==NULL)
	{
		GL_THROW("Failure to find devices for %s specified as: %s",hdr->name,customer_group.get_string());
		/*  TROUBLESHOOT
		While attempting to populate the list of devices to check for reliability metrics, the metrics
		object failed to find any desired objects.  Please make sure the objects exist and try again.
		If the bug persists, please submit your code using the trac website.
		*/
	}

	//Do a zero-find check as well
	if (CandidateObjs->hit_count == 0)
	{
		GL_THROW("Failure to find devices for %s specified as: %s",hdr->name,customer_group.get_string());
		//Defined above
	}

	//Pull the count
	CustomerCount = CandidateObjs->hit_count;

	//Make us an array!
	Customers = (CUSTARRAY*)gl_malloc(CustomerCount*sizeof(CUSTARRAY));

	//Make sure it worked
	if (Customers == NULL)
	{
		GL_THROW("Failure to allocate customer list memory in metrics:%s",hdr->name);
		/*  TROUBLESHOOT
		While allocating the memory for the list of customers, GridLAB-D encountered a problem.
		Please try again.  If the error persists, please submit your code and a bug report via the
		trac website.
		*/
	}

	//Let's populate the beast now!
	temp_obj = NULL;
	for (index=0; index<CustomerCount; index++)
	{
		//Find the object
		temp_obj = gl_find_next(CandidateObjs, temp_obj);

		if (temp_obj == NULL)
		{
			GL_THROW("Failed to populate customer list in metrics: %s",hdr->name);
			/*  TROUBLESHOOT
			While populating the metrics customer list, an object failed to be
			located.  Please try again.  If the error persists, please submit your
			code and a bug report to the trac website.
			*/
		}

		Customers[index].CustomerObj = temp_obj;

		//Try to find our "outage" indicator and map its address
		temp_bool = get_outage_flag(temp_obj, "customer_interrupted");

		//make sure it found it
		if (temp_bool == NULL)
		{
			GL_THROW("Unable to find interrupted flag for customer object %s in metrics:%s",temp_obj->name,hdr->name);
			/*  TROUBLESHOOT
			While attempting to link to the 'customer interrupted' flag, an error occurred.  Please ensure the object
			supports being polled by reliability as a customer (customer_interrupted exists as a published property) and
			try again.  If the error persists, please submit your code and a bug report via the trac website.
			*/
		}

		//Write this value in
		Customers[index].CustInterrupted = temp_bool;

		if (index == 0)	//First customer, handle slightly different
		{
			//Populate the secondary index - needs to exist, even if never used
			//Try to find our secondary "outage" indicator and map its address
			temp_bool = get_outage_flag(temp_obj, "customer_interrupted_secondary");

			//make sure it found it
			if (temp_bool == NULL)	//Not found, assume no one else wants one
			{
				gl_warning("Unable to find secondary interruption flag, no secondary interruptions recorded in metrics:%s",hdr->name);
				/*  TROUBLESHOOT
				While attempting to link to the 'secondary customer interrupted' flag, it was not found.  THe object may not support
				"secondary interruption counts" and this message is valid.  If a secondary count was desired, ensure the object
				supports being polled by reliability as a customer (customer_interrupted_secondary exists as a published property) and
				try again.  If the error persists, please submit your code and a bug report via the trac website.
				*/
			}
			else	//One found, assume all want one now
			{
				secondary_interruptions_count = true;
				
				//Write this value in
				Customers[index].CustInterrupted_Secondary = temp_bool;
			}
		}
		else if (secondary_interruptions_count == true)	//Decided we want it
		{
			//Populate the secondary index - needs to exist, even if never used
			//Try to find our secondary "outage" indicator and map its address
			temp_bool = get_outage_flag(temp_obj, "customer_interrupted_secondary");

			//make sure it found it
			if (temp_bool == NULL)
			{
				GL_THROW("Unable to find secondary interruption flag for customer object %s in metrics:%s",temp_obj->name,hdr->name);
				/*  TROUBLESHOOT
				While attempting to link to the 'secondary customer interrupted' flag, an error occurred.  Please ensure the object
				supports being polled by reliability as a customer (customer_interrupted_secondary exists as a published property) and
				try again.  If the error persists, please submit your code and a bug report via the trac website.
				*/
			}

			//Write this value in
			Customers[index].CustInterrupted_Secondary = temp_bool;
		}
		//Defaulted else - unwanted

	}//end population loop

	//Free up list
	gl_free(CandidateObjs);

	//Write the customer count and header information to the file we have going
	fprintf(FPVal,"Number of customers = %d\n\n",CustomerCount);

	//See if the particular metrics object has any "comments" to add to the file header (units, notes, etc.)
	funadd = NULL;	//Reset function pointer - just in case

	//Map up the "extra print" function - if it isn't there, well nothing is done
	funadd = (FUNCTIONADDR)(gl_get_function(module_metrics_obj,"logfile_extra"));

	//See if it was found
	if (funadd != NULL)
	{
		//Do the extra printing
		returnval = ((int (*)(OBJECT *, char *))(*funadd))(module_metrics_obj,workbuffer);

		//Make sure it worked
		if (returnval==0)
		{
			GL_THROW("Failed to write extra header material for %s in %s",module_metrics_obj->name,hdr->name);
			/*  TROUBLESHOOT
			While attempting to write the extra material into the file header, an error occurred.  Please try again.
			If the error persists, please submit your code and a bug report via the trac website.
			*/
		}

		//Print it out
		fprintf(FPVal,"%s",workbuffer);
	}

	//Close the file handle
	fclose(FPVal);

	return 1; /* return 1 on success, 0 on failure - We're so awesome we always assume we work */
}
示例#4
0
// Initialize a distribution meter, return 1 on success
int meter::init(OBJECT *parent)
{
	char temp_buff[128];

	if(power_market != 0){
		price_prop = gl_get_property(power_market, "current_market.clearing_price");
		if(price_prop == 0){
			GL_THROW("meter::power_market object \'%s\' does not publish \'current_market.clearing_price\'", (power_market->name ? power_market->name : "(anon)"));
		}
	}

	// Count the number of phases...for use with meter_power_consumption
	if (meter_power_consumption != complex(0,0))
	{
		no_phases = 0;
		if (has_phase(PHASE_A))
			no_phases += 1;
		if (has_phase(PHASE_B))
			no_phases += 1;
		if (has_phase(PHASE_C))
			no_phases += 1;
	}

	check_prices();
	last_t = dt = 0;

	//Update tracking flag
	//Get server mode variable
	gl_global_getvar("multirun_mode",temp_buff,sizeof(temp_buff));

	//See if we're not in standalone
	if (strcmp(temp_buff,"STANDALONE"))	//strcmp returns a 0 if they are the same
	{
		if ((solver_method == SM_NR) && (bustype == SWING))
		{
			meter_NR_servered = true;	//Set this flag for later use

			//Allocate the storage vector
			prev_voltage_value = (complex *)gl_malloc(3*sizeof(complex));

			//Check it
			if (prev_voltage_value==NULL)
			{
				GL_THROW("Failure to allocate memory for voltage tracking array");
				/*  TROUBLESHOOT
				While attempting to allocate memory for the voltage tracking array used
				by the master/slave functionality, an error occurred.  Please try again.
				If the error persists, please submit your code and a bug report via the trac
				website.
				*/
			}

			//Populate it with zeros for now, just cause - init sets voltages in node
			prev_voltage_value[0] = complex(0.0,0.0);
			prev_voltage_value[1] = complex(0.0,0.0);
			prev_voltage_value[2] = complex(0.0,0.0);
		}
	}

	return node::init(parent);
}
示例#5
0
//EXPORT for object-level call (as opposed to module-level)
EXPORT SIMULATIONMODE update_double_assert(OBJECT *obj, TIMESTAMP t0, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
{
	char buff[64];
	char dateformat[8]="";
	char error_output_buff[1024];
	char datebuff[64];
	double_assert *da = OBJECTDATA(obj,double_assert);
	DATETIME delta_dt_val;
	double del_clock;
	TIMESTAMP del_clock_int;
	int del_microseconds;
	double *x;

	if(da->get_once() == da->ONCE_TRUE){
		da->set_once_value(da->get_value());
		da->set_once(da->ONCE_DONE);
	} else if (da->get_once() == da->ONCE_DONE){
		if(da->get_once_value() == da->get_value()){
			gl_verbose("Assert skipped with ONCE logic");
			return SM_EVENT;
		} else {
			da->set_once_value(da->get_value());
		}
	}

	// get the within range
	double range = 0.0;
	if ( da->get_within_mode() == da->IN_RATIO ) 
	{
		range = da->get_value() * da->get_within();

		//if ( range<0.001 ) //minimum bounds removed since many deltamode items are small
		//{	// minimum bounds
		//	range = 0.001;
		//}
	} 
	else if ( da->get_within_mode()== da->IN_ABS ) 
	{
		range = da->get_within();
	}
		
	//Iteration checker - assert only valid on the first timestep
	if (iteration_count_val == 0)
	{
		//Skip first timestep of any delta iteration -- nature of delta means it really isn't checking the right one
		if (delta_time>=dt)
		{
			//Get value
			x = (double*)gl_get_double_by_name(obj->parent,da->get_target());

			if (x==NULL) 
			{
				gl_error("Specified target %s for %s is not valid.",da->get_target(),gl_name(obj->parent,buff,64));
				/*  TROUBLESHOOT
				Check to make sure the target you are specifying is a published variable for the object
				that you are pointing to.  Refer to the documentation of the command flag --modhelp, or 
				check the wiki page to determine which variables can be published within the object you
				are pointing to with the assert function.
				*/
				return SM_ERROR;
			}
			else if (da->get_status() == da->ASSERT_TRUE)
			{
				double m = fabs(*x-da->get_value());
				if (_isnan(m) || m>range)
				{
					//Calculate time
					if (delta_time>=dt)	//After first iteration
						del_clock  = (double)t0 + (double)(delta_time-dt)/(double)DT_SECOND;
					else	//First second different, don't back out
						del_clock  = (double)t0 + (double)(delta_time)/(double)DT_SECOND;

					del_clock_int = (TIMESTAMP)del_clock;	/* Whole seconds - update from global clock because we could be in delta for over 1 second */
					del_microseconds = (int)((del_clock-(int)(del_clock))*1000000+0.5);	/* microseconds roll-over - biased upward (by 0.5) */
					
					//Convert out
					gl_localtime(del_clock_int,&delta_dt_val);

					//Determine output format
					gl_global_getvar("dateformat",dateformat,sizeof(dateformat));

					//Output date appropriately
					if ( strcmp(dateformat,"ISO")==0)
						sprintf(datebuff,"ERROR    [%04d-%02d-%02d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.year,delta_dt_val.month,delta_dt_val.day,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz);
					else if ( strcmp(dateformat,"US")==0)
						sprintf(datebuff,"ERROR    [%02d-%02d-%04d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.month,delta_dt_val.day,delta_dt_val.year,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz);
					else if ( strcmp(dateformat,"EURO")==0)
						sprintf(datebuff,"ERROR    [%02d-%02d-%04d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.day,delta_dt_val.month,delta_dt_val.year,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz);
					else
						sprintf(datebuff,"ERROR    .09f : ",del_clock);

					//Actual error part
					sprintf(error_output_buff,"Assert failed on %s - %s (%g) not within %f of given value %g",gl_name(obj->parent, buff, 64),da->get_target(), *x, da->get_within(), da->get_value());

					//Send it out
					gl_output("%s%s",datebuff,error_output_buff);

					return SM_ERROR;
				}
				gl_verbose("Assert passed on %s", gl_name(obj->parent, buff, 64));
				return SM_EVENT;
			}
			else if (da->get_status() == da->ASSERT_FALSE)
			{
				double m = fabs(*x-da->get_value());
				if (_isnan(m) || m<range)
				{				
					//Calculate time
					if (delta_time>=dt)	//After first iteration
						del_clock  = (double)t0 + (double)(delta_time-dt)/(double)DT_SECOND;
					else	//First second different, don't back out
						del_clock  = (double)t0 + (double)(delta_time)/(double)DT_SECOND;

					del_clock_int = (TIMESTAMP)del_clock;	/* Whole seconds - update from global clock because we could be in delta for over 1 second */
					del_microseconds = (int)((del_clock-(int)(del_clock))*1000000+0.5);	/* microseconds roll-over - biased upward (by 0.5) */
					
					//Convert out
					gl_localtime(del_clock_int,&delta_dt_val);

					//Determine output format
					gl_global_getvar("dateformat",dateformat,sizeof(dateformat));

					//Output date appropriately
					if ( strcmp(dateformat,"ISO")==0)
						sprintf(datebuff,"ERROR    [%04d-%02d-%02d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.year,delta_dt_val.month,delta_dt_val.day,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz);
					else if ( strcmp(dateformat,"US")==0)
						sprintf(datebuff,"ERROR    [%02d-%02d-%04d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.month,delta_dt_val.day,delta_dt_val.year,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz);
					else if ( strcmp(dateformat,"EURO")==0)
						sprintf(datebuff,"ERROR    [%02d-%02d-%04d %02d:%02d:%02d.%.06d %s] : ",delta_dt_val.day,delta_dt_val.month,delta_dt_val.year,delta_dt_val.hour,delta_dt_val.minute,delta_dt_val.second,del_microseconds,delta_dt_val.tz);
					else
						sprintf(datebuff,"ERROR    .09f : ",del_clock);

					//Actual error part
					sprintf(error_output_buff,"Assert failed on %s - %s (%g) not within %f of given value %g",gl_name(obj->parent, buff, 64),da->get_target(), *x, da->get_within(), da->get_value());

					//Send it out
					gl_output("%s%s",datebuff,error_output_buff);

					return SM_ERROR;
				}
				gl_verbose("Assert passed on %s", gl_name(obj->parent, buff, 64));
				return SM_EVENT;
			}
			else
			{
				gl_verbose("Assert test is not being run on %s", gl_name(obj->parent, buff, 64));
				return SM_EVENT;
			}
		}
		else	//First pass, just proceed
			return SM_EVENT;
	}
	else	//Iteration, so don't care
		return SM_EVENT;
}
示例#6
0
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[])
{
	if (set_callback(fntable)==NULL)
	{
		errno = EINVAL;
		return NULL;
	}

	// open a connection to the Matlab engine
	int status=0;
	static char server[1024];
	if (gl_global_getvar("matlab_server",server,sizeof(server)))
		matlab_server = server;
	if (strcmp(matlab_server,"standalone")==0)
		engine = engOpenSingleUse(NULL,NULL,&status);
	else
		engine = engOpen(matlab_server);
	if (engine==NULL)
	{
		gl_error("unable to start Matlab engine (code %d)",status);
		return NULL;
	}

	// prepare session
	char debug[8];
	if (gl_global_getvar("debug",debug,sizeof(debug)))
		debugmode = (atoi(debug)==1);
	engSetVisible(engine,debugmode?1:0);
	engEvalString(engine,"clear all;");
	char env[1024];
	_snprintf(env,sizeof(env),"NEVER=%g;INVALID=%g;",TOSERIAL(TS_NEVER),TOSERIAL(TS_INVALID));
	engEvalString(engine,env);

	// collect output from Matlab
	engOutputBuffer(engine,output,sizeof(output)); 

	// setup the Matlab module and run the class constructor
	engEvalString(engine,"global passconfig;");
	if (engEvalString(engine,argv[0])!=0)
		gl_error("unable to evaluate function '%s' in Matlab", argv[0]);
	else
		gl_matlab_output();

	// read the pass configuration
	mxArray *pcfg= engGetVariable(engine,"passconfig");
	if (pcfg && mxIsChar(pcfg))
	{
		char passinfo[1024];
		KEYWORD keys[] = {
			{"NOSYNC",PC_NOSYNC,keys+1},
			{"PRETOPDOWN",PC_PRETOPDOWN,keys+2},
			{"BOTTOMUP",PC_BOTTOMUP,keys+3},
			{"POSTTOPDOWN",PC_POSTTOPDOWN,NULL},
		};
		PROPERTY pctype = {0,"passconfig",PT_set,1,PA_PUBLIC,NULL,&passconfig,NULL,keys,NULL};
		set passdata;
		if (mxGetString(pcfg,passinfo,sizeof(passinfo))==0 && callback->convert.string_to_property(&pctype,&passdata,passinfo)>0)
		{
			passconfig = (PASSCONFIG)passdata;
			oclass=gl_register_class(module,argv[0],passconfig);
			if (oclass==NULL)
				gl_error("unable to register '%s' as a class",argv[0]);

			DELEGATEDTYPE *pDelegate = new DELEGATEDTYPE;
			pDelegate->oclass = oclass;
			strncpy(pDelegate->type,"matlab",sizeof(pDelegate->type));
			pDelegate->from_string = object_from_string;
			pDelegate->to_string = object_to_string;
			if (gl_publish_variable(oclass,PT_delegated,pDelegate,"data",0,NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);

		}
		else
			gl_error("passconfig is invalid (expected set of NOSYNC, PRETOPDOWN, BOTTOMUP, and POSTTOPDOWN)", passinfo);
	}
	else
		gl_error("passconfig not specified");

	// read the pass configuration
	mxArray *ans= engGetVariable(engine,"ans");
	if (ans && mxIsStruct(ans))
	{
		defaults = mxDuplicateArray(ans);

		// process the answer
		int nFields = mxGetNumberOfFields(ans), i;
		for (i=0; i<nFields; i++)
		{
			const char *name = mxGetFieldNameByNumber(ans,i);
			mxArray *data = mxGetFieldByNumber(ans,0,i);
			// @todo publish the structure
		}
	}
	else
		gl_error("result of call to matlab::%s did not return a structure", argv[0]);

#ifdef OPTIONAL
	/* TODO: publish global variables (see class_define_map() for details) */
	gl_global_create(char *name, ..., NULL);
	/* TODO: use gl_global_setvar, gl_global_getvar, and gl_global_find for access */
#endif

	/* always return the first class registered */
	return oclass;
}
TIMESTAMP player_read(OBJECT *obj)
{
	char buffer[256];
	char timebuf[64], valbuf[256], tbuf[64];
	char tz[6];
	int Y=0,m=0,d=0,H=0,M=0;
	double S=0;
	struct player *my = OBJECTDATA(obj,struct player);
	char unit[2];
	TIMESTAMP t1;
	char *result=NULL;
	char256 value;
	int voff=0;

	/* TODO move this to tape.c and make the variable available to all classes in tape */
	static enum {UNKNOWN,ISO,US,EURO} dateformat = UNKNOWN;
	if ( dateformat==UNKNOWN )
	{
		static char global_dateformat[8]="";
		gl_global_getvar("dateformat",global_dateformat,sizeof(global_dateformat));
		if (strcmp(global_dateformat,"ISO")==0) dateformat = ISO;
		else if (strcmp(global_dateformat,"US")==0) dateformat = US;
		else if (strcmp(global_dateformat,"EURO")==0) dateformat = EURO;
		else dateformat = ISO;
	}

Retry:
	result = my->ops->read(my, buffer, sizeof(buffer));

	memset(timebuf, 0, 64);
	memset(valbuf, 0, 256);
	memset(tbuf, 0, 64);
	memset(value, 0, 256);
	memset(tz, 0, 6);
	if (result==NULL)
	{
		if (my->loopnum>0)
		{
			rewind_player(my);
			my->loopnum--;
			goto Retry;
		}
		else {
			close_player(my);
			my->status=TS_DONE;
			my->next.ts = TS_NEVER;
			my->next.ns = 0;
			goto Done;
		}
	}
	if (result[0]=='#' || result[0]=='\n') /* ignore comments and blank lines */
		goto Retry;

	if(sscanf(result, "%32[^,],%256[^\n\r;]", tbuf, valbuf) == 2){
		trim(tbuf, timebuf);
		trim(valbuf, value);
		if (sscanf(timebuf,"%d-%d-%d %d:%d:%lf %4s",&Y,&m,&d,&H,&M,&S, tz)==7){
			//struct tm dt = {S,M,H,d,m-1,Y-1900,0,0,0};
			DATETIME dt;
			switch ( dateformat ) {
			case ISO:
				dt.year = Y;
				dt.month = m;
				dt.day = d;
				break;
			case US:
				dt.year = d;
				dt.month = Y;
				dt.day = m;
				break;
			case EURO:
				dt.year = d;
				dt.month = m;
				dt.day = Y;
				break;
			}
			dt.hour = H;
			dt.minute = M;
			dt.second = (unsigned short)S;
			dt.nanosecond = (unsigned int)(1e9*(S-dt.second));
			strcpy(dt.tz, tz);
			t1 = (TIMESTAMP)gl_mktime(&dt);
			if ((obj->flags & OF_DELTAMODE)==OF_DELTAMODE)	/* Only request deltamode if we're explicitly enabled */
				enable_deltamode(dt.nanosecond==0?TS_NEVER:t1);
			if (t1!=TS_INVALID && my->loop==my->loopnum){
				my->next.ts = t1;
				my->next.ns = dt.nanosecond;
				while(value[voff] == ' '){
					++voff;
				}
				strcpy(my->next.value, value+voff);
			}
		}
		else if (sscanf(timebuf,"%d-%d-%d %d:%d:%lf",&Y,&m,&d,&H,&M,&S)>=4)
		{
			//struct tm dt = {S,M,H,d,m-1,Y-1900,0,0,0};
			DATETIME dt;
			switch ( dateformat ) {
			case ISO:
				dt.year = Y;
				dt.month = m;
				dt.day = d;
				break;
			case US:
				dt.year = d;
				dt.month = Y;
				dt.day = m;
				break;
			case EURO:
				dt.year = d;
				dt.month = m;
				dt.day = Y;
				break;
			}
			dt.hour = H;
			dt.minute = M;
			dt.second = (unsigned short)S;
			dt.tz[0] = 0;
			dt.nanosecond = (unsigned int)(1e9*(S-dt.second));
			t1 = (TIMESTAMP)gl_mktime(&dt);
			if ((obj->flags & OF_DELTAMODE)==OF_DELTAMODE)	/* Only request deltamode if we're explicitly enabled */
				enable_deltamode(dt.nanosecond==0?TS_NEVER:t1);
			if (t1!=TS_INVALID && my->loop==my->loopnum){
				my->next.ts = t1;
				my->next.ns = dt.nanosecond;
				while(value[voff] == ' '){
					++voff;
				}
				strcpy(my->next.value, value+voff);
			}
		}
		else if (sscanf(timebuf,"%" FMT_INT64 "d%1s", &t1, unit)==2)
		{
			{
				int64 scale=1;
				switch(unit[0]) {
				case 's': scale=TS_SECOND; break;
				case 'm': scale=60*TS_SECOND; break;
				case 'h': scale=3600*TS_SECOND; break;
				case 'd': scale=86400*TS_SECOND; break;
				default: break;
				}
				t1 *= scale;
				if (result[0]=='+'){ /* timeshifts have leading + */
					my->next.ts += t1;
					while(value[voff] == ' '){
						++voff;
					}
					strcpy(my->next.value, value+voff);
				} else if (my->loop==my->loopnum){ /* absolute times are ignored on all but first loops */
					my->next.ts = t1;
					while(value[voff] == ' '){
						++voff;
					}
					strcpy(my->next.value, value+voff);
				}
			}
		}
		else if (sscanf(timebuf,"%lf", &S)==1)
		{
			if (my->loop==my->loopnum) {
				my->next.ts = (unsigned short)S;
				my->next.ns = (unsigned int)(1e9*(S-my->next.ts));
				if ((obj->flags & OF_DELTAMODE)==OF_DELTAMODE)	/* Only request deltamode if we're explicitly enabled */
					enable_deltamode(my->next.ns==0?TS_NEVER:t1);
				while(value[voff] == ' '){
					++voff;
				}
				strcpy(my->next.value, value+voff);
			}
		}
		else
		{
			gl_warning("player was unable to parse timestamp \'%s\'", result);
		}
	} else {
		gl_warning("player was unable to split input string \'%s\'", result);
	}

Done:
	return my->next.ns==0 ? my->next.ts : (my->next.ts+1);
}