static const char* ODSGetOperatorName( ods_formula_op eOp ) { switch (eOp) { case ODS_OR : return "OR"; case ODS_AND : return "AND"; case ODS_NOT : return "NOT"; case ODS_IF : return "IF"; case ODS_PI : return "PI"; //case ODS_T : return "T"; case ODS_LEN : return "LEN"; case ODS_LEFT : return "LEFT"; case ODS_RIGHT : return "RIGHT"; case ODS_MID : return "MID"; case ODS_SUM : return "SUM"; case ODS_AVERAGE : return "AVERAGE"; case ODS_MIN : return "MIN"; case ODS_MAX : return "MAX"; case ODS_COUNT : return "COUNT"; case ODS_COUNTA : return "COUNTA"; case ODS_EQ : return "="; case ODS_NE : return "<>"; case ODS_GE : return ">="; case ODS_LE : return "<="; case ODS_LT : return "<"; case ODS_GT : return ">"; case ODS_ADD : return "+"; case ODS_SUBTRACT : return "-"; case ODS_MULTIPLY : return "*"; case ODS_DIVIDE : return "/"; case ODS_MODULUS : return "MOD"; case ODS_CONCAT : return "&"; case ODS_LIST : return "*list*"; case ODS_CELL : return "*cell*"; case ODS_CELL_RANGE : return "*cell_range*"; default: { const SingleOpStruct* psSingleOp = ODSGetSingleOpEntry(eOp); if (psSingleOp != NULL) return psSingleOp->pszName; return "*unknown*"; } } }
int ods_formula_node::EvaluateSingleArgOp(IODSCellEvaluator* poEvaluator) { CPLAssert( eNodeType == SNT_OPERATION ); const SingleOpStruct* psSingleOp = ODSGetSingleOpEntry(eOp); CPLAssert(psSingleOp); CPLAssert(nSubExprCount == 1); if (!(papoSubExpr[0]->Evaluate(poEvaluator))) return FALSE; CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT ); double dfVal = 0; if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER) { dfVal = psSingleOp->pfnEval(papoSubExpr[0]->int_value); } else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT) { dfVal = psSingleOp->pfnEval(papoSubExpr[0]->float_value); } else { CPLError(CE_Failure, CPLE_NotSupported, "Bad argument type for %s", psSingleOp->pszName); return FALSE; } eNodeType = SNT_CONSTANT; field_type = ODS_FIELD_TYPE_FLOAT; float_value = dfVal; FreeSubExpr(); return TRUE; }
int ods_formulalex( YYSTYPE *ppNode, ods_formula_parse_context *context ) { const char *pszInput = context->pszNext; *ppNode = NULL; /* -------------------------------------------------------------------- */ /* Do we have a start symbol to return? */ /* -------------------------------------------------------------------- */ if( context->nStartToken != 0 ) { int nRet = context->nStartToken; context->nStartToken = 0; return nRet; } /* -------------------------------------------------------------------- */ /* Skip white space. */ /* -------------------------------------------------------------------- */ while( *pszInput == ' ' || *pszInput == '\t' || *pszInput == 10 || *pszInput == 13 ) pszInput++; if( *pszInput == '\0' ) { context->pszNext = pszInput; return EOF; } /* -------------------------------------------------------------------- */ /* Handle string constants. */ /* -------------------------------------------------------------------- */ if( *pszInput == '"' ) { char *token; int i_token; pszInput++; token = (char *) CPLMalloc(strlen(pszInput)+1); i_token = 0; while( *pszInput != '\0' ) { if( *pszInput == '\\' && pszInput[1] == '"' ) pszInput++; else if( *pszInput == '\\' && pszInput[1] == '\'' ) pszInput++; else if( *pszInput == '\'' && pszInput[1] == '\'' ) pszInput++; else if( *pszInput == '"' ) { pszInput++; break; } else if( *pszInput == '\'' ) { pszInput++; break; } token[i_token++] = *(pszInput++); } token[i_token] = '\0'; *ppNode = new ods_formula_node( token ); CPLFree( token ); context->pszNext = pszInput; return ODST_STRING; } /* -------------------------------------------------------------------- */ /* Handle numbers. */ /* -------------------------------------------------------------------- */ else if( *pszInput >= '0' && *pszInput <= '9' ) { CPLString osToken; const char *pszNext = pszInput + 1; osToken += *pszInput; // collect non-decimal part of number while( *pszNext >= '0' && *pszNext <= '9' ) osToken += *(pszNext++); // collect decimal places. if( *pszNext == '.' ) { osToken += *(pszNext++); while( *pszNext >= '0' && *pszNext <= '9' ) osToken += *(pszNext++); } // collect exponent if( *pszNext == 'e' || *pszNext == 'E' ) { osToken += *(pszNext++); if( *pszNext == '-' || *pszNext == '+' ) osToken += *(pszNext++); while( *pszNext >= '0' && *pszNext <= '9' ) osToken += *(pszNext++); } context->pszNext = pszNext; if( strstr(osToken,".") || strstr(osToken,"e") || strstr(osToken,"E") ) { *ppNode = new ods_formula_node( CPLAtof(osToken) ); } else { *ppNode = new ods_formula_node( atoi(osToken) ); } return ODST_NUMBER; } /* -------------------------------------------------------------------- */ /* Handle alpha-numerics. */ /* -------------------------------------------------------------------- */ else if( *pszInput == '.' || isalnum( *pszInput ) ) { int nReturn = ODST_IDENTIFIER; CPLString osToken; const char *pszNext = pszInput + 1; osToken += *pszInput; // collect text characters while( isalnum( *pszNext ) || *pszNext == '_' || ((unsigned char) *pszNext) > 127 ) osToken += *(pszNext++); context->pszNext = pszNext; /* Constants */ if( EQUAL(osToken,"TRUE") ) { *ppNode = new ods_formula_node( 1 ); return ODST_NUMBER; } else if( EQUAL(osToken,"FALSE") ) { *ppNode = new ods_formula_node( 0 ); return ODST_NUMBER; } else if( EQUAL(osToken,"NOT") ) nReturn = ODST_NOT; else if( EQUAL(osToken,"AND") ) nReturn = ODST_AND; else if( EQUAL(osToken,"OR") ) nReturn = ODST_OR; else if( EQUAL(osToken,"IF") ) nReturn = ODST_IF; /* No-arg functions */ else if( EQUAL(osToken,"PI") ) { *ppNode = new ods_formula_node( ODS_PI ); return ODST_FUNCTION_NO_ARG; } /* Single-arg functions */ else if( EQUAL(osToken,"LEN") ) { *ppNode = new ods_formula_node( ODS_LEN ); return ODST_FUNCTION_SINGLE_ARG; } /* else if( EQUAL(osToken,"T") ) { *ppNode = new ods_formula_node( ODS_T ); return ODST_FUNCTION_SINGLE_ARG; }*/ /* Tow-arg functions */ else if( EQUAL(osToken,"MOD") ) { *ppNode = new ods_formula_node( ODS_MODULUS ); return ODST_FUNCTION_TWO_ARG; } else if( EQUAL(osToken,"LEFT") ) { *ppNode = new ods_formula_node( ODS_LEFT ); return ODST_FUNCTION_TWO_ARG; } else if( EQUAL(osToken,"RIGHT") ) { *ppNode = new ods_formula_node( ODS_RIGHT ); return ODST_FUNCTION_TWO_ARG; } /* Three-arg functions */ else if( EQUAL(osToken,"MID") ) { *ppNode = new ods_formula_node( ODS_MID ); return ODST_FUNCTION_THREE_ARG; } /* Multiple-arg functions */ else if( EQUAL(osToken,"SUM") ) { *ppNode = new ods_formula_node( ODS_SUM ); nReturn = ODST_FUNCTION_ARG_LIST; } else if( EQUAL(osToken,"AVERAGE") ) { *ppNode = new ods_formula_node( ODS_AVERAGE ); nReturn = ODST_FUNCTION_ARG_LIST; } else if( EQUAL(osToken,"MIN") ) { *ppNode = new ods_formula_node( ODS_MIN ); nReturn = ODST_FUNCTION_ARG_LIST; } else if( EQUAL(osToken,"MAX") ) { *ppNode = new ods_formula_node( ODS_MAX ); nReturn = ODST_FUNCTION_ARG_LIST; } else if( EQUAL(osToken,"COUNT") ) { *ppNode = new ods_formula_node( ODS_COUNT ); nReturn = ODST_FUNCTION_ARG_LIST; } else if( EQUAL(osToken,"COUNTA") ) { *ppNode = new ods_formula_node( ODS_COUNTA ); nReturn = ODST_FUNCTION_ARG_LIST; } else { const SingleOpStruct* psSingleOp = ODSGetSingleOpEntry(osToken); if (psSingleOp != NULL) { *ppNode = new ods_formula_node( psSingleOp->eOp ); nReturn = ODST_FUNCTION_SINGLE_ARG; } else { *ppNode = new ods_formula_node( osToken ); nReturn = ODST_IDENTIFIER; } } return nReturn; } /* -------------------------------------------------------------------- */ /* Handle special tokens. */ /* -------------------------------------------------------------------- */ else { context->pszNext = pszInput+1; return *pszInput; } }