You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2021/05/22 20:56:49 UTC

svn commit: r1890120 [38/43] - in /poi/trunk/poi/src: main/java/org/apache/poi/ main/java/org/apache/poi/ddf/ main/java/org/apache/poi/extractor/ main/java/org/apache/poi/hpsf/ main/java/org/apache/poi/hssf/ main/java/org/apache/poi/hssf/dev/ main/java...

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java Sat May 22 20:56:44 2021
@@ -58,42 +58,42 @@ public final class TestFormulasFromSprea
     private static Locale userLocale;
 
     /**
-	 * This class defines constants for navigating around the test data spreadsheet used for these tests.
-	 */
-	private interface SS {
-
-		/**
-		 * Name of the test spreadsheet (found in the standard test data folder)
-		 */
-		String FILENAME = "FormulaEvalTestData.xls";
-		/**
-		 * Row (zero-based) in the test spreadsheet where the operator examples start.
-		 */
-		int START_OPERATORS_ROW_INDEX = 22; // Row '23'
-		/**
-		 * Row (zero-based) in the test spreadsheet where the function examples start.
-		 */
-		int START_FUNCTIONS_ROW_INDEX = 95; // Row '96'
-		/**
-		 * Index of the column that contains the function names
-		 */
-		int COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B'
-
-		/**
-		 * Used to indicate when there are no more functions left
-		 */
-		String FUNCTION_NAMES_END_SENTINEL = "<END-OF-FUNCTIONS>";
-
-		/**
-		 * Index of the column where the test values start (for each function)
-		 */
-		short COLUMN_INDEX_FIRST_TEST_VALUE = 3; // Column 'D'
-
-		/**
-		 * Each function takes 4 rows in the test spreadsheet
-		 */
-		int NUMBER_OF_ROWS_PER_FUNCTION = 4;
-	}
+     * This class defines constants for navigating around the test data spreadsheet used for these tests.
+     */
+    private interface SS {
+
+        /**
+         * Name of the test spreadsheet (found in the standard test data folder)
+         */
+        String FILENAME = "FormulaEvalTestData.xls";
+        /**
+         * Row (zero-based) in the test spreadsheet where the operator examples start.
+         */
+        int START_OPERATORS_ROW_INDEX = 22; // Row '23'
+        /**
+         * Row (zero-based) in the test spreadsheet where the function examples start.
+         */
+        int START_FUNCTIONS_ROW_INDEX = 95; // Row '96'
+        /**
+         * Index of the column that contains the function names
+         */
+        int COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B'
+
+        /**
+         * Used to indicate when there are no more functions left
+         */
+        String FUNCTION_NAMES_END_SENTINEL = "<END-OF-FUNCTIONS>";
+
+        /**
+         * Index of the column where the test values start (for each function)
+         */
+        short COLUMN_INDEX_FIRST_TEST_VALUE = 3; // Column 'D'
+
+        /**
+         * Each function takes 4 rows in the test spreadsheet
+         */
+        int NUMBER_OF_ROWS_PER_FUNCTION = 4;
+    }
 
     @AfterAll
     public static void closeResource() throws Exception {
@@ -201,24 +201,24 @@ public final class TestFormulasFromSprea
            }
        }
    }
