/** * 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); }