Exemple #1
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;

	}
Exemple #2
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;

    }
Exemple #3
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;

	}
Exemple #4
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;

	}