aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/sbbuilder/Toml.js
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/modules/sbbuilder/Toml.js')
-rw-r--r--desktop/modules/sbbuilder/Toml.js17
1 files changed, 13 insertions, 4 deletions
diff --git a/desktop/modules/sbbuilder/Toml.js b/desktop/modules/sbbuilder/Toml.js
index 7fd940a..46b9914 100644
--- a/desktop/modules/sbbuilder/Toml.js
+++ b/desktop/modules/sbbuilder/Toml.js
@@ -17,8 +17,11 @@
// set again is activated. Top-level keys are section "".
//
// ponytail: the TOML these files use, one key per line: strings, integers,
-// booleans, one-line arrays. A value spanning lines makes set() throw rather
-// than write a duplicate key; such a file is edited by hand.
+// booleans, one-line arrays. A value with anything but a comment after it
+// (multi-line strings and arrays included) is refused: entries() skips it and
+// set() throws rather than write a duplicate key; such a file is edited by
+// hand. Also not recognised: CRLF line endings, `[ spaced ]` and `[[array]]`
+// headers, and 'literal' keys.
const HEADER = /^\s*\[([A-Za-z0-9_.-]+)\]\s*(#.*)?$/;
const KEY = /^(\s*)(#\s*)?("(?:[^"\\]|\\.)*"|[A-Za-z0-9_-]+)\s*=\s*(.*)$/;
@@ -70,6 +73,12 @@ function val(s, i) {
return { v: v, i: i + m[1].length };
}
+// A whole line's value: the rest of the line must be blank or a comment.
+function whole(s) {
+ const p = val(s, 0);
+ return p && /^\s*(#.*)?$/.test(s.slice(p.i)) ? p : null;
+}
+
// [{name, h, end}]: the header's line and the line after the section. The
// top-level keys are a section "" with its header at -1.
function ranges(lines) {
@@ -91,7 +100,7 @@ function entries(text, section) {
const out = [];
for (let i = r.h + 1; i < r.end; i++) {
const m = KEY.exec(lines[i]);
- const p = m && !m[2] ? val(m[4], 0) : null;
+ const p = m && !m[2] ? whole(m[4]) : null;
if (p) out.push({ key: unkey(m[3]), value: p.v });
}
return out;
@@ -118,7 +127,7 @@ function set(text, section, key, v) {
if (!m) continue;
if (!m[2]) last = i;
if (unkey(m[3]) !== key) continue;
- const p = val(m[4], 0);
+ const p = whole(m[4]);
if (!m[2]) {
if (!p) throw new Error(key + ": a value this page cannot edit; change it in the file");
lines[i] = v === null ? m[1] + "# " + lines[i].slice(m[1].length)