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 2b0e2e7916b882c981c766b68cb8be75b353fbf6
Author: Pedro Giffuni <[email protected]>
AuthorDate: Wed Nov 11 17:15:48 2026 -0500

    docs: OpenFormula Small Group semantic conformance audit (Milestone F)
    
    Source-level audit of COUNTA/COUNTBLANK, INDEX row-vector, criteria syntax, 
and Basic Limits/syntax against ODF 1.4 Part 4. Creates semantic-audit.md, 
semantic-gaps.tsv (15 gaps), and milestone-g-sequence.md. No production source 
modified; no runtime verification performed.
---
 openformula-milestone-g-sequence.md       | 120 ++++++++++++
 openformula-small-group-semantic-audit.md | 310 ++++++++++++++++++++++++++++++
 openformula-small-group-semantic-gaps.tsv |  16 ++
 3 files changed, 446 insertions(+)

diff --git a/openformula-milestone-g-sequence.md 
b/openformula-milestone-g-sequence.md
new file mode 100644
index 0000000000..f8797f675d
--- /dev/null
+++ b/openformula-milestone-g-sequence.md
@@ -0,0 +1,120 @@
+# Milestone G — OpenFormula Small Group Semantic Conformance: Implementation 
Sequence
+
+**Branch:** `openformula`  
+**Baseline:** `9c42008d93` (post-E.1.1)  
+**Source:** `openformula-small-group-semantic-audit.md`, 
`openformula-small-group-semantic-gaps.tsv`  
+**Scope:** Implementation planning only. No code changes in this document.
+
+## Principles
+
+1. **Audit-first:** Implementation follows the F-audit findings; no 
speculative fixes.
+2. **Dependency-ordered:** Changes with no dependencies first; dependent 
changes after.
+3. **Risk-ordered:** Lower-risk, self-contained changes before higher-risk 
behavior changes.
+4. **No LibreOffice code:** All fixes derived from AOO source inspection only.
+5. **No production changes without runtime validation:** All changes deferred 
until a configured AOO build tree exists and calcval can run (currently 
macOS-only).
+
+## Phase G.1 — Zero-Risk Documentation & Test Harness (No Code Changes)
+
+These items require no production source modification and can be completed 
immediately.
+
+| Order | Gap ID | Area | Action | Rationale |
+|---|---|---|---|---|
+| G.1.1 | F-GAP-008 | Basic Limits — strings | Locate `STRING_MAXLEN` 
definition; confirm value >= 32767 or document actual limit | Static lookup; no 
code change |
+| G.1.2 | F-GAP-012 | Syntax — named expressions | Document named expression 
test requirement (pre-defined `MYNAME` not available in calcval harness) | Test 
infrastructure note |
+| G.1.3 | F-GAP-015 | COUNTA/COUNTBLANK | Document scalar `""` vs formula-cell 
`""` distinction as implementation-defined | Audit documentation |
+
+## Phase G.2 — Low-Risk: Criteria Syntax Empty-Cell Fix (ScDBCount)
+
+This is a targeted fix with a clear TODO in source and contained blast radius.
+
+| Order | Gap ID | Area | File | Change | Risk |
+|---|---|---|---|---|---|
+| G.2.1 | F-GAP-004 / F-GAP-005 | Criteria — DCOUNT empty-cell matching | 
`main/sc/source/core/tool/interpr1.cxx:6838-6845` | Address ScDBCount TODO: 
ensure empty cells matched by query are counted when field is missing; adapt 
ScQueryCellIterator callers as noted | Low — isolated to DCOUNT without field; 
documented TODO already exists |
+
+**Dependencies:** None.  
+**Runtime validation needed:** Yes — DCOUNT with empty result cells.
+
+## Phase G.3 — Medium-Risk: COUNTA/COUNTBLANK Behavior Review
+
+These are behavior decisions, not necessarily code changes. ODF 1.4 permits 
implementation-defined behavior for formula cells returning `""`.
+
+| Order | Gap ID | Area | Decision Point | Action If Change Needed | Risk |
+|---|---|---|---|---|---|
+| G.3.1 | F-GAP-001 | COUNTA matrix | Confirm matrix empty-string handling is 
acceptable | None needed (ODF 1.4 silent) | Low |
+| G.3.2 | F-GAP-002 | COUNTBLANK formula-cell `""` | Decide whether to inspect 
formula result for `""` | Modify `ScCountEmptyCells()` cell-type check to also 
check formula result | Medium — behavior change; document as compatibility 
option |
+
+**Dependencies:** G.2.1 (empty-cell iteration patterns shared).  
+**Runtime validation needed:** Yes — COUNTBLANK with formula cells returning 
`""`.
+
+## Phase G.4 — Medium-Risk: INDEX Row-Vector Compatibility
+
+No code change needed for ODF 1.4 conformance (Milestone A already fixed). 
Compatibility option is optional.
+
+| Order | Gap ID | Area | Decision Point | Action If Needed | Risk |
+|---|---|---|---|---|---|
+| G.4.1 | F-GAP-003 | INDEX row-vector | Assess legacy document regression 
from Milestone A fix | Add document-compatibility option if corpus testing 
shows impact | Medium — affects existing documents |
+
+**Dependencies:** None (Milestone A already applied).  
+**Runtime validation needed:** Yes — corpus regression test against existing 
documents.
+
+## Phase G.5 — Low-Risk: Basic Limits Runtime Verification
+
+No code changes expected (no hard limits found). Verification only.
+
+| Order | Gap ID | Area | Test | Expected Result |
+|---|---|---|---|---|
+| G.5.1 | F-GAP-006 | Formula length | 1024+ char formula (1026-char 
`=1+1+...+1`) | Accepted, result 513 |
+| G.5.2 | F-GAP-007 | Parameter count | 30-parameter MAX call | Accepted, 
result 30 |
+| G.5.3 | F-GAP-008 | String length | 32767-char string (after STRING_MAXLEN 
confirmed) | Accepted |
+| G.5.4 | F-GAP-009 | Nesting depth | 7 nested IFs | Accepted, result 1 |
+
+**Dependencies:** None.  
+**Runtime validation needed:** Yes — all four tests.
+
+## Phase G.6 — Low-Risk: Syntax Verification
+
+| Order | Gap ID | Area | Test | Expected Result |
+|---|---|---|---|---|
+| G.6.1 | F-GAP-010 | Operator precedence | `2+3*4=14`, `2^3^2=512` | Correct 
precedence/associativity |
+| G.6.2 | F-GAP-011 | References | Cell and range resolution | Correct values |
+| G.6.3 | F-GAP-013 | Error propagation | `=NA()` → #N/A; error args propagate 
| Correct |
+| G.6.4 | F-GAP-014 | Whitespace | `=2 + 3 * 4` → 14 | Whitespace-transparent |
+
+**Dependencies:** None.  
+**Runtime validation needed:** Yes — all syntax tests.
+
+## Dependency Summary
+
+```
+G.1 (docs/tests, no code) ──┐
+                            ├── G.2 (ScDBCount empty-cell) ──┐
+G.5 (limits verification) ──┤                                ├── G.3 
(COUNTBLANK decision)
+G.6 (syntax verification) ──┤                                │
+G.4 (INDEX compatibility) ──┘                                └── 
(runtime-validated)
+```
+
+## Estimated Implementation Complexity
+
+| Phase | Complexity | Rationale |
+|---|---|---|
+| G.1 (docs) | Trivial | No code changes |
+| G.2 (ScDBCount) | Low | Isolated TODO; contained scope |
+| G.3 (COUNTBLANK) | Medium | Behavior decision; may need compatibility option 
|
+| G.4 (INDEX compat) | Medium | Corpus regression analysis needed |
+| G.5/G.6 (verification) | Low | Test execution only; no code changes |
+
+## Definition of Done for Milestone G
+
+- All G.1 documentation items complete
+- G.2 ScDBCount empty-cell fix implemented (if corpus testing confirms need)
+- G.3 COUNTBLANK behavior documented (change or no-change decision recorded)
+- G.4 INDEX compatibility impact assessed
+- G.5/G.6 all runtime tests executed against built AOO
+- No production changes without corresponding calcval test coverage
+- All changes verified against ODF 1.4 normative expected results
+
+## Deferred Items (Post-G)
+
+- Full function-by-function semantic verification of all 110 Small Group 
functions (requires runtime)
+- ODF save/reload round-trip testing
+- Excel import/export function name alignment
diff --git a/openformula-small-group-semantic-audit.md 
b/openformula-small-group-semantic-audit.md
new file mode 100644
index 0000000000..017ee5fc7b
--- /dev/null
+++ b/openformula-small-group-semantic-audit.md
@@ -0,0 +1,310 @@
+# OpenFormula 1.4 Small Group Semantic Conformance Audit
+
+**Branch:** `openformula`  
+**Baseline:** `9c42008d93`  
+**Scope:** Audit and report only. No production code modifications.  
+**Method:** Source-level static inspection only. No runtime verification 
possible (no AOO build tree; calcval harness macOS-only).
+
+## Normative Source
+
+OASIS Open Document Format for Office Applications (OpenDocument) Version 1.4, 
Part 4: Recalculated Formula (OpenFormula) Format, OASIS Standard, 6 October 
2025.
+
+---
+
+## F.1 COUNTA / COUNTBLANK (§6.13.7–6.13.8)
+
+### Normative Requirement
+
+**COUNTA (§6.13.7):** Counts non-empty cells. Empty string `""` is not blank 
and is counted.
+
+**COUNTBLANK (§6.13.8):** Counts empty cells. Whether a cell returning `""` is 
blank is implementation-defined.
+
+### AOO Implementation Locations
+
+- `ScCount2()` — `main/sc/source/core/tool/interpr1.cxx:3834`
+- `ScCountEmptyCells()` — `main/sc/source/core/tool/interpr1.cxx:4714`
+- `IterateParameters(ifCOUNT2)` — `main/sc/source/core/tool/interpr1.cxx:3487` 
(shared by COUNTA, COUNT, and others)
+- Dispatch: `interpr4.cxx:3591` (ocCount2 → ScCount2), `interpr4.cxx:3640` 
(ocCountEmptyCells → ScCountEmptyCells)
+- Declaration: `main/sc/source/core/inc/interpre.hxx:505` (ScCount2), `:526` 
(ScCountEmptyCells)
+
+### Execution Path — COUNTA
+
+`ScCount2()` calls `IterateParameters(ifCOUNT2)` which iterates over 
parameters via a `switch(GetStackType())`:
+
+| Stack Type | Code Path | Behavior |
+|---|---|---|
+| `svString` (literal string, incl. `""`) | interpr1.cxx:3506-3543 → `default` 
branch | `Pop(); nCount++;` — **counts string argument** (empty string counted) 
|
+| `svDouble` (numeric literal) | interpr1.cxx:3546 | Counts |
+| `svSingleRef` (single cell) | interpr1.cxx:3567-3624 | `eCellType != 
CELLTYPE_NONE && eCellType != CELLTYPE_NOTE` → counts non-empty cell |
+| `svDoubleRef` / `svRefList` (range) | interpr1.cxx:3626-3711 | 
`ScCellIterator` over range; `eType != CELLTYPE_NONE && eType != CELLTYPE_NOTE` 
→ counts non-empty cells |
+| `svMatrix` (array) | interpr1.cxx:3713-3760 | `nCount += nC * nR` — **counts 
ALL matrix elements** including strings (no `IsString` check for COUNT2) |
+| `svError` | interpr1.cxx:3762-3774 | `nCount++` — counts error values |
+
+### Execution Path — COUNTBLANK
+
+`ScCountEmptyCells()`:
+
+| Stack Type | Code Path | Behavior |
+|---|---|---|
+| `svSingleRef` | interpr1.cxx:4723-4731 | `eCellType != CELLTYPE_NONE && 
eCellType != CELLTYPE_NOTE` → nCount=1 (not blank), else blank |
+| `svDoubleRef` / `svRefList` | interpr1.cxx:4733-4757 | `ScCellIterator`; 
same cell-type check; result = `nMaxCount - nCount` |
+| `default` | interpr1.cxx:4760 | `SetError(errIllegalParameter)` — scalar 
args not supported |
+
+### Current Behavior vs ODF 1.4
+
+| Scenario | ODF 1.4 Normative | AOO Behavior | Match? |
+|---|---|---|---|
+| Truly empty cell (CELLTYPE_NONE) | COUNTA: not counted; COUNTBLANK: blank | 
Cell type CELLTYPE_NONE → not counted by COUNTA, blank by COUNTBLANK | Yes |
+| Cell with text | COUNTA: counted; COUNTBLANK: not blank | CELLTYPE_STRING → 
counted/not blank | Yes |
+| Cell with number | COUNTA: counted; COUNTBLANK: not blank | CELLTYPE_VALUE → 
counted/not blank | Yes |
+| Scalar `""` argument | COUNTA: counted (not blank) | svString → counted | 
Yes |
+| Formula cell returning `""` | COUNTBLANK: implementation-defined whether 
blank | CELLTYPE_FORMULA ≠ CELLTYPE_NONE → counted by COUNTA, NOT blank by 
COUNTBLANK; formula result not inspected | Implementation-defined; AOO does not 
check formula result |
+| Matrix with empty-string cells | COUNTA: not specified explicitly | `nCount 
+= nC * nR` counts all elements including strings | Counts empty-string cells 
as non-empty |
+| Scalar `""` to COUNTBLANK | Not applicable (COUNTBLANK takes ranges) | 
`SetError(errIllegalParameter)` — only reference types accepted | N/A |
+
+### Conformance Classification
+
+- **COUNTA scalar `""`**: Required by ODF 1.4 — matches (empty string counted 
as non-blank).
+- **COUNTA empty cells**: Required by ODF 1.4 — matches (CELLTYPE_NONE not 
counted).
+- **COUNTBLANK truly empty cells**: Required by ODF 1.4 — matches.
+- **COUNTBLANK formula cell returning `""`**: Implementation-defined (§6.13.8) 
— AOO uses cell-type-only check; does not inspect formula result.
+- **COUNTA matrix with strings**: ODF 1.4 does not explicitly address matrix 
empty-string handling — AOO counts all matrix elements including strings.
+
+### Known Compatibility Risks
+
+- A `ScDBCount` TODO comment (interpr1.cxx:6838-6845) notes that 
`ScQueryCellIterator` only returns pointers to existing cells, so empty cells 
matched by a query are not counted. This affects DCOUNT without a field, not 
COUNTA/COUNTBLANK directly.
+- Changing COUNTBLANK to inspect formula results (treating `""`-returning 
formulas as blank) would be a behavior change affecting existing documents.
+
+### Recommended Implementation Changes
+
+None required for ODF 1.4 conformance (implementation-defined behavior is 
permitted). If a compatibility option is desired, document the current 
cell-type-only behavior and consider adding formula-result inspection as an 
option.
+
+### Suggested Regression Tests
+
+- `COUNTA` over range with truly empty cells, text, numbers, and `""` scalar 
argument
+- `COUNTBLANK` over range with truly empty cells vs. cells containing 
text/numbers
+- `COUNTBLANK` over formula cells returning `""` (document current behavior as 
implementation-defined)
+
+---
+
+## F.2 INDEX Row-Vector Behavior (§6.14.6)
+
+### Normative Requirement
+
+ODF 1.4 §6.14.6: `INDEX` with a single row argument on a single-row range (row 
vector) returns an error. The ODF 1.3 rule allowing the Row argument to act as 
a column offset for row vectors was removed.
+
+### AOO Implementation Location
+
+- `ScIndex()` — `main/sc/source/core/tool/interpr1.cxx:7419`
+- Dispatch: `interpr4.cxx:3650` (ocIndex → ScIndex)
+- Declaration: `main/sc/source/core/inc/interpre.hxx:564`
+- Parameter class: `main/sc/source/core/tool/parclass.cxx:123` (`ocIndex: {{ 
Reference, Value, Value, Value }, 0}`)
+
+### Execution Path — ScIndex
+
+```
+nParamCount = GetByte()           // number of arguments
+nArea     = (nParamCount == 4) ? GetDouble() : 1
+nCol      = (nParamCount >= 3) ? GetDouble() : 0
+nRow      = (nParamCount >= 2) ? GetDouble() : 0
+```
+
+Then `switch(GetStackType())`:
+
+| Stack Type | Behavior |
+|---|---|
+| `svMatrix` | Bounds check against matrix dimensions; vector access when 
nCol==0 or nRow==0 |
+| `svSingleRef` | `if (nCol > 1 || nRow > 1) PushIllegalArgument();` — single 
cell, only row/col 0 or 1 valid |
+| `svDoubleRef` / `svRefList` | Full range bounds checking; returns 
sub-reference or single cell |
+
+### Before and After Milestone A (commit bb58e28fc2)
+
+**Before Milestone A:** A `bRowArray` flag was set when `nParamCount == 2 && 
nRow1 == nRow2` (single-row range with row argument). This caused:
+- Row bounds check to be skipped: `(nRow > 0 && nRow1+nRow-1 > nRow2 && 
!bRowArray)`
+- Alternative row bounds: `(nRow > nCol2 - nCol1 + 1 && bRowArray)` — checked 
against column width
+- Row argument reinterpreted as column: `nCol = (SCCOL) nRow; nRow = 1;`
+
+Effect: `INDEX(H1:L1;3)` returned the 3rd column (value 30) instead of an 
error.
+
+**After Milestone A:** All `bRowArray` logic removed. `INDEX(H1:L1;3)` now:
+- nCol=0, nRow=3
+- svDoubleRef path: `(nRow > 0 && nRow1+nRow-1 > nRow2)` → `(3 > 0 && 1+3-1 > 
1)` → true → `PushIllegalArgument()` → error
+
+This matches ODF 1.4 §6.14.6.
+
+### Conformance Classification
+
+**Required by ODF 1.4** — Fixed in Milestone A. `INDEX(H1:L1;3)` returns error 
as required.
+
+### Known Compatibility Risks
+
+- Legacy ODF 1.3 documents relying on `INDEX(rowvector; n)` returning column n 
will now get an error. Regression risk for document compatibility.
+- Compatibility handling can be isolated: the fix is localized to `ScIndex()`; 
no other code paths depend on `bRowArray`.
+
+### Recommended Implementation Changes
+
+None needed for ODF 1.4 conformance. Consider a document-compatibility option 
if legacy document regression is observed (out of scope for this milestone).
+
+### Suggested Regression Tests
+
+- `INDEX(H1:L1;3)` → error (single-arg row vector)
+- `INDEX(H1:L1;;3)` → column value (column-only arg)
+- `INDEX(D1:D5;6)` → error (row out of range)
+- `INDEX(D1:F3;2;3)` → 2D result
+
+---
+
+## F.3 Criteria Syntax (§4.11.11) — Database Functions
+
+### Normative Requirement
+
+ODF 1.4 §4.11.11: Criteria syntax supported in database functions (DCOUNT, 
DCOUNTA, DSUM, DAVERAGE, DMAX, DMIN, etc.). Criteria support comparison 
operators (`<`, `<=`, `>`, `>=`, `=`, `<>`), text criteria, wildcards, and 
criteria ranges.
+
+### AOO Implementation Locations
+
+- `GetDBParams()` — `main/sc/source/core/tool/interpr1.cxx:6621` (parses 
database + field + criteria range)
+- `DBIterator()` — `main/sc/source/core/tool/interpr1.cxx:6760` (iterates 
matching records for DBSum, DBAverage, DBMax, DBMin, DBProduct)
+- `ScDBCount()` — `main/sc/source/core/tool/interpr1.cxx:6828` (DCOUNT)
+- `ScDBCount2()` — `main/sc/source/core/tool/interpr1.cxx:6882` (DCOUNTA)
+- `ScDBSum()` — `main/sc/source/core/tool/interpr1.cxx:6821` (DSUM)
+- `ScDBAverage()` — `main/sc/source/core/tool/interpr1.cxx:6909` (DAVERAGE)
+- `ScDBMax()` — `main/sc/source/core/tool/interpr1.cxx:6916` (DMAX)
+- `ScDBMin()` — `main/sc/source/core/tool/interpr1.cxx:6923` (DMIN)
+- Operator prefix parsing — `main/sc/source/core/tool/queryparam.cxx:106-144`
+- `ScQueryEntry` struct — `main/sc/inc/global.hxx:797`
+- `ScQueryOp` enum — `main/sc/inc/global.hxx:733-740` (SC_EQUAL, SC_LESS, 
SC_GREATER, SC_LESS_EQUAL, SC_GREATER_EQUAL, SC_NOT_EQUAL)
+
+### Function-to-Opcode Mapping
+
+| Function | Opcode | Implementation |
+|---|---|---|
+| DCOUNT | ocDBCount → SC_OPCODE_DB_COUNT | ScDBCount() |
+| DCOUNTA | ocDBCount2 → SC_OPCODE_DB_COUNT_2 | ScDBCount2() |
+| DSUM | ocDBSum → SC_OPCODE_DB_SUM | ScDBSum() → DBIterator(ifSUM) |
+| DAVERAGE | ocDBAverage → SC_OPCODE_DB_AVERAGE | ScDBAverage() → 
DBIterator(ifAVERAGE) |
+| DMAX | ocDBMax → SC_OPCODE_DB_MAX | ScDBMax() → DBIterator(ifMAX) |
+| DMIN | ocDBMin → SC_OPCODE_DB_MIN | ScDBMin() → DBIterator(ifMIN) |
+
+Name mapping: `main/formula/source/core/resource/core_resource.src:227-228` 
(`DCOUNT` → SC_OPCODE_DB_COUNT, `DCOUNTA` → SC_OPCODE_DB_COUNT_2)
+
+### Criteria Parsing Execution Path
+
+1. Formula compiler parses `DCOUNT(database, field, criteria)` into opcodes 
with three Reference parameters.
+2. `GetDBParams()` pops:
+   - Criteria range (double ref)
+   - Field (double, string, single ref, double ref, or missing)
+   - Database range (double ref)
+3. For each criteria entry, `queryparam.cxx:106-144` parses operator prefixes:
+   - `<>` → SC_NOT_EQUAL
+   - `<=` → SC_LESS_EQUAL
+   - `<` → SC_LESS
+   - `>=` → SC_GREATER_EQUAL
+   - `>` → SC_GREATER
+   - `=` or default → SC_EQUAL
+4. `bQueryByString` set via `IsNumberFormat()` (GetDBParams :6745-6746) — 
determines if criteria is text or numeric
+5. `bRegExp` set via `MayBeRegExp()` (GetDBParams :6748) — enables 
wildcard/RegExp matching
+6. `DBIterator()` iterates matching records using `ScDBQueryDataIterator`
+
+### Current Behavior vs ODF 1.4
+
+| Requirement | ODF 1.4 Normative | AOO Behavior | Match? |
+|---|---|---|---|
+| Comparison operators `<, <=, >, >=, =, <>` | Required | Parsed from criteria 
cell prefix (queryparam.cxx:106-144) | Yes |
+| Text criteria | Required | `bQueryByString` via `IsNumberFormat` | Yes |
+| Wildcards / RegExp | Required | `bRegExp` via `MayBeRegExp` | Yes |
+| Empty criteria field | Field may be omitted (count all matching) | 
`bMissingField` path in ScDBCount | Yes |
+| Criteria range with multiple rows | AND across rows | ScQueryParamBase 
entries | Yes |
+| DCOUNT without field counts all matching records | Required | ScDBCount: 
bMissingField + INTERNAL type → counts all matching | Yes, with TODO limitation 
|
+| DCOUNT with field counts values in field | Required | ScDBQueryDataIterator 
over field column | Yes |
+
+### Known Limitations
+
+**ScDBCount empty-cell limitation (interpr1.cxx:6838-6845):**
+```
+// TODO: currently the QueryIterators only return cell pointers of
+// existing cells, so if a query matches an empty cell there's
+// nothing returned, and therefor not counted!
+```
+This means DCOUNT without a field may undercount when matching records have 
empty cells in the result column.
+
+### Conformance Classification
+
+**Required by ODF 1.4** — Criteria syntax parsing and database function 
evaluation are implemented. The empty-cell matching limitation in ScDBCount is 
a known gap.
+
+### Recommended Implementation Changes
+
+Address the ScDBCount TODO (empty-cell matching) if DCOUNT without field is 
used with empty result cells. This is a targeted fix, not a broad change.
+
+### Suggested Regression Tests
+
+- `DCOUNT(R1:T6;;V1:V2)` with `Age>=30` → 4 (B,C,D,E)
+- `DSUM` with criteria
+- `DAVERAGE`, `DMAX`, `DMIN` with criteria
+- Text criteria, wildcard criteria, empty criteria cell
+
+---
+
+## F.4 Basic Limits and Syntax (§3.7, §5)
+
+### F.4.1 Basic Limits (§3.7)
+
+#### Formula Length — at least 1024 characters
+
+**Source finding:** No explicit formula length limit (MAXFORMULA or 
equivalent) found in `main/sc/source/core/tool/interpr1.cxx`, 
`main/sc/source/core/inc/interpre.hxx`, or 
`main/formula/source/core/api/FormulaCompiler.cxx`. The FormulaCompiler parses 
token arrays dynamically.
+
+**Classification:** Unverifiable by static inspection. Absence of a hard limit 
does not prove conformance. Runtime test required.
+
+#### Function Parameters — at least 30
+
+**Source finding:** `MustHaveParamCount()` family (`interpre.hxx:897-927`) 
enforces per-function min/max parameter counts. No global 30-parameter cap 
found. Individual functions like MAX use `MustHaveParamCountMin` or exact 
counts.
+
+**Classification:** Unverifiable by static inspection. No cap found, but 
runtime test required.
+
+#### ASCII Strings — at least 32767 characters
+
+**Source finding:** `CheckStringResultLen()` (`interpre.hxx:930-936`) checks 
string concatenation against `STRING_MAXLEN`. The `STRING_MAXLEN` definition 
was not located in the sc module headers during this audit.
+
+**Classification:** Unverifiable by static inspection. STRING_MAXLEN value not 
confirmed.
+
+#### Nesting Depth — at least 7 levels
+
+**Source finding:** No nesting depth limit (MAXNEST or equivalent) found in 
FormulaCompiler or ScInterpreter source. No recursion depth enforcement found.
+
+**Classification:** Unverifiable by static inspection. Absence of limit does 
not prove conformance.
+
+### F.4.2 Remaining Syntax Requirements (§5)
+
+| Requirement | Section | AOO Implementation | Status |
+|---|---|---|---|
+| Parenthesized expressions | §5.2 | FormulaCompiler.cxx handles via 
RangeLine/IntersectionLine/UnaryLine | Present, runtime-unverified |
+| Constant Numbers | §5.3 | FormulaCompiler.cxx tokenizes numeric literals | 
Present, runtime-unverified |
+| Constant Strings with quote escaping | §5.4 | FormulaCompiler.cxx tokenizes 
string literals | Present, runtime-unverified |
+| Operator precedence (Table 1) | §5.5 | Parser: UnionLine → IntersectionLine 
→ RangeLine → UnaryLine → binary ops | Present, runtime-unverified |
+| Functions and parameters | §5.6 | FormulaCompiler.cxx compiles function 
calls | Present, runtime-unverified |
+| Nonstandard function names as errors | §5.7 | ocNoName opcode; xlformula.cxx 
stubs | Present, runtime-unverified |
+| Cell and range references | §5.8 | compiler.cxx PopDoubleRef/PopSingleRef | 
Present, runtime-unverified |
+| Simple Named Expressions | §5.11 | compiler.cxx:NameLine (ocName opcode) | 
Present; requires pre-defined name |
+| Error constants and propagation | §5.12 | ocErrNull-ocErrNA in compiler.hrc; 
nGlobalError/SetError in interpre.hxx | Present, runtime-unverified |
+| Whitespace handling | §5.14 | ocSpaces → ocIntersect at 
FormulaCompiler.cxx:830-831 | Present, runtime-unverified |
+| Reference intersection `!` | §6.4.12 | interpr1.cxx:ScIntersect | Present, 
runtime-unverified |
+| Reference range `:` | §6.4.11 | interpr1.cxx:ScRangeFunc | Present, 
runtime-unverified |
+
+### Cross-Cutting Finding
+
+**Static source tracing confirms implementation presence, not semantic 
equivalence.** All Small Group syntax and basic limits infrastructure exists in 
source, but none has been verified against ODF 1.4 normative expected results 
at runtime. This is consistent with the E.1/E.1.1 finding that all requirements 
are UNVERIFIED pending runtime execution.
+
+---
+
+## Conformance Summary
+
+| Category | Count | Status |
+|---|---|---|
+| Basic Limits (§3.7) | 4 | Unverifiable statically; no hard limits found |
+| Syntax (§5) | 11 | Implementation present; runtime-unverified |
+| COUNTA/COUNTBLANK (§6.13.7-8) | 2 | Partially matches; formula-cell `""` is 
implementation-defined |
+| INDEX (§6.14.6) | 1 | ODF 1.4 compliant after Milestone A; regression risk |
+| Criteria Syntax (§4.11.11) | 1 | Implemented; ScDBCount empty-cell TODO 
limitation |
+| Operators (§6.4) | 14 | Implementation present; runtime-unverified |
+| Functions (§2.3.2.E) | 110 | Implementation present; runtime-unverified |
+
+**No production code changes are recommended at this audit stage.** Milestone 
G should implement targeted fixes based on this audit's findings, prioritized 
by dependency and risk.
diff --git a/openformula-small-group-semantic-gaps.tsv 
b/openformula-small-group-semantic-gaps.tsv
new file mode 100644
index 0000000000..acbb1a35af
--- /dev/null
+++ b/openformula-small-group-semantic-gaps.tsv
@@ -0,0 +1,16 @@
+GapID  ODF Clause      Requirement     AOO Implementation Location     Current 
Behavior        Classification  Severity        Proposed Next Action    Test 
Coverage Status
+F-GAP-001      §6.13.7 COUNTA counts non-empty cells; empty string "" is not 
blank     main/sc/source/core/tool/interpr1.cxx:3834 (ScCount2 via 
IterateParameters(ifCOUNT2) at :3487)  COUNTA counts scalar string args 
including ""; counts cells where eCellType != CELLTYPE_NONE && != 
CELLTYPE_NOTE; matrix case counts ALL elements including strings; formula cells 
returning "" counted as non-blank based on CELLTYPE_FORMULA (result not 
checked)     Required by ODF 1.4; implementation-defined for formula cel [...]
+F-GAP-002      §6.13.8 COUNTBLANK counts empty cells; cell returning "" 
blankness is implementation-defined    
main/sc/source/core/tool/interpr1.cxx:4714 (ScCountEmptyCells)  COUNTBLANK uses 
cell-type-only check: eCellType != CELLTYPE_NONE && != CELLTYPE_NOTE → not 
blank; truly empty CELLTYPE_NONE cells are blank; formula cells returning "" 
treated as not blank (CELLTYPE_FORMULA != CELLTYPE_NONE); scalar "" argument 
not supported (only references)    Implementation-defined (§6.13.8); differs 
from po [...]
+F-GAP-003      §6.14.6 INDEX single-argument row vector returns error (no 
row-vector shortcut) main/sc/source/core/tool/interpr1.cxx:7419 (ScIndex); 
Milestone A commit bb58e28fc2 removed bRowArray shortcut  INDEX(H1:L1;3) 
returns error (nRow > 1 on single row → PushIllegalArgument); INDEX(H1:L1;;3) 
works (column-only); INDEX on matrix/vector handled per ODF 1.4    Required by 
ODF 1.4; fixed in Milestone A; regression risk for legacy ODF 1.3 documents 
High    Regression-test against existing document [...]
+F-GAP-004      §4.11.11        Criteria syntax supported in database functions 
main/sc/source/core/tool/interpr1.cxx:6621 (GetDBParams), :6760 (DBIterator); 
queryparam.cxx:106-144 (operator prefix parsing)  Criteria operators parsed: 
<>, <=, <, >=, >, =; bQueryByString via IsNumberFormat; bRegExp via 
MayBeRegExp; DBCount has TODO about empty-cell matching 
(interpr1.cxx:6838-6845) Required by ODF 1.4; parser and evaluation present; 
empty-cell matching limitation documented   Medium  Verify criteria match [...]
+F-GAP-005      §4.11.11        Database criteria: text criteria, wildcards, 
empty criteria     main/sc/source/core/tool/queryparam.cxx:106-144 (operator 
parsing); interpr1.cxx:6745-6748 (bQueryByString/bRegExp)     Text criteria 
supported via bQueryByString; wildcard/RegExp via MayBeRegExp; empty criteria 
cell (svMissing) handled as missing field   Required by ODF 1.4; partially 
verified Medium  Verify wildcard and text criteria matching      calcval: no 
dedicated wildcard/empty-criteria cases — not covered
+F-GAP-006      §3.7    Formula length at least 1024 characters No explicit 
formula length limit found in main/sc or main/formula source        No 
MAXFORMULA or formula-size enforcement found; FormulaCompiler parses token 
arrays dynamically        Unverifiable (static); absence of hard limit doesn't 
prove conformance  Low     Runtime test with 1024+ char formula    calcval: 
BL-001-1024chars (1026-char expression) — UNVERIFIED
+F-GAP-007      §3.7    At least 30 parameters per function where prototype 
permits     main/sc/source/core/inc/interpre.hxx:897-927 (MustHaveParamCount 
family)        Per-function parameter count enforced via 
MustHaveParamCount/MustHaveParamCountMin; no global 30-param cap found        
Unverifiable (static); no 30-param cap found    Low     Runtime test with 
30-parameter function call    calcval: BL-002-30params (MAX with 30 params) — 
UNVERIFIED
+F-GAP-008      §3.7    Strings up to 32767 ASCII characters    
main/sc/source/core/inc/interpre.hxx:930-936 (CheckStringResultLen vs 
STRING_MAXLEN); STRING_MAXLEN definition not located in sc headers        
String overflow checked via CheckStringResultLen against STRING_MAXLEN; exact 
STRING_MAXLEN value not confirmed in sc module    Unverifiable (static); 
STRING_MAXLEN definition not located     Low     Locate STRING_MAXLEN 
definition; runtime test with 32767-char string    calcval: BL-003-32767chars — 
UNVERIFIED
+F-GAP-009      §3.7    At least 7 nesting levels of functions  No nesting 
depth limit found in FormulaCompiler or ScInterpreter source No MAXNEST or 
recursion depth enforcement found Unverifiable (static); absence of limit 
doesn't prove conformance       Low     Runtime test with 7+ nested functions   
calcval: BL-004-7nesting (7 nested IFs) — UNVERIFIED
+F-GAP-010      §5.5    Operator precedence per Table 1 
main/formula/source/core/api/FormulaCompiler.cxx (parser grammar: UnionLine → 
IntersectionLine → RangeLine → UnaryLine → binary ops)    Parser structure 
exists (RangeLine/IntersectionLine/UnionLine); precedence not verified at 
runtime      Unverifiable (static); parser infrastructure present    Medium  
Runtime precedence test (2+3*4=14, 2^3^2=512)   calcval: SYN-005-precedence, 
SYN-005-power — UNVERIFIED
+F-GAP-011      §5.8    Reference syntax supported      
main/sc/source/core/tool/compiler.cxx (PopDoubleRef/PopSingleRef)       Cell 
and range reference handling present in compiler   Unverifiable (static); 
implementation present   Low     Runtime reference test  calcval: SYN-008-ref, 
SYN-008-range — UNVERIFIED
+F-GAP-012      §5.11   Simple Named Expressions supported      
main/sc/source/core/tool/compiler.cxx:NameLine (ocName opcode)  Named 
expression compilation present; requires pre-defined name not set up in calcval 
harness   Unverifiable (static); harness limitation       Medium  Define named 
expression in test environment; verify     calcval: SYN-009-named (=MYNAME) — 
not directly executable (no name setup)
+F-GAP-013      §5.12   Error syntax and propagation    
main/sc/source/core/inc/interpre.hxx:196 (nGlobalError), :854 (SetError), :263 
(Push substitutes FormulaErrorToken); error constants ocErrNull-ocErrNA in 
compiler.hrc  Error constants and propagation present; not verified against ODF 
1.4 normative results Unverifiable (static)   Medium  Runtime error propagation 
test  calcval: SYN-010-error (=NA() → #N/A), CONV-005-error — UNVERIFIED
+F-GAP-014      §5.14   Whitespace handling     
main/formula/source/core/api/FormulaCompiler.cxx:830-831 (ocSpaces → 
ocIntersect)       Whitespace converted to intersection at compile time; not 
runtime-verified      Unverifiable (static)   Low     Runtime whitespace test 
calcval: SYN-011-whitespace — UNVERIFIED
+F-GAP-015      §6.13.7 / §6.13.8       COUNTA/COUNTBLANK distinction: scalar 
"" vs cell formula returning ""   main/sc/source/core/tool/interpr1.cxx:3487 
(svString case counts ""), :4714 (cell-type-only check for COUNTBLANK)       
AOO distinguishes scalar "" (counted by COUNTA) from cell formula returning "" 
(COUNTBLANK uses cell type, not result)  Implementation-defined; cell-type-only 
approach may not match ODF intent for formula cells returning "" Medium  
Document distinction; consider formula-result insp [...]

Reply via email to