This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch openformula in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit 950b9feb2bb63eaf24eb92076981c0c0ce6bc9b2 Author: Pedro Giffuni <[email protected]> AuthorDate: Wed Nov 11 14:05:11 2026 -0500 sc: audit ODF 1.4 Small Group requirements Produces an authoritative, source-grounded inventory of the ODF 1.4 Part 4 Small Group Formula Evaluator requirements (§2.3.2) and audits Apache OpenOffice Calc against each requirement. New files: - openformula-small-group-1.4.tsv: Machine-readable requirements inventory covering Basic Limits (§3.7, 4 items), Syntax (§5, 11 items), Implicit Conversions (§6.3, 5 items), Operators (§6.4, 14 items), Required Functions (§2.3.2.E, 110 functions), and Explicit Allowances (§2.3.2.F/G, 4 items). - openformula-small-group-audit.md: Audit report with methodology, findings per requirement category, source references with file:line, summary counts, known semantic differences, runtime-verification limitations, and prioritized candidate gaps. Updated files: - openformula-functions.tsv: IFNA and SKEWP status changed from MISSING to IMPLEMENTED (Milestone B added opcodes 409/410, implementations, dispatch, metadata). - openformula-conformance.md: Removed IFNA/SKEWP from missing functions list; marked CONVERT atm and INDEX row-vector as fixed in Milestones C/A. - openformula-test-gap-analysis.md: Removed IFNA/SKEWP from missing function tests; updated gap summary. - openformula-modernization-plan.md: Moved IFNA/SKEWP/CONVERT to completed work; new P1 focuses on Small Group semantic conformance. Key findings: - All 110 Small Group functions are implemented (opcodes, dispatch, metadata) - 0 missing functions, 0 partial implementations - AOO claims NO Part 4 conformance group (per IMPLEMENTATION-DEFINED:134) - Runtime verification deferred (no configured AOO build tree) - No production code changes in this milestone Static validation: TSV column counts (7 columns, 0 issues), no duplicate ReqIDs, no duplicate function names, IFNA/SKEWP no longer reported as MISSING. --- openformula-conformance.md | 42 +++--- openformula-functions.tsv | 4 +- openformula-modernization-plan.md | 74 ++++----- openformula-small-group-1.4.tsv | 149 +++++++++++++++++++ openformula-small-group-audit.md | 305 ++++++++++++++++++++++++++++++++++++++ openformula-test-gap-analysis.md | 16 +- 6 files changed, 518 insertions(+), 72 deletions(-) diff --git a/openformula-conformance.md b/openformula-conformance.md index 6f541bfc57..9bb04e8b72 100644 --- a/openformula-conformance.md +++ b/openformula-conformance.md @@ -9,41 +9,43 @@ Source-of-truth: AOO source (main/sc) and `odf_docs/ODF14-IMPLEMENTATION-DEFINED Therefore **no conformance level (Small/Medium/Large) may be claimed for AOO Calc.** This audit reports implementation coverage only; it does not certify conformance. -## 2. Coverage of mandatory functions by group (based on function inventory) +## 2. Coverage of mandatory functions by group -The ODF 1.2 function baseline (used by AOO's own `test/aoo-test/data/openformula-functions.txt` and `test/odf-validate/openformula-functions.txt`, titled "OpenDocument 1.2 Part 2 chapter 6") lists 414 function names. AOO's opcode map (`main/formula/inc/formula/compiler.hrc`, last opcode id 408) covers all of those except two that appear only as Excel-filter `ocNoName` stubs: +The ODF 1.2 function baseline (used by AOO's own `test/aoo-test/data/openformula-functions.txt` and `test/odf-validate/openformula-functions.txt`, titled "OpenDocument 1.2 Part 2 chapter 6") lists 414 function names. AOO's opcode map (`main/formula/inc/formula/compiler.hrc`, last opcode id 410 = SKEWP) covers all of those. IFNA (opcode 409) and SKEWP (opcode 410) were implemented in Milestone B and are no longer missing. -| Function | Status | Evidence | -|----------|--------|----------| -| IFNA | MISSING | No opcode (compiler.hrc max = 408 = BITRSHIFT), no `ScIfNA`, no `scfuncs.src` entry, no `core_resource.src` entry. Only `main/sc/source/filter/excel/xlformula.cxx:404` `EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "IFNA" )`. | -| SKEWP | MISSING | No opcode, no `ScSkewP`, no `scfuncs.src`/`core_resource.src` entry. Only `xlformula.cxx:415` `EXC_FUNCENTRY_ODF( ocNoName, 1, MX, 0, "SKEWP" )`. `SKEW` (sample skewness, `SC_OPCODE_SCHIEFE=325`) is present. | +All 414 baseline functions have opcodes, implementations in `interpr*.cxx`, `scfuncs.src` metadata, and `core_resource.src` name mappings (see `openformula-functions.tsv`). -All other ODF 1.2 baseline functions have opcodes, implementations in `interpr*.cxx`, `scfuncs.src` metadata, and `core_resource.src` name mappings (see `openformula-functions.tsv`). +**[CONFIRMED] IFNA and SKEWP are now implemented (Milestone B).** +- IFNA: `SC_OPCODE_IFNA=409` in `compiler.hrc`, `ocIfna` in `opcode.hxx`, `ScInterpreter::ScIfna()` in `interpr1.cxx:392`, dispatch `case ocIfna` in `interpr4.cxx:3451`, `scfuncs.src:1027`, `core_resource.src:357`. +- SKEWP: `SC_OPCODE_SKEWP=410` in `compiler.hrc`, `ocSkewP` in `opcode.hxx`, `ScInterpreter::ScSkewP()` in `interpr3.cxx`, dispatch `case ocSkewP` in `interpr4.cxx:3695`, `scfuncs.src:5300`, `core_resource.src:358`. **[UNVERIFIED]** Whether every mandatory function in each conformance group (Small/Medium/Large) is semantically correct per ODF 1.4. Presence of an opcode does not imply correct semantics (per audit mandate). ## 3. Small Group -**[UNVERIFIED]** Cannot certify Small Group. AOO does not claim it. Coverage indicators: -- Core IS*/logical/text/math/date/financial functions largely present (opcodes exist). -- Confirmed missing from baseline: IFNA, SKEWP (both are ODF 1.3+, likely Medium/Large or optional depending on the group definitions in ODF 1.4 Part 4). -- Operators present (range, intersection, union, arithmetic, comparison, logical, concatenation, percent). +AOO does not claim the Small Group. However, the Small Group audit (`openformula-small-group-audit.md`) found that all 110 required Small Group functions (§2.3.2.E) are implemented with opcodes, dispatch, and metadata. Coverage indicators: + +- Core IS*/logical/text/math/date/financial functions present and implemented (Milestone B added IFNA/SKEWP, though neither is Small Group). +- All Small Group operators present (range, intersection, arithmetic, comparison, logical, concatenation, percent). +- No Small Group functions are missing. +- **[UNVERIFIED]** Semantic correctness per ODF 1.4 not runtime-tested; see `openformula-small-group-audit.md` for details. ## 4. Medium Group -**[UNVERIFIED]** Cannot certify Medium Group. Coverage indicators: +**[UNVERIFIED]** Cannot certify Medium Group. AOO does not claim it. Coverage indicators: - Array functions (MMULT, MDETERM, MINVERSE, TRANSPOSE, MUNIT, SUMPRODUCT) present. - Statistical/distribution functions present. - Lookup/reference functions (VLOOKUP, HLOOKUP, INDEX, MATCH, OFFSET, INDIRECT) present. -- IFNA and SKEWP missing (may be Medium-group mandatory in ODF 1.4). +- SKEWP implemented in Milestone B (`SC_OPCODE_SKEWP=410`, `ScSkewP` in `interpr3.cxx`) — SKEWP is a Medium Group function (§2.3.3 Medium Group), not Small Group. ## 5. Large Group -**[UNVERIFIED]** Cannot certify Large Group. Coverage indicators: +**[UNVERIFIED]** Cannot certify Large Group. AOO does not claim it. Coverage indicators: - Financial functions (PV, FV, PMT, NPER, RATE, IPMT, PPMT, NPV, IRR, MIRR, etc.) present. - Engineering/bitwise (BITAND/BITOR/BITXOR/BITLSHIFT/BITRSHIFT) present. - Complex-number (IM*) functions present. - Database (D*) functions present. +- IFNA implemented in Milestone B (`SC_OPCODE_IFNA=409`, `ScIfna` in `interpr1.cxx`) — IFNA is a Large Group function (§2.3.4 Large Group), not Small Group. ## 6. Unsupported optional capabilities vs actual failures @@ -52,18 +54,18 @@ All other ODF 1.2 baseline functions have opcodes, implementations in `interpr*. | Item | AOO behavior | ODF 1.4 status | Source | |------|-------------|----------------|--------| | DATE pre-1583 | #VALUE! before 15 Oct 1582 | impl-defined (§7.4) | IMPLEMENTATION-DEFINED:155; KNOWN-LIMITATIONS:74 | -| CONVERT atm | 101324.996583 Pa | ODF 1.4 table = 1.0132510E+5 | KNOWN-LIMITATIONS:72 | -| INDEX row-vector single-arg | returns column | ODF 1.4: error | KNOWN-LIMITATIONS:71 | +| CONVERT atm | Fixed: 101325.1 Pa | Matches ODF 1.4 table | Fixed in Milestone C; KNOWN-LIMITATIONS:72 | +| INDEX row-vector single-arg | Fixed: error per ODF 1.4 | Error (ODF 1.4 removed rule) | Fixed in Milestone A; KNOWN-LIMITATIONS:71 | | Trailing empty param (`NPER(;;)`) | error except IF | ODF 1.4 rule | KNOWN-LIMITATIONS:73 | | Error cells on save | written as `office:value-type="string"` | ODF 1.4 adds `error` type (no `office:error` attr) | KNOWN-LIMITATIONS producer:2 | ## 7. Conformance conclusion - **Claimed conformance group: none.** AOO does not claim Small/Medium/Large. -- **Confirmed missing mandatory-candidate functions:** IFNA, SKEWP. -- **Confirmed semantic discrepancies vs ODF 1.4:** CONVERT `atm` (1e-6 relative), INDEX row-vector rule, EASTERSUNDAY naming alias (behavior correct). -- **Cannot certify any group** without checking every mandatory requirement against the ODF 1.4 Part 4 normative text, which was not available in full for this audit. +- **Confirmed missing functions: none.** All 110 Small Group functions (§2.3.2.E) are implemented. IFNA (Large Group) and SKEWP (Medium Group) were implemented in Milestone B. +- **Confirmed semantic discrepancies vs ODF 1.4:** INDEX row-vector rule (corrected in Milestone A), CONVERT `atm` (corrected in Milestone C), EASTERSUNDAY naming alias (behavior correct). +- **Cannot certify any group** without runtime testing every mandatory requirement against the ODF 1.4 Part 4 normative text. ## 8. Recommended next step for conformance -Obtain ODF 1.4 Part 4, enumerate the mandatory function/operator set per group, and execute each against AOO with expected results. Until then, report only coverage (see `openformula-functions.tsv`) and discrepancies (see `openformula-semantics.md`, `openformula-odf13-14-diff.md`). +Runtime-test all 110 Small Group functions against ODF 1.4 Part 4 expected results. Prioritize: COUNTA/COUNTBLANK empty-cell semantics (ODF 1.4 changed), DATE pre-1583 proleptic Gregorian, and INDEX row-vector regression risk. Until runtime verification is complete, report only coverage (see `openformula-small-group-1.4.tsv` and `openformula-small-group-audit.md`) and discrepancies (see `openformula-semantics.md`, `openformula-odf13-14-diff.md`). diff --git a/openformula-functions.tsv b/openformula-functions.tsv index dd4203fa6a..8fb266c9df 100644 --- a/openformula-functions.tsv +++ b/openformula-functions.tsv @@ -323,5 +323,5 @@ BITOR BITOR ODF 1.2 ocBitOr 405 interpr1.cxx:ScBitOr compiler.cxx core_resource. BITXOR BITXOR ODF 1.2 ocBitXor 406 interpr1.cxx:ScBitXor compiler.cxx core_resource.src:354 FULL Exactly 2 params enforced; ODF 1.4 semantics verify. BITLSHIFT BITLSHIFT ODF 1.2 ocBitLShift 407 interpr1.cxx:ScBitLShift compiler.cxx core_resource.src:355 FULL Negative shift handling inverted in interpr1.cxx:1231-1234 (verify vs ODF 1.4). BITRSHIFT BITRSHIFT ODF 1.2 ocBitRShift 408 interpr1.cxx:ScBitRShift compiler.cxx core_resource.src:356 FULL Negative shift handling inverted in interpr1.cxx:1231-1234 (verify vs ODF 1.4). -IFNA IFNA ODF 1.3 (none) (none) absent xlformula.cxx:404 (ocNoName) absent MISSING No opcode, no ScIfNA, no scfuncs entry; only Excel-filter ocNoName stub. -SKEWP SKEWP ODF 1.3 (none) (none) absent xlformula.cxx:415 (ocNoName) absent MISSING No opcode, no ScSkewP, no scfuncs entry; only Excel-filter ocNoName stub. SKEW (sample) present. +IFNA IFNA ODF 1.3 ocIfna 409 main/sc/source/core/tool/interpr1.cxx:ScIfna main/formula/source/core/api/FormulaCompiler.cxx:ocIfna main/formula/source/core/resource/core_resource.src:357 / main/sc/source/ui/src/scfuncs.src:1027 IMPLEMENTED Implemented Milestone B; ODF 1.3/1.4 §6.15.6; Large Group only, not Small Group; Excel-filter stub replaced with real opcode at xlformula.cxx. +SKEWP SKEWP ODF 1.3 ocSkewP 410 main/sc/source/core/tool/interpr3.cxx:ScSkewP main/formula/source/core/api/FormulaCompiler.cxx:ocSkewP main/formula/source/core/resource/core_resource.src:358 / main/sc/source/ui/src/scfuncs.src:5300 IMPLEMENTED Implemented Milestone B; ODF 1.3/1.4 §6.18.68; Medium Group, not Small Group; Excel-filter stub replaced with real opcode at xlformula.cxx. diff --git a/openformula-modernization-plan.md b/openformula-modernization-plan.md index 7ea96988f7..0837cad8db 100644 --- a/openformula-modernization-plan.md +++ b/openformula-modernization-plan.md @@ -8,37 +8,32 @@ Source-of-truth: `openformula-functions.tsv`, `openformula-operators.tsv`, `open ### P1 — Interoperability-critical missing functions -**P1.1 IFNA (ODF 1.3, §6.x)** -- Gap: No opcode, no implementation, no `scfuncs.src`, no `core_resource.src` entry. Only Excel-filter `ocNoName` stub (`xlformula.cxx:404`). -- Work: Add opcode `SC_OPCODE_IFNA` to `compiler.hrc`/`opcode.hxx`; map name "IFNA" in `core_resource.src`; implement `ScInterpreter::ScIfNA` in `interpr1.cxx`/`interpr4.cxx` dispatch; add `scfuncs.src` metadata; add to ODF export symbol map. -- Depends on: opcode value allocation (next free after 408; note `SC_OPCODE_LAST_OPCODE_ID=408`, `SC_OPCODE_DATA_TOKEN_1=10000`). -- Files: `main/formula/inc/formula/compiler.hrc`, `main/formula/inc/formula/opcode.hxx`, `main/formula/source/core/resource/core_resource.src`, `main/sc/source/core/tool/interpr1.cxx`, `main/sc/source/core/tool/interpr4.cxx`, `main/sc/inc/interpre.hxx`, `main/sc/source/ui/src/scfuncs.src`. -- Interoperability impact: High — IFNA is widely used and ODF 1.3/1.4 standard. - -**P1.2 SKEWP (ODF 1.3, population skewness)** -- Gap: No opcode/implementation/metadata. Only Excel-filter stub (`xlformula.cxx:415`). `SKEW` (sample, `SC_OPCODE_SCHIEFE=325`) present. -- Work: Add opcode `SC_OPCODE_SKEWP`; map "SKEWP"; implement `ScSkewP` (population skewness, distinct from sample `ScSkew`); dispatch; metadata. -- Depends on: opcode value allocation; `CalculateSkew` helper (`interpr5.cxx:712`) may be reusable. -- Files: same as IFNA plus `interpr5.cxx`. -- Interoperability impact: High — statistical interop. +**P1.1 IFNA (ODF 1.3, Large Group)** — Implemented in Milestone B. +- `SC_OPCODE_IFNA=409`, `ScIfna()` in `interpr1.cxx`, dispatch in `interpr4.cxx:3451`, `scfuncs.src`, `core_resource.src:357`, `xlformula.cxx` stub replaced. +- Status: Complete. + +**P1.2 SKEWP (ODF 1.3, Medium Group)** — Implemented in Milestone B. +- `SC_OPCODE_SKEWP=410`, `ScSkewP()` in `interpr3.cxx`, dispatch in `interpr4.cxx:3695`, `scfuncs.src`, `core_resource.src:358`, `xlformula.cxx` stub replaced. +- Status: Complete. ### P2 — Semantic discrepancies vs ODF 1.4 -**P2.1 CONVERT `atm` unit value (Low severity, high visibility)** -- Gap: AOO uses 101324.996583 Pa; ODF 1.4 table = 1.0132510E+5 Pa (relative 1e-6) (`odf_docs/ODF14-KNOWN-LIMITATIONS-PUBLIC.md:72`). -- Work: Update CONVERT unit table in `ScConvert` (`interpr2.cxx`) to ODF 1.4 values; verify all affected units. -- Files: `main/sc/source/core/tool/interpr2.cxx` (ScConvert), unit data source. +**P2.1 CONVERT `atm` unit value** — Corrected in Milestone C. +- `atm` changed from 101324.996583 Pa to 101325.1 Pa per ODF 1.4 Table 24. +- Files: `main/scaddins/source/analysis/analysishelper.cxx`. +- Status: Complete. -**P2.2 INDEX row-vector single-argument (High severity)** -- Gap: AOO returns the column (legacy); ODF 1.4 removed that rule → error (`KNOWN-LIMITATIONS:71`). -- Work: Change `ScIndex` (`interpr1.cxx:ScIndex`) to return error when called with only a row argument on a row vector per ODF 1.4. -- Regression risk: High — existing documents/workbooks may rely on legacy column-return behavior; needs a compatibility option or version-gated behavior. -- Files: `main/sc/source/core/tool/interpr1.cxx`. +**P2.2 INDEX row-vector single-argument** — Fixed in Milestone A. +- AOO previously returned column (legacy); ODF 1.4 requires error for single-arg row vector. +- Work: Regression-test against existing document corpus; consider compatibility option if needed. +- Files: `main/sc/source/core/tool/interpr1.cxx` (ScIndex). +- Status: Implemented; regression risk documented. **P2.3 BITAND/BITOR/BITXOR variadic & BITLSHIFT/BITRSHIFT negative shift** -- Gap: `ScBitArithmeticOps` enforces exactly 2 params (`interpr1.cxx:1180`); ODF 1.4 may allow 1+. `ScBitShiftOps` inverts shift direction for negative `n` (`interpr1.cxx:1231-1234`). -- Work: Verify ODF 1.4 parameter count; relax or document; fix shift direction or reject negative shift per spec. +- Gap: `ScBitArithmeticOps` enforces exactly 2 params (`interpr1.cxx:1180`); `ScBitShiftOps` handles negative shift counts. +- Work: Verify ODF 1.4 parameter count; confirm shift direction correctness. - Files: `main/sc/source/core/tool/interpr1.cxx`. +- Status: UNVERIFIED — requires ODF 1.4 Part 4 spec text review. ### P3 — Metadata / naming alignment @@ -58,7 +53,7 @@ Source-of-truth: `openformula-functions.tsv`, `openformula-operators.tsv`, `open - Files: `test/odf-validate/`, `test/odf-validate/formulacheck.py`. **P4.2 Semantic and parser test cases** -- Add calcval cases for CONVERT atm, INDEX row-vector, DATE pre-1583, BIT ops, short-circuit AND/OR, operator precedence. +- Add calcval cases for COUNTA empty cells, DATE pre-1583, INDEX row-vector regression, BIT ops, short-circuit AND/OR, operator precedence. - Do NOT add to normal production build (per audit constraint). **P4.3 Round-trip tests** @@ -66,22 +61,16 @@ Source-of-truth: `openformula-functions.tsv`, `openformula-operators.tsv`, `open ## 2. Dependencies between proposed changes -1. Opcode value allocation (`SC_OPCODE_LAST_OPCODE_ID`/`SC_OPCODE_DATA_TOKEN_1`) must be done once before adding IFNA and SKEWP opcodes — do both in the same opcode-block change. -2. `core_resource.src` name mapping must be added for IFNA/SKEWP before compiler recognition works. -3. `scfuncs.src` metadata depends on opcode existing. -4. INDEX behavior change (P2.2) should be coordinated with any document-compatibility option; test against existing corpus before enabling. -5. Test inventories (P4) depend on having the ODF 1.4 function list extracted; do P4.1 before P4.2/P4.3. +1. COUNTA/COUNTBLANK change should be coordinated with any document-compatibility option; test against existing corpus before enabling. +2. Test inventories depend on having the ODF 1.4 function list extracted; do P3.1 before P3.2/P3.3. ## 3. Estimated implementation complexity | Item | Complexity | Rationale | |------|------------|-----------| -| IFNA | Low-Medium | Simple 2-arg function; follows IFERROR pattern; opcode+metadata boilerplate. | -| SKEWP | Medium | Statistical computation; reuse `CalculateSkew`/`GetSortArray` helpers; population vs sample distinction. | -| CONVERT atm | Low | Single constant change in unit table; regression test all units. | -| INDEX row-vector | Medium | Behavior change; regression risk high; needs corpus testing / compat option. | -| BIT ops variadic/negative shift | Low-Medium | Small logic change; verify spec parameter count. | -| Naming/export alignment | Medium | Multiple symbol-map entry points; strict vs extended mode handling. | +| COUNTA/COUNTBLANK empty-cell semantics | Medium | Behavior change; regression risk medium; needs corpus testing. | +| DATE pre-1583 documentation | Low | Document existing impl-defined behavior; no code change needed. | +| INDEX row-vector regression testing | Medium | Corpus regression run; may need compatibility option. | | Test inventories | Medium | Requires ODF 1.4 Part 4 text extraction; tooling exists (formulacheck.py). | | Semantic/parser/round-trip tests | Medium-High | Many cases; runtime validation needed. | @@ -89,10 +78,8 @@ Source-of-truth: `openformula-functions.tsv`, `openformula-operators.tsv`, `open | Risk | Area | Mitigation | |------|------|------------| -| Existing documents rely on INDEX column-return legacy | INDEX (P2.2) | Version-gate or document-compatibility option; corpus regression run. | -| Changing CONVERT `atm` alters results | CONVERT | Verify tolerance; document 1e-6 change; spot-check conversions. | -| Adding IFNA/SKEWP opcodes shifts opcode space | Global opcode map | Allocate contiguous values; update `SC_OPCODE_LAST_OPCODE_ID`; rebuild all symbol maps. | -| BIT op behavior change | BITAND/.../BITRSHIFT | Confirm ODF 1.4 parameter-count rule before relaxing; negative-shift fix may change results for inputs that previously "worked". | +| Existing documents rely on INDEX column-return legacy | INDEX (Milestone A) | Version-gate or document-compatibility option; corpus regression run. | +| Changing COUNTA empty-cell semantics alters results | COUNTA/COUNTBLANK | Verify tolerance; document change; spot-check against existing documents. | | Export name changes break round-trip with older AOO | Symbol map | Keep legacy aliases as read-only (already done for EASTERSUNDAY); write standard names only in strict 1.4. | ## 5. What must NOT change (per audit constraints) @@ -102,9 +89,10 @@ Source-of-truth: `openformula-functions.tsv`, `openformula-operators.tsv`, `open - No third-party formula engines. - Existing Calc functionality and legacy formula compatibility preserved. -## 6. Definition of done for P1/P2 +## 6. Definition of done for P1 -- IFNA and SKEWP: opcode, implementation, dispatch, `scfuncs.src`, `core_resource.src` mapping; smoke-tested against known expected results. -- CONVERT `atm` matches ODF 1.4 table; INDEX row-vector behaves per ODF 1.4 (with compat path if retained); BIT ops verified. +- COUNTA/COUNTBLANK: verified against ODF 1.4 §6.13.7/§6.13.8; documented any semantic differences. +- DATE pre-1583: documented impl-defined behavior per ODF 1.4 §7.4. +- INDEX row-vector: regression-tested against document corpus. - Versioned test inventories created (not in production build). - All findings documented with file:line references (this audit's deliverables). diff --git a/openformula-small-group-1.4.tsv b/openformula-small-group-1.4.tsv new file mode 100644 index 0000000000..25a1c0a67f --- /dev/null +++ b/openformula-small-group-1.4.tsv @@ -0,0 +1,149 @@ +ReqID Section Requirement Description Mandatory/Optional Conformance Group ODF Version Introduced/Changed Suggested Test +SG-BL-001 3.7 Formula length: at least 1024 characters long as measured in OpenDocument interchange format Mandatory Small ODF 1.4 Parse a 1024+ character formula; verify accepted. +SG-BL-002 3.7 At least 30 parameters per function when prototype permits parameter list Mandatory Small ODF 1.4 Call function with 30 parameters; verify accepted. +SG-BL-003 3.7 Permit strings of ASCII characters up to 32767 (2^15-1) characters Mandatory Small ODF 1.4 Parse/return 32767-character string; verify accepted. +SG-BL-004 3.7 Support at least 7 nesting levels of functions Mandatory Small ODF 1.4 Nest 7 levels of functions; verify accepted. +SG-FN-001 6.16.2 ABS Mandatory Small ODF 1.2 Evaluate ABS(-3); verify 3. +SG-FN-002 6.16.3 ACOS Mandatory Small ODF 1.2 Evaluate ACOS(0); verify pi/2. +SG-FN-003 6.15.2 AND Mandatory Small ODF 1.2 Evaluate AND(TRUE,TRUE); verify TRUE. +SG-FN-004 6.16.7 ASIN Mandatory Small ODF 1.2 Evaluate ASIN(0); verify 0. +SG-FN-005 6.16.9 ATAN Mandatory Small ODF 1.2 Evaluate ATAN(0); verify 0. +SG-FN-006 6.16.10 ATAN2 Mandatory Small ODF 1.2 Evaluate ATAN2(1,1); verify pi/4. +SG-FN-007 6.18.3 AVERAGE Mandatory Small ODF 1.2 Evaluate AVERAGE(1,2,3); verify 2. +SG-FN-008 6.18.5 AVERAGEIF Mandatory Small ODF 1.2 Evaluate AVERAGEIF(range,criteria); verify average. +SG-FN-009 6.14.3 CHOOSE Mandatory Small ODF 1.2 Evaluate CHOOSE(2,"a","b","c"); verify "b". +SG-FN-010 6.13.5 COLUMNS Mandatory Small ODF 1.2 Evaluate COLUMNS(A1:C1); verify 3. +SG-FN-011 6.16.19 COS Mandatory Small ODF 1.2 Evaluate COS(0); verify 1. +SG-FN-012 6.13.6 COUNT Mandatory Small ODF 1.2 Evaluate COUNT(1,2,"x"); verify 2. +SG-FN-013 6.13.7 COUNTA Mandatory Small ODF 1.2 Evaluate COUNTA(1,"x",""); verify non-empty count. +SG-FN-014 6.13.8 COUNTBLANK Mandatory Small ODF 1.2 Evaluate COUNTBLANK(range); verify blank count. +SG-FN-015 6.13.9 COUNTIF Mandatory Small ODF 1.2 Evaluate COUNTIF(range,criteria); verify count. +SG-FN-016 6.10.2 DATE Mandatory Small ODF 1.2 Evaluate DATE(2025,1,1); verify serial. +SG-FN-017 6.9.2 DAVERAGE Mandatory Small ODF 1.2 Evaluate DAVERAGE(database,field,criteria); verify average. +SG-FN-018 6.10.5 DAY Mandatory Small ODF 1.2 Evaluate DAY(DATE(2025,3,15)); verify 15. +SG-FN-019 6.9.3 DCOUNT Mandatory Small ODF 1.2 Evaluate DCOUNT(database,field,criteria); verify count. +SG-FN-020 6.9.4 DCOUNTA Mandatory Small ODF 1.2 Evaluate DCOUNTA(database,field,criteria); verify count. +SG-FN-021 6.12.14 DDB Mandatory Small ODF 1.2 Evaluate DDB(cost,salvage,life,period); verify depreciation. +SG-FN-022 6.16.25 DEGREES Mandatory Small ODF 1.2 Evaluate DEGREES(PI()); verify 180. +SG-FN-023 6.9.5 DGET Mandatory Small ODF 1.2 Evaluate DGET(database,field,criteria); verify value. +SG-FN-024 6.9.6 DMAX Mandatory Small ODF 1.2 Evaluate DMAX(database,field,criteria); verify max. +SG-FN-025 6.9.7 DMIN Mandatory Small ODF 1.2 Evaluate DMIN(database,field,criteria); verify min. +SG-FN-026 6.9.8 DPRODUCT Mandatory Small ODF 1.2 Evaluate DPRODUCT(database,field,criteria); verify product. +SG-FN-027 6.9.9 DSTDEV Mandatory Small ODF 1.2 Evaluate DSTDEV(database,field,criteria); verify stddev. +SG-FN-028 6.9.10 DSTDEVP Mandatory Small ODF 1.2 Evaluate DSTDEVP(database,field,criteria); verify stddevp. +SG-FN-029 6.9.11 DSUM Mandatory Small ODF 1.2 Evaluate DSUM(database,field,criteria); verify sum. +SG-FN-030 6.9.12 DVAR Mandatory Small ODF 1.2 Evaluate DVAR(database,field,criteria); verify variance. +SG-FN-031 6.9.13 DVARP Mandatory Small ODF 1.2 Evaluate DVARP(database,field,criteria); verify variancep. +SG-FN-032 6.16.30 EVEN Mandatory Small ODF 1.2 Evaluate EVEN(1.3); verify 2. +SG-FN-033 6.20.8 EXACT Mandatory Small ODF 1.2 Evaluate EXACT("a","a"); verify TRUE. +SG-FN-034 6.16.31 EXP Mandatory Small ODF 1.2 Evaluate EXP(1); verify e. +SG-FN-035 6.16.32 FACT Mandatory Small ODF 1.2 Evaluate FACT(5); verify 120. +SG-FN-036 6.15.3 FALSE Mandatory Small ODF 1.2 Evaluate FALSE(); verify FALSE. +SG-FN-037 6.20.9 FIND Mandatory Small ODF 1.2 Evaluate FIND("b","abc"); verify 2. +SG-FN-038 6.12.20 FV Mandatory Small ODF 1.2 Evaluate FV(rate,nper,pmt); verify future value. +SG-FN-039 6.14.5 HLOOKUP Mandatory Small ODF 1.2 Evaluate HLOOKUP(value,table,row); verify result. +SG-FN-040 6.10.11 HOUR Mandatory Small ODF 1.2 Evaluate HOUR(TIME(12,30,0)); verify 12. +SG-FN-041 6.15.4 IF Mandatory Small ODF 1.2 Evaluate IF(TRUE,1,2); verify 1. +SG-FN-042 6.14.6 INDEX Mandatory Small ODF 1.2 Evaluate INDEX(range,row,col); verify cell value. +SG-FN-043 6.17.2 INT Mandatory Small ODF 1.2 Evaluate INT(1.9); verify 1. +SG-FN-044 6.12.24 IRR Mandatory Small ODF 1.2 Evaluate IRR(values); verify internal rate of return. +SG-FN-045 6.13.14 ISBLANK Mandatory Small ODF 1.2 Evaluate ISBLANK(cell); verify TRUE/FALSE. +SG-FN-046 6.13.15 ISERR Mandatory Small ODF 1.2 Evaluate ISERR(1/0); verify TRUE. +SG-FN-047 6.13.16 ISERROR Mandatory Small ODF 1.2 Evaluate ISERROR(1/0); verify TRUE. +SG-FN-048 6.13.19 ISLOGICAL Mandatory Small ODF 1.2 Evaluate ISLOGICAL(TRUE); verify TRUE. +SG-FN-049 6.13.20 ISNA Mandatory Small ODF 1.2 Evaluate ISNA(NA()); verify TRUE. +SG-FN-050 6.13.21 ISNONTEXT Mandatory Small ODF 1.2 Evaluate ISNONTEXT(1); verify TRUE. +SG-FN-051 6.13.22 ISNUMBER Mandatory Small ODF 1.2 Evaluate ISNUMBER(1); verify TRUE. +SG-FN-052 6.13.25 ISTEXT Mandatory Small ODF 1.2 Evaluate ISTEXT("a"); verify TRUE. +SG-FN-053 6.20.12 LEFT Mandatory Small ODF 1.2 Evaluate LEFT("abc",2); verify "ab". +SG-FN-054 6.20.13 LEN Mandatory Small ODF 1.2 Evaluate LEN("abc"); verify 3. +SG-FN-055 6.16.39 LN Mandatory Small ODF 1.2 Evaluate LN(1); verify 0. +SG-FN-056 6.16.40 LOG Mandatory Small ODF 1.2 Evaluate LOG(100,10); verify 2. +SG-FN-057 6.16.41 LOG10 Mandatory Small ODF 1.2 Evaluate LOG10(100); verify 2. +SG-FN-058 6.20.14 LOWER Mandatory Small ODF 1.2 Evaluate LOWER("ABC"); verify "abc". +SG-FN-059 6.14.9 MATCH Mandatory Small ODF 1.2 Evaluate MATCH(value,range,type); verify position. +SG-FN-060 6.18.45 MAX Mandatory Small ODF 1.2 Evaluate MAX(1,2,3); verify 3. +SG-FN-061 6.20.15 MID Mandatory Small ODF 1.2 Evaluate MID("abc",2,1); verify "b". +SG-FN-062 6.18.48 MIN Mandatory Small ODF 1.2 Evaluate MIN(1,2,3); verify 1. +SG-FN-063 6.10.13 MINUTE Mandatory Small ODF 1.2 Evaluate MINUTE(TIME(12,30,0)); verify 30. +SG-FN-064 6.16.42 MOD Mandatory Small ODF 1.2 Evaluate MOD(5,2); verify 1. +SG-FN-065 6.10.14 MONTH Mandatory Small ODF 1.2 Evaluate MONTH(DATE(2025,3,15)); verify 3. +SG-FN-066 6.13.26 N Mandatory Small ODF 1.2 Evaluate N(TRUE); verify 1. +SG-FN-067 6.13.27 NA Mandatory Small ODF 1.2 Evaluate NA(); verify #N/A error. +SG-FN-068 6.15.7 NOT Mandatory Small ODF 1.2 Evaluate NOT(TRUE); verify FALSE. +SG-FN-069 6.10.16 NOW Mandatory Small ODF 1.2 Evaluate NOW(); verify current datetime. +SG-FN-070 6.12.29 NPER Mandatory Small ODF 1.2 Evaluate NPER(rate,pmt,pv); verify periods. +SG-FN-071 6.12.30 NPV Mandatory Small ODF 1.2 Evaluate NPV(rate,values); verify net present value. +SG-FN-072 6.16.44 ODD Mandatory Small ODF 1.2 Evaluate ODD(1.3); verify 3. +SG-FN-073 6.15.8 OR Mandatory Small ODF 1.2 Evaluate OR(FALSE,TRUE); verify TRUE. +SG-FN-074 6.16.45 PI Mandatory Small ODF 1.2 Evaluate PI(); verify pi. +SG-FN-075 6.12.36 PMT Mandatory Small ODF 1.2 Evaluate PMT(rate,nper,pv); verify payment. +SG-FN-076 6.16.46 POWER Mandatory Small ODF 1.2 Evaluate POWER(2,3); verify 8. +SG-FN-077 6.16.47 PRODUCT Mandatory Small ODF 1.2 Evaluate PRODUCT(2,3); verify 6. +SG-FN-078 6.20.16 PROPER Mandatory Small ODF 1.2 Evaluate PROPER("abc"); verify "Abc". +SG-FN-079 6.12.41 PV Mandatory Small ODF 1.2 Evaluate PV(rate,nper,pmt); verify present value. +SG-FN-080 6.16.49 RADIANS Mandatory Small ODF 1.2 Evaluate RADIANS(180); verify pi. +SG-FN-081 6.12.42 RATE Mandatory Small ODF 1.2 Evaluate RATE(nper,pmt,pv); verify rate. +SG-FN-082 6.20.17 REPLACE Mandatory Small ODF 1.2 Evaluate REPLACE("abc",2,1,"x"); verify "axc". +SG-FN-083 6.20.18 REPT Mandatory Small ODF 1.2 Evaluate REPT("a",3); verify "aaa". +SG-FN-084 6.20.19 RIGHT Mandatory Small ODF 1.2 Evaluate RIGHT("abc",2); verify "bc". +SG-FN-085 6.17.5 ROUND Mandatory Small ODF 1.2 Evaluate ROUND(1.6,0); verify 2. +SG-FN-086 6.13.30 ROWS Mandatory Small ODF 1.2 Evaluate ROWS(A1:A3); verify 3. +SG-FN-087 6.10.17 SECOND Mandatory Small ODF 1.2 Evaluate SECOND(TIME(12,30,45)); verify 45. +SG-FN-088 6.16.55 SIN Mandatory Small ODF 1.2 Evaluate SIN(0); verify 0. +SG-FN-089 6.12.45 SLN Mandatory Small ODF 1.2 Evaluate SLN(cost,salvage,life); verify depreciation. +SG-FN-090 6.16.58 SQRT Mandatory Small ODF 1.2 Evaluate SQRT(4); verify 2. +SG-FN-091 6.18.72 STDEV Mandatory Small ODF 1.2 Evaluate STDEV(values); verify sample stddev. +SG-FN-092 6.18.74 STDEVP Mandatory Small ODF 1.2 Evaluate STDEVP(values); verify population stddev. +SG-FN-093 6.20.21 SUBSTITUTE Mandatory Small ODF 1.2 Evaluate SUBSTITUTE("aaa","a","b"); verify "bbb". +SG-FN-094 6.16.61 SUM Mandatory Small ODF 1.2 Evaluate SUM(1,2,3); verify 6. +SG-FN-095 6.16.62 SUMIF Mandatory Small ODF 1.2 Evaluate SUMIF(range,criteria,sumrange); verify sum. +SG-FN-096 6.12.46 SYD Mandatory Small ODF 1.2 Evaluate SYD(cost,salvage,life,period); verify depreciation. +SG-FN-097 6.20.22 T Mandatory Small ODF 1.2 Evaluate T("abc"); verify "abc". +SG-FN-098 6.16.69 TAN Mandatory Small ODF 1.2 Evaluate TAN(0); verify 0. +SG-FN-099 6.10.18 TIME Mandatory Small ODF 1.2 Evaluate TIME(12,30,0); verify time serial. +SG-FN-100 6.10.20 TODAY Mandatory Small ODF 1.2 Evaluate TODAY(); verify current date serial. +SG-FN-101 6.20.24 TRIM Mandatory Small ODF 1.2 Evaluate TRIM(" a b "); verify "a b". +SG-FN-102 6.15.9 TRUE Mandatory Small ODF 1.2 Evaluate TRUE(); verify TRUE. +SG-FN-103 6.17.8 TRUNC Mandatory Small ODF 1.2 Evaluate TRUNC(1.9); verify 1. +SG-FN-104 6.20.27 UPPER Mandatory Small ODF 1.2 Evaluate UPPER("abc"); verify "ABC". +SG-FN-105 6.13.34 VALUE Mandatory Small ODF 1.2 Evaluate VALUE("123"); verify 123. +SG-FN-106 6.18.82 VAR Mandatory Small ODF 1.2 Evaluate VAR(values); verify sample variance. +SG-FN-107 6.18.84 VARP Mandatory Small ODF 1.2 Evaluate VARP(values); verify population variance. +SG-FN-108 6.14.12 VLOOKUP Mandatory Small ODF 1.2 Evaluate VLOOKUP(value,table,col,range); verify result. +SG-FN-109 6.10.21 WEEKDAY Mandatory Small ODF 1.2 Evaluate WEEKDAY(date); verify day number. +SG-FN-110 6.10.24 YEAR Mandatory Small ODF 1.2 Evaluate YEAR(DATE(2025,3,15)); verify 2025. +SG-ALW-001 2.3.2.F References containing more than one area need not be evaluated Optional Small ODF 1.4 Reference with multiple areas; may return error or partial result. +SG-ALW-002 2.3.2.G Inline arrays need not be implemented Optional Small ODF 1.4 Use {1,2} inline array; may return error. +SG-ALW-003 2.3.2.G Complex numbers need not be implemented Optional Small ODF 1.4 Use COMPLEX function; may return error. +SG-ALW-004 2.3.2.G Reference union operator (~) need not be implemented Optional Small ODF 1.4 Use A1:B2~C3:D4; may return error. +SG-SYN-001 4.11.11 Criteria syntax supported Mandatory Small ODF 1.4 Use criteria in database functions; verify parsed correctly. +SG-SYN-002 5.2 Basic Expressions syntax supported Mandatory Small ODF 1.4 Parse parenthesized expressions; verify evaluation. +SG-SYN-003 5.3 Constant Numbers syntax supported Mandatory Small ODF 1.4 Parse numeric literals including decimals, scientific notation; verify. +SG-SYN-004 5.4 Constant Strings syntax supported Mandatory Small ODF 1.4 Parse string literals with quote escaping; verify. +SG-SYN-005 5.5 Operators syntax supported (precedence per Table 1) Mandatory Small ODF 1.4 Evaluate 2+3*4 and 2^3^2; verify correct precedence. +SG-SYN-006 5.6 Functions and Function Parameters syntax supported Mandatory Small ODF 1.4 Call functions with various argument counts; verify. +SG-SYN-007 5.7 Nonstandard Function Names recognized as errors Mandatory Small ODF 1.4 Use unknown function name; verify error result. +SG-SYN-008 5.8 References syntax supported Mandatory Small ODF 1.4 Use cell and range references; verify resolution. +SG-SYN-009 5.11 Simple Named Expressions supported Mandatory Small ODF 1.4 Define and use named expression; verify. +SG-SYN-010 5.12 Errors syntax supported Mandatory Small ODF 1.4 Use error constants (#N/A, etc.); verify propagation. +SG-SYN-011 5.14 Whitespace handling per specification Mandatory Small ODF 1.4 Insert whitespace in formula; verify identical result. +SG-CONV-001 6.3.14 Conversion to Text implemented Mandatory Small ODF 1.4 Convert number/date/logical to text; verify result. +SG-CONV-002 6.3.5 Conversion to Number implemented Mandatory Small ODF 1.4 Convert text to number; verify result. +SG-CONV-003 4.8 Reference conversion implemented Mandatory Small ODF 1.4 Convert reference to scalar value; verify result. +SG-CONV-004 6.3.12 Conversion to Logical implemented Mandatory Small ODF 1.4 Convert number to logical; verify result. +SG-CONV-005 5.12 Error propagation when expression returns Error Mandatory Small ODF 1.4 Pass error as argument; verify error propagates. +SG-OP-001 6.4.9 Infix Operator Ordered Comparison (<, <=, >, >=) implemented Mandatory Small ODF 1.4 Evaluate comparisons; verify results. +SG-OP-002 6.4.10 Infix Operator "&" (concatenation) implemented Mandatory Small ODF 1.4 Evaluate "a"&"b"; verify "ab". +SG-OP-003 6.4.2 Infix Operator "+" implemented Mandatory Small ODF 1.4 Evaluate 2+3; verify 5. +SG-OP-004 6.4.3 Infix Operator "-" implemented Mandatory Small ODF 1.4 Evaluate 5-3; verify 2. +SG-OP-005 6.4.4 Infix Operator "*" implemented Mandatory Small ODF 1.4 Evaluate 2*3; verify 6. +SG-OP-006 6.4.5 Infix Operator "/" implemented Mandatory Small ODF 1.4 Evaluate 6/3; verify 2. +SG-OP-007 6.4.6 Infix Operator "^" implemented Mandatory Small ODF 1.4 Evaluate 2^3; verify 8. +SG-OP-008 6.4.7 Infix Operator "=" implemented Mandatory Small ODF 1.4 Evaluate 2=2; verify TRUE. +SG-OP-009 6.4.8 Infix Operator "<>" implemented Mandatory Small ODF 1.4 Evaluate 2<>3; verify TRUE. +SG-OP-010 6.4.14 Postfix Operator "%" implemented Mandatory Small ODF 1.4 Evaluate 50%; verify 0.5. +SG-OP-011 6.4.15 Prefix Operator "+" implemented Mandatory Small ODF 1.4 Evaluate +5; verify 5. +SG-OP-012 6.4.16 Prefix Operator "-" implemented Mandatory Small ODF 1.4 Evaluate -5; verify -5. +SG-OP-013 6.4.12 Infix Operator Reference Intersection ("!") implemented Mandatory Small ODF 1.4 Evaluate A1:C3!B1:D2; verify intersection. +SG-OP-014 6.4.11 Infix Operator Range (":") implemented Mandatory Small ODF 1.4 Evaluate SUM(A1:A3); verify range. \ No newline at end of file diff --git a/openformula-small-group-audit.md b/openformula-small-group-audit.md new file mode 100644 index 0000000000..647a2e5799 --- /dev/null +++ b/openformula-small-group-audit.md @@ -0,0 +1,305 @@ +# OpenFormula 1.4 Small Group Audit — Apache OpenOffice Calc + +## Methodology and Normative Source + +**Normative source:** OASIS Open Document Format for Office Applications (OpenDocument) Version 1.4, Part 4: Recalculated Formula (OpenFormula) Format, OASIS Standard, 6 October 2025. + +URL: https://docs.oasis-open.org/office/OpenDocument/v1.4/os/part4-formula/OpenDocument-v1.4-os-part4-formula.html + +**Primary sections audited:** +- §2.3.1 — OpenDocument Formula Evaluator +- §2.3.2 — OpenDocument Formula Small Group Evaluator +- §3.7 — Basic Limits +- §4 — Types +- §5 — Expression Syntax +- §6 — Operators and Functions + +**Source-of-truth:** Apache OpenOffice implementation (main/sc, main/formula, main/scaddins). Findings marked **[CONFIRMED]** have source file:line evidence; **[UNVERIFIED]** require runtime testing or full spec text not available locally. + +**Milestone context:** Milestones A, B, and C have been completed on branch `openformula`. Milestone B implemented IFNA and SKEWP. Milestone C corrected CONVERT unit constants and completed the Pica unit family. This audit reflects the current branch state after those changes. + +--- + +## 1. Conformance Group Claim + +**[CONFIRMED] AOO claims NO Part 4 conformance group.** +- `odf_docs/ODF14-IMPLEMENTATION-DEFINED-PUBLIC.md:134` (§4): "AOO does not claim the Part 4 evaluator groups (Small, Medium, Large)." + +Therefore **no conformance level (Small/Medium/Large) may be claimed for AOO Calc.** This audit reports implementation coverage only; it does not certify conformance. + +--- + +## 2. Basic Limits (§3.7) + +| ReqID | Requirement | Status | Source Evidence | Runtime Verified | +|-------|-------------|--------|-----------------|-------------------| +| SG-BL-001 | Formula length >= 1024 characters | **[CONFIRMED]** structurally | FormulaCompiler parses token arrays dynamically; no fixed 1024-char limit found in source | No | +| SG-BL-002 | >= 30 parameters per function | **[CONFIRMED]** structurally | MustHaveParamCount validates exact counts; no 30-param cap found | No | +| SG-BL-003 | Strings up to 32767 ASCII chars | **[UNVERIFIED]** | OUString used for strings; no specific 32767 limit found | No | +| SG-BL-004 | >= 7 nesting levels of functions | **[CONFIRMED]** structurally | No nesting depth limit found in compiler/interpreter | No | + +**Finding:** All basic limit requirements appear satisfied by the dynamic architecture (no hard-coded limits below the spec minimums). Runtime verification is outstanding for all four. + +--- + +## 3. Syntax (§2.3.2.B) + +| ReqID | Section | Requirement | Status | Source Evidence | +|-------|---------|-------------|--------|-----------------| +| SG-SYN-001 | 4.11.11 | Criteria syntax | **[CONFIRMED]** | Database functions (DSUM, DCOUNT, etc.) use criteria; interpr1.cxx implements DBSum/DBCount | +| SG-SYN-002 | 5.2 | Basic Expressions | **[CONFIRMED]** | FormulaCompiler.cxx handles parenthesized expressions via RangeLine/IntersectionLine/UnaryLine | +| SG-SYN-003 | 5.3 | Constant Numbers | **[CONFIRMED]** | FormulaCompiler.cxx tokenizes numeric literals | +| SG-SYN-004 | 5.4 | Constant Strings | **[CONFIRMED]** | FormulaCompiler.cxx tokenizes string literals with quote escaping | +| SG-SYN-005 | 5.5 | Operators precedence (Table 1) | **[CONFIRMED]** | FormulaCompiler.cxx:1203-1237 implements UnionLine -> IntersectionLine -> RangeLine -> UnaryLine -> binary ops | +| SG-SYN-006 | 5.6 | Functions and parameters | **[CONFIRMED]** | FormulaCompiler.cxx compiles function calls with argument lists | +| SG-SYN-007 | 5.7 | Nonstandard function names as errors | **[CONFIRMED]** | ocNoName opcode; xlformula.cxx uses ocNoName stubs | +| SG-SYN-008 | 5.8 | References | **[CONFIRMED]** | compiler.cxx PopDoubleRef/PopSingleRef handle cell/range references | +| SG-SYN-009 | 5.11 | Simple Named Expressions | **[CONFIRMED]** | compiler.cxx:NameLine handles named expressions; ocName opcode | +| SG-SYN-010 | 5.12 | Errors | **[CONFIRMED]** | Error constants (ocErrNull through ocErrNA) in compiler.hrc; interpr1.cxx error handling | +| SG-SYN-011 | 5.14 | Whitespace | **[CONFIRMED]** | ocSpaces converted to intersection at FormulaCompiler.cxx:830-831 | + +**Finding:** All syntax requirements are structurally supported by the parser/compiler. No gaps identified. + +--- + +## 4. Implicit Conversions (§2.3.2.C) + +| ReqID | Section | Requirement | Status | Source Evidence | +|-------|---------|-------------|--------|-----------------| +| SG-CONV-001 | 6.3.14 | Conversion to Text | **[CONFIRMED]** | ScInterpreter::GetString() (interpre.hxx:374), ScText() (interpr1.cxx) | +| SG-CONV-002 | 6.3.5 | Conversion to Number | **[CONFIRMED]** | ScInterpreter::GetDouble() (interpre.hxx:370), ConvertStringToValue() (interpre.hxx:228) | +| SG-CONV-003 | 4.8 | Reference conversion | **[CONFIRMED]** | ScInterpreter::GetCellValueOrZero() (interpre.hxx:231), PopSingleRef/PopDoubleRef | +| SG-CONV-004 | 6.3.12 | Conversion to Logical | **[CONFIRMED]** | ScInterpreter::GetBool() returns GetDouble() != 0.0 (interpre.hxx:373) | +| SG-CONV-005 | 5.12 | Error propagation | **[CONFIRMED]** | nGlobalError (interpre.hxx:196), SetError() (interpre.hxx:854), Push() substitutes FormulaErrorToken (interpre.hxx:263) | + +**Finding:** All conversion requirements are implemented. Edge cases (locale-sensitive conversion, text-to-number with thousands separators) are impl-defined per ODF 1.4 and documented in openformula-semantics.md. + +--- + +## 5. Operators (§2.3.2.D) + +All operators required by §2.3.2.D (all operators except reference union `~`) are implemented: + +| ReqID | Section | Operator | Status | Source | +|-------|---------|----------|--------|--------| +| SG-OP-001 | 6.4.9 | Ordered comparison (<, <=, >, >=) | **[CONFIRMED]** | interpr1.cxx:ScLess/ScLessEqual/ScGreater/ScGreaterEqual | +| SG-OP-002 | 6.4.10 | Concatenation (&) | **[CONFIRMED]** | interpr5.cxx:ScAmpersand | +| SG-OP-003 | 6.4.2 | Addition (+) | **[CONFIRMED]** | interpr5.cxx:ScAdd | +| SG-OP-004 | 6.4.3 | Subtraction (-) | **[CONFIRMED]** | interpr5.cxx:ScSub | +| SG-OP-005 | 6.4.4 | Multiplication (*) | **[CONFIRMED]** | interpr5.cxx:ScMul | +| SG-OP-006 | 6.4.5 | Division (/) | **[CONFIRMED]** | interpr5.cxx:ScDiv; division by zero -> errDivisionByZero (interpre.hxx:955-959) | +| SG-OP-007 | 6.4.6 | Power (^) | **[CONFIRMED]** | interpr5.cxx:ScPow; right-associative | +| SG-OP-008 | 6.4.7 | Equality (=) | **[CONFIRMED]** | interpr1.cxx:ScEqual | +| SG-OP-009 | 6.4.8 | Not equal (<>) | **[CONFIRMED]** | interpr1.cxx:ScNotEqual | +| SG-OP-010 | 6.4.14 | Postfix % | **[CONFIRMED]** | interpr1.cxx:ScPercentSign | +| SG-OP-011 | 6.4.15 | Prefix + | **[CONFIRMED]** | Unary plus handled by compiler; ocAdd with single operand | +| SG-OP-012 | 6.4.16 | Prefix - | **[CONFIRMED]** | interpr1.cxx:ScNeg | +| SG-OP-013 | 6.4.12 | Reference intersection (!) | **[CONFIRMED]** | interpr1.cxx:ScIntersect | +| SG-OP-014 | 6.4.11 | Reference range (:) | **[CONFIRMED]** | interpr1.cxx:ScRangeFunc | + +**Finding:** All 14 operator requirements are implemented. Reference union (`~`) is explicitly NOT required for Small Group (§2.3.2.G). + +--- + +## 6. Required Functions (§2.3.2.E) + +The Small Group requires 110 functions (§2.3.2.E). All 110 have opcodes and implementations in the current source. IFNA and SKEWP were implemented in Milestone B (IFNA = Large Group only; SKEWP = Medium Group only — neither is Small Group). + +### Function status summary + +| Status | Count | Description | +|--------|-------|-------------| +| IMPLEMENTED_MATCH | 110 | All 110 Small Group functions have opcodes, implementations, dispatch, and metadata | + +### Function detail (selected examples) + +| Function | Section | Opcode | Value | Implementation | Status | +|----------|---------|--------|-------|----------------|--------| +| ABS | 6.16.2 | ocAbs | 113 | interpr1.cxx:ScAbs | IMPLEMENTED_MATCH | +| ACOS | 6.16.3 | ocArcCos | 87 | interpr1.cxx:ScArcCos | IMPLEMENTED_MATCH | +| AND | 6.15.2 | ocAnd | 52 | interpr1.cxx:ScAnd | IMPLEMENTED_MATCH | +| ASIN | 6.16.7 | ocArcSin | 86 | interpr1.cxx:ScArcSin | IMPLEMENTED_MATCH | +| ATAN | 6.16.9 | ocArcTan | 88 | interpr1.cxx:ScArcTan | IMPLEMENTED_MATCH | +| ATAN2 | 6.16.10 | ocArcTan2 | 201 | interpr2.cxx:ScArcTan2 | IMPLEMENTED_MATCH (ODF 1.4: ATAN2(0,0) impl-defined) | +| AVERAGE | 6.18.3 | ocAverage | 226 | interpr1.cxx:ScAverage | IMPLEMENTED_MATCH | +| AVERAGEIF | 6.18.5 | ocAverageIf | 395 | interpr1.cxx:ScAverageIf | IMPLEMENTED_MATCH | +| CHOOSE | 6.14.3 | ocChose | 7 | interpr1.cxx:ScChose | IMPLEMENTED_MATCH | +| COLUMNS | 6.13.5 | ocColumns | 252 | interpr1.cxx:ScColumns | IMPLEMENTED_MATCH | +| COS | 6.16.19 | ocCos | 83 | interpr1.cxx:ScCos | IMPLEMENTED_MATCH | +| COUNT | 6.13.6 | ocCount | 227 | interpr1.cxx:ScCount | IMPLEMENTED_MATCH | +| COUNTA | 6.13.7 | ocCount2 | 228 | interpr1.cxx:ScCount2 | IMPLEMENTED_MATCH (ODF 1.4 empty-cell semantics changed) | +| COUNTBLANK | 6.13.8 | ocCountEmptyCells | 282 | interpr1.cxx:ScCountEmptyCells | IMPLEMENTED_MATCH (ODF 1.4: "" case impl-defined) | +| COUNTIF | 6.13.9 | ocCountIf | 283 | interpr1.cxx:ScCountIf | IMPLEMENTED_MATCH | +| DATE | 6.10.2 | ocGetDate | 218 | interpr2.cxx:ScGetDate | IMPLEMENTED_MATCH (ODF 1.4: pre-1583 impl-defined) | +| DAVERAGE | 6.9.2 | ocDBAverage | 270 | interpr1.cxx:ScDBAverage | IMPLEMENTED_MATCH | +| DAY | 6.10.5 | ocGetDay | 108 | interpr2.cxx:ScGetDay | IMPLEMENTED_MATCH | +| DCOUNT | 6.9.3 | ocDBCount | 268 | interpr1.cxx:ScDBCount | IMPLEMENTED_MATCH | +| DCOUNTA | 6.9.4 | ocDBCount2 | 269 | interpr1.cxx:ScDBCount2 | IMPLEMENTED_MATCH | +| DDB | 6.12.14 | ocGDA | 246 | interpr2.cxx:ScGDA | IMPLEMENTED_MATCH | +| DEGREES | 6.16.25 | ocDeg | 80 | interpr2.cxx:ScDeg | IMPLEMENTED_MATCH | +| DGET | 6.9.5 | ocDBGet | 271 | interpr1.cxx:ScDBGet | IMPLEMENTED_MATCH | +| DMAX | 6.9.6 | ocDBMax | 272 | interpr1.cxx:ScDBMax | IMPLEMENTED_MATCH | +| DMIN | 6.9.7 | ocDBMin | 273 | interpr1.cxx:ScDBMin | IMPLEMENTED_MATCH | +| DPRODUCT | 6.9.8 | ocDBProduct | 274 | interpr1.cxx:ScDBProduct | IMPLEMENTED_MATCH | +| DSTDEV | 6.9.9 | ocDBStdDev | 275 | interpr1.cxx:ScDBStdDev | IMPLEMENTED_MATCH | +| DSTDEVP | 6.9.10 | ocDBStdDevP | 276 | interpr1.cxx:ScDBStdDevP | IMPLEMENTED_MATCH | +| DSUM | 6.9.11 | ocDBSum | 267 | interpr1.cxx:ScDBSum | IMPLEMENTED_MATCH | +| DVAR | 6.9.12 | ocDBVar | 277 | interpr1.cxx:ScDBVar | IMPLEMENTED_MATCH | +| DVARP | 6.9.13 | ocDBVarP | 278 | interpr1.cxx:ScDBVarP | IMPLEMENTED_MATCH | +| EVEN | 6.16.30 | ocEven | 144 | interpr2.cxx:ScEven | IMPLEMENTED_MATCH | +| EXACT | 6.20.8 | ocExact | 296 | interpr1.cxx:ScExact | IMPLEMENTED_MATCH | +| EXP | 6.16.31 | ocExp | 102 | interpr1.cxx:ScExp | IMPLEMENTED_MATCH | +| FACT | 6.16.32 | ocFact | 105 | interpr3.cxx:ScFact | IMPLEMENTED_MATCH | +| FALSE | 6.15.3 | ocFalse | 68 | interpr1.cxx:ScFalse | IMPLEMENTED_MATCH | +| FIND | 6.20.9 | ocFind | 295 | interpr1.cxx:ScFind | IMPLEMENTED_MATCH | +| FV | 6.12.20 | ocZW | 257 | interpr2.cxx:ScZW | IMPLEMENTED_MATCH | +| HLOOKUP | 6.14.5 | ocHLookup | 287 | interpr1.cxx:ScHLookup | IMPLEMENTED_MATCH (ODF 1.4: unsorted data impl-defined) | +| HOUR | 6.10.11 | ocGetHour | 109 | interpr2.cxx:ScGetHour | IMPLEMENTED_MATCH | +| IF | 6.15.4 | ocIf | 6 | interpr1.cxx:ScIfJump | IMPLEMENTED_MATCH (lazy evaluation via jumps) | +| INDEX | 6.14.6 | ocIndex | 290 | interpr1.cxx:ScIndex | IMPLEMENTED_MATCH (ODF 1.4: row-vector single-arg now error — Milestone A fix) | +| INT | 6.17.2 | ocInt | 114 | interpr2.cxx:ScInt | IMPLEMENTED_MATCH | +| IRR | 6.12.24 | ocIRR | 230 | interpr2.cxx:ScIRR | IMPLEMENTED_MATCH | +| ISBLANK | 6.13.14 | ocIsEmpty | 117 | interpr1.cxx:ScIsEmpty | IMPLEMENTED_MATCH | +| ISERR | 6.13.15 | ocIsErr | 127 | interpr1.cxx:ScIsErr | IMPLEMENTED_MATCH | +| ISERROR | 6.13.16 | ocIsError | 128 | interpr1.cxx:ScIsError | IMPLEMENTED_MATCH | +| ISLOGICAL | 6.13.19 | ocIsLogical | 120 | interpr1.cxx:ScIsLogical | IMPLEMENTED_MATCH (complex-number case impl-defined) | +| ISNA | 6.13.20 | ocIsNA | 126 | interpr1.cxx:ScIsNV | IMPLEMENTED_MATCH | +| ISNONTEXT | 6.13.21 | ocIsNonString | 119 | interpr1.cxx:ScIsNonString | IMPLEMENTED_MATCH | +| ISNUMBER | 6.13.22 | ocIsValue | 124 | interpr1.cxx:ScIsValue | IMPLEMENTED_MATCH (complex-number case impl-defined) | +| ISTEXT | 6.13.25 | ocIsString | 118 | interpr1.cxx:ScIsString | IMPLEMENTED_MATCH | +| LEFT | 6.20.12 | ocLeft | 297 | interpr1.cxx:ScLeft | IMPLEMENTED_MATCH | +| LEN | 6.20.13 | ocLen | 139 | interpr1.cxx:ScLen | IMPLEMENTED_MATCH | +| LN | 6.16.39 | ocLn | 103 | interpr1.cxx:ScLn | IMPLEMENTED_MATCH | +| LOG | 6.16.40 | ocLog | 208 | interpr2.cxx:ScLog | IMPLEMENTED_MATCH | +| LOG10 | 6.16.41 | ocLog10 | 143 | interpr1.cxx:ScLog10 | IMPLEMENTED_MATCH | +| LOWER | 6.20.14 | ocLower | 138 | interpr1.cxx:ScLower | IMPLEMENTED_MATCH | +| MATCH | 6.14.9 | ocMatch | 281 | interpr1.cxx:ScMatch | IMPLEMENTED_MATCH | +| MAX | 6.18.45 | ocMax | 223 | interpr1.cxx:ScMax | IMPLEMENTED_MATCH (ODF 1.4: 0 parameters impl-defined) | +| MID | 6.20.15 | ocMid | 300 | interpr1.cxx:ScMid | IMPLEMENTED_MATCH | +| MIN | 6.18.48 | ocMin | 222 | interpr1.cxx:ScMin | IMPLEMENTED_MATCH (ODF 1.4: 0 parameters impl-defined) | +| MINUTE | 6.10.13 | ocGetMin | 110 | interpr2.cxx:ScGetMin | IMPLEMENTED_MATCH | +| MOD | 6.16.42 | ocMod | 212 | interpr5.cxx:ScMod | IMPLEMENTED_MATCH | +| MONTH | 6.10.14 | ocGetMonth | 107 | interpr2.cxx:ScGetMonth | IMPLEMENTED_MATCH | +| N | 6.13.26 | ocN | 131 | interpr1.cxx:ScN | IMPLEMENTED_MATCH (ODF 1.4: text case impl-defined) | +| NA | 6.13.27 | ocNotAvail | 71 | interpr1.cxx (via ScNA) | IMPLEMENTED_MATCH | +| NOT | 6.15.7 | ocNot | 60 | interpr1.cxx:ScNot | IMPLEMENTED_MATCH | +| NOW | 6.10.16 | ocGetActTime | 70 | interpr2.cxx:ScGetActTime | IMPLEMENTED_MATCH | +| NPER | 6.12.29 | ocZZR | 258 | interpr2.cxx:ScZZR | IMPLEMENTED_MATCH (trailing-empty-param rule documented) | +| NPV | 6.12.30 | ocNPV | 229 | interpr2.cxx:ScNPV | IMPLEMENTED_MATCH | +| ODD | 6.16.44 | ocOdd | 145 | interpr2.cxx:ScOdd | IMPLEMENTED_MATCH | +| OR | 6.15.8 | ocOr | 53 | interpr1.cxx:ScOr | IMPLEMENTED_MATCH | +| PI | 6.16.45 | ocPi | 65 | interpr1.cxx:ScPi | IMPLEMENTED_MATCH | +| PMT | 6.12.36 | ocRMZ | 251 | interpr2.cxx:ScRMZ | IMPLEMENTED_MATCH | +| POWER | 6.16.46 | ocPower | 209 | interpr2.cxx:ScPower | IMPLEMENTED_MATCH (ODF 1.4: POWER(0,0) impl-defined) | +| PRODUCT | 6.16.47 | ocProduct | 225 | interpr1.cxx:ScProduct | IMPLEMENTED_MATCH | +| PROPER | 6.20.16 | ocPropper | 137 | interpr1.cxx:ScPropper | IMPLEMENTED_MATCH | +| PV | 6.12.41 | ocBW | 244 | interpr2.cxx:ScBW | IMPLEMENTED_MATCH | +| RADIANS | 6.16.49 | ocRad | 81 | interpr2.cxx:ScRad | IMPLEMENTED_MATCH | +| RATE | 6.12.42 | ocZins | 259 | interpr2.cxx:ScZins | IMPLEMENTED_MATCH | +| REPLACE | 6.20.17 | ocReplace | 293 | interpr1.cxx:ScReplace | IMPLEMENTED_MATCH | +| REPT | 6.20.18 | ocRept | 303 | interpr1.cxx:ScRept | IMPLEMENTED_MATCH | +| RIGHT | 6.20.19 | ocRight | 298 | interpr1.cxx:ScRight | IMPLEMENTED_MATCH | +| ROUND | 6.17.5 | ocRound | 204 | interpr2.cxx:ScRound | IMPLEMENTED_MATCH | +| ROWS | 6.13.30 | ocRows | 253 | interpr1.cxx:ScRows | IMPLEMENTED_MATCH | +| SECOND | 6.10.17 | ocGetSec | 111 | interpr2.cxx:ScGetSec | IMPLEMENTED_MATCH | +| SIN | 6.16.55 | ocSin | 82 | interpr1.cxx:ScSin | IMPLEMENTED_MATCH | +| SLN | 6.12.45 | ocLIA | 250 | interpr2.cxx:ScLIA | IMPLEMENTED_MATCH | +| SQRT | 6.16.58 | ocSqrt | 104 | interpr1.cxx:ScSqrt | IMPLEMENTED_MATCH | +| STDEV | 6.18.72 | ocStDev | 233 | interpr3.cxx | IMPLEMENTED_MATCH | +| STDEVP | 6.18.74 | ocStDevP | 234 | interpr3.cxx | IMPLEMENTED_MATCH | +| SUBSTITUTE | 6.20.21 | ocSubstitute | 302 | interpr1.cxx:ScSubstitute | IMPLEMENTED_MATCH | +| SUM | 6.16.61 | ocSum | 224 | interpr1.cxx:ScSum | IMPLEMENTED_MATCH | +| SUMIF | 6.16.62 | ocSumIf | 284 | interpr1.cxx:ScSumIf | IMPLEMENTED_MATCH | +| SYD | 6.12.46 | ocDIA | 245 | interpr2.cxx:ScDIA | IMPLEMENTED_MATCH | +| T | 6.20.22 | ocT | 140 | interpr1.cxx:ScT | IMPLEMENTED_MATCH | +| TAN | 6.16.69 | ocTan | 84 | interpr1.cxx:ScTan | IMPLEMENTED_MATCH | +| TIME | 6.10.18 | ocGetTime | 219 | interpr2.cxx:ScGetTime | IMPLEMENTED_MATCH | +| TODAY | 6.10.20 | ocGetActDate | 69 | interpr2.cxx:ScGetActDate | IMPLEMENTED_MATCH | +| TRIM | 6.20.24 | ocTrim | 135 | interpr1.cxx:ScTrim | IMPLEMENTED_MATCH | +| TRUE | 6.15.9 | ocTrue | 67 | interpr1.cxx:ScTrue | IMPLEMENTED_MATCH | +| TRUNC | 6.17.8 | ocTrunc | 207 | interpr2.cxx:ScTrunc | IMPLEMENTED_MATCH | +| UPPER | 6.20.27 | ocUpper | 136 | interpr1.cxx:ScUpper | IMPLEMENTED_MATCH | +| VALUE | 6.13.34 | ocValue | 141 | interpr1.cxx:ScValue | IMPLEMENTED_MATCH (ODF 1.4: non-text impl-defined) | +| VAR | 6.18.82 | ocVar | 231 | interpr3.cxx | IMPLEMENTED_MATCH | +| VARP | 6.18.84 | ocVarP | 232 | interpr3.cxx | IMPLEMENTED_MATCH | +| VLOOKUP | 6.14.12 | ocVLookup | 286 | interpr1.cxx:ScVLookup | IMPLEMENTED_MATCH (ODF 1.4: unsorted data impl-defined) | +| WEEKDAY | 6.10.21 | ocGetDayOfWeek | 366 | interpr2.cxx:ScGetDayOfWeek | IMPLEMENTED_MATCH | +| YEAR | 6.10.24 | ocGetYear | 106 | interpr2.cxx:ScGetYear | IMPLEMENTED_MATCH | + +**Note:** IFNA (§6.15.6) and SKEWP (§6.18.68) were implemented in Milestone B but are NOT Small Group functions — IFNA is Large Group only, SKEWP is Medium Group only. + +--- + +## 7. Explicit Small Group Allowances (§2.3.2.F and G) + +| Allowance | Section | Description | Status | +|-----------|---------|-------------|--------| +| SG-ALW-001 | 2.3.2.F | References containing more than one area need not be evaluated | Documented — AOO returns as-is for ref lists | +| SG-ALW-002 | 2.3.2.G | Inline arrays need not be implemented | Documented — inline arrays not required for Small Group | +| SG-ALW-003 | 2.3.2.G | Complex numbers need not be implemented | Documented — complex functions not required | +| SG-ALW-004 | 2.3.2.G | Reference union operator (~) need not be implemented | Documented — union not required for Small Group | + +**Finding:** These are explicit permissions to omit, not conformance failures. + +--- + +## 8. Summary Counts + +| Category | Total | Status | Count | +|----------|-------|--------|-------| +| Basic Limits | 4 | CONFIRMED structurally / UNVERIFIED runtime | 4 confirmed, 0 missing | +| Syntax | 11 | CONFIRMED | 11 confirmed, 0 missing | +| Conversions | 5 | CONFIRMED | 5 confirmed, 0 missing | +| Operators | 14 | CONFIRMED | 14 confirmed, 0 missing | +| Functions | 110 | IMPLEMENTED_MATCH | 110 implemented, 0 missing | +| Allowances | 4 | Documented | 4 documented | + +**Grand total: 148 requirements, 0 missing, 0 partial.** + +--- + +## 9. Known Semantic Differences (ODF 1.4 vs AOO) + +| Function/Area | Section | AOO Behavior | ODF 1.4 Normative | Severity | Source | +|---------------|---------|-------------|-------------------|----------|--------| +| INDEX row-vector single-arg | 6.14.6 | Returns column (legacy) | Error (ODF 1.4 removed rule) | Fixed in Milestone A | interpr1.cxx; KNOWN-LIMITATIONS:71 | +| CONVERT atm | 6.16.18 | 101324.996583 Pa | 101325.1 Pa | Fixed in Milestone C | interpr2.cxx; KNOWN-LIMITATIONS:72 | +| DATE pre-1583 | 6.10.2 | #VALUE! before 15 Oct 1582 | Support from 1583; earlier impl-defined | Documented impl-defined | interpr2.cxx; IMPLEMENTATION-DEFINED:155 | +| COUNTA empty cells | 6.13.7 | ODF 1.3 semantics | ODF 1.4 changed empty-cell handling | UNVERIFIED | interpr1.cxx:ScCount2 | +| COUNTBLANK "" | 6.13.8 | Unverified | ODF 1.4: "" case impl-defined | UNVERIFIED | interpr1.cxx:ScCountEmptyCells | + +--- + +## 10. Runtime-Verification Limitations + +The following could not be verified at runtime because no configured AOO build tree exists in this environment: +- All 4 Basic Limits requirements (structural confirmation only) +- Runtime behavior of all 110 Small Group functions +- Error propagation edge cases +- Locale-sensitive conversions +- ODF save/reload round-trip + +Static source tracing confirms all opcodes, implementations, dispatch, and metadata are present. + +--- + +## 11. Prioritized Candidate Gaps for Next Implementation Milestone + +| Priority | Gap | Category | Rationale | Effort | +|----------|-----|----------|-----------|--------| +| 1 | COUNTA ODF 1.4 empty-cell semantics | Semantic difference | ODF 1.4 changed COUNTA/COUNTBLANK empty-cell handling; AOO uses ODF 1.3 semantics | Medium | +| 2 | COUNTBLANK "" impl-defined | Semantic difference | ODF 1.4 marks "" case as impl-defined; AOO behavior unverified | Low | +| 3 | DATE pre-1583 proleptic Gregorian | Semantic difference | YEAR/MONTH/DAY of pre-1583 serial computed proleptic Gregorian with no validity check | Low | +| 4 | INDEX row-vector compatibility | Semantic difference | Milestone A fixed ODF 1.4 behavior; legacy ODF 1.3 documents may break | High (regression risk) | + +**Recommended next milestone:** Small Group semantic conformance — verify and correct COUNTA/COUNTBLANK empty-cell semantics per ODF 1.4, verify DATE pre-1583 behavior, and assess INDEX row-vector regression risk. + +--- + +## 12. What Was NOT Checked + +- Runtime execution of any function (no build available) +- ODF save/reload round-trip +- Excel import/export of function names +- Function wizard integration +- Numerical precision beyond 48-bit integer handling diff --git a/openformula-test-gap-analysis.md b/openformula-test-gap-analysis.md index be5e3e5062..80122d75c3 100644 --- a/openformula-test-gap-analysis.md +++ b/openformula-test-gap-analysis.md @@ -16,7 +16,7 @@ Source-of-truth: `test/aoo-test/`, `test/odf-validate/`, and AOO source. Finding - **[CONFIRMED]** Includes IFNA (line 162), SKEWP (line 329), BIT functions. - **[CONFIRMED]** Does NOT include EASTERSUNDAY. -**[CONFIRMED] Both inventories are ODF 1.2-based baselines.** They are stale relative to ODF 1.4 (2025-10-06): EASTERSUNDAY (ODF 1.3/1.4) is absent from both. They list IFNA/SKEWP as "standard" but AOO does not implement them (see `openformula-functions.tsv`), so the inventories themselves contain functions AOO lacks — false negatives for conformance. +**[CONFIRMED] Both inventories are ODF 1.2-based baselines.** They are stale relative to ODF 1.4 (2025-10-06): EASTERSUNDAY (ODF 1.3/1.4) is absent from both. They list IFNA/SKEWP as "standard" — IFNA and SKEWP were implemented in Milestone B and are no longer missing, so this is no longer a false-negative for conformance. ### test/aoo-test/data/calcval-cases.tsv - Present (test/aoo-test/data/). Formula evaluation test cases. @@ -32,12 +32,14 @@ Source-of-truth: `test/aoo-test/`, `test/odf-validate/`, and AOO source. Finding ### Outdated specification inventories - Both `openformula-functions.txt` files are explicitly ODF 1.2 chapter 6. No ODF 1.3 or ODF 1.4 function inventory exists in test data. - **[GAP]** No machine-readable ODF 1.4 Part 4 function/operator/requirements inventory in `test/`. - ### Missing function tests -- **[CONFIRMED]** IFNA: listed in inventories but NOT implemented in AOO (`xlformula.cxx:404` ocNoName stub only). No AOO function test can pass; inventory lists it as standard — false expectation. -- **[CONFIRMED]** SKEWP: listed in inventories but NOT implemented (`xlformula.cxx:415` ocNoName stub only). `SKEW` (sample) is implemented; SKEWP (population) missing. + +- **[CONFIRMED]** IFNA: listed in inventories; implemented in Milestone B (`SC_OPCODE_IFNA=409`, `ScIfna` in `interpr1.cxx`, dispatch in `interpr4.cxx:3451`). Regression tests added to `calcval-cases14.tsv` (IFNA.num, IFNA.text, IFNA.na.num, IFNA.na.text, IFNA.otherr, IFNA.lazy.ok, IFNA.lazy.err, IFNA.nested, IFNA.ref, IFNA.ref.text, IFNA.range). +- **[CONFIRMED]** SKEWP: listed in inventories; implemented in Milestone B (`SC_OPCODE_SKEWP=410`, `ScSkewP` in `interpr3.cxx`, dispatch in `interpr4.cxx:3695`). Regression tests added to `calcval-cases14.tsv` (SKEWP.sym, SKEWP.pos, SKEWP.neg, SKEWP.vs.skew, SKEWP.one, SKEWP.zero, SKEWP.two, SKEWP.range, SKEWP.array, SKEWP.mixed, SKEWP.err). - **[CONFIRMED]** EASTERSUNDAY: implemented (`interpr2.cxx:261`) but NOT in either function inventory. No dedicated test coverage confirmed. +**[CONFIRMED] IFNA and SKEWP are no longer missing functions.** Both were implemented in Milestone B. The test inventories list them as standard ODF functions, which is now correct. + ### Missing semantic tests - No confirmed semantic test for CONVERT `atm` discrepancy (101324.996583 Pa vs ODF 1.4 1.0132510E+5). - No confirmed semantic test for INDEX row-vector single-argument (ODF 1.4: error; AOO: returns column). @@ -80,9 +82,9 @@ Source-of-truth: `test/aoo-test/`, `test/odf-validate/`, and AOO source. Finding | Category | Gap | Severity | |----------|-----|----------| | Spec inventory | No ODF 1.3/1.4 function/operator inventory in test/ | High | -| Missing functions | IFNA, SKEWP not implemented (inventories falsely list them) | High | +| Missing functions | None — IFNA and SKEWP implemented in Milestone B | None | | Implemented but uninventoried | EASTERSUNDAY not in either test inventory | Medium | -| Semantic tests | CONVERT atm, INDEX row-vector, DATE pre-1583, bit ops, short-circuit | High | +| Semantic tests | CONVERT atm (fixed Milestone C), INDEX row-vector (fixed Milestone A), DATE pre-1583, bit ops, short-circuit | High | | Parser tests | Precedence, intersection, union, quoted labels | Medium | | Round-trip tests | Function-name export aliases, error value type | Medium | -| False confidence | ODF 1.2 inventories listing unimplemented IFNA/SKEWP | High | +| False confidence | None — IFNA/SKEWP now implemented, matching inventory | None |
