Beispiel #1
0
//////////
//
// Function: VARTYPE()
// Returns the variable type, parsing NULL values.
//
//////
// Version 0.58
// Last update:
//     Apr.06.2015
//////
// Change log:
//     Apr.06.2015 - Initial creation
//////
// Parameters:
//     P1			-- The variable to examine
//     P2			-- (Optional) If provided, .t. or .f. indicating if NULL values should return the type (default to .f.)
//
//////
// Returns:
//    Character		-- A one-digit value indicating the type
//////
	void function_vartype(SReturnsParams* rpar)
	{
		SVariable* var		= rpar->ip[0];
		SVariable* varNull	= rpar->ip[1];

		bool	llNullIsType;
		bool	error;
		u32		errorNum;


		//////////
		// varLookup must exist
		//////
			rpar->rp[0] = NULL;
			if (!iVariable_isValidType(var))
			{
				iError_report_byNumber(_ERROR_P1_IS_INCORRECT, iVariable_get_relatedComp(var), false);
				return;
			}


		//////////
		// If varNull is specified, must be logical
		//////
			if (varNull)
			{

				//////////
				// Must be logical
				//////
					if (!iVariable_isValid(varNull) || !iVariable_isTypeLogical(varNull))
					{
						iError_report_byNumber(_ERROR_P2_IS_INCORRECT, iVariable_get_relatedComp(varNull), false);
						return;
					}


				//////////
				// Grab the value
				//////
					llNullIsType = iiVariable_getAs_bool(varNull, false, &error, &errorNum);
					if (error)
					{
						iError_report_byNumber(errorNum, iVariable_get_relatedComp(varNull), false);
						return;
					}


			} else {
				// Do not report on NULL types
				llNullIsType = false;
			}


		//////////
		// Compute our result
		//////
			ifunction_type_common(rpar, var, false, true, llNullIsType);

	}
Beispiel #2
0
//////////
//
// Function: EMPTY()
// Determines whether an expression evaluates to empty.
//
//////
// Version 0.58
// Last update:
//     Mar.20.2015
//////
// Change log:
//     Mar.20.2015 - Refactoring by Stefano D'Amico
//     Mar.19.2015 - Refactoring by Rick C. Hodgin
//     Mar.19.2015 - Initial creation by Stefano D'Amico
//////
// Parameters:
//     p1	-- Specifies the expression that EMPTY( ) evaluates.
//
//////
// Returns:
//    EMPTY( ) returns True (.T.) if the expression eExpression evaluates to empty;
//    otherwise, EMPTY( ) returns False (.F.)
//////
// Example:
//    ? EMPTY("AA")	&& Display .F.
//    ? EMPTY("  ")	&& Display .T.
//    ? EMPTY(0.0)	&& Display .T.
//////
	void function_empty(SReturnsParams* rpar)
	{
		SVariable*	varExpr = rpar->ip[0];
		bool		llEmpty;
		SVariable*	result;


		//////////
		// Verify the expression is correct
		//////
			rpar->rp[0] = NULL;
			if (!iVariable_isValid(varExpr))
			{
				iError_report_byNumber(_ERROR_PARAMETER_IS_INCORRECT, iVariable_get_relatedComp(varExpr), false);
				return;
			}


		//////////
		// Create and populate the return variable
		//////
			llEmpty	= function_isempty_common(rpar, varExpr);
			result	= iVariable_createAndPopulate_byText(_VAR_TYPE_LOGICAL, iVariable_populate_byBool(llEmpty), 1, false);
			if (!result)
				iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(varExpr), false);


		//////////
		// Signify our result
		//////
			rpar->rp[0] = result;

	}
Beispiel #3
0
//////////
//
// Function: ISNULL()
// Determines whether an expression evaluates to null.
//
//////
// Version 0.58
// Last update:
//     Apr.22.2015
//////
// Change log:
//     Apr.06.2015 - Initial creation by Hernan Cano M
//////
// Parameters:
//     p1	-- Specifies the expression that ISNULL() evaluates.
//
//////
// Returns:
//    ISNULL() returns True (.T.) if the expression eExpression evaluates to null;
//    otherwise, ISNULL() returns False (.F.)
//////
// Example:
//    ? ISNULL("AA")	&& Display .F.
//    ? ISNULL("  ")	&& Display .F.
//    ? ISNULL(0.0)  	&& Display .F.
//    ? ISNULL(.null.)  && Display .T.
//////
	void function_isnull(SReturnsParams* rpar)
	{
		SVariable*	varExpr = rpar->ip[0];

		bool		llIsNull;


		//////////
		// Verify the variable is of a valid format
		//////
			rpar->rp[0] = NULL;
			if (!iVariable_isValidType(varExpr))
			{
				iError_report_byNumber(_ERROR_PARAMETER_IS_INCORRECT, iVariable_get_relatedComp(varExpr), false);
				return;
			}


		//////////
		// Create and populate the return variable
		//////
			llIsNull	= ifunction_isnull_common(varExpr);
			rpar->rp[0]	= iVariable_createAndPopulate_byText(_VAR_TYPE_LOGICAL, iVariable_populate_byBool(llIsNull), 1, true);
			if (!rpar->rp[0])
				iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(varExpr), false);

	}
Beispiel #4
0
//////////
//
// Function: IIF()
// Immediate if.
//
//////
// Version 0.58
// Last update:
//     Mar.22.2015
//////
// Change log:
//     Mar.22.2015 - Initial creation
//////
// Parameters:
//     varTest		-- The logical test result
//     varTrue		-- The value to use if true
//     varFalse		-- The value to use if false
//
//////
// Returns:
//    A copy of either varTrue or varFalse.
//////
	void function_iif(SReturnsParams* rpar)
	{
		SVariable*	varTest		= rpar->ip[0];
		SVariable*	varTrue		= rpar->ip[1];
		SVariable*	varFalse	= rpar->ip[2];
		bool		llTest;
		SVariable*	result;
		u32			errorNum;
        bool		error;


		//////////
		// Parameter 1 must be logical
		//////
			rpar->rp[0] = NULL;
			if (!iVariable_isValid(varTest) || !iVariable_isFundamentalTypeLogical(varTest))
			{
				iError_report_byNumber(_ERROR_MUST_BE_LOGICAL, iVariable_get_relatedComp(varTest), false);
				return;
			}


		//////////
        // Grab the test result
		//////
			llTest = iiVariable_getAs_bool(varTest, false, &error, &errorNum);
			if (error)
			{
				iError_report_byNumber(errorNum, iVariable_get_relatedComp(varTest), false);
				return;
			}


		//////////
		// Based on the test, copy either varTrue or varFalse
		//////
			if (llTest)
			{
				// Copy true
				result = iVariable_copy(varTrue, false);

			} else {
				// Copy false
				result = iVariable_copy(varFalse, false);
			}


		//////////
		// Are we good?
		//////
			if (!result)
				iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(((llTest) ? varTrue : varFalse)), false);


		//////////
        // Return our converted result
		//////
			rpar->rp[0] = result;

	}