-	/**
-	 * @return {@code null} if cell is missing, empty or blank
-	 */
-	private static String getTargetFunctionName(Row r) {
-		if(r == null) {
-			System.err.println("Warning - given null row, can't figure out function name");
-			return null;
-		}
-		Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME);
-		if(cell == null) {
-			System.err.println("Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
-			return null;
-		}
+    /**
+     * @return {@code null} if cell is missing, empty or blank
+     */
+    private static String getTargetFunctionName(Row r) {
+        if(r == null) {
+            System.err.println("Warning - given null row, can't figure out function name");
+            return null;
+        }
+        Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME);
+        if(cell == null) {
+            System.err.println("Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
+            return null;
+        }
 
         CellType ct = cell.getCellType();
         assertTrue(ct == CellType.BLANK || ct == CellType.STRING,
             "Bad cell type for 'function name' column: (" + cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")");
 
         return (ct == CellType.STRING) ? cell.getRichStringCellValue().getString() : null;
-	}
+    }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java Sat May 22 20:56:44 2021
@@ -23,7 +23,7 @@ import org.apache.poi.hssf.HSSFITestData
  * Tests HSSFFormulaEvaluator for its handling of cell formula circular references.
  */
 final class TestHSSFCircularReferences extends BaseTestCircularReferences {
-	public TestHSSFCircularReferences() {
+    public TestHSSFCircularReferences() {
         super(HSSFITestDataProvider.instance);
     }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java Sat May 22 20:56:44 2021
@@ -38,113 +38,113 @@ import org.junit.jupiter.api.Test;
  * </ol>
  */
 final class TestMinusZeroResult {
-	private static final double MINUS_ZERO = -0.0;
+    private static final double MINUS_ZERO = -0.0;
 
-	@Test
-	void testSimpleOperators() {
+    @Test
+    void testSimpleOperators() {
 
-		// unary plus is a no-op
-		checkEval(MINUS_ZERO, UnaryPlusEval.instance, MINUS_ZERO);
+        // unary plus is a no-op
+        checkEval(MINUS_ZERO, UnaryPlusEval.instance, MINUS_ZERO);
 
-		// most simple operators convert -0.0 to +0.0
-		checkEval(0.0, EvalInstances.UnaryMinus, 0.0);
-		checkEval(0.0, EvalInstances.Percent, MINUS_ZERO);
-		checkEval(0.0, EvalInstances.Multiply, MINUS_ZERO, 1.0);
-		checkEval(0.0, EvalInstances.Divide, MINUS_ZERO, 1.0);
-		checkEval(0.0, EvalInstances.Power, MINUS_ZERO, 1.0);
-
-		// but SubtractEval does not convert -0.0, so '-' and '+' work like java
-		checkEval(MINUS_ZERO, EvalInstances.Subtract, MINUS_ZERO, 0.0); // this is the main point of bug 47198
-		checkEval(0.0, EvalInstances.Add, MINUS_ZERO, 0.0);
-	}
-
-	/**
-	 * These results are hard to see in Excel (since -0.0 is usually converted to +0.0 before it
-	 * gets to the comparison operator)
-	 */
-	@Test
-	void testComparisonOperators() {
-		checkEval(false, EvalInstances.Equal, 0.0, MINUS_ZERO);
-		checkEval(true, EvalInstances.GreaterThan, 0.0, MINUS_ZERO);
-		checkEval(true, EvalInstances.LessThan, MINUS_ZERO, 0.0);
-	}
-
-	@Test
-	void testTextRendering() {
-		confirmTextRendering(MINUS_ZERO);
-		// sub-normal negative numbers also display as '-0'
-		confirmTextRendering(Double.longBitsToDouble(0x8000100020003000L));
-	}
-
-	/**
-	 * Uses {@link ConcatEval} to force number-to-text conversion
-	 */
-	private static void confirmTextRendering(double d) {
-		ValueEval[] args = { StringEval.EMPTY_INSTANCE, new NumberEval(d), };
-		StringEval se = (StringEval) EvalInstances.Concat.evaluate(args, -1, (short)-1);
-		String result = se.getStringValue();
-		assertEquals("-0", result);
-	}
-
-	private static void checkEval(double expectedResult, Function instance, double... dArgs) {
-		NumberEval result = (NumberEval) evaluate(instance, dArgs);
-		assertDouble(expectedResult, result.getNumberValue());
-	}
-	private static void checkEval(boolean expectedResult, Function instance, double... dArgs) {
-		BoolEval result = (BoolEval) evaluate(instance, dArgs);
-		assertEquals(expectedResult, result.getBooleanValue());
-	}
-	private static ValueEval evaluate(Function instance, double... dArgs) {
-		ValueEval[] evalArgs;
-		evalArgs = new ValueEval[dArgs.length];
-		for (int i = 0; i < evalArgs.length; i++) {
-			evalArgs[i] = new NumberEval(dArgs[i]);
-		}
+        // most simple operators convert -0.0 to +0.0
+        checkEval(0.0, EvalInstances.UnaryMinus, 0.0);
+        checkEval(0.0, EvalInstances.Percent, MINUS_ZERO);
+        checkEval(0.0, EvalInstances.Multiply, MINUS_ZERO, 1.0);
+        checkEval(0.0, EvalInstances.Divide, MINUS_ZERO, 1.0);
+        checkEval(0.0, EvalInstances.Power, MINUS_ZERO, 1.0);
+
+        // but SubtractEval does not convert -0.0, so '-' and '+' work like java
+        checkEval(MINUS_ZERO, EvalInstances.Subtract, MINUS_ZERO, 0.0); // this is the main point of bug 47198
+        checkEval(0.0, EvalInstances.Add, MINUS_ZERO, 0.0);
+    }
+
+    /**
+     * These results are hard to see in Excel (since -0.0 is usually converted to +0.0 before it
+     * gets to the comparison operator)
+     */
+    @Test
+    void testComparisonOperators() {
+        checkEval(false, EvalInstances.Equal, 0.0, MINUS_ZERO);
+        checkEval(true, EvalInstances.GreaterThan, 0.0, MINUS_ZERO);
+        checkEval(true, EvalInstances.LessThan, MINUS_ZERO, 0.0);
+    }
+
+    @Test
+    void testTextRendering() {
+        confirmTextRendering(MINUS_ZERO);
+        // sub-normal negative numbers also display as '-0'
+        confirmTextRendering(Double.longBitsToDouble(0x8000100020003000L));
+    }
+
+    /**
+     * Uses {@link ConcatEval} to force number-to-text conversion
+     */
+    private static void confirmTextRendering(double d) {
+        ValueEval[] args = { StringEval.EMPTY_INSTANCE, new NumberEval(d), };
+        StringEval se = (StringEval) EvalInstances.Concat.evaluate(args, -1, (short)-1);
+        String result = se.getStringValue();
+        assertEquals("-0", result);
+    }
+
+    private static void checkEval(double expectedResult, Function instance, double... dArgs) {
+        NumberEval result = (NumberEval) evaluate(instance, dArgs);
+        assertDouble(expectedResult, result.getNumberValue());
+    }
+    private static void checkEval(boolean expectedResult, Function instance, double... dArgs) {
+        BoolEval result = (BoolEval) evaluate(instance, dArgs);
+        assertEquals(expectedResult, result.getBooleanValue());
+    }
+    private static ValueEval evaluate(Function instance, double... dArgs) {
+        ValueEval[] evalArgs;
+        evalArgs = new ValueEval[dArgs.length];
+        for (int i = 0; i < evalArgs.length; i++) {
+            evalArgs[i] = new NumberEval(dArgs[i]);
+        }
         return instance.evaluate(evalArgs, -1, (short)-1);
-	}
+    }
 
-	/**
-	 * Not really a POI test - just shows similar behaviour of '-0.0' in Java.
-	 */
-	@Test
-	void testJava() {
-		assertEquals(0x8000000000000000L, Double.doubleToLongBits(MINUS_ZERO));
-
-		// The simple operators consider all zeros to be the same
-		//noinspection SimplifiableJUnitAssertion,ConstantConditions
-		assertTrue(MINUS_ZERO == MINUS_ZERO);
-		//noinspection SimplifiableJUnitAssertion,ConstantConditions
-		assertTrue(MINUS_ZERO == +0.0);
-		//noinspection ConstantConditions
-		assertFalse(MINUS_ZERO < +0.0);
-
-		// Double.compare() considers them different
-		assertTrue(Double.compare(MINUS_ZERO, +0.0) < 0);
-
-		// multiplying zero by any negative quantity yields minus zero
-		assertDouble(MINUS_ZERO, 0.0*-1);
-		assertDouble(MINUS_ZERO, 0.0*-1e300);
-		assertDouble(MINUS_ZERO, 0.0*-1e-300);
-
-		// minus zero can be produced as a result of underflow
-		assertDouble(MINUS_ZERO, -1e-300 / 1e100);
-
-		// multiplying or dividing minus zero by a positive quantity yields minus zero
-		assertDouble(MINUS_ZERO, MINUS_ZERO * 1.0);
-		assertDouble(MINUS_ZERO, MINUS_ZERO / 1.0);
-
-		// subtracting positive zero gives minus zero
-		assertDouble(MINUS_ZERO, MINUS_ZERO - 0.0);
-		// BUT adding positive zero gives positive zero
-		assertDouble(0.0, MINUS_ZERO + 0.0);  // <<----
-	}
-
-	/**
-	 * Just so there is no ambiguity.  The two double values have to be exactly equal
-	 */
-	private static void assertDouble(double a, double b) {
-		long bitsA = Double.doubleToLongBits(a);
-		long bitsB = Double.doubleToLongBits(b);
-		assertEquals(bitsA, bitsB);
-	}
+    /**
+     * Not really a POI test - just shows similar behaviour of '-0.0' in Java.
+     */
+    @Test
+    void testJava() {
+        assertEquals(0x8000000000000000L, Double.doubleToLongBits(MINUS_ZERO));
+
+        // The simple operators consider all zeros to be the same
+        //noinspection SimplifiableJUnitAssertion,ConstantConditions
+        assertTrue(MINUS_ZERO == MINUS_ZERO);
+        //noinspection SimplifiableJUnitAssertion,ConstantConditions
+        assertTrue(MINUS_ZERO == +0.0);
+        //noinspection ConstantConditions
+        assertFalse(MINUS_ZERO < +0.0);
+
+        // Double.compare() considers them different
+        assertTrue(Double.compare(MINUS_ZERO, +0.0) < 0);
+
+        // multiplying zero by any negative quantity yields minus zero
+        assertDouble(MINUS_ZERO, 0.0*-1);
+        assertDouble(MINUS_ZERO, 0.0*-1e300);
+        assertDouble(MINUS_ZERO, 0.0*-1e-300);
+
+        // minus zero can be produced as a result of underflow
+        assertDouble(MINUS_ZERO, -1e-300 / 1e100);
+
+        // multiplying or dividing minus zero by a positive quantity yields minus zero
+        assertDouble(MINUS_ZERO, MINUS_ZERO * 1.0);
+        assertDouble(MINUS_ZERO, MINUS_ZERO / 1.0);
+
+        // subtracting positive zero gives minus zero
+        assertDouble(MINUS_ZERO, MINUS_ZERO - 0.0);
+        // BUT adding positive zero gives positive zero
+        assertDouble(0.0, MINUS_ZERO + 0.0);  // <<----
+    }
+
+    /**
+     * Just so there is no ambiguity.  The two double values have to be exactly equal
+     */
+    private static void assertDouble(double a, double b) {
+        long bitsA = Double.doubleToLongBits(a);
+        long bitsB = Double.doubleToLongBits(b);
+        assertEquals(bitsA, bitsB);
+    }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMissingArgEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMissingArgEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMissingArgEval.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMissingArgEval.java Sat May 22 20:56:44 2021
@@ -35,61 +35,61 @@ import org.junit.jupiter.api.Test;
  */
 final class TestMissingArgEval {
 
-	@Test
-	void testEvaluateMissingArgs() throws IOException {
-		try (HSSFWorkbook wb = new HSSFWorkbook()) {
-			HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
-			HSSFSheet sheet = wb.createSheet("Sheet1");
-			HSSFCell cell = sheet.createRow(0).createCell(0);
-
-			cell.setCellFormula("if(true,)");
-			fe.clearAllCachedResultValues();
-			// EmptyStackException -> Missing args evaluation not implemented (bug 43354)
-			CellValue cv = fe.evaluate(cell);
-			// MissingArg -> BlankEval -> zero (as formula result)
-			assertEquals(0.0, cv.getNumberValue(), 0.0);
-
-			// MissingArg -> BlankEval -> empty string (in concatenation)
-			cell.setCellFormula("\"abc\"&if(true,)");
-			fe.clearAllCachedResultValues();
-			assertEquals("abc", fe.evaluate(cell).getStringValue());
-		}
-	}
-
-	@Test
-	void testCompareMissingArgs() throws IOException {
-		try (HSSFWorkbook wb = new HSSFWorkbook()) {
-			HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
-			HSSFSheet sheet = wb.createSheet("Sheet1");
-			HSSFCell cell = sheet.createRow(0).createCell(0);
-
-			cell.setCellFormula("iferror(0/0,)<0");
-			fe.clearAllCachedResultValues();
-			CellValue cv = fe.evaluate(cell);
-			assertFalse(cv.getBooleanValue());
-
-			cell.setCellFormula("iferror(0/0,)<=0");
-			fe.clearAllCachedResultValues();
-			cv = fe.evaluate(cell);
-			assertTrue(cv.getBooleanValue());
-
-			cell.setCellFormula("iferror(0/0,)=0");
-			fe.clearAllCachedResultValues();
-			cv = fe.evaluate(cell);
-			assertTrue(cv.getBooleanValue());
-
-			cell.setCellFormula("iferror(0/0,)>=0");
-			fe.clearAllCachedResultValues();
-			cv = fe.evaluate(cell);
-			assertTrue(cv.getBooleanValue());
-
-			cell.setCellFormula("iferror(0/0,)>0");
-			fe.clearAllCachedResultValues();
-			cv = fe.evaluate(cell);
-			assertFalse(cv.getBooleanValue());
+    @Test
+    void testEvaluateMissingArgs() throws IOException {
+        try (HSSFWorkbook wb = new HSSFWorkbook()) {
+            HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+            HSSFSheet sheet = wb.createSheet("Sheet1");
+            HSSFCell cell = sheet.createRow(0).createCell(0);
 
-			// invert above for code coverage
-			cell.setCellFormula("0<iferror(0/0,)");
+            cell.setCellFormula("if(true,)");
+            fe.clearAllCachedResultValues();
+            // EmptyStackException -> Missing args evaluation not implemented (bug 43354)
+            CellValue cv = fe.evaluate(cell);
+            // MissingArg -> BlankEval -> zero (as formula result)
+            assertEquals(0.0, cv.getNumberValue(), 0.0);
+
+            // MissingArg -> BlankEval -> empty string (in concatenation)
+            cell.setCellFormula("\"abc\"&if(true,)");
+            fe.clearAllCachedResultValues();
+            assertEquals("abc", fe.evaluate(cell).getStringValue());
+        }
+    }
+
+    @Test
+    void testCompareMissingArgs() throws IOException {
+        try (HSSFWorkbook wb = new HSSFWorkbook()) {
+            HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+            HSSFSheet sheet = wb.createSheet("Sheet1");
+            HSSFCell cell = sheet.createRow(0).createCell(0);
+
+            cell.setCellFormula("iferror(0/0,)<0");
+            fe.clearAllCachedResultValues();
+            CellValue cv = fe.evaluate(cell);
+            assertFalse(cv.getBooleanValue());
+
+            cell.setCellFormula("iferror(0/0,)<=0");
+            fe.clearAllCachedResultValues();
+            cv = fe.evaluate(cell);
+            assertTrue(cv.getBooleanValue());
+
+            cell.setCellFormula("iferror(0/0,)=0");
+            fe.clearAllCachedResultValues();
+            cv = fe.evaluate(cell);
+            assertTrue(cv.getBooleanValue());
+
+            cell.setCellFormula("iferror(0/0,)>=0");
+            fe.clearAllCachedResultValues();
+            cv = fe.evaluate(cell);
+            assertTrue(cv.getBooleanValue());
+
+            cell.setCellFormula("iferror(0/0,)>0");
+            fe.clearAllCachedResultValues();
+            cv = fe.evaluate(cell);
+            assertFalse(cv.getBooleanValue());
+
+            // invert above for code coverage
+            cell.setCellFormula("0<iferror(0/0,)");
             fe.clearAllCachedResultValues();
             cv = fe.evaluate(cell);
             assertFalse(cv.getBooleanValue());
@@ -113,22 +113,22 @@ final class TestMissingArgEval {
             fe.clearAllCachedResultValues();
             cv = fe.evaluate(cell);
             assertFalse(cv.getBooleanValue());
-		}
-	}
+        }
+    }
 
-	@Test
-	void testCountFuncs() throws IOException {
-		try (HSSFWorkbook wb = new HSSFWorkbook()) {
-			HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
-			HSSFSheet sheet = wb.createSheet("Sheet1");
-			HSSFCell cell = sheet.createRow(0).createCell(0);
-
-			cell.setCellFormula("COUNT(C5,,,,)"); // 4 missing args, C5 is blank
-			assertEquals(4.0, fe.evaluate(cell).getNumberValue(), 0.0);
-
-			cell.setCellFormula("COUNTA(C5,,)"); // 2 missing args, C5 is blank
-			fe.clearAllCachedResultValues();
-			assertEquals(2.0, fe.evaluate(cell).getNumberValue(), 0.0);
-		}
-	}
+    @Test
+    void testCountFuncs() throws IOException {
+        try (HSSFWorkbook wb = new HSSFWorkbook()) {
+            HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+            HSSFSheet sheet = wb.createSheet("Sheet1");
+            HSSFCell cell = sheet.createRow(0).createCell(0);
+
+            cell.setCellFormula("COUNT(C5,,,,)"); // 4 missing args, C5 is blank
+            assertEquals(4.0, fe.evaluate(cell).getNumberValue(), 0.0);
+
+            cell.setCellFormula("COUNTA(C5,,)"); // 2 missing args, C5 is blank
+            fe.clearAllCachedResultValues();
+            assertEquals(2.0, fe.evaluate(cell).getNumberValue(), 0.0);
+        }
+    }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java Sat May 22 20:56:44 2021
@@ -45,144 +45,144 @@ import org.junit.jupiter.params.provider
  * Tests formulas for multi sheet reference (i.e. SUM(Sheet1:Sheet5!A1))
  */
 final class TestMultiSheetEval {
-	/**
-	 * This class defines constants for navigating around the test data spreadsheet used for these tests.
-	 */
-	private static final class SS {
-
-		/**
-		 * Name of the test spreadsheet (found in the standard test data folder)
-		 */
-		public static final String FILENAME = "FormulaSheetRange.xls";
-		/**
-		 * Row (zero-based) in the test spreadsheet where the function examples start.
-		 */
-		public static final int START_FUNCTIONS_ROW_INDEX = 10; // Row '11'
-		/**
-		 * Index of the column that contains the function names
-		 */
-		public static final int COLUMN_INDEX_FUNCTION_NAME = 0; // Column 'A'
-		/**
-		 * Index of the column that contains the test names
-		 */
-		public static final int COLUMN_INDEX_TEST_NAME = 1; // Column 'B'
-		/**
-		 * Used to indicate when there are no more functions left
-		 */
-		public static final String FUNCTION_NAMES_END_SENTINEL = "<END>";
-
-		/**
-		 * Index of the column where the test expected value is present
-		 */
-		public static final short COLUMN_INDEX_EXPECTED_VALUE = 2; // Column 'C'
-		/**
-		 * Index of the column where the test actual value is present
-		 */
-		public static final short COLUMN_INDEX_ACTUAL_VALUE = 3; // Column 'D'
-		/**
-		 * Test sheet name (sheet with all test formulae)
-		 */
-		public static final String TEST_SHEET_NAME = "test";
-	}
-
-	private static HSSFFormulaEvaluator evaluator;
-	private static Collection<String> funcs;
-
-
-	public static Stream<Arguments> data() {
-		HSSFWorkbook workbook = HSSFTestDataSamples.openSampleWorkbook(SS.FILENAME);
-		Sheet sheet = workbook.getSheet(SS.TEST_SHEET_NAME);
-		evaluator = new HSSFFormulaEvaluator(workbook);
-		funcs = FunctionEval.getSupportedFunctionNames();
-
-		List<Arguments> data = new ArrayList<>();
-		for (int rowIndex = SS.START_FUNCTIONS_ROW_INDEX;true;rowIndex++) {
-			Row r = sheet.getRow(rowIndex);
-
-			// only evaluate non empty row
-			if (r == null) {
-				continue;
-			}
-
-			String targetFunctionName = getTargetFunctionName(r);
-			assertNotNull(targetFunctionName, "Expected function name or '" + SS.FUNCTION_NAMES_END_SENTINEL + "'");
-			if (targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
-				// found end of functions list
-				break;
-			}
-			String targetTestName = getTargetTestName(r);
-
-			// expected results are on the row below
-			Cell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_VALUE);
-			assertNotNull(expectedValueCell, "Missing expected values cell for function '" + targetFunctionName);
-
-			data.add(Arguments.of( targetTestName, targetFunctionName, expectedValueCell, r ));
-		}
-
-		return data.stream();
-	}
-
-	@ParameterizedTest
-	@MethodSource("data")
-	void testFunction(String testName, String functionName, Cell expected, Row testRow) {
-
-		Cell c = testRow.getCell(SS.COLUMN_INDEX_ACTUAL_VALUE);
-		if (c == null || c.getCellType() != CellType.FORMULA) {
-			// missing test data
-			assertTrue(testRow.getRowNum() >= SS.START_FUNCTIONS_ROW_INDEX);
-			assertTrue(funcs.contains(functionName.toUpperCase(Locale.ROOT)), "unsupported function");
-			return;
-		}
-
-		CellValue actual = evaluator.evaluate(c);
-
-		assertNotNull(expected, "Bad setup data expected value is null");
-		assertNotNull(actual, "actual value was null");
-
-		final CellType cellType = expected.getCellType();
-
-		switch (cellType) {
-			case BLANK:
-				assertEquals(CellType.BLANK, actual.getCellType());
-				break;
-			case BOOLEAN:
-				assertEquals(CellType.BOOLEAN, actual.getCellType());
-				assertEquals(expected.getBooleanCellValue(), actual.getBooleanValue());
-				break;
-			case ERROR:
-				assertEquals(CellType.ERROR, actual.getCellType());
-				assertEquals(ErrorEval.getText(expected.getErrorCellValue()), ErrorEval.getText(actual.getErrorValue()));
-				break;
-			case FORMULA: // will never be used, since we will call method after formula evaluation
-				fail("Cannot expect formula as result of formula evaluation.");
-				break;
-			case NUMERIC:
-				assertEquals(CellType.NUMERIC, actual.getCellType());
-				TestMathX.assertDouble("", expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR);
-				break;
-			case STRING:
-				assertEquals(CellType.STRING, actual.getCellType());
-				assertEquals(expected.getRichStringCellValue().getString(), actual.getStringValue());
-				break;
-			default:
-				fail("Unexpected cell type: " + cellType);
-				break;
-		}
-	}
-
-	private static String getTargetFunctionName(Row r) {
-		assertNotNull(r, "given null row, can't figure out function name");
-		Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME);
-		assertNotNull(cell, "Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
-		assertEquals(CellType.STRING, cell.getCellType());
-		return cell.getRichStringCellValue().getString();
-	}
-
-	private static String getTargetTestName(Row r) {
-		assertNotNull(r, "Given null row, can't figure out test name");
-		Cell cell = r.getCell(SS.COLUMN_INDEX_TEST_NAME);
-		assertNotNull(cell, "Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_TEST_NAME + ", can't figure out test name");
-		assertEquals(CellType.STRING, cell.getCellType());
-		return cell.getRichStringCellValue().getString();
-	}
+    /**
+     * This class defines constants for navigating around the test data spreadsheet used for these tests.
+     */
+    private static final class SS {
+
+        /**
+         * Name of the test spreadsheet (found in the standard test data folder)
+         */
+        public static final String FILENAME = "FormulaSheetRange.xls";
+        /**
+         * Row (zero-based) in the test spreadsheet where the function examples start.
+         */
+        public static final int START_FUNCTIONS_ROW_INDEX = 10; // Row '11'
+        /**
+         * Index of the column that contains the function names
+         */
+        public static final int COLUMN_INDEX_FUNCTION_NAME = 0; // Column 'A'
+        /**
+         * Index of the column that contains the test names
+         */
+        public static final int COLUMN_INDEX_TEST_NAME = 1; // Column 'B'
+        /**
+         * Used to indicate when there are no more functions left
+         */
+        public static final String FUNCTION_NAMES_END_SENTINEL = "<END>";
+
+        /**
+         * Index of the column where the test expected value is present
+         */
+        public static final short COLUMN_INDEX_EXPECTED_VALUE = 2; // Column 'C'
+        /**
+         * Index of the column where the test actual value is present
+         */
+        public static final short COLUMN_INDEX_ACTUAL_VALUE = 3; // Column 'D'
+        /**
+         * Test sheet name (sheet with all test formulae)
+         */
+        public static final String TEST_SHEET_NAME = "test";
+    }
+
+    private static HSSFFormulaEvaluator evaluator;
+    private static Collection<String> funcs;
+
+
+    public static Stream<Arguments> data() {
+        HSSFWorkbook workbook = HSSFTestDataSamples.openSampleWorkbook(SS.FILENAME);
+        Sheet sheet = workbook.getSheet(SS.TEST_SHEET_NAME);
+        evaluator = new HSSFFormulaEvaluator(workbook);
+        funcs = FunctionEval.getSupportedFunctionNames();
+
+        List<Arguments> data = new ArrayList<>();
+        for (int rowIndex = SS.START_FUNCTIONS_ROW_INDEX;true;rowIndex++) {
+            Row r = sheet.getRow(rowIndex);
+
+            // only evaluate non empty row
+            if (r == null) {
+                continue;
+            }
+
+            String targetFunctionName = getTargetFunctionName(r);
+            assertNotNull(targetFunctionName, "Expected function name or '" + SS.FUNCTION_NAMES_END_SENTINEL + "'");
+            if (targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
+                // found end of functions list
+                break;
+            }
+            String targetTestName = getTargetTestName(r);
+
+            // expected results are on the row below
+            Cell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_VALUE);
+            assertNotNull(expectedValueCell, "Missing expected values cell for function '" + targetFunctionName);
+
+            data.add(Arguments.of( targetTestName, targetFunctionName, expectedValueCell, r ));
+        }
+
+        return data.stream();
+    }
+
+    @ParameterizedTest
+    @MethodSource("data")
+    void testFunction(String testName, String functionName, Cell expected, Row testRow) {
+
+        Cell c = testRow.getCell(SS.COLUMN_INDEX_ACTUAL_VALUE);
+        if (c == null || c.getCellType() != CellType.FORMULA) {
+            // missing test data
+            assertTrue(testRow.getRowNum() >= SS.START_FUNCTIONS_ROW_INDEX);
+            assertTrue(funcs.contains(functionName.toUpperCase(Locale.ROOT)), "unsupported function");
+            return;
+        }
+
+        CellValue actual = evaluator.evaluate(c);
+
+        assertNotNull(expected, "Bad setup data expected value is null");
+        assertNotNull(actual, "actual value was null");
+
+        final CellType cellType = expected.getCellType();
+
+        switch (cellType) {
+            case BLANK:
+                assertEquals(CellType.BLANK, actual.getCellType());
+                break;
+            case BOOLEAN:
+                assertEquals(CellType.BOOLEAN, actual.getCellType());
+                assertEquals(expected.getBooleanCellValue(), actual.getBooleanValue());
+                break;
+            case ERROR:
+                assertEquals(CellType.ERROR, actual.getCellType());
+                assertEquals(ErrorEval.getText(expected.getErrorCellValue()), ErrorEval.getText(actual.getErrorValue()));
+                break;
+            case FORMULA: // will never be used, since we will call method after formula evaluation
+                fail("Cannot expect formula as result of formula evaluation.");
+                break;
+            case NUMERIC:
+                assertEquals(CellType.NUMERIC, actual.getCellType());
+                TestMathX.assertDouble("", expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR);
+                break;
+            case STRING:
+                assertEquals(CellType.STRING, actual.getCellType());
+                assertEquals(expected.getRichStringCellValue().getString(), actual.getStringValue());
+                break;
+            default:
+                fail("Unexpected cell type: " + cellType);
+                break;
+        }
+    }
+
+    private static String getTargetFunctionName(Row r) {
+        assertNotNull(r, "given null row, can't figure out function name");
+        Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME);
+        assertNotNull(cell, "Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
+        assertEquals(CellType.STRING, cell.getCellType());
+        return cell.getRichStringCellValue().getString();
+    }
+
+    private static String getTargetTestName(Row r) {
+        assertNotNull(r, "Given null row, can't figure out test name");
+        Cell cell = r.getCell(SS.COLUMN_INDEX_TEST_NAME);
+        assertNotNull(cell, "Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_TEST_NAME + ", can't figure out test name");
+        assertEquals(CellType.STRING, cell.getCellType());
+        return cell.getRichStringCellValue().getString();
+    }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestOperandResolver.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestOperandResolver.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestOperandResolver.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestOperandResolver.java Sat May 22 20:56:44 2021
@@ -30,72 +30,72 @@ import org.junit.jupiter.api.Test;
  * Tests for {@code OperandResolver}
  */
 final class TestOperandResolver {
-	@Test
-	void testParseDouble_bug48472() {
-		// bug 48472 - StringIndexOutOfBoundsException
-		Double resolvedValue = OperandResolver.parseDouble("-");
-		assertNull(resolvedValue);
-	}
-
-	@Test
-	void testParseDouble_bug49723() {
-		String value = ".1";
-		Double resolvedValue = OperandResolver.parseDouble(value);
-
-		assertNotNull(resolvedValue, "Identified bug 49723");
-	}
-
-	/**
-	 * Tests that a list of valid strings all return a non null value from {@link OperandResolver#parseDouble(String)}
-	 */
-	@Test
-	void testParseDoubleValidStrings() {
-		String[] values = new String[]{".19", "0.19", "1.9", "1E4", "-.19", "-0.19",
-				"8.5","-1E4", ".5E6","+1.5","+1E5", "  +1E5  ", " 123 ", "1E4", "-123" };
-
-		for (String value : values) {
-			Double act = OperandResolver.parseDouble(value);
-			assertNotNull(act);
-			assertEquals(act, Double.parseDouble(value), 0);
-		}
-	}
-
-	/**
-	 * Tests that a list of invalid strings all return null from {@link OperandResolver#parseDouble(String)}
-	 */
-	@Test
-	void testParseDoubleInvalidStrings() {
-		String[] values = new String[]{"-", "ABC", "-X", "1E5a", "Infinity", "NaN", ".5F", "1,000"};
-
-		for (String value : values) {
-			assertNull(OperandResolver.parseDouble(value));
-		}
-	}
-
-	@Test
-	void testCoerceDateStringToNumber() throws EvaluationException {
-		Map<String, Double> values = new LinkedHashMap<>();
-		values.put("2019/1/18", 43483.);
-		values.put("01/18/2019", 43483.);
-		values.put("18 Jan 2019", 43483.);
-		values.put("18-Jan-2019", 43483.);
-
-		for (String str : values.keySet()) {
-			assertEquals(OperandResolver.coerceValueToDouble(new StringEval(str)), values.get(str), 0.00001);
-		}
-	}
-
-	@Test
-	void testCoerceTimeStringToNumber() throws EvaluationException {
-		Map<String, Double> values = new LinkedHashMap<>();
-		values.put("00:00", 0.0);
-		values.put("12:00", 0.5);
-		values.put("15:43:09", 0.654965278);
-		values.put("15:43", 0.654861111);
-		values.put("3:43 PM", 0.654861111);
-
-		for (String str : values.keySet()) {
-			assertEquals(OperandResolver.coerceValueToDouble(new StringEval(str)), values.get(str), 0.00001);
-		}
-	}
+    @Test
+    void testParseDouble_bug48472() {
+        // bug 48472 - StringIndexOutOfBoundsException
+        Double resolvedValue = OperandResolver.parseDouble("-");
+        assertNull(resolvedValue);
+    }
+
+    @Test
+    void testParseDouble_bug49723() {
+        String value = ".1";
+        Double resolvedValue = OperandResolver.parseDouble(value);
+
+        assertNotNull(resolvedValue, "Identified bug 49723");
+    }
+
+    /**
+     * Tests that a list of valid strings all return a non null value from {@link OperandResolver#parseDouble(String)}
+     */
+    @Test
+    void testParseDoubleValidStrings() {
+        String[] values = new String[]{".19", "0.19", "1.9", "1E4", "-.19", "-0.19",
+                "8.5","-1E4", ".5E6","+1.5","+1E5", "  +1E5  ", " 123 ", "1E4", "-123" };
+
+        for (String value : values) {
+            Double act = OperandResolver.parseDouble(value);
+            assertNotNull(act);
+            assertEquals(act, Double.parseDouble(value), 0);
+        }
+    }
+
+    /**
+     * Tests that a list of invalid strings all return null from {@link OperandResolver#parseDouble(String)}
+     */
+    @Test
+    void testParseDoubleInvalidStrings() {
+        String[] values = new String[]{"-", "ABC", "-X", "1E5a", "Infinity", "NaN", ".5F", "1,000"};
+
+        for (String value : values) {
+            assertNull(OperandResolver.parseDouble(value));
+        }
+    }
+
+    @Test
+    void testCoerceDateStringToNumber() throws EvaluationException {
+        Map<String, Double> values = new LinkedHashMap<>();
+        values.put("2019/1/18", 43483.);
+        values.put("01/18/2019", 43483.);
+        values.put("18 Jan 2019", 43483.);
+        values.put("18-Jan-2019", 43483.);
+
+        for (String str : values.keySet()) {
+            assertEquals(OperandResolver.coerceValueToDouble(new StringEval(str)), values.get(str), 0.00001);
+        }
+    }
+
+    @Test
+    void testCoerceTimeStringToNumber() throws EvaluationException {
+        Map<String, Double> values = new LinkedHashMap<>();
+        values.put("00:00", 0.0);
+        values.put("12:00", 0.5);
+        values.put("15:43:09", 0.654965278);
+        values.put("15:43", 0.654861111);
+        values.put("3:43 PM", 0.654861111);
+
+        for (String str : values.keySet()) {
+            assertEquals(OperandResolver.coerceValueToDouble(new StringEval(str)), values.get(str), 0.00001);
+        }
+    }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestPercentEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestPercentEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestPercentEval.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestPercentEval.java Sat May 22 20:56:44 2021
@@ -37,46 +37,46 @@ import org.junit.jupiter.api.Test;
  */
 final class TestPercentEval {
 
-	private static void confirm(ValueEval arg, double expectedResult) {
-		ValueEval[] args = {
-			arg,
-		};
-
-		double result = NumericFunctionInvoker.invoke(PercentEval.instance, args, 0, 0);
-
-		assertEquals(expectedResult, result, 0);
-	}
-
-	@Test
-	void testBasic() {
-		confirm(new NumberEval(5), 0.05);
-		confirm(new NumberEval(3000), 30.0);
-		confirm(new NumberEval(-150), -1.5);
-		confirm(new StringEval("0.2"), 0.002);
-		confirm(BoolEval.TRUE, 0.01);
-	}
-
-	@Test
-	void test1x1Area() {
-		AreaEval ae = EvalFactory.createAreaEval("B2:B2", new ValueEval[] { new NumberEval(50), });
-		confirm(ae, 0.5);
-	}
-
-	@Test
-	void testInSpreadSheet() throws IOException {
-		try (HSSFWorkbook wb = new HSSFWorkbook()) {
-			HSSFSheet sheet = wb.createSheet("Sheet1");
-			HSSFRow row = sheet.createRow(0);
-			HSSFCell cell = row.createCell(0);
-			cell.setCellFormula("B1%");
-			row.createCell(1).setCellValue(50.0);
-
-			HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
-
-			// bug 44608 - NullPointerException
-			CellValue cv = fe.evaluate(cell);
-			assertEquals(CellType.NUMERIC, cv.getCellType());
-			assertEquals(0.5, cv.getNumberValue(), 0.0);
-		}
-	}
+    private static void confirm(ValueEval arg, double expectedResult) {
+        ValueEval[] args = {
+            arg,
+        };
+
+        double result = NumericFunctionInvoker.invoke(PercentEval.instance, args, 0, 0);
+
+        assertEquals(expectedResult, result, 0);
+    }
+
+    @Test
+    void testBasic() {
+        confirm(new NumberEval(5), 0.05);
+        confirm(new NumberEval(3000), 30.0);
+        confirm(new NumberEval(-150), -1.5);
+        confirm(new StringEval("0.2"), 0.002);
+        confirm(BoolEval.TRUE, 0.01);
+    }
+
+    @Test
+    void test1x1Area() {
+        AreaEval ae = EvalFactory.createAreaEval("B2:B2", new ValueEval[] { new NumberEval(50), });
+        confirm(ae, 0.5);
+    }
+
+    @Test
+    void testInSpreadSheet() throws IOException {
+        try (HSSFWorkbook wb = new HSSFWorkbook()) {
+            HSSFSheet sheet = wb.createSheet("Sheet1");
+            HSSFRow row = sheet.createRow(0);
+            HSSFCell cell = row.createCell(0);
+            cell.setCellFormula("B1%");
+            row.createCell(1).setCellValue(50.0);
+
+            HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+
+            // bug 44608 - NullPointerException
+            CellValue cv = fe.evaluate(cell);
+            assertEquals(CellType.NUMERIC, cv.getCellType());
+            assertEquals(0.5, cv.getNumberValue(), 0.0);
+        }
+    }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestRangeEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestRangeEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestRangeEval.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestRangeEval.java Sat May 22 20:56:44 2021
@@ -40,130 +40,130 @@ import org.junit.jupiter.api.Test;
  * Test for unary plus operator evaluator.
  */
 final class TestRangeEval {
-	@Test
-	void testPermutations() {
+    @Test
+    void testPermutations() {
 
-		confirm("B3", "D7", "B3:D7");
-		confirm("B1", "B1", "B1:B1");
+        confirm("B3", "D7", "B3:D7");
+        confirm("B1", "B1", "B1:B1");
 
-		confirm("B7", "D3", "B3:D7");
-		confirm("D3", "B7", "B3:D7");
-		confirm("D7", "B3", "B3:D7");
-	}
-
-	private static void confirm(String refA, String refB, String expectedAreaRef) {
-
-		ValueEval[] args = {
-			createRefEval(refA),
-			createRefEval(refB),
-		};
+        confirm("B7", "D3", "B3:D7");
+        confirm("D3", "B7", "B3:D7");
+        confirm("D7", "B3", "B3:D7");
+    }
+
+    private static void confirm(String refA, String refB, String expectedAreaRef) {
+
+        ValueEval[] args = {
+            createRefEval(refA),
+            createRefEval(refB),
+        };
         List<SpreadsheetVersion> versions = Arrays.asList(SpreadsheetVersion.EXCEL97, SpreadsheetVersion.EXCEL2007);
         for(SpreadsheetVersion version : versions) {
             AreaReference ar = new AreaReference(expectedAreaRef, version);
-    		ValueEval result = EvalInstances.Range.evaluate(args, 0, (short)0);
-    		assertTrue(result instanceof AreaEval);
-    		AreaEval ae = (AreaEval) result;
-    		assertEquals(ar.getFirstCell().getRow(), ae.getFirstRow());
-    		assertEquals(ar.getLastCell().getRow(), ae.getLastRow());
-    		assertEquals(ar.getFirstCell().getCol(), ae.getFirstColumn());
-    		assertEquals(ar.getLastCell().getCol(), ae.getLastColumn());
-        }
-	}
-
-	private static ValueEval createRefEval(String refStr) {
-		CellReference cr = new CellReference(refStr);
-		return new MockRefEval(cr.getRow(), cr.getCol());
-
-	}
-
-	private static final class MockRefEval extends RefEvalBase {
-		public MockRefEval(int rowIndex, int columnIndex) {
-			super(-1, -1, rowIndex, columnIndex);
-		}
-		@Override
+            ValueEval result = EvalInstances.Range.evaluate(args, 0, (short)0);
+            assertTrue(result instanceof AreaEval);
+            AreaEval ae = (AreaEval) result;
+            assertEquals(ar.getFirstCell().getRow(), ae.getFirstRow());
+            assertEquals(ar.getLastCell().getRow(), ae.getLastRow());
+            assertEquals(ar.getFirstCell().getCol(), ae.getFirstColumn());
+            assertEquals(ar.getLastCell().getCol(), ae.getLastColumn());
+        }
+    }
+
+    private static ValueEval createRefEval(String refStr) {
+        CellReference cr = new CellReference(refStr);
+        return new MockRefEval(cr.getRow(), cr.getCol());
+
+    }
+
+    private static final class MockRefEval extends RefEvalBase {
+        public MockRefEval(int rowIndex, int columnIndex) {
+            super(-1, -1, rowIndex, columnIndex);
+        }
+        @Override
         public ValueEval getInnerValueEval(int sheetIndex) {
-			throw new RuntimeException("not expected to be called during this test");
-		}
-		@Override
+            throw new RuntimeException("not expected to be called during this test");
+        }
+        @Override
         public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx,
-				int relLastColIx) {
-			AreaI area = new OffsetArea(getRow(), getColumn(),
-					relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
-			return new MockAreaEval(area);
-		}
-	}
-
-	private static final class MockAreaEval extends AreaEvalBase {
-
-		public MockAreaEval(AreaI ptg) {
-			super(ptg);
-		}
-		private MockAreaEval(int firstRow, int firstColumn, int lastRow, int lastColumn) {
-			super(firstRow, firstColumn, lastRow, lastColumn);
-		}
-		@Override
+                int relLastColIx) {
+            AreaI area = new OffsetArea(getRow(), getColumn(),
+                    relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
+            return new MockAreaEval(area);
+        }
+    }
+
+    private static final class MockAreaEval extends AreaEvalBase {
+
+        public MockAreaEval(AreaI ptg) {
+            super(ptg);
+        }
+        private MockAreaEval(int firstRow, int firstColumn, int lastRow, int lastColumn) {
+            super(firstRow, firstColumn, lastRow, lastColumn);
+        }
+        @Override
         public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
-			throw new RuntimeException("not expected to be called during this test");
-		}
+            throw new RuntimeException("not expected to be called during this test");
+        }
         @Override
         public ValueEval getRelativeValue(int sheetIndex, int relativeRowIndex, int relativeColumnIndex) {
             throw new RuntimeException("not expected to be called during this test");
         }
-		@Override
+        @Override
         public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx,
-				int relLastColIx) {
-			AreaI area = new OffsetArea(getFirstRow(), getFirstColumn(),
-					relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
-
-			return new MockAreaEval(area);
-		}
-		@Override
+                int relLastColIx) {
+            AreaI area = new OffsetArea(getFirstRow(), getFirstColumn(),
+                    relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
+
+            return new MockAreaEval(area);
+        }
+        @Override
         public TwoDEval getRow(int rowIndex) {
-			if (rowIndex >= getHeight()) {
-				throw new IllegalArgumentException("Invalid rowIndex " + rowIndex
-						+ ".  Allowable range is (0.." + getHeight() + ").");
-			}
-			return new MockAreaEval(rowIndex, getFirstColumn(), rowIndex, getLastColumn());
-		}
-		@Override
+            if (rowIndex >= getHeight()) {
+                throw new IllegalArgumentException("Invalid rowIndex " + rowIndex
+                        + ".  Allowable range is (0.." + getHeight() + ").");
+            }
+            return new MockAreaEval(rowIndex, getFirstColumn(), rowIndex, getLastColumn());
+        }
+        @Override
         public TwoDEval getColumn(int columnIndex) {
-			if (columnIndex >= getWidth()) {
-				throw new IllegalArgumentException("Invalid columnIndex " + columnIndex
-						+ ".  Allowable range is (0.." + getWidth() + ").");
-			}
-			return new MockAreaEval(getFirstRow(), columnIndex, getLastRow(), columnIndex);
-		}
-	}
-
-	@Test
-	void testRangeUsingOffsetFunc_bug46948() {
-		HSSFWorkbook wb = new HSSFWorkbook();
-		HSSFRow row = wb.createSheet("Sheet1").createRow(0);
-		HSSFCell cellA1 = row.createCell(0);
-		HSSFCell cellB1 = row.createCell(1);
-		row.createCell(2).setCellValue(5.0); // C1
-		row.createCell(3).setCellValue(7.0); // D1
-		row.createCell(4).setCellValue(9.0); // E1
-
-
-		cellA1.setCellFormula("SUM(C1:OFFSET(C1,0,B1))");
-
-		cellB1.setCellValue(1.0); // range will be C1:D1
-
-		HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
-		// bug 46948 - Unexpected ref arg class (org.apache.poi.ss.formula.LazyAreaEval)
-		CellValue cv = fe.evaluate(cellA1);
-
-		assertEquals(12.0, cv.getNumberValue(), 0.0);
-
-		cellB1.setCellValue(2.0); // range will be C1:E1
-		fe.notifyUpdateCell(cellB1);
-		cv = fe.evaluate(cellA1);
-		assertEquals(21.0, cv.getNumberValue(), 0.0);
-
-		cellB1.setCellValue(0.0); // range will be C1:C1
-		fe.notifyUpdateCell(cellB1);
-		cv = fe.evaluate(cellA1);
-		assertEquals(5.0, cv.getNumberValue(), 0.0);
-	}
+            if (columnIndex >= getWidth()) {
+                throw new IllegalArgumentException("Invalid columnIndex " + columnIndex
+                        + ".  Allowable range is (0.." + getWidth() + ").");
+            }
+            return new MockAreaEval(getFirstRow(), columnIndex, getLastRow(), columnIndex);
+        }
+    }
+
+    @Test
+    void testRangeUsingOffsetFunc_bug46948() {
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFRow row = wb.createSheet("Sheet1").createRow(0);
+        HSSFCell cellA1 = row.createCell(0);
+        HSSFCell cellB1 = row.createCell(1);
+        row.createCell(2).setCellValue(5.0); // C1
+        row.createCell(3).setCellValue(7.0); // D1
+        row.createCell(4).setCellValue(9.0); // E1
+
+
+        cellA1.setCellFormula("SUM(C1:OFFSET(C1,0,B1))");
+
+        cellB1.setCellValue(1.0); // range will be C1:D1
+
+        HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+        // bug 46948 - Unexpected ref arg class (org.apache.poi.ss.formula.LazyAreaEval)
+        CellValue cv = fe.evaluate(cellA1);
+
+        assertEquals(12.0, cv.getNumberValue(), 0.0);
+
+        cellB1.setCellValue(2.0); // range will be C1:E1
+        fe.notifyUpdateCell(cellB1);
+        cv = fe.evaluate(cellA1);
+        assertEquals(21.0, cv.getNumberValue(), 0.0);
+
+        cellB1.setCellValue(0.0); // range will be C1:C1
+        fe.notifyUpdateCell(cellB1);
+        cv = fe.evaluate(cellA1);
+        assertEquals(5.0, cv.getNumberValue(), 0.0);
+    }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java Sat May 22 20:56:44 2021
@@ -29,30 +29,30 @@ import org.junit.jupiter.api.Test;
  */
 final class TestUnaryPlusEval {
 
-	/**
-	 * Test for bug observable at svn revision 618865 (5-Feb-2008)<br>
-	 * The code for handling column operands had been copy-pasted from the row handling code.
-	 */
-	@Test
-	void testColumnOperand() {
+    /**
+     * Test for bug observable at svn revision 618865 (5-Feb-2008)<br>
+     * The code for handling column operands had been copy-pasted from the row handling code.
+     */
+    @Test
+    void testColumnOperand() {
 
-		short firstRow = (short)8;
-		short lastRow = (short)12;
-		short colNum = (short)5;
-		AreaPtg areaPtg = new AreaPtg(firstRow, lastRow, colNum, colNum, false, false, false, false);
-		ValueEval[] values = {
-				new NumberEval(27),
-				new NumberEval(29),
-				new NumberEval(35),	// value in row 10
-				new NumberEval(37),
-				new NumberEval(38),
-		};
-		ValueEval[] args = {
-			EvalFactory.createAreaEval(areaPtg, values),
-		};
+        short firstRow = (short)8;
+        short lastRow = (short)12;
+        short colNum = (short)5;
+        AreaPtg areaPtg = new AreaPtg(firstRow, lastRow, colNum, colNum, false, false, false, false);
+        ValueEval[] values = {
+                new NumberEval(27),
+                new NumberEval(29),
+                new NumberEval(35), // value in row 10
+                new NumberEval(37),
+                new NumberEval(38),
+        };
+        ValueEval[] args = {
+            EvalFactory.createAreaEval(areaPtg, values),
+        };
 
-		double result = NumericFunctionInvoker.invoke(EvalInstances.UnaryPlus, args, 10, (short)20);
+        double result = NumericFunctionInvoker.invoke(EvalInstances.UnaryPlus, args, 10, (short)20);
 
-		assertEquals(35, result, 0);
-	}
+        assertEquals(35, result, 0);
+    }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/forked/BaseTestForkedEvaluator.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/forked/BaseTestForkedEvaluator.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/forked/BaseTestForkedEvaluator.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/forked/BaseTestForkedEvaluator.java Sat May 22 20:56:44 2021
@@ -37,81 +37,81 @@ public class BaseTestForkedEvaluator {
         return new HSSFWorkbook();
     }
 
-	/**
-	 * set up a calculation workbook with input cells nicely segregated on a
-	 * sheet called "Inputs"
-	 */
-	protected Workbook createWorkbook() {
-		Workbook wb = newWorkbook();
-		Sheet sheet1 = wb.createSheet("Inputs");
-		Sheet sheet2 = wb.createSheet("Calculations");
-		Row row;
-		row = sheet2.createRow(0);
-		row.createCell(0).setCellFormula("B1*Inputs!A1-Inputs!B1");
-		row.createCell(1).setCellValue(5.0); // Calculations!B1
-
-		// some default input values
-		row = sheet1.createRow(0);
-		row.createCell(0).setCellValue(2.0); // Inputs!A1
-		row.createCell(1).setCellValue(3.0); // Inputs!B1
-		return wb;
-	}
-
-	/**
-	 * Shows a basic use-case for {@link ForkedEvaluator}
-	 */
-	@Test
-	void testBasic() throws IOException {
-		try (Workbook wb = createWorkbook()) {
-
-			// The stability classifier is useful to reduce memory consumption of caching logic
-			IStabilityClassifier stabilityClassifier = (sheetIndex, rowIndex, columnIndex) -> sheetIndex == 1;
-
-			ForkedEvaluator fe1 = ForkedEvaluator.create(wb, stabilityClassifier, null);
-			ForkedEvaluator fe2 = ForkedEvaluator.create(wb, stabilityClassifier, null);
-
-			// fe1 and fe2 can be used concurrently on separate threads
-
-			fe1.updateCell("Inputs", 0, 0, new NumberEval(4.0));
-			fe1.updateCell("Inputs", 0, 1, new NumberEval(1.1));
-
-			fe2.updateCell("Inputs", 0, 0, new NumberEval(1.2));
-			fe2.updateCell("Inputs", 0, 1, new NumberEval(2.0));
-
-			NumberEval eval1 = (NumberEval) fe1.evaluate("Calculations", 0, 0);
-			assertNotNull(eval1);
-			assertEquals(18.9, eval1.getNumberValue(), 0.0);
-			NumberEval eval2 = (NumberEval) fe2.evaluate("Calculations", 0, 0);
-			assertNotNull(eval2);
-			assertEquals(4.0, eval2.getNumberValue(), 0.0);
-			fe1.updateCell("Inputs", 0, 0, new NumberEval(3.0));
-			eval1 = (NumberEval) fe1.evaluate("Calculations", 0, 0);
-			assertNotNull(eval1);
-			assertEquals(13.9, eval1.getNumberValue(), 0.0);
-		}
-	}
-
-	/**
-	 * As of Sep 2009, the Forked evaluator can update values from existing cells (this is because
-	 * the underlying 'master' cell is used as a key into the calculation cache.  Prior to the fix
-	 * for this bug, an attempt to update a missing cell would result in NPE.  This junit tests for
-	 * a more meaningful error message.<br>
-	 *
-	 * An alternate solution might involve allowing empty cells to be created as necessary.  That
-	 * was considered less desirable because so far, the underlying 'master' workbook is strictly
-	 * <i>read-only</i> with respect to the ForkedEvaluator.
-	 */
-	@Test
-	void testMissingInputCellH() throws IOException {
-
-		try (Workbook wb = createWorkbook()) {
-			ForkedEvaluator fe = ForkedEvaluator.create(wb, null, null);
-			// attempt update input at cell A2 (which is missing)
-			UnsupportedOperationException ex = assertThrows(
-				UnsupportedOperationException.class,
-				 () -> fe.updateCell("Inputs", 1, 0, new NumberEval(4.0))
-			);
-			assertEquals("Underlying cell 'A2' is missing in master sheet.", ex.getMessage());
-		}
-	}
+    /**
+     * set up a calculation workbook with input cells nicely segregated on a
+     * sheet called "Inputs"
+     */
+    protected Workbook createWorkbook() {
+        Workbook wb = newWorkbook();
+        Sheet sheet1 = wb.createSheet("Inputs");
+        Sheet sheet2 = wb.createSheet("Calculations");
+        Row row;
+        row = sheet2.createRow(0);
+        row.createCell(0).setCellFormula("B1*Inputs!A1-Inputs!B1");
+        row.createCell(1).setCellValue(5.0); // Calculations!B1
+
+        // some default input values
+        row = sheet1.createRow(0);
+        row.createCell(0).setCellValue(2.0); // Inputs!A1
+        row.createCell(1).setCellValue(3.0); // Inputs!B1
+        return wb;
+    }
+
+    /**
+     * Shows a basic use-case for {@link ForkedEvaluator}
+     */
+    @Test
+    void testBasic() throws IOException {
+        try (Workbook wb = createWorkbook()) {
+
+            // The stability classifier is useful to reduce memory consumption of caching logic
+            IStabilityClassifier stabilityClassifier = (sheetIndex, rowIndex, columnIndex) -> sheetIndex == 1;
+
+            ForkedEvaluator fe1 = ForkedEvaluator.create(wb, stabilityClassifier, null);
+            ForkedEvaluator fe2 = ForkedEvaluator.create(wb, stabilityClassifier, null);
+
+            // fe1 and fe2 can be used concurrently on separate threads
+
+            fe1.updateCell("Inputs", 0, 0, new NumberEval(4.0));
+            fe1.updateCell("Inputs", 0, 1, new NumberEval(1.1));
+
+            fe2.updateCell("Inputs", 0, 0, new NumberEval(1.2));
+            fe2.updateCell("Inputs", 0, 1, new NumberEval(2.0));
+
+            NumberEval eval1 = (NumberEval) fe1.evaluate("Calculations", 0, 0);
+            assertNotNull(eval1);
+            assertEquals(18.9, eval1.getNumberValue(), 0.0);
+            NumberEval eval2 = (NumberEval) fe2.evaluate("Calculations", 0, 0);
+            assertNotNull(eval2);
+            assertEquals(4.0, eval2.getNumberValue(), 0.0);
+            fe1.updateCell("Inputs", 0, 0, new NumberEval(3.0));
+            eval1 = (NumberEval) fe1.evaluate("Calculations", 0, 0);
+            assertNotNull(eval1);
+            assertEquals(13.9, eval1.getNumberValue(), 0.0);
+        }
+    }
+
+    /**
+     * As of Sep 2009, the Forked evaluator can update values from existing cells (this is because
+     * the underlying 'master' cell is used as a key into the calculation cache.  Prior to the fix
+     * for this bug, an attempt to update a missing cell would result in NPE.  This junit tests for
+     * a more meaningful error message.<br>
+     *
+     * An alternate solution might involve allowing empty cells to be created as necessary.  That
+     * was considered less desirable because so far, the underlying 'master' workbook is strictly
+     * <i>read-only</i> with respect to the ForkedEvaluator.
+     */
+    @Test
+    void testMissingInputCellH() throws IOException {
+
+        try (Workbook wb = createWorkbook()) {
+            ForkedEvaluator fe = ForkedEvaluator.create(wb, null, null);
+            // attempt update input at cell A2 (which is missing)
+            UnsupportedOperationException ex = assertThrows(
+                UnsupportedOperationException.class,
+                 () -> fe.updateCell("Inputs", 1, 0, new NumberEval(4.0))
+            );
+            assertEquals("Underlying cell 'A2' is missing in master sheet.", ex.getMessage());
+        }
+    }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/function/ExcelCetabFunctionExtractor.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/function/ExcelCetabFunctionExtractor.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/function/ExcelCetabFunctionExtractor.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/function/ExcelCetabFunctionExtractor.java Sat May 22 20:56:44 2021
@@ -43,336 +43,336 @@ import java.util.regex.Pattern;
  */
 public final class ExcelCetabFunctionExtractor {
 
-	private static final String SOURCE_DOC_FILE_NAME = "functionMetadataCetab-PDF.txt";
+    private static final String SOURCE_DOC_FILE_NAME = "functionMetadataCetab-PDF.txt";
 
-	/**
-	 * For simplicity, the output file is strictly simple ASCII.
-	 * This method detects any unexpected characters.
-	 */
-	/* package */ static boolean isSimpleAscii(char c) {
-
-		if (c>=0x21 && c<=0x7E) {
-			// everything from '!' to '~' (includes letters, digits, punctuation
-			return true;
-		}
-		// some specific whitespace chars below 0x21:
-		switch(c) {
-			case ' ':
-			case '\t':
-			case '\r':
-			case '\n':
-				return true;
-		}
-		return false;
-	}
-
-
-	private static final class FunctionData {
-		// special characters from the ooo document
-		private static final int CHAR_ELLIPSIS_8230 = 8230;
-		private static final int CHAR_NDASH_8211 = 8211;
-
-		private final int _index;
-		private final boolean _hasFootnote;
-		private final String _name;
-		private final int _minParams;
-		private final int _maxParams;
-		private final String _returnClass;
-		private final String _paramClasses;
-		private final boolean _isVolatile;
-
-		public FunctionData(int funcIx, boolean hasFootnote, String funcName, int minParams, int maxParams,
-					String returnClass, String paramClasses, boolean isVolatile) {
-			_index = funcIx;
-			_hasFootnote = hasFootnote;
-			_name = funcName;
-			_minParams = minParams;
-			_maxParams = maxParams;
-			_returnClass = convertSpecialChars(returnClass);
-			_paramClasses = convertSpecialChars(paramClasses);
-			_isVolatile = isVolatile;
-		}
-		private static String convertSpecialChars(String ss) {
-			StringBuilder sb = new StringBuilder(ss.length() + 4);
-			for(int i=0; i<ss.length(); i++) {
-				char c = ss.charAt(i);
-				if (isSimpleAscii(c)) {
-					sb.append(c);
-					continue;
-				}
-				switch (c) {
-					case CHAR_NDASH_8211:
-						sb.append('-');
-						continue;
-					case CHAR_ELLIPSIS_8230:
-						sb.append("...");
-						continue;
-				}
-				throw new RuntimeException("bad char (" + ((int)c) + ") in string '" + ss + "'");
-			}
-			return sb.toString();
-		}
-		public int getIndex() {
-			return _index;
-		}
-		public String getName() {
-			return _name;
-		}
-		public boolean hasFootnote() {
-			return _hasFootnote;
-		}
-		public String formatAsDataLine() {
-			return _index + "\t" + _name + "\t" + _minParams + "\t"
-					+ _maxParams + "\t" + _returnClass + "\t" + _paramClasses
-					+ "\t" + checkMark(_isVolatile) + "\t" + checkMark(_hasFootnote);
-		}
-		private static String checkMark(boolean b) {
-			return b ? "x" : "";
-		}
-	}
-
-	private static final class FunctionDataCollector {
-
-		private final Map<Integer, FunctionData> _allFunctionsByIndex;
-		private final Map<String, FunctionData> _allFunctionsByName;
-		private final Set<Integer> _groupFunctionIndexes;
-		private final Set<String> _groupFunctionNames;
-		private final PrintStream _ps;
-
-		public FunctionDataCollector(PrintStream ps) {
-			_ps = ps;
-			_allFunctionsByIndex = new HashMap<>();
-			_allFunctionsByName = new HashMap<>();
-			_groupFunctionIndexes = new HashSet<>();
-			_groupFunctionNames = new HashSet<>();
-		}
-
-		public void addFunction(int funcIx, boolean hasFootnote, String funcName, int minParams, int maxParams,
-								String returnClass, String paramClasses, String volatileFlagStr) {
-			boolean isVolatile = volatileFlagStr.length() > 0;
-
-			Integer funcIxKey = Integer.valueOf(funcIx);
-			if(!_groupFunctionIndexes.add(funcIxKey)) {
-				throw new RuntimeException("Duplicate function index (" + funcIx + ")");
-			}
-			if(!_groupFunctionNames.add(funcName)) {
-				throw new RuntimeException("Duplicate function name '" + funcName + "'");
-			}
-
-			checkRedefinedFunction(hasFootnote, funcName, funcIxKey);
-			FunctionData fd = new FunctionData(funcIx, hasFootnote, funcName,
-					minParams, maxParams, returnClass, paramClasses, isVolatile);
-
-			_allFunctionsByIndex.put(funcIxKey, fd);
-			_allFunctionsByName.put(funcName, fd);
-		}
-
-		/**
-		 * Some extra validation here.
-		 * Any function which changes definition will have a footnote in the source document
-		 */
-		private void checkRedefinedFunction(boolean hasNote, String funcName, Integer funcIxKey) {
-			FunctionData fdPrev;
-			// check by index
-			fdPrev = _allFunctionsByIndex.get(funcIxKey);
-			if(fdPrev != null) {
-				if(!fdPrev.hasFootnote() || !hasNote) {
-					throw new RuntimeException("changing function ["
-							+ funcIxKey + "] definition without foot-note");
-				}
-				_allFunctionsByName.remove(fdPrev.getName());
-			}
-			// check by name
-			fdPrev = _allFunctionsByName.get(funcName);
-			if(fdPrev != null) {
-				if(!fdPrev.hasFootnote() || !hasNote) {
-					throw new RuntimeException("changing function '"
-							+ funcName + "' definition without foot-note");
-				}
-				_allFunctionsByIndex.remove(Integer.valueOf(fdPrev.getIndex()));
-			}
-		}
-
-		public void endTableGroup(String headingText) {
-			Integer[] keys = new Integer[_groupFunctionIndexes.size()];
-			_groupFunctionIndexes.toArray(keys);
-			_groupFunctionIndexes.clear();
-			_groupFunctionNames.clear();
-			Arrays.sort(keys);
-
-			_ps.println("# " + headingText);
-			for (Integer key : keys) {
-				FunctionData fd = _allFunctionsByIndex.get(key);
-				_ps.println(fd.formatAsDataLine());
-			}
-		}
-	}
-
-	private static final Pattern ID_MATCH = Pattern.compile("0x([\\dA-F]+)");
-	private static final Pattern NAME_MATCH = Pattern.compile("([0-9A-Z.]+)");
-	private static final Pattern ID_NAME_MATCH = Pattern.compile("0x([\\dA-F]+)\\s+([0-9A-Z.]+)");
-
-	private static final Set<String> IGNORED_LINES = new HashSet<>();
-	static {
-		IGNORED_LINES.add("[MS-XLS] — v20141018");
-		IGNORED_LINES.add("Excel Binary File Format (.xls) Structure");
-		IGNORED_LINES.add("Copyright © 2014 Microsoft Corporation.");
-		IGNORED_LINES.add("Release: October 30, 2014Value Meaning");
-		IGNORED_LINES.add("Release: October 30, 2014Value");
-		IGNORED_LINES.add("Meaning");
-	}
-
-	private static void extractFunctionData(FunctionDataCollector fdc, InputStream is) throws IOException {
-		try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
-
-			String id = null;
-			String name = null;
-			while (true) {
-				String line = reader.readLine();
-				if(line == null) {
-					break;
-				}
-
-				if(IGNORED_LINES.contains(line) || line.matches("\\d+ / \\d+")) {
-					continue;
-				}
-
-				Matcher idMatcher = ID_MATCH.matcher(line);
-				boolean foundID = idMatcher.matches();
-				Matcher nameMatcher = NAME_MATCH.matcher(line);
-				boolean foundName = nameMatcher.matches();
-				Matcher idAndNameMatcher = ID_NAME_MATCH.matcher(line);
-				boolean foundIDandName = idAndNameMatcher.matches();
-				if(foundID && foundName ||
-						foundName && foundIDandName ||
-						foundID && foundIDandName) {
-					throw new IllegalStateException("Should not find id and name: " +
-							foundID + "/" + foundName + "/" + foundIDandName +
-							", line: " + line);
-				}
-
-				if(foundID && id != null) {
-					throw new IllegalStateException("Found ID, but already had one: " + id + ", line: " + line);
-				}
-				if(foundName && name != null) {
-					throw new IllegalStateException("Found name, but already had one: " + name + ", line: " + line);
-				}
-				if(foundIDandName && (name != null || id != null)) {
-					throw new IllegalStateException("Found name and id, but already had one: id: " + id + ", name: " + name + ", line: " + line);
-				}
-
-				if(foundID) {
-					id = idMatcher.group(1);
-				} else if (foundName) {
-					name = nameMatcher.group(1);
-				} else if (foundIDandName) {
-					id = idAndNameMatcher.group(1);
-					name = idAndNameMatcher.group(2);
-					// manual override for one function name which contains lowercase characters
-				} else if(line.equals("VBAActivate")) {
-					name = line;
-				} else if (id == null || name == null) {
-					throw new IllegalStateException("Found params, but had empty id or name, id: " + id +
-							", name: " + name + ", line: " + line);
-				} else {
-					System.out.println("Found function " + id + " " + name + " " + line);
-					fdc.addFunction(Integer.parseInt(id, 16), false, name, 0, 0,
-							"", "", "");
-
-					id = null;
-					name = null;
-				}
-			}
-		}
-
-		fdc.endTableGroup("");
-	}
-	/**
-	 * To be sure that no tricky unicode chars make it through to the output file.
-	 */
-	private static final class SimpleAsciiOutputStream extends OutputStream {
-
-		private final OutputStream _os;
-
-		public SimpleAsciiOutputStream(OutputStream os) {
-			_os = os;
-		}
-		
-		@Override
+    /**
+     * For simplicity, the output file is strictly simple ASCII.
+     * This method detects any unexpected characters.
+     */
+    /* package */ static boolean isSimpleAscii(char c) {
+
+        if (c>=0x21 && c<=0x7E) {
+            // everything from '!' to '~' (includes letters, digits, punctuation
+            return true;
+        }
+        // some specific whitespace chars below 0x21:
+        switch(c) {
+            case ' ':
+            case '\t':
+            case '\r':
+            case '\n':
+                return true;
+        }
+        return false;
+    }
+
+
+    private static final class FunctionData {
+        // special characters from the ooo document
+        private static final int CHAR_ELLIPSIS_8230 = 8230;
+        private static final int CHAR_NDASH_8211 = 8211;
+
+        private final int _index;
+        private final boolean _hasFootnote;
+        private final String _name;
+        private final int _minParams;
+        private final int _maxParams;
+        private final String _returnClass;
+        private final String _paramClasses;
+        private final boolean _isVolatile;
+
+        public FunctionData(int funcIx, boolean hasFootnote, String funcName, int minParams, int maxParams,
+                    String returnClass, String paramClasses, boolean isVolatile) {
+            _index = funcIx;
+            _hasFootnote = hasFootnote;
+            _name = funcName;
+            _minParams = minParams;
+            _maxParams = maxParams;
+            _returnClass = convertSpecialChars(returnClass);
+            _paramClasses = convertSpecialChars(paramClasses);
+            _isVolatile = isVolatile;
+        }
+        private static String convertSpecialChars(String ss) {
+            StringBuilder sb = new StringBuilder(ss.length() + 4);
+            for(int i=0; i<ss.length(); i++) {
+                char c = ss.charAt(i);
+                if (isSimpleAscii(c)) {
+                    sb.append(c);
+                    continue;
+                }
+                switch (c) {
+                    case CHAR_NDASH_8211:
+                        sb.append('-');
+                        continue;
+                    case CHAR_ELLIPSIS_8230:
+                        sb.append("...");
+                        continue;
+                }
+                throw new RuntimeException("bad char (" + ((int)c) + ") in string '" + ss + "'");
+            }
+            return sb.toString();
+        }
+        public int getIndex() {
+            return _index;
+        }
+        public String getName() {
+            return _name;
+        }
+        public boolean hasFootnote() {
+            return _hasFootnote;
+        }
+        public String formatAsDataLine() {
+            return _index + "\t" + _name + "\t" + _minParams + "\t"
+                    + _maxParams + "\t" + _returnClass + "\t" + _paramClasses
+                    + "\t" + checkMark(_isVolatile) + "\t" + checkMark(_hasFootnote);
+        }
+        private static String checkMark(boolean b) {
+            return b ? "x" : "";
+        }
+    }
+
+    private static final class FunctionDataCollector {
+
+        private final Map<Integer, FunctionData> _allFunctionsByIndex;
+        private final Map<String, FunctionData> _allFunctionsByName;
+        private final Set<Integer> _groupFunctionIndexes;
+        private final Set<String> _groupFunctionNames;
+        private final PrintStream _ps;
+
+        public FunctionDataCollector(PrintStream ps) {
+            _ps = ps;
+            _allFunctionsByIndex = new HashMap<>();
+            _allFunctionsByName = new HashMap<>();
+            _groupFunctionIndexes = new HashSet<>();
+            _groupFunctionNames = new HashSet<>();
+        }
+
+        public void addFunction(int funcIx, boolean hasFootnote, String funcName, int minParams, int maxParams,
+                                String returnClass, String paramClasses, String volatileFlagStr) {
+            boolean isVolatile = volatileFlagStr.length() > 0;
+
+            Integer funcIxKey = Integer.valueOf(funcIx);
+            if(!_groupFunctionIndexes.add(funcIxKey)) {
+                throw new RuntimeException("Duplicate function index (" + funcIx + ")");
+            }
+            if(!_groupFunctionNames.add(funcName)) {
+                throw new RuntimeException("Duplicate function name '" + funcName + "'");
+            }
+
+            checkRedefinedFunction(hasFootnote, funcName, funcIxKey);
+            FunctionData fd = new FunctionData(funcIx, hasFootnote, funcName,
+                    minParams, maxParams, returnClass, paramClasses, isVolatile);
+
+            _allFunctionsByIndex.put(funcIxKey, fd);
+            _allFunctionsByName.put(funcName, fd);
+        }
+
+        /**
+         * Some extra validation here.
+         * Any function which changes definition will have a footnote in the source document
+         */
+        private void checkRedefinedFunction(boolean hasNote, String funcName, Integer funcIxKey) {
+            FunctionData fdPrev;
+            // check by index
+            fdPrev = _allFunctionsByIndex.get(funcIxKey);
+            if(fdPrev != null) {
+                if(!fdPrev.hasFootnote() || !hasNote) {
+                    throw new RuntimeException("changing function ["
+                            + funcIxKey + "] definition without foot-note");
+                }
+                _allFunctionsByName.remove(fdPrev.getName());
+            }
+            // check by name
+            fdPrev = _allFunctionsByName.get(funcName);
+            if(fdPrev != null) {
+                if(!fdPrev.hasFootnote() || !hasNote) {
+                    throw new RuntimeException("changing function '"
+                            + funcName + "' definition without foot-note");
+                }
+                _allFunctionsByIndex.remove(Integer.valueOf(fdPrev.getIndex()));
+            }
+        }
+
+        public void endTableGroup(String headingText) {
+            Integer[] keys = new Integer[_groupFunctionIndexes.size()];
+            _groupFunctionIndexes.toArray(keys);
+            _groupFunctionIndexes.clear();
+            _groupFunctionNames.clear();
+            Arrays.sort(keys);
+
+            _ps.println("# " + headingText);
+            for (Integer key : keys) {
+                FunctionData fd = _allFunctionsByIndex.get(key);
+                _ps.println(fd.formatAsDataLine());
+            }
+        }
+    }
+
+    private static final Pattern ID_MATCH = Pattern.compile("0x([\\dA-F]+)");
+    private static final Pattern NAME_MATCH = Pattern.compile("([0-9A-Z.]+)");
+    private static final Pattern ID_NAME_MATCH = Pattern.compile("0x([\\dA-F]+)\\s+([0-9A-Z.]+)");
+
+    private static final Set<String> IGNORED_LINES = new HashSet<>();
+    static {
+        IGNORED_LINES.add("[MS-XLS] — v20141018");
+        IGNORED_LINES.add("Excel Binary File Format (.xls) Structure");
+        IGNORED_LINES.add("Copyright © 2014 Microsoft Corporation.");
+        IGNORED_LINES.add("Release: October 30, 2014Value Meaning");
+        IGNORED_LINES.add("Release: October 30, 2014Value");
+        IGNORED_LINES.add("Meaning");
+    }
+
+    private static void extractFunctionData(FunctionDataCollector fdc, InputStream is) throws IOException {
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
+
+            String id = null;
+            String name = null;
+            while (true) {
+                String line = reader.readLine();
+                if(line == null) {
+                    break;
+                }
+
+                if(IGNORED_LINES.contains(line) || line.matches("\\d+ / \\d+")) {
+                    continue;
+                }
+
+                Matcher idMatcher = ID_MATCH.matcher(line);
+                boolean foundID = idMatcher.matches();
+                Matcher nameMatcher = NAME_MATCH.matcher(line);
+                boolean foundName = nameMatcher.matches();
+                Matcher idAndNameMatcher = ID_NAME_MATCH.matcher(line);
+                boolean foundIDandName = idAndNameMatcher.matches();
+                if(foundID && foundName ||
+                        foundName && foundIDandName ||
+                        foundID && foundIDandName) {
+                    throw new IllegalStateException("Should not find id and name: " +
+                            foundID + "/" + foundName + "/" + foundIDandName +
+                            ", line: " + line);
+                }
+
+                if(foundID && id != null) {
+                    throw new IllegalStateException("Found ID, but already had one: " + id + ", line: " + line);
+                }
+                if(foundName && name != null) {
+                    throw new IllegalStateException("Found name, but already had one: " + name + ", line: " + line);
+                }
+                if(foundIDandName && (name != null || id != null)) {
+                    throw new IllegalStateException("Found name and id, but already had one: id: " + id + ", name: " + name + ", line: " + line);
+                }
+
+                if(foundID) {
+                    id = idMatcher.group(1);
+                } else if (foundName) {
+                    name = nameMatcher.group(1);
+                } else if (foundIDandName) {
+                    id = idAndNameMatcher.group(1);
+                    name = idAndNameMatcher.group(2);
+                    // manual override for one function name which contains lowercase characters
+                } else if(line.equals("VBAActivate")) {
+                    name = line;
+                } else if (id == null || name == null) {
+                    throw new IllegalStateException("Found params, but had empty id or name, id: " + id +
+                            ", name: " + name + ", line: " + line);
+                } else {
+                    System.out.println("Found function " + id + " " + name + " " + line);
+                    fdc.addFunction(Integer.parseInt(id, 16), false, name, 0, 0,
+                            "", "", "");
+
+                    id = null;
+                    name = null;
+                }
+            }
+        }
+
+        fdc.endTableGroup("");
+    }
+    /**
+     * To be sure that no tricky unicode chars make it through to the output file.
+     */
+    private static final class SimpleAsciiOutputStream extends OutputStream {
+
+        private final OutputStream _os;
+
+        public SimpleAsciiOutputStream(OutputStream os) {
+            _os = os;
+        }
+        
+        @Override
         public void write(int b) throws IOException {
-			checkByte(b);
-			_os.write(b);
-		}
-
-		private static void checkByte(int b) {
-			if (!isSimpleAscii((char)b)) {
-				throw new RuntimeException("Encountered char (" + b + ") which was not simple ascii as expected");
-			}
-		}
+            checkByte(b);
+            _os.write(b);
+        }
+
+        private static void checkByte(int b) {
+            if (!isSimpleAscii((char)b)) {
+                throw new RuntimeException("Encountered char (" + b + ") which was not simple ascii as expected");
+            }
+        }
 
-		@Override
+        @Override
         public void write(byte[] b, int off, int len) throws IOException {
-			for (int i = 0; i < len; i++) {
-				checkByte(b[i + off]);
+            for (int i = 0; i < len; i++) {
+                checkByte(b[i + off]);
 
-			}
-			_os.write(b, off, len);
-		}
-	}
-
-	private static void processFile(InputStream input, File outFile) throws IOException {
-		try (OutputStream os = new SimpleAsciiOutputStream(new FileOutputStream(outFile));
-		PrintStream ps = new PrintStream(os, true, "UTF-8")) {
-
-			outputLicenseHeader(ps);
-			Class<?> genClass = ExcelCetabFunctionExtractor.class;
-			ps.println("# Created by (" + genClass.getName() + ")");
-			// identify the source file
-			ps.println("# from source file '" + SOURCE_DOC_FILE_NAME + "'");
-			ps.println("#");
-			ps.println("#Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote )");
-			ps.println();
-			extractFunctionData(new FunctionDataCollector(ps), input);
-			ps.close();
-
-			String canonicalOutputFileName = outFile.getCanonicalPath();
-			System.out.println("Successfully output to '" + canonicalOutputFileName + "'");
-		}
-	}
-
-	private static void outputLicenseHeader(PrintStream ps) {
-		String[] lines= {
-			"Licensed to the Apache Software Foundation (ASF) under one or more",
-			"contributor license agreements.  See the NOTICE file distributed with",
-			"this work for additional information regarding copyright ownership.",
-			"The ASF licenses this file to You under the Apache License, Version 2.0",
-			"(the \"License\"); you may not use this file except in compliance with",
-			"the License.  You may obtain a copy of the License at",
-			"",
-			"    http://www.apache.org/licenses/LICENSE-2.0",
-			"",
-			"Unless required by applicable law or agreed to in writing, software",
-			"distributed under the License is distributed on an \"AS IS\" BASIS,",
-			"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.",
-			"See the License for the specific language governing permissions and",
-			"limitations under the License.",
-		};
-		for (String line : lines) {
-			ps.print("# ");
-			ps.println(line);
-		}
-		ps.println();
-	}
-
-	public static void main(String[] args) throws IOException {
-		if(!new File(SOURCE_DOC_FILE_NAME).exists()) {
-			throw new IllegalStateException("Did not find file " + SOURCE_DOC_FILE_NAME + " in the resources");
-		}
-
-		try (InputStream stream = new FileInputStream(SOURCE_DOC_FILE_NAME)) {
-			File outFile = new File("functionMetadataCetab.txt");
-
-			processFile(stream, outFile);
-		}
-	}
+            }
+            _os.write(b, off, len);
+        }
+    }
+
+    private static void processFile(InputStream input, File outFile) throws IOException {
+        try (OutputStream os = new SimpleAsciiOutputStream(new FileOutputStream(outFile));
+        PrintStream ps = new PrintStream(os, true, "UTF-8")) {
+
+            outputLicenseHeader(ps);
+            Class<?> genClass = ExcelCetabFunctionExtractor.class;
+            ps.println("# Created by (" + genClass.getName() + ")");
+            // identify the source file
+            ps.println("# from source file '" + SOURCE_DOC_FILE_NAME + "'");
+            ps.println("#");
+            ps.println("#Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote )");
+            ps.println();
+            extractFunctionData(new FunctionDataCollector(ps), input);
+            ps.close();
+
+            String canonicalOutputFileName = outFile.getCanonicalPath();
+            System.out.println("Successfully output to '" + canonicalOutputFileName + "'");
+        }
+    }
+
+    private static void outputLicenseHeader(PrintStream ps) {
+        String[] lines= {
+            "Licensed to the Apache Software Foundation (ASF) under one or more",
+            "contributor license agreements.  See the NOTICE file distributed with",
+            "this work for additional information regarding copyright ownership.",
+            "The ASF licenses this file to You under the Apache License, Version 2.0",
+            "(the \"License\"); you may not use this file except in compliance with",
+            "the License.  You may obtain a copy of the License at",
+            "",
+            "    http://www.apache.org/licenses/LICENSE-2.0",
+            "",
+            "Unless required by applicable law or agreed to in writing, software",
+            "distributed under the License is distributed on an \"AS IS\" BASIS,",
+            "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.",
+            "See the License for the specific language governing permissions and",
+            "limitations under the License.",
+        };
+        for (String line : lines) {
+            ps.print("# ");
+            ps.println(line);
+        }
+        ps.println();
+    }
+
+    public static void main(String[] args) throws IOException {
+        if(!new File(SOURCE_DOC_FILE_NAME).exists()) {
+            throw new IllegalStateException("Did not find file " + SOURCE_DOC_FILE_NAME + " in the resources");
+        }
+
+        try (InputStream stream = new FileInputStream(SOURCE_DOC_FILE_NAME)) {
+            File outFile = new File("functionMetadataCetab.txt");
+
+            processFile(stream, outFile);
+        }
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org