/** * Generates the variable function ptg for the formula. * * <p>For IF Formulas, additional PTGs are added to the tokens * * @param name a {@link NamePtg} or {@link NameXPtg} or <code>null</code> * @return Ptg a null is returned if we're in an IF formula, it needs extreme manipulation and is * handled in this function */ private ParseNode getFunction(String name, Ptg namePtg, ParseNode[] args) { FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByName(name.toUpperCase()); int numArgs = args.length; if (fm == null) { if (namePtg == null) { throw new IllegalStateException("NamePtg must be supplied for external functions"); } // must be external function ParseNode[] allArgs = new ParseNode[numArgs + 1]; allArgs[0] = new ParseNode(namePtg); System.arraycopy(args, 0, allArgs, 1, numArgs); return new ParseNode(FuncVarPtg.create(name, numArgs + 1), allArgs); } if (namePtg != null) { throw new IllegalStateException("NamePtg no applicable to internal functions"); } boolean isVarArgs = !fm.hasFixedArgsLength(); int funcIx = fm.getIndex(); if (funcIx == FunctionMetadataRegistry.FUNCTION_INDEX_SUM && args.length == 1) { // Excel encodes the sum of a single argument as tAttrSum // POI does the same for consistency, but this is not critical return new ParseNode(AttrPtg.getSumSingle(), args); // The code below would encode tFuncVar(SUM) which seems to do no harm } validateNumArgs(args.length, fm); AbstractFunctionPtg retval; if (isVarArgs) { retval = FuncVarPtg.create(name, numArgs); } else { retval = FuncPtg.create(funcIx); } return new ParseNode(retval, args); }
/** @return <code>true</code> if the specified name is a valid cell reference */ private boolean isValidCellReference(String str) { // check range bounds against grid max boolean result = CellReference.classifyCellReference(str, _ssVersion) == NameType.CELL; if (result) { /** * Check if the argument is a function. Certain names can be either a cell reference or a * function name depending on the contenxt. Compare the following examples in Excel 2007: (a) * LOG10(100) + 1 (b) LOG10 + 1 In (a) LOG10 is a name of a built-in function. In (b) LOG10 is * a cell reference */ boolean isFunc = FunctionMetadataRegistry.getFunctionByName(str.toUpperCase()) != null; if (isFunc) { int savePointer = _pointer; resetPointer(_pointer + str.length()); SkipWhite(); // open bracket indicates that the argument is a function, // the returning value should be false, i.e. "not a valid cell reference" result = look != '('; resetPointer(savePointer); } } return result; }