Пример #1
0
void
MapFile::PerformSubstitution(ExtArray<MyString> & groups,
							 const MyString pattern,
							 MyString & output)
{
	for (int index = 0; index < pattern.Length(); index++) {
		if ('\\' == pattern[index]) {
			index++;
			if (index < pattern.Length()) {
				if ('1' <= pattern[index] &&
					'9' >= pattern[index]) {
					int match = pattern[index] - '0';
					if (groups.getlast() >= match) {
						output += groups[match];
						continue;
					}
				}

				output += '\\';
			}
		}

		output += pattern[index];
	}
}
Пример #2
0
/**
 * Ascending Insertion Sort
 * This is here so I can sort ExtArray<int>'s
 * 
 * @param list - the array to sort
 **/
void
CronTab::sort( ExtArray<int> &list )
{
	int ctr, ctr2, value;
	for ( ctr = 1; ctr <= list.getlast(); ctr++ ) {
		value = list[ctr];
    	ctr2 = ctr;
		while ( ( ctr2 > 0 ) && ( list[ctr2 - 1] > value ) ) {
			list[ctr2] = list[ctr2 - 1];
			ctr2--;
		} // WHILE
		list[ctr2] = value;
	} // FOR
	return;
}
Пример #3
0
/**
 * Just checks to see if a value is in an array
 * 
 * @param list - the array to search for the value
 * @param elt - the value to search for in the array
 * @return true if the element exists in the list
 **/
bool
CronTab::contains( ExtArray<int> &list, const int &elt ) 
{
		//
		// Just run through our array and look for the 
		// the element
		//
	bool ret = false;
	int ctr;
	for ( ctr = 0; ctr <= list.getlast(); ctr++ ) {
			//
			// All we can really do is do a simple comparison
			//
		if ( elt == list[ctr] ) {
			ret = true;
			break;	
		}
	} // FOR
	return ( ret );
}
Пример #4
0
/**
 * Important helper function that actually does the grunt work of
 * find the next runtime. We need to be given an array of the different
 * time fields so that we can match the current time with different 
 * parameters. The function will recursively call itself until
 * it can find a match at the MINUTES level. If one recursive call
 * cannot find a match, it will return false and the previous level
 * will increment its range index by one and try to find a match. On the 
 * the subsequent call useFirst will be set to true meaning that the level
 * does not need to look for a value in the range that is greater than or
 * equal to the current time value. If the failing returns to the MONTHS level, 
 * that means we've exhausted all our possiblities from the current time to the
 * the end of the year. So we'll increase the year by 1 and try the same logic again
 * using January 1st as the starting point.
 * The array match will contain the timestamp information of the job's
 * next run time
 * 
 * @param curTime - an array of time attributes for where we start our calculations
 * @param match - an array of time attributes that is the next run time
 * @param attribute_idx - the index for the current parameter in CronTab::attributes
 * @param useFirst - whether we should base ourselves off of Jan 1st
 * @return true if we able to find a new run time
 **/
bool
CronTab::matchFields( int *curTime, int *match, int attribute_idx, bool useFirst )
{
		//
		// Whether we need to tell the next level above that they
		// should use the first element in their range. If we were told
		// to then certainly the next level will as well
		//
	bool nextUseFirst = useFirst;
		//
		// First initialize ourself to know that we don't have a match
		//
	match[attribute_idx] = -1;
	
		//
		// Special Day of Week Handling
		// In order to get the day of week stuff to work, we have 
		// to insert all the days of the month for the matching days of the
		// week in the range.
		//
	ExtArray<int> *curRange = NULL;
	if ( attribute_idx == CRONTAB_DOM_IDX ) {
			//
			// We have to take the current month & year
			// and convert the days of the week range into
			// days of the month
			//
			
			//Issue here is that range for dom will be 1-31
			//for * and if one doesn't specify day_of_month in a job file
		if (this->ranges[attribute_idx]->length()==CRONTAB_DAY_OF_MONTH_MAX){	
			if ((this->ranges[CRONTAB_DOW_IDX]->length()==CRONTAB_DAY_OF_WEEK_MAX)||
			   (this->ranges[CRONTAB_DOW_IDX]->length()==0)){ 
				//if both wildcards, use month range
				//if DOW range empty use DOM range
				curRange = new ExtArray<int>( *this->ranges[attribute_idx] );
			} else {
				//only wildcard in month, so use day of week range
				//this isn't quite right
				curRange = new ExtArray<int>( CRONTAB_DAY_OF_MONTH_MAX );
			}
		}else{
		      // get to here means DOM was specified
		      curRange = new ExtArray<int>( *this->ranges[attribute_idx] );
		}
		
		int firstDay = dayOfWeek( match[CRONTAB_MONTHS_IDX],
								  1,
								  match[CRONTAB_YEARS_IDX] );
		int ctr, cnt;
		for ( ctr = 0, cnt = this->ranges[CRONTAB_DOW_IDX]->getlast();
			  ctr <= cnt;
			  ctr++ ) {
				//
				// Now figure out all the days for this specific day of the week
				//
			int day = (this->ranges[CRONTAB_DOW_IDX]->getElementAt(ctr) - firstDay) + 1;
			while ( day <= CRONTAB_DAY_OF_MONTH_MAX ) {
				if (curRange && day > 0 && !this->contains( *curRange, day ) ) {
					curRange->add( day );
				}
				day += 7;
			} // WHILE
		} // FOR
			//
			// We have sort the list since we've added new elements
			//
		this->sort( *curRange );
		
		//
		// Otherwise we'll just use the unmodified range
		//
	} else {
		curRange = this->ranges[attribute_idx];
	}

		//
		// Find the first match for this field
		// If our value isn't in the list, then we'll take the next one
		//
	bool ret = false;
	int range_idx, cnt;
	for ( range_idx = 0, cnt = curRange->getlast();
		  range_idx <= cnt;
		  range_idx++ ) {
			//
			// Two ways to make a match:
			//
			//	1) The level below told us that we need to just 
			//	   the first value in our range if we can. 
			//	2) We need to select the first value in our range
			//	   that is greater than or equal to the current
			//	   time value for this field. This is usually
			//	   what we will do on the very first call to
			//	   us. If we fail and return back to the previous
			//	   level, when they call us again they'll ask
			//	   us to just use the first value that we can
			//
		int value = curRange->getElementAt( range_idx );
		if ( useFirst || value >= curTime[attribute_idx] ) {
				//
				// If this value is greater than the current time value,
				// ask the next level to useFirst
				//
			if ( value > curTime[attribute_idx] ) nextUseFirst = true;
				//
				// Day of Month Check!
				// If this day doesn't exist in this month for
				// the current year in our search, we have to skip it
				//
			if ( attribute_idx == CRONTAB_DOM_IDX ) {
				int maxDOM = daysInMonth( 	match[CRONTAB_MONTHS_IDX],
											match[CRONTAB_YEARS_IDX] );
				if ( value > maxDOM ) {
					continue;
				}
			}
			match[attribute_idx] = value;
				//
				// If we're the last field for the crontab (i.e. minutes),
				// then we should have a valid time now!
				//
			if ( attribute_idx == CRONTAB_MINUTES_IDX ) {
				ret = true;
				break;
				
				//
				// Now that we have a current value for this field, call to the
				// next field level and see if they can find a match using our
				// If we roll back then we'll want the next time around for the
				// next level to just use the first parameter in their range
				// if they can
				//
			} else {
				ret = this->matchFields( curTime, match, attribute_idx - 1, nextUseFirst );
				nextUseFirst = true;
				if ( ret ) break;
			}
		}
	} // FOR
		//
		// If the next level up failed, we need to have
		// special handling for months so we can roll over the year
		// While this may seem trivial it's needed so that we 
		// can change the year in the matching for leap years
		// We will call ourself to make a nice little loop!
		//
	if ( !ret && attribute_idx == CRONTAB_MONTHS_IDX ) {
		match[CRONTAB_YEARS_IDX]++;	
		ret = this->matchFields( curTime, match, attribute_idx, true );
	}
	
		//
		// We only need to delete curRange if we had
		// instantiated a new object for it
		//
	if ( attribute_idx == CRONTAB_DOM_IDX && curRange ) delete curRange;
	
	return ( ret );
}