Beispiel #5
0
//////////
//
// Function: INT()
// Takes a value and returns the INT(n) of that value.
//
//////
// Version 0.58
// Last update:
//     Apr.02.2015
//////
// Change log:
//     Apr.02.2015 - Refactoring
//     Jul.13.2014 - Initial creation
//////
// Parameters:
//     p1			-- Numeric or floating point
//
//////
// Returns:
//    INT(n) of the value in p1
//////
    void function_int(SReturnsParams* rpar)
    {
		SVariable*	varNumber = rpar->ip[0];
		f64			fValue;
		u32			errorNum;
        bool		error;
        SVariable*	result;


		//////////
		// Parameter 1 must be numeric
		//////
			rpar->rp[0] = NULL;
			if (!iVariable_isValid(varNumber) || !iVariable_isTypeNumeric(varNumber))
			{
				iError_report_byNumber(_ERROR_PARAMETER_IS_INCORRECT, iVariable_get_relatedComp(varNumber), false);
				return;
			}


		//////////
        // Based on its type, process it accordingly
		//////
			if (iVariable_isTypeFloatingPoint(varNumber))
			{
				fValue = iiVariable_getAs_f64(varNumber, false, &error, &errorNum);
				if (error)
				{
					iError_report_byNumber(errorNum, iVariable_get_relatedComp(varNumber), false);
					return;
				}

				// Convert to S64
				result = iVariable_create(_VAR_TYPE_S64, NULL, true);
				if (result)
					*(s64*)result->value.data_s8 = (s64)fValue;

			} else {
				// Copy whatever it already is
				result = iVariable_copy(varNumber, false);
			}


		//////////
		// Are we good?
		//////
			if (!result)
			{
				iError_report(cgcInternalError, false);
				return;
			}


		//////////
        // Return our converted result
		//////
			rpar->rp[0] = result;

    }
Beispiel #6
0
//////////
//
// Function: ISUPPER()
// Determines whether the first character in a character expression is an uppercase alphabetic character.
//
//////
// Version 0.58
// Last update:
//     Sep.15.2015
//////
// Change log:
//     Sep.15.2015 - Initial creation by Stefano D'Amico
//////
// Parameters:
//     p1	-- Specifies the character expression that ISUPPER( ) evaluates.
//     p2	-- Optional, if true evaluates all string
//
//////
// Returns:
//    ISUPPER( ) returns true (.T.) if the first character in a character expression is an uppercase alphabetic character;
//    otherwise, ISUPPER( ) returns false (.F.).
//////
// Example:
//    ? ISUPPER("Aa")		&& Display .T.
//    ? ISUPPER("Aa")		&& Display .T.
//    ? ISUPPER("Aa", .T.) 	&& Display .F.
//    ? ISUPPER("AA", .T.)	&& Display .T.
//////
	void function_isupper(SReturnsParams* rpar)
	{
		SVariable*	varStr				= rpar->ip[0];
		SVariable*	varTestWholeString	= rpar->ip[1];

		bool		llTestWholeString, llIsUpper;
		bool		error;
		u32			errorNum;


		//////////
		// Parameters 1 must be present and character
		//////
			rpar->rp[0] = NULL;
			if (!iVariable_isValid(varStr) || !iVariable_isTypeCharacter(varStr))
			{
				iError_report_byNumber(_ERROR_P1_IS_INCORRECT, iVariable_get_relatedComp(varStr), false);
				return;
			}


		//////////
		// If present, parameter 2 must be bool
		//////
			if (varTestWholeString)
			{
				if (!iVariable_isFundamentalTypeLogical(varTestWholeString))
				{
					iError_report_byNumber(_ERROR_P2_IS_INCORRECT, iVariable_get_relatedComp(varTestWholeString), false);
					return;
				}

				// Grab the value
				llTestWholeString = iiVariable_getAs_bool(varTestWholeString, false, &error, &errorNum);
				if (error)
				{
					iError_report_byNumber(errorNum, iVariable_get_relatedComp(varTestWholeString), false);
					return;
				}

			} else {
				// Just testing the first character
				llTestWholeString = false;
			}


		//////////
		// Create and populate the return variable
		//////
			llIsUpper	= ifunction_iscommon(varStr, llTestWholeString, _isUpper);
			rpar->rp[0]	= iVariable_createAndPopulate_byText(_VAR_TYPE_LOGICAL, iVariable_populate_byBool(llIsUpper), 1, true);
			if (!rpar->rp[0])
				iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(varStr), false);

	}
Beispiel #7
0
//////////
//
// Function: VECCOUNT()
// The vector element count.
//
//////
// Version 0.58
// Last update:
//     Mar.21.2015
//////
// Change log:
//     Mar.21.2015 - Initial creation
//////
// Parameters:
//     varVec		- Vector
//
//////
// Returns:
//     Numeric, the number of elements in the vector.
//////
	void function_veccount(SReturnsParams* rpar)
	{
		SVariable* varVec = rpar->ip[0];


		// Not yet completed
		iError_report_byNumber(_ERROR_FEATURE_NOT_AVAILABLE, iVariable_get_relatedComp(varVec), false);
		rpar->rp[0] = NULL;
	}
Beispiel #8
0
//////////
//
// Function: EVL()
// Returns a non-empty value from two expressions.
//
//////
// Version 0.58
// Last update:
//     Mar.20.2015
//////
// Change log:
//     Mar.20.2015 - Some refactoring by Rick C. Hodgin
//     Mar.20.2015 - Initial creation by Stefano D'Amico
//////
// Parameters:
//     p1	-- Specifies the expression that EMPTY( ) evaluates.
//     p2	-- Specifies the expression to return if p1 is empty.
//
//////
// Returns:
//    EVL( ) returns p1 if it does not evaluate to an empty value; otherwise, it returns p2.
//////
// Example:
//    ? EVL("  ", "None")	&& Display "None"
//////
	void function_evl(SReturnsParams* rpar)
	{
		SVariable*	varExpr1 = rpar->ip[0];
		SVariable*	varExpr2 = rpar->ip[1];
		bool		llEmpty;
		SVariable*	result;


		//////////
		// Verify p1 is correct
		//////
			rpar->rp[0] = NULL;
			if (!iVariable_isValid(varExpr1))
			{
				iError_report_byNumber(_ERROR_P1_IS_INCORRECT, iVariable_get_relatedComp(varExpr1), false);
				return;
			}


		//////////
		// Verify p2 is correct
		//////
			if (!iVariable_isValid(varExpr2))
			{
				iError_report_byNumber(_ERROR_P2_IS_INCORRECT, iVariable_get_relatedComp(varExpr2), false);
				return;
			}


		//////////
		// Create our result
		//////
			llEmpty	= function_isempty_common(rpar, varExpr1);
			result	= iVariable_copy(((llEmpty) ? varExpr2 : varExpr1), false);
			if (!result)
				iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(((llEmpty) ? varExpr2 : varExpr1)), false);


		//////////
		// Signify our result
		//////
			rpar->rp[0] = result;

	}
Beispiel #9
0
//////////
//
// Function: _VJRSYS()
// Internal function.  Not published.  Used to access VJr system variables.
//
//////
// Version 0.58
// Last update:
//     Oct.28.2015
//////
// Change log:
//     Oct.28.2015 - Initial creation by Rick C. Hodgin
//////
// Parameters:
//     varIndex			-- Index function to access the variable
//
//////
// Returns:
//     Varies			-- Based on index, returns the VJr system variable
//////
	void function__vjrsys(SReturnsParams* rpar)
	{
		SVariable* varIndex		= rpar->ip[0];

		s32			lnIndex;
		u32			errorNum;
		bool		error;


		//////////
		// Parameter 1 must be valid and numeric
		//////
			rpar->rp[0] = NULL;
			if (!iVariable_isValid(varIndex) || !iVariable_isTypeNumeric(varIndex))
			{
				iError_report_byNumber(_ERROR_P1_IS_INCORRECT, iVariable_get_relatedComp(varIndex), false);
				return;
			}

			// Grab the index value
			lnIndex = iiVariable_getAs_s32(varIndex, false, &error, &errorNum);
			if (error)
			{
				iError_report_byNumber(errorNum, iVariable_get_relatedComp(varIndex), false);
				return;
			}


		//////////
		// Dispatch based on operation
		//////
			switch (lnIndex)
			{
				case 1:
					rpar->rp[0] = iVariable_createAndPopulate_byText(_VAR_TYPE_LOGICAL, iVariable_populate_byBool(glShuttingDown), 1, false);
					break;

				default:
					iError_report_byNumber(_ERROR_FEATURE_NOT_AVAILABLE, iVariable_get_relatedComp(varIndex), false);
					break;
			}

	}
Beispiel #10
0
//////////
//
// Function: ENDSWITHC()
// Case-insensitive version of ENDSWITH()
//
//////
	void function_endswithc(SReturnsParams* rpar)
	{
		SVariable* varString	= rpar->ip[0];
//		SVariable* varSearch	= rpar->params[1];
//		SVariable* varStart		= rpar->params[2];
//		SVariable* varEnd		= rpar->params[3];


		// Not yet completed
		iError_report_byNumber(_ERROR_FEATURE_NOT_AVAILABLE, iVariable_get_relatedComp(varString), false);
	}
Beispiel #11
0
//////////
//
// Function: VECSTUFF()
// Updates or resizes a vector element. Works like STUFF().
//
//////
// Version 0.58
// Last update:
//     Mar.21.2015
//////
// Change log:
//     Mar.21.2015 - Initial creation
//////
// Parameters:
//     varVec			- Vector
//     varStartEl		- Element to start the operation at.
//     varRemoveCount	- The number of elements to remove
//     varVecStuff		- (Optional) The new vector to stuff in there after varStartEl
//
//////
// Returns:
//    if varNewValue was specified, returns the new vector
//    else                          returns the value of that element
//////
	void function_vecstuff(SReturnsParams* rpar)
	{
		SVariable* varVec			= rpar->ip[0];
//		SVariable* varStartEl		= rpar->params[1];
//		SVariable* varRemoveCount	= rpar->params[2];
//		SVariable* varVecStuff		= rpar->params[3];


		// Not yet completed
		iError_report_byNumber(_ERROR_FEATURE_NOT_AVAILABLE, iVariable_get_relatedComp(varVec), false);
		rpar->rp[0] = NULL;
	}
