DKVPX reader: honor --ifs and --ips instead of hard-coding comma and equals (#2172)

The DKVPX record reader set dkvpxReader.Comma = ',' unconditionally,
ignoring the resolved --ifs value; the key-value separator '=' was
likewise hard-coded in the dkvpx parser, ignoring --ips. So e.g.

  printf 'a=1;b=2\n' | mlr -i dkvpx --ifs semicolon --ojson cat

produced a single field {"a": "1;b=2"} instead of {"a": 1, "b": 2}.

Fixes:

* pkg/dkvpx.Reader gains an Equals field (default '=') alongside Comma.
* The DKVPX record reader now passes the resolved IFS/IPS through,
  validating that each is a single character (mirroring the CSV
  reader's "IFS can only be a single character" error) rather than
  silently ignoring or truncating them.
* The DKVPX record writer already emitted OFS/OPS, but its quoting
  decisions were based on the default separators, so with --ofs
  semicolon a value containing ';' went out unquoted (ambiguous) while
  a value containing ',' was quoted needlessly. Quoting now keys off
  the actual OFS/OPS.

Adds unit tests, regression cases under test/cases/io-dkvpx/, and a
note in the separators reference table.

Discovered while investigating #369; tracked in #2170.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
John Kerl 2026-07-06 17:37:07 -04:00 committed by GitHub
parent 5f152d7669
commit 78363f1cc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 152 additions and 18 deletions

View file

@ -278,7 +278,7 @@ Notes:
| [**YAML**](file-formats.md#yaml) | N/A; documents separated by `---` or single array | N/A; not alterable | Always `:`; not alterable |
| [**DCF**](file-formats.md#dcf-debian-control-file) | N/A; paragraphs separated by blank lines | N/A; not alterable | Always `:`; not alterable |
| [**DKVP**](file-formats.md#dkvp-key-value-pairs) | Default `\n` | Default `,` | Default `=` |
| [**DKVPX**](file-formats.md#dkvpx-key-value-pairs-with-csv-style-quoting) | Default `\n` | Default `,` | Default `=` |
| [**DKVPX**](file-formats.md#dkvpx-key-value-pairs-with-csv-style-quoting) | Default `\n` | Default `,`; must be single-character for input | Default `=`; must be single-character for input |
| [**NIDX**](file-formats.md#nidx-index-numbered-toolkit-style) | Default `\n` | Default space | None |
| [**XTAB**](file-formats.md#xtab-vertical-tabular) | Not used; records are separated by an extra FS | `\n` * | Default: space with repeats |
| [**PPRINT**](file-formats.md#pprint-pretty-printed-tabular) | Default `\n` * | Space with repeats | None |

View file

@ -168,7 +168,7 @@ Notes:
| [**YAML**](file-formats.md#yaml) | N/A; documents separated by `---` or single array | N/A; not alterable | Always `:`; not alterable |
| [**DCF**](file-formats.md#dcf-debian-control-file) | N/A; paragraphs separated by blank lines | N/A; not alterable | Always `:`; not alterable |
| [**DKVP**](file-formats.md#dkvp-key-value-pairs) | Default `\n` | Default `,` | Default `=` |
| [**DKVPX**](file-formats.md#dkvpx-key-value-pairs-with-csv-style-quoting) | Default `\n` | Default `,` | Default `=` |
| [**DKVPX**](file-formats.md#dkvpx-key-value-pairs-with-csv-style-quoting) | Default `\n` | Default `,`; must be single-character for input | Default `=`; must be single-character for input |
| [**NIDX**](file-formats.md#nidx-index-numbered-toolkit-style) | Default `\n` | Default space | None |
| [**XTAB**](file-formats.md#xtab-vertical-tabular) | Not used; records are separated by an extra FS | `\n` * | Default: space with repeats |
| [**PPRINT**](file-formats.md#pprint-pretty-printed-tabular) | Default `\n` * | Space with repeats | None |