/// <summary> Constructor for use when this is called when parsing a string /// /// </summary> /// <param name="sf">the built in function /// </param> /// <param name="ws">the workbook settings /// </param> public Attribute(StringFunction sf, WorkbookSettings ws) { settings = ws; if (sf.getFunction(settings) == NExcel.Biff.Formula.Function.SUM) { options |= sumMask; } else if (sf.getFunction(settings) == NExcel.Biff.Formula.Function.IF) { options |= ifMask; } }
/// <summary> Handles the case when parsing a string when a token is a function /// /// </summary> /// <param name="sf">the string function /// </param> /// <param name="i"> the token iterator /// </param> /// <param name="stack">the parse tree stack /// </param> /// <exception cref=""> FormulaException if an error occurs /// </exception> private void handleFunction(StringFunction sf, ArrayList pis, Stack stack) { ParseItem pi2 = parseCurrent(pis); // If the function is unknown, then throw an error if (sf.getFunction(settings) == Function.UNKNOWN) { throw new FormulaException(FormulaException.unrecognizedFunction); } // First check for possible optimized functions and possible // use of the Attribute token if (sf.getFunction(settings) == Function.SUM && arguments == null) { // this is handled by an attribute Attribute a = new Attribute(sf, settings); a.add(pi2); stack.Push(a); return; } if (sf.getFunction(settings) == Function.IF) { // this is handled by an attribute Attribute a = new Attribute(sf, settings); // Add in the if conditions as a var arg function in // the correct order VariableArgFunction vaf = new VariableArgFunction(settings); // [TODO] TEST is the order the same as in Java? object[] argumentsArray = arguments.ToArray(); for (int j = 0; j < argumentsArray.Length; j++) { vaf.add((ParseItem)argumentsArray[j]); } a.IfConditions = vaf; stack.Push(a); return; } // Function cannot be optimized. See if it is a variable argument // function or not if (sf.getFunction(settings).NumArgs == 0xff) { // If the arg stack has not been initialized, it means // that there was only one argument, which is the // returned parse item if (arguments == null) { VariableArgFunction vaf = new VariableArgFunction(sf.getFunction(settings), 1, settings); vaf.add(pi2); stack.Push(vaf); } else { // Add the args to the function in reverse order. The // VariableArgFunction will reverse these when it writes out the // byte version as they are stored in the correct order // within Excel int numargs = arguments.Count; VariableArgFunction vaf = new VariableArgFunction(sf.getFunction(settings), numargs, settings); for (int j = 0; j < numargs; j++) { ParseItem pi3 = (ParseItem)arguments.Pop(); vaf.add(pi3); } stack.Push(vaf); // [TODO] - check it // arguments.empty(); arguments.Clear(); arguments = null; } return; } // Function is a standard built in function BuiltInFunction bif = new BuiltInFunction(sf.getFunction(settings), settings); int numargs2 = sf.getFunction(settings).NumArgs; if (numargs2 == 1) { // only one item which is the returned ParseItem bif.add(pi2); } else { if ((arguments == null && numargs2 != 0) || (arguments != null && numargs2 != arguments.Count)) { throw new FormulaException(FormulaException.incorrectArguments); } // multiple arguments so go to the arguments stack. // Unlike the variable argument function, the args are // stored in reverse order // [TODO] TEST is the order the same as in Java? object[] argumentsArray = arguments.ToArray(); for (int j = 0; j < numargs2; j++) { bif.add((ParseItem)argumentsArray[j]); } } stack.Push(bif); }