Beispiel #12
0
//////////
//
// Function: VAL()
// Returns a numeric or currency value from a expression.
//
//////
// Version 0.58
// Last update:
//     Mar.22.2015
//////
// Change log:
//     Mar.21.2015 - Initial creation by Stefano D'Amico
//////
// Parameters:
//     varExpr			-- Any, to convert
//	   varIgnoreList	-- Characters to ignore
//
//////
// Returns:
//    Numeric		--	VAL( ) returns the numbers in the character expression from left to right until a non-numeric character is encountered.
//						Leading blanks are ignored.
//						VAL( ) returns 0 if the first character of the character expression is not a number, a dollar sign ($), a plus sign (+), or minus sign (-).
//////
	void function_val(SReturnsParams* rpar)
	{
		SVariable*	varExpr			= rpar->ip[0];
		SVariable*	varIgnoreChars	= rpar->ip[1];

		s8			c, cCurrency, cPoint, cSeparator;
		s32			lnI, lnJ, lnBuffOffset;
		s64			lnValue;
		f64			lfValue;
		bool		llAsInteger, llStillGoing, llCurrency;
		SVariable*	varCurrency;
		SVariable*	varPoint;
		SVariable*	varSeparator;
		SVariable*	result;
		u32			errorNum;
        bool		error;
		s8			buffer[64];


		//////////
		// Parameter 1 must be valid
		//////
			rpar->rp[0] = NULL;
			if (!iVariable_isValid(varExpr))
			{
				iError_report_byNumber(_ERROR_P1_IS_INCORRECT, iVariable_get_relatedComp(varExpr), false);
				return;
			}


		//////////
		// If numeric, copy whatever's already there
		//////
			if (varExpr->varType >= _VAR_TYPE_NUMERIC_START && varExpr->varType <= _VAR_TYPE_NUMERIC_END)
			{
				// Copy The existing variable
				result = iVariable_copy(varExpr, false);
				if (!result)
					iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(varExpr), false);

				// Success or failure, return our result
				rpar->rp[0] = result;
				return;
			}



		//////////
		// Determine what we're evaluating
		//////
			switch (varExpr->varType)
			{
				case _VAR_TYPE_NULL:
					iError_report_byNumber(_ERROR_P1_IS_INCORRECT, iVariable_get_relatedComp(varExpr), false);
					return;
					break;

				case _VAR_TYPE_LOGICAL:		// 0=.F., 1=.T.
				case _VAR_TYPE_DATE:		// YYYYMMDD
					result = iVariable_create(_VAR_TYPE_S32, NULL, true);
					if (result)
					{
						// Populate the s32
						*result->value.data_s32 = iiVariable_getAs_s32(varExpr, true, &error, &errorNum);
						if (error)
							iError_report_byNumber(errorNum, iVariable_get_relatedComp(varExpr), false);
					}
					break;

				case _VAR_TYPE_DATETIME:
					// YYYYMMDDHhMmSsMss as s64
				case _VAR_TYPE_DATETIMEX:
					// YYYYMMDDHhMmSsNssssssss
					result = iVariable_create(_VAR_TYPE_S64, NULL, true);
					if (result)
					{
						// Populate the s64
						*result->value.data_s64 = iiVariable_getAs_s64(varExpr, true, &error, &errorNum);
						if (error)
							iError_report_byNumber(errorNum, iVariable_get_relatedComp(varExpr), false);
					}
					break;

				case _VAR_TYPE_CHARACTER:

					//////////
					// If present, parameter 2 must be valid
					//////
						if (varIgnoreChars)
						{
							if (!iVariable_isValid(varIgnoreChars) || !iVariable_isTypeCharacter(varIgnoreChars))
							{
								iError_report_byNumber(_ERROR_P2_IS_INCORRECT, iVariable_get_relatedComp(varIgnoreChars), false);
								return;
							}
						}


					//////////
					// Prepare our characters
					//////
						varCurrency		= propGet_settings_Currency(_settings);
						varPoint		= propGet_settings_Point(_settings);
						varSeparator	= propGet_settings_Separator(_settings);
						if (!varCurrency || !varPoint || !varSeparator)
						{
							// Should never happen
							iError_report_byNumber(_ERROR_INTERNAL_ERROR, NULL, false);
							return;
						}


					//////////
					// Create single characters
					//////
						cCurrency	= varCurrency->value.data_s8[0];
						cPoint		= varPoint->value.data_s8[0];
						cSeparator	= varSeparator->value.data_s8[0];


					//////////
					// Iterate through each character
					//////
						for (lnI = 0, lnBuffOffset = 0, llStillGoing = true, llCurrency = false; llStillGoing && lnI < (s32)varExpr->value.length && lnBuffOffset < (s32)sizeof(buffer) - 1; lnI++)
						{

							//////////
							// Grab this character
							//////
								c = varExpr->value.data[lnI];


							//////////
							// Is it a character we're including in our buffer (a number, or natural number-related symbol)?
							//////
								if ((c >= '0' && c <= '9' ) || c == '+' || c == '-' || c == cPoint)
								{
									// Yes, Copy this character
									buffer[lnBuffOffset++] = c;

								} else {
									// Are we still in a valid sequence of characters to skip?
									if (c == ' ' || c == cSeparator)
									{
										// It's a character we're skipping naturally (space, separator symbol)
										// We don't do anything here ... it's just more clear to keep this logic visible rather than inverting it. :-)

									} else if (c == cCurrency) {
										// We encountered the currency symbol, so the output will be currency
										llCurrency = true;

									} else if (varIgnoreChars) {
										// We won't continue unless we're sitting on a character in the varIgnoreChars
										for (lnJ = 0, llStillGoing = false; lnJ < varIgnoreChars->value.length; lnJ++)
										{
											// Is this one of our skip characters?
											if (c == varIgnoreChars->value.data_s8[lnJ])
											{
												llStillGoing = true;
												break;
											}
										}

									} else {
										// We're done
										break;
									}
								}

						}

						// NULL terminate
						buffer[lnBuffOffset] = 0;


					//////////
					// Convert to f64, and s64
					//////
						lfValue = atof(buffer);
#if defined(__GNUC__) || defined(__solaris__)
						lnValue = strtoll(buffer, NULL, 10);
#else
						lnValue = _strtoi64(buffer, NULL, 10);
#endif


					//////////
					// Is currency or not? If it's an integer value, store it as the same, otherwise use floating point
					//////
						if ((f64)lnValue == lfValue)
						{
							// We can return as an integer
							llAsInteger = true;
							if (llCurrency)
							{
								// Multiply by 10000 to obtain the 4 implied decimal places
								lnValue = lnValue * 10000;
								result	= iVariable_create(_VAR_TYPE_CURRENCY, NULL, true);

							} else {
								if (lnValue < (s64)_s32_max)
								{
									// We can create as an s32
									result = iVariable_create(_VAR_TYPE_S32, NULL, true);

								} else {
									// Create as an s64
									result = iVariable_create(_VAR_TYPE_S64, NULL, true);
								}
							}

						} else {
							// Must return as f64
							llAsInteger	= false;
							if (llCurrency)
							{
								// As currency
								lfValue	*= 10000.0;
								result	= iVariable_create(_VAR_TYPE_CURRENCY, NULL, true);

							} else {
								// As is
								result	= iVariable_create(_VAR_TYPE_F64, NULL, true);
							}
						}


					//////////
					// Store the result
					//////
						if (result)
						{
							if (llAsInteger)	iVariable_setNumeric_toNumericType(result, NULL, NULL, NULL, NULL, &lnValue, NULL);
							else				iVariable_setNumeric_toNumericType(result, NULL, &lfValue, NULL, NULL, NULL, NULL);
						}
						break;

				default:
					// Unrecognized type
					iError_report_byNumber(_ERROR_FEATURE_NOT_AVAILABLE, iVariable_get_relatedComp(varExpr), false);
					return;
			}


		//////////
		// Are we good?
		//////
			if (!result)
				iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(varExpr), false);


		//////////
        // Return our converted result
		//////
			rpar->rp[0] = result;

	}
Beispiel #13
0
//////////
//
// Function: WEEK()
// Returns a number representing the week of the year from a Date or DateTime expression.
//
//////
// Version 0.58
// Last update:
//     May.01.2015
//////
// Change log:
//     May.01.2015 - Initial creation by Stefano D'Amico
//////
// Parameters:
//     p1			-- Date or DateTime
//     p2			-- Numeric [nMinDaysOfWeek] Minimum number of days in first week of year (1..7)
//     p3			-- Numeric [nFirstDayOfWeek] 
//
//////
// Returns:
//    WEEK() returns a number representing the week of the year.
//////
// Example:
//	  dt = datetime()	&& May.01.2015
//    ? WEEK(dt)		&& Displays 18
//////
	void function_week(SReturnsParams* rpar)
	{
		SVariable*	varParam			= rpar->ip[0];
		SVariable*	varFirstWeek		= rpar->ip[1];
		SVariable*	varFirstDayOfWeek	= rpar->ip[2];

		u32			lnYear, lnMonth, lnDay;
		s32			lnWeek, lnMinDaysInWeek, lnFirstDayOfWeek;
		SYSTEMTIME	lst;
		bool		error;
		u32			errorNum;
		SVariable*	result;


		//////////
		// If provided, parameter 1 must be date or datetime
		//////
			rpar->rp[0] = NULL;
			if (varParam)
			{
				if (!iVariable_isValid(varParam) || !(iVariable_isTypeDate(varParam) || iVariable_isTypeDatetime(varParam) || iVariable_isTypeDatetimeX(varParam)))
				{
					iError_report_byNumber(_ERROR_INVALID_ARGUMENT_TYPE_COUNT, iVariable_get_relatedComp(varParam), false);
					return;
				}

			//////////
			// Grab year, month, day from datetime or date
			//////
				     if (iVariable_isTypeDatetime(varParam))		iiDateMath_get_YyyyMmDd_from_julian					(varParam->value.data_dt->julian,			&lnYear, &lnMonth, &lnDay);
				else if (iVariable_isTypeDatetimeX(varParam))		iiDateMath_get_YyyyMmDdHhMmSsMssNss_from_jseconds	(varParam->value.data_dtx->jseconds, NULL,	&lnYear, &lnMonth, &lnDay, NULL, NULL, NULL, NULL, NULL);
				else /* date */										iiDateMath_get_YyyyMmDd_from_YYYYMMDD				(varParam->value.data_u8,					&lnYear, &lnMonth, &lnDay);

			} else {
				// Use the current date
				if (_settings)		iTime_getLocalOrSystem(&lst, propGet_settings_TimeLocal(_settings));
				else				GetLocalTime(&lst);

				lnYear	= lst.wYear;
				lnMonth	= lst.wMonth;
				lnDay	= lst.wDay;
			}


		//////////
		// Parameter 2 must be numeric
		//////
			if (varFirstWeek)
			{
				if (!iVariable_isValid(varFirstWeek) || !iVariable_isTypeNumeric(varFirstWeek))
				{
					iError_report_byNumber(_ERROR_P2_IS_INCORRECT, iVariable_get_relatedComp(varFirstWeek), false);
					return;
				}

				// Grab the minimum number of days in week
				lnMinDaysInWeek = iiVariable_getAs_s32(varFirstWeek, false, &error, &errorNum);
				if (error)
				{
					// An error extracting the value (should never happen)
					iError_report_byNumber(errorNum, iVariable_get_relatedComp(varFirstWeek), false);
					return;
				}

				if (lnMinDaysInWeek < 1 || 7 < lnMinDaysInWeek)
				{
					iError_report_byNumber(_ERROR_OUT_OF_RANGE, iVariable_get_relatedComp(varFirstWeek), false);
					return;				
				}

			} else {
				// First week contains January 1st.
				lnMinDaysInWeek = 1;
			}


		//////////
		// Parameter 3 must be numeric
		//////
			if (varFirstDayOfWeek)
			{
				if (!iVariable_isValid(varFirstDayOfWeek) || !iVariable_isTypeNumeric(varFirstDayOfWeek))
				{
					iError_report_byNumber(_ERROR_P3_IS_INCORRECT, iVariable_get_relatedComp(varFirstDayOfWeek), false);
					return;
				}

				// Grab the first day of week
				lnFirstDayOfWeek = iiVariable_getAs_s32(varFirstDayOfWeek, false, &error, &errorNum);
				if (error)
				{
					// An error extracting the value (should never happen)
					iError_report_byNumber(errorNum, iVariable_get_relatedComp(varFirstDayOfWeek), false);
					return;
				}

				if (lnFirstDayOfWeek < 0 || 6 < lnFirstDayOfWeek)
				{
					iError_report_byNumber(_ERROR_OUT_OF_RANGE, iVariable_get_relatedComp(varFirstWeek), false);
					return;				
				}

			} else {
				// Sunday
				lnFirstDayOfWeek = 0;
			}


		/////////
		// Grab week
		//////
			lnWeek = ifunction_week_common(rpar, lnYear, lnMonth, lnDay, lnMinDaysInWeek, lnFirstDayOfWeek);


		//////////
		// Create and populate our output variable
		//////
			result = iVariable_createAndPopulate_byText(_VAR_TYPE_S32, (cs8*)&lnWeek, 4, false);
			if (!result)
				iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(varParam), false);


		//////////
		// Indicate our result
		//////
			rpar->rp[0] = result;

	}
Beispiel #14
0
//////////
//
// Function: INLIST()
// A test if the value is in the list.
//
//////
// Version 0.58
// Last update:
//     Mar.22.2015
//////
// Change log:
//     Mar.22.2015 - Initial creation
//////
// Parameters:
//     varValue		-- The value to compare
//     varList1		-- A value in the list
//     varList2		-- A value in the list
//     ..
//     varList9		-- A value in the list
//
//////
// Returns:
//    Logical		-- .t. if the item is found in the list, .f. otherwise
//////
	void function_inlist(SReturnsParams* rpar)
	{
		SVariable*	varValue = rpar->ip[0];
		SVariable*	varList1 = rpar->ip[1];
		bool		llResult;
		s32			lnI, lnType;
		SVariable*	result;
		u32			errorNum;
        bool		error;


		//////////
		// Parameters 1 and 2 must be present, and of equal types
		//////
			rpar->rp[0] = NULL;
			if (!iVariable_isValid(varValue))
			{
				iError_report_byNumber(_ERROR_MISSING_PARAMETER, iVariable_get_relatedComp(varValue), false);
				return;
			}
			if (!iVariable_isValid(varList1))
			{
				iError_report_byNumber(_ERROR_MISSING_PARAMETER, iVariable_get_relatedComp(varList1), false);
				return;
			}


		//////////
		// Each type must be fundamentally the same type
		//////
			for (lnI = 1, lnType = iVariable_get_fundamentalType(varValue); lnI < (s32)_MAX_PARAMS_COUNT && rpar->ip[lnI]; lnI++)
			{

				//////////
				// Make sure this variable type matches the test value
				//////
					if (iVariable_get_fundamentalType(rpar->ip[lnI]) != lnType)
					{
						// The types do not match
						iError_report_byNumber(_ERROR_DATA_TYPE_MISMATCH, iVariable_get_relatedComp(rpar->ip[lnI]), false);
						return;
					}

			}


		//////////
		// Iterate through to see if the parameters are equal
		//////
			for (lnI = 1, llResult = false; lnI < (s32)_MAX_PARAMS_COUNT && rpar->ip[lnI]; lnI++)
			{

				//////////
				// Compare the value with each list item
				//////
					if (iVariable_compare(varValue, rpar->ip[lnI], false, &error, &errorNum) == 0 && !error)
					{
						// We found a match
						llResult = true;
						break;
					}


				//////////
				// Report on errors
				//////
					if (error)
					{
						iError_report_byNumber(errorNum, iVariable_get_relatedComp(rpar->ip[lnI]), false);
						return;
					}

			}


		//////////
		// Based on the result, create the return(result)
		//////
			result = iVariable_createAndPopulate_byText(_VAR_TYPE_LOGICAL, iVariable_populate_byBool(llResult), 1, false);
			if (!result)
				iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(varValue), false);


		//////////
		// Indicate our result
		//////
			rpar->rp[0] = result;

	}
Beispiel #15
0
	// Common numeric functions used for EXP(), LOG(), LOG10(), PI(), SQRT(), CEILING(), FLOOR(), DTOR(), RTOD(), ...
    void ifunction_numbers_common(SReturnsParams* rpar, SVariable* varNumber1, SVariable* varNumber2, SVariable* varNumber3, u32 tnFunctionType, const u32 tnResultType, bool tlSameInputType, bool tlNoEmptyParam)
    {
		f64			lfResult, lfValue1, lfValue2, lfValue3;
		u32			errorNum;
        bool		error;
        SVariable*	result;


		//////////
		// If varNumber1 is provided, must also be numeric
		//////
			rpar->rp[0] = NULL;
			if (varNumber1)
			{
				//////////
				// Must be numeric
				//////
					if (!iVariable_isValid(varNumber1) || !iVariable_isTypeNumeric(varNumber1))
					{
						iError_report_byNumber(_ERROR_PARAMETER_IS_INCORRECT, iVariable_get_relatedComp(varNumber1), false);
						return;
					}


				//////////
				// Convert to f64
				//////
					lfValue1 = iiVariable_getAs_f64(varNumber1, false, &error, &errorNum);
					if (error)
					{
						iError_report_byNumber(errorNum, iVariable_get_relatedComp(varNumber1), false);
						return;
					}

				//////////
				// Check empty param
				//////
					if (tlNoEmptyParam && lfValue1 == 0.0)
					{
						iError_report_byNumber(_ERROR_CANNOT_BE_ZERO, iVariable_get_relatedComp(varNumber1), false);
						return;
					}

			} else {
				lfValue1 = 0.0;
			}


		//////////
		// If varNumber2 is provided, must also be numeric
		//////
			if (varNumber2)
			{
				//////////
				// Must be numeric
				//////
					if (!iVariable_isValid(varNumber2) || !iVariable_isTypeNumeric(varNumber2))
					{
						iError_report_byNumber(_ERROR_PARAMETER_IS_INCORRECT, iVariable_get_relatedComp(varNumber2), false);
						return;
					}


				//////////
				// Convert to f64
				//////
					lfValue2 = iiVariable_getAs_f64(varNumber2, false, &error, &errorNum);
					if (error)
					{
						iError_report_byNumber(errorNum, iVariable_get_relatedComp(varNumber2), false);
						return;
					}

				//////////
				// Check empty param
				//////
					if (tlNoEmptyParam && lfValue2 == 0.0)
					{
						iError_report_byNumber(_ERROR_CANNOT_BE_ZERO, iVariable_get_relatedComp(varNumber2), false);
						return;
					}

			} else {
				lfValue2 = 0.0;
			}


		//////////
		// If varNumber3 is provided, must also be numeric
		//////
			if (varNumber3)
			{
				//////////
				// Must be numeric
				//////
					if (!iVariable_isValid(varNumber3) || !iVariable_isTypeNumeric(varNumber3))
					{
						iError_report_byNumber(_ERROR_PARAMETER_IS_INCORRECT, iVariable_get_relatedComp(varNumber3), false);
						return;
					}


				//////////
				// Convert to f64
				//////
					lfValue3 = iiVariable_getAs_f64(varNumber3, false, &error, &errorNum);
					if (error)
					{
						iError_report_byNumber(errorNum, iVariable_get_relatedComp(varNumber3), false);
						return;
					}

				//////////
				// Check empty param
				//////
					if (tlNoEmptyParam && lfValue3 == 0.0)
					{
						iError_report_byNumber(_ERROR_CANNOT_BE_ZERO, iVariable_get_relatedComp(varNumber3), false);
						return;
					}

			} else {
				lfValue3 = 0.0;
			}


		//////////
		// Compute numeric function
		//////
			switch (tnFunctionType)
			{

// SQRT()
				case _FP_COMMON_SQRT:

					//////////
					// Verify p1 >= 0
					//////
						if (lfValue1 < 0.0)
						{
							// Oops!
							iError_report_byNumber(_ERROR_CANNOT_BE_NEGATIVE, iVariable_get_relatedComp(varNumber1), false);
							return;
						}


					//////////
					// Compute sqrt
					//////
						lfResult = sqrt(lfValue1);
						break;

// EXP()
				case _FP_COMMON_EXP:
					lfResult = exp(lfValue1);
					break;

// PI()
				case _FP_COMMON_PI:
					lfResult = _MATH_PI;
					break;

// LOG()
// LOG10()
				case _FP_COMMON_LOG:
				case _FP_COMMON_LOG10:

					//////////
					// Verify p1 > 0
					//////
						if (lfValue1 <= 0.0)
						{
							// Oops!
							iError_report_byNumber(_ERROR_CANNOT_BE_ZERO_OR_NEGATIVE, iVariable_get_relatedComp(varNumber1), false);
							return;
						}


					//////////
					// Compute
					//////
						if (tnFunctionType == _FP_COMMON_LOG)		lfResult = log(lfValue1);
						else										lfResult = log10(lfValue1);
						break;

// CEILING()
				case _FP_COMMON_CEILING:
					lfResult = ceil(lfValue1);
					break;

// FLOOR()
				case _FP_COMMON_FLOOR:
					lfResult = floor(lfValue1);
					break;

// DTOR()
				case _FP_COMMON_DTOR:
					lfResult = lfValue1 * _MATH_PI180;
					break;

// RTOD()
				case _FP_COMMON_RTOD:
					lfResult = lfValue1 * _MATH_180PI;
					break;

// COS()
				case _FP_COMMON_COS:
					lfResult = cos(lfValue1);
					break;

// SIN()
				case _FP_COMMON_SIN:
					lfResult = sin(lfValue1);
					break;

// ABS()
				case _FP_COMMON_ABS:
					lfResult = abs(lfValue1);
					break;

// ACOS()
// ASIN()
				case _FP_COMMON_ACOS:
				case _FP_COMMON_ASIN:

					//////////
					// Verify p1 > 0
					//////
						if (lfValue1 < -1 || lfValue1 > 1)
						{
							// Oops!
							iError_report_byNumber(_ERROR_OUT_OF_RANGE, iVariable_get_relatedComp(varNumber1), false);
							return;
						}

					//////////
					// Compute
					//////
						if (tnFunctionType == _FP_COMMON_ACOS)		lfResult = acos(lfValue1);
						else										lfResult = asin(lfValue1);
						break;

// ATAN()
				case _FP_COMMON_ATAN:

					//////////
					// Verify p1 > 0
					//////
						if (lfValue1 < -_MATH_PI2 || lfValue1 > _MATH_PI2)
						{
							// Oops!
							iError_report_byNumber(_ERROR_OUT_OF_RANGE, iVariable_get_relatedComp(varNumber1), false);
							return;
						}

					//////////
					// Compute
					//////
						lfResult = atan(lfValue1);
						break;

// ATN2()
				case _FP_COMMON_ATN2:
					lfResult = atan2(lfValue1, lfValue2);
					break;
// TAN()
				case _FP_COMMON_TAN:
					lfResult = tan(lfValue1);
					break;
// MOD()
				case _FP_COMMON_MOD:

					//////////
					// Verify divisor not 0
					//////
						if (lfValue2 == 0.0)
						{
							// Oops!
							iError_report_byNumber(_ERROR_DIVISION_BY_ZERO, iVariable_get_relatedComp(varNumber2), false);
							return;
						}


					//////////
					// Compute
					//////
						lfResult = fmod(lfValue1, abs(lfValue2));
						if (lfValue2 < 0 && lfResult != 0.0)			// Mar.14.2015
							lfResult += lfValue2;

					break;

// FV()
				case _FP_COMMON_FV:

					//////////
					// Future value
					//////
						lfResult = (pow((1 + lfValue2), lfValue3) - 1) / lfValue2 * lfValue1;
						break;

// PV()
				case _FP_COMMON_PV:

					//////////
					// Present value
					//////
						lfResult = lfValue1 * ((1 - pow((1 + lfValue2), -lfValue3)) / lfValue2);
						break;

// PAYMENT()
				case _FP_COMMON_PAYMENT:

					//////////
					// Payment
					//////
						lfValue1 = (lfValue1 * pow(lfValue2 + 1, lfValue3) * lfValue2) / (pow(lfValue2 + 1, lfValue3) - 1);
						break;

				default:
					// Programmer error... this is an internal function and we should never get here
					iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(varNumber1), false);
					return;
			}


		//////////
		// Create output variable
		//////
			if (tlSameInputType)	result = iVariable_create(varNumber1->varType, NULL, true);
			else					result = iVariable_create(tnResultType, NULL, true);

			if (!result)
			{
				iError_report_byNumber(errorNum, iVariable_get_relatedComp(varNumber1), false);
				return;
			}


		//////////
		// Set the value
		//////
			if (!iVariable_setNumeric_toNumericType(result, NULL, &lfResult, NULL, NULL, NULL, NULL))
				iError_report_byNumber(errorNum, iVariable_get_relatedComp(varNumber1), false);


		//////////
        // return(result)
		//////
			rpar->rp[0] = result;
	}
Beispiel #16
0
//////////
//
// Function: VERSION()
// Based on input, retrieves various version information.
//
//////
// Version 0.58
// Last update:
//     Jul.13.2014
//////
// Change log:
//     Jul.13.2014 - Initial creation
//////
// Parameters:
//     pIndex		-- (Optional) If present, Numeric, in the range 1..5
//
//////
// Returns:
//    Numeric or Character	-- Depending on index, various values are returned
//////
    void function_version(SReturnsParams* rpar)
    {
		SVariable*	varIndex = rpar->ip[0];
        s32			index;
		u32			errorNum;
        bool		error;
		u8*			lptr;
        SVariable*	result;


		//////////
		// Parameter 1 must be numeric
		//////
			rpar->rp[0]	= NULL;
			lptr				= NULL;
			if (!iVariable_isValid(varIndex))
			{
				// They are requesting the default information
				lptr = (u8*)cgcVersionText;

			} else if (!iVariable_isTypeNumeric(varIndex)) {
				// The parameter is not numeric
				iError_report_byNumber(_ERROR_P1_IS_INCORRECT, iVariable_get_relatedComp(varIndex), false);
				return;

			} else {
				// It must be in the range 1..5
				index = iiVariable_getAs_s32(varIndex, false, &error, &errorNum);
				if (error)
				{
					iError_report_byNumber(errorNum, iVariable_get_relatedComp(varIndex), false);
					return;

				} else if (index < 1 || index > 5) {
					// We report our own error
					iError_report((cu8*)"Parameter must be in the range 1..5", false);
					return;
				}
			}


		//////////
        // Create our return result
		//////
			if (lptr || index == 1 || index == 4)
			{
				// Character return
				result = iVariable_create(_VAR_TYPE_CHARACTER, NULL, true);
				if (lptr)
				{
					// Copy the version info
					iDatum_duplicate(&result->value, lptr, -1);

				} else if (index == 1) {
					// Copy the version1 info
					iDatum_duplicate(&result->value, cgcVersion1Text, -1);

				} else {
					// Copy the version4 info
					iDatum_duplicate(&result->value, cgcVersion4Text, -1);
				}

			} else {
				result = iVariable_create(_VAR_TYPE_S32, NULL, true);
				if (index == 2)
				{
					// 0=runtime, 1=standard, 2=professional
					*(s32*)result->value.data = gnVersion2;	// Oh yeah!

				} else if (index == 3) {
					// Localized version
					*(s32*)result->value.data = gnVersion3;	// English

				} else {
					// Version in a form like Major.Minor as M.mm, or 123 for version 1.23
					*(s32*)result->value.data = gnVersion5;
				}
			}
			if (!result)
			{
				iError_report(cgcInternalError, false);
				return;
			}


		//////////
        // Return our converted result
		//////
			rpar->rp[0] = result;

    }
Beispiel #17
0
	void ifunction_hhmmss_common(SReturnsParams* rpar, SVariable* varParam, u32 tnFunctionType)
	{

		s32			lnMillisecond, lnMicrosecond;
		u32			lnResult, lnHour, lnMinute, lnSecond;
		SYSTEMTIME	lst;
		SVariable*	result;


		//////////
		// If Parameter 1 is provided, it must be datetime or datetimex
		//////
			rpar->rp[0] = NULL;
			if (varParam)
			{
				if (!iVariable_isValid(varParam))
				{
					iError_report_byNumber(_ERROR_INVALID_ARGUMENT_TYPE_COUNT, iVariable_get_relatedComp(varParam), false);
					return;

				} else if (!iVariable_isTypeDatetime(varParam)) {
					// Grab hour, minute, second, millisecond from datetime
					iiDateMath_get_HhMmSsMss_from_seconds(varParam->value.data_dt->seconds, &lnHour, &lnMinute, &lnSecond, &lnMillisecond);
					lnMicrosecond = lnMillisecond * 1000;

				} else if (!iVariable_isTypeDatetimeX(varParam)) {
					// Grab hour, minute, second, millisecond from datetime
					iiDateMath_get_julian_and_YyyyMmDdHhMmSsMssNss_from_jseconds(varParam->value.data_dtx->jseconds, NULL, NULL, NULL, NULL, NULL, &lnHour, &lnMinute, &lnSecond, &lnMillisecond, &lnMicrosecond);

				} else {
					iError_report_byNumber(_ERROR_INVALID_ARGUMENT_TYPE_COUNT, iVariable_get_relatedComp(varParam), false);
					return;
				}

			} else {
				// Use the current datetimex
				if (_settings)		iTime_getLocalOrSystem(&lst, propGet_settings_TimeLocal(_settings));
				else				GetLocalTime(&lst);

				lnHour			= lst.wHour;
				lnMinute		= lst.wMinute;
				lnSecond		= lst.wSecond;
				lnMillisecond	= lst.wMilliseconds;
				lnMicrosecond	= iiDateMath_get_currentMicrosecond();
			}


		//////////
		// Create output variable
		//////
			switch (tnFunctionType)
			{
				case _HMS_COMMON_HOUR:			lnResult = lnHour;			break;
				case _HMS_COMMON_MINUTE:		lnResult = lnMinute;		break;
				case _HMS_COMMON_SECOND:		lnResult = lnSecond;		break;
				case _HMS_COMMON_MILLISECOND:	lnResult = lnMillisecond;	break;
				case _HMS_COMMON_MICROSECOND:	lnResult = lnMicrosecond;	break;

				// Should never happen
				default:
					iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(varParam), false);
					return;
			}


		//////////
		// Create the value
		//////
			result = iVariable_createAndPopulate_byText(_VAR_TYPE_U32, (cs8*)&lnResult, sizeof(lnResult), false);
			if (!result)
				iError_report_byNumber(_ERROR_INTERNAL_ERROR, iVariable_get_relatedComp(varParam), false);


		//////////
		// Return the result
		//////
			rpar->rp[0] = result;

	}