@poe-platform/safe-bash 0.1.726 → 0.1.727
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/safe-bash/chunks/{chunk-6VZX7ESE.js → chunk-26N7BLXE.js} +3 -3
- package/dist/safe-bash/chunks/{chunk-ZZ7JQBPX.js → chunk-4A2OLEML.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-LTREB3HX.js → chunk-54MC6XF5.js} +4 -4
- package/dist/safe-bash/chunks/{chunk-Z3CCN6Y2.js → chunk-6J5FUESH.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-YR5RZBWS.js → chunk-6TBFZ5JE.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-6HJNJ625.js → chunk-7MMYQG3P.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-WTZZX4LV.js → chunk-A4MB2KXV.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-EM2JW7ZH.js → chunk-ATYJKRBZ.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-VV24PRPB.js → chunk-AZQOEGP3.js} +1050 -101
- package/dist/safe-bash/chunks/chunk-AZQOEGP3.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-EFMXWUYE.js → chunk-B6JEJ6AT.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-JFGGQUYP.js → chunk-BFXGHT3R.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-RP5IZOOR.js → chunk-BJYV5J65.js} +1050 -101
- package/dist/safe-bash/chunks/chunk-BJYV5J65.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-HNHOPD3P.js → chunk-DIEFWGXO.js} +46 -26
- package/dist/safe-bash/chunks/{chunk-HNHOPD3P.js.map → chunk-DIEFWGXO.js.map} +2 -2
- package/dist/safe-bash/chunks/{chunk-SME47P4B.js → chunk-DV6EZOKM.js} +46 -26
- package/dist/safe-bash/chunks/{chunk-SME47P4B.js.map → chunk-DV6EZOKM.js.map} +2 -2
- package/dist/safe-bash/chunks/{chunk-646RTREQ.js → chunk-EEDOYIPC.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-OFAAHWL5.js → chunk-GCQ5A2T2.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-MJW4KSKV.js → chunk-GLPJEDLY.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-FOOJWH7J.js → chunk-GO5OKPBO.js} +4 -4
- package/dist/safe-bash/chunks/{chunk-5JANWFJ3.js → chunk-GWYXCCGO.js} +4 -4
- package/dist/safe-bash/chunks/{chunk-DPHRNHPT.js → chunk-H6KJ4L22.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-FLX2BZBF.js → chunk-HGBYIDAK.js} +4 -4
- package/dist/safe-bash/chunks/{chunk-VGJIDLZM.js → chunk-KS5VSJYM.js} +15 -8
- package/dist/safe-bash/chunks/chunk-KS5VSJYM.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-PO3Z7W3A.js → chunk-MUHYGUFD.js} +4 -4
- package/dist/safe-bash/chunks/{chunk-5DLGYPGJ.js → chunk-PDSTXORC.js} +126 -58
- package/dist/safe-bash/chunks/chunk-PDSTXORC.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-TIHMU25L.js → chunk-PQ37GDJF.js} +3 -3
- package/dist/safe-bash/chunks/{chunk-OTM5RCWZ.js → chunk-QNEDWYC2.js} +15 -8
- package/dist/safe-bash/chunks/chunk-QNEDWYC2.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-LZ7FUN6K.js → chunk-RHHDOA67.js} +5 -5
- package/dist/safe-bash/chunks/{chunk-DSCL3VA2.js → chunk-SJ3B26XV.js} +4 -4
- package/dist/safe-bash/chunks/{chunk-6JBTVWHH.js → chunk-SWACYEIT.js} +5 -5
- package/dist/safe-bash/chunks/{chunk-7UJW7TYR.js → chunk-TD6NWAUK.js} +126 -58
- package/dist/safe-bash/chunks/chunk-TD6NWAUK.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-Q4I754TV.js → chunk-THOBFD5C.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-XELW5O3R.js → chunk-U2STHT7S.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-5X4SOSTT.js → chunk-UJHE5PTK.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-B6YFFKYG.js → chunk-X4I3RHTC.js} +5 -1
- package/dist/safe-bash/chunks/chunk-X4I3RHTC.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-YOK5UHA7.js → chunk-XKXFX3RH.js} +5 -1
- package/dist/safe-bash/chunks/chunk-XKXFX3RH.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-PLCYP2E5.js → chunk-XV4K3UUF.js} +2 -2
- package/dist/safe-bash/commands/csplit/index.browser.js +2 -2
- package/dist/safe-bash/commands/factor/index.browser.js +2 -2
- package/dist/safe-bash/commands/getopt/index.browser.js +2 -2
- package/dist/safe-bash/commands/hexdump/index.browser.js +2 -2
- package/dist/safe-bash/commands/iconv/index.browser.js +2 -2
- package/dist/safe-bash/commands/internal.d.ts.map +1 -1
- package/dist/safe-bash/commands/internal.js +4 -3
- package/dist/safe-bash/commands/internal.js.map +1 -1
- package/dist/safe-bash/commands/line-endings/index.browser.js +2 -2
- package/dist/safe-bash/commands/llm/index.browser.js +4 -4
- package/dist/safe-bash/commands/network/index.browser.js +4 -4
- package/dist/safe-bash/commands/node/index.browser.js +4 -4
- package/dist/safe-bash/commands/pandoc/index.js.map +1 -1
- package/dist/safe-bash/commands/pr/index.browser.js +3 -3
- package/dist/safe-bash/commands/python/index.browser.js +2 -2
- package/dist/safe-bash/commands/record-buffer.d.ts.map +1 -1
- package/dist/safe-bash/commands/record-buffer.js +12 -4
- package/dist/safe-bash/commands/record-buffer.js.map +1 -1
- package/dist/safe-bash/commands/regex-execution/bounded-provider.d.ts.map +1 -1
- package/dist/safe-bash/commands/regex-execution/bounded-provider.js +75 -8
- package/dist/safe-bash/commands/regex-execution/bounded-provider.js.map +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/limits.d.ts +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/limits.d.ts.map +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/limits.js +6 -4
- package/dist/safe-bash/commands/regex-execution/ere/limits.js.map +1 -1
- package/dist/safe-bash/commands/regex-execution/portable.d.ts.map +1 -1
- package/dist/safe-bash/commands/regex-execution/portable.js +7 -2
- package/dist/safe-bash/commands/regex-execution/portable.js.map +1 -1
- package/dist/safe-bash/commands/regex-execution/protocol.d.ts +2 -0
- package/dist/safe-bash/commands/regex-execution/protocol.d.ts.map +1 -1
- package/dist/safe-bash/commands/regex-execution/protocol.js +26 -0
- package/dist/safe-bash/commands/regex-execution/protocol.js.map +1 -1
- package/dist/safe-bash/commands/regex-execution/utf8.d.ts +1 -1
- package/dist/safe-bash/commands/regex-execution/utf8.d.ts.map +1 -1
- package/dist/safe-bash/commands/regex-execution/utf8.js +26 -2
- package/dist/safe-bash/commands/regex-execution/utf8.js.map +1 -1
- package/dist/safe-bash/commands/search/grep.d.ts.map +1 -1
- package/dist/safe-bash/commands/search/grep.js +109 -15
- package/dist/safe-bash/commands/search/grep.js.map +1 -1
- package/dist/safe-bash/commands/search/matcher.d.ts +1 -1
- package/dist/safe-bash/commands/search/matcher.d.ts.map +1 -1
- package/dist/safe-bash/commands/search/matcher.js +2 -0
- package/dist/safe-bash/commands/search/matcher.js.map +1 -1
- package/dist/safe-bash/commands/search/shared.d.ts.map +1 -1
- package/dist/safe-bash/commands/search/shared.js +23 -12
- package/dist/safe-bash/commands/search/shared.js.map +1 -1
- package/dist/safe-bash/commands/standard.d.ts.map +1 -1
- package/dist/safe-bash/commands/standard.js +22 -0
- package/dist/safe-bash/commands/standard.js.map +1 -1
- package/dist/safe-bash/commands/streams.d.ts.map +1 -1
- package/dist/safe-bash/commands/streams.js +54 -10
- package/dist/safe-bash/commands/streams.js.map +1 -1
- package/dist/safe-bash/commands/structured/input.d.ts.map +1 -1
- package/dist/safe-bash/commands/structured/input.js +484 -55
- package/dist/safe-bash/commands/structured/input.js.map +1 -1
- package/dist/safe-bash/commands/structured/interpreter.d.ts +3 -0
- package/dist/safe-bash/commands/structured/interpreter.d.ts.map +1 -1
- package/dist/safe-bash/commands/structured/interpreter.js +157 -1
- package/dist/safe-bash/commands/structured/interpreter.js.map +1 -1
- package/dist/safe-bash/commands/structured/jq.d.ts.map +1 -1
- package/dist/safe-bash/commands/structured/jq.js +50 -24
- package/dist/safe-bash/commands/structured/jq.js.map +1 -1
- package/dist/safe-bash/commands/structured/limits.d.ts +5 -0
- package/dist/safe-bash/commands/structured/limits.d.ts.map +1 -1
- package/dist/safe-bash/commands/structured/limits.js +51 -36
- package/dist/safe-bash/commands/structured/limits.js.map +1 -1
- package/dist/safe-bash/commands/structured/numbers.d.ts +1 -0
- package/dist/safe-bash/commands/structured/numbers.d.ts.map +1 -1
- package/dist/safe-bash/commands/structured/numbers.js +32 -0
- package/dist/safe-bash/commands/structured/numbers.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-reader.d.ts +1 -0
- package/dist/safe-bash/commands/text-programs/awk-reader.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-reader.js +41 -5
- package/dist/safe-bash/commands/text-programs/awk-reader.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-retention.d.ts +1 -0
- package/dist/safe-bash/commands/text-programs/awk-retention.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-retention.js +9 -0
- package/dist/safe-bash/commands/text-programs/awk-retention.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-runtime.d.ts +13 -0
- package/dist/safe-bash/commands/text-programs/awk-runtime.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-runtime.js +421 -83
- package/dist/safe-bash/commands/text-programs/awk-runtime.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-values.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-values.js +21 -0
- package/dist/safe-bash/commands/text-programs/awk-values.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/regex.d.ts +15 -2
- package/dist/safe-bash/commands/text-programs/regex.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/regex.js +501 -13
- package/dist/safe-bash/commands/text-programs/regex.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/sed.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/sed.js +242 -102
- package/dist/safe-bash/commands/text-programs/sed.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/shared.d.ts +2 -0
- package/dist/safe-bash/commands/text-programs/shared.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/shared.js +36 -0
- package/dist/safe-bash/commands/text-programs/shared.js.map +1 -1
- package/dist/safe-bash/commands/text.d.ts.map +1 -1
- package/dist/safe-bash/commands/text.js +136 -19
- package/dist/safe-bash/commands/text.js.map +1 -1
- package/dist/safe-bash/commands/tsort/index.browser.js +2 -2
- package/dist/safe-bash/commands/xml/index.browser.js +5 -5
- package/dist/safe-bash/commands/yq/index.browser.js +5 -5
- package/dist/safe-bash/contracts/yield.d.ts +1 -0
- package/dist/safe-bash/contracts/yield.d.ts.map +1 -1
- package/dist/safe-bash/contracts/yield.js +3 -0
- package/dist/safe-bash/contracts/yield.js.map +1 -1
- package/dist/safe-bash/core.browser.js +1052 -256
- package/dist/safe-bash/core.browser.js.map +3 -3
- package/dist/safe-bash/plugins/composition.d.ts +1 -0
- package/dist/safe-bash/plugins/composition.d.ts.map +1 -1
- package/dist/safe-bash/plugins/composition.js +80 -2
- package/dist/safe-bash/plugins/composition.js.map +1 -1
- package/dist/safe-bash/plugins/index.d.ts.map +1 -1
- package/dist/safe-bash/plugins/index.js +2 -2
- package/dist/safe-bash/plugins/index.js.map +1 -1
- package/dist/safe-bash-command-fold/arguments.d.ts +1 -1
- package/dist/safe-bash-command-fold/contracts.d.ts +2 -1
- package/dist/safe-bash-command-fold/engine.d.ts +1 -1
- package/dist/safe-bash-command-fold/index.js +10 -8
- package/dist/safe-bash-command-fold/index.js.map +2 -2
- package/dist/safe-bash-command-sips/index.js +231 -67
- package/dist/safe-bash-command-sips/index.js.map +2 -2
- package/dist/safe-bash-command-unrtf/contracts.d.ts +5 -2
- package/dist/safe-bash-command-unrtf/index.js +6 -5
- package/dist/safe-bash-command-unrtf/index.js.map +2 -2
- package/dist/safe-playwright-cloudflare/browser-run-code.js +22 -6
- package/package.json +2 -2
- package/dist/safe-bash/chunks/chunk-5DLGYPGJ.js.map +0 -7
- package/dist/safe-bash/chunks/chunk-7UJW7TYR.js.map +0 -7
- package/dist/safe-bash/chunks/chunk-B6YFFKYG.js.map +0 -7
- package/dist/safe-bash/chunks/chunk-OTM5RCWZ.js.map +0 -7
- package/dist/safe-bash/chunks/chunk-RP5IZOOR.js.map +0 -7
- package/dist/safe-bash/chunks/chunk-VGJIDLZM.js.map +0 -7
- package/dist/safe-bash/chunks/chunk-VV24PRPB.js.map +0 -7
- package/dist/safe-bash/chunks/chunk-YOK5UHA7.js.map +0 -7
- /package/dist/safe-bash/chunks/{chunk-6VZX7ESE.js.map → chunk-26N7BLXE.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-ZZ7JQBPX.js.map → chunk-4A2OLEML.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-LTREB3HX.js.map → chunk-54MC6XF5.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-Z3CCN6Y2.js.map → chunk-6J5FUESH.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-YR5RZBWS.js.map → chunk-6TBFZ5JE.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-6HJNJ625.js.map → chunk-7MMYQG3P.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-WTZZX4LV.js.map → chunk-A4MB2KXV.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-EM2JW7ZH.js.map → chunk-ATYJKRBZ.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-EFMXWUYE.js.map → chunk-B6JEJ6AT.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-JFGGQUYP.js.map → chunk-BFXGHT3R.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-646RTREQ.js.map → chunk-EEDOYIPC.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-OFAAHWL5.js.map → chunk-GCQ5A2T2.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-MJW4KSKV.js.map → chunk-GLPJEDLY.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-FOOJWH7J.js.map → chunk-GO5OKPBO.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-5JANWFJ3.js.map → chunk-GWYXCCGO.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-DPHRNHPT.js.map → chunk-H6KJ4L22.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-FLX2BZBF.js.map → chunk-HGBYIDAK.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-PO3Z7W3A.js.map → chunk-MUHYGUFD.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-TIHMU25L.js.map → chunk-PQ37GDJF.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-LZ7FUN6K.js.map → chunk-RHHDOA67.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-DSCL3VA2.js.map → chunk-SJ3B26XV.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-6JBTVWHH.js.map → chunk-SWACYEIT.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-Q4I754TV.js.map → chunk-THOBFD5C.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-XELW5O3R.js.map → chunk-U2STHT7S.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-5X4SOSTT.js.map → chunk-UJHE5PTK.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-PLCYP2E5.js.map → chunk-XV4K3UUF.js.map} +0 -0
|
@@ -96,6 +96,8 @@ export class Pattern {
|
|
|
96
96
|
parsed;
|
|
97
97
|
anchored;
|
|
98
98
|
linear = false;
|
|
99
|
+
literalMatch;
|
|
100
|
+
simpleRepeatMatch;
|
|
99
101
|
backreferences = false;
|
|
100
102
|
constructor(source, extended = true, ignoreCase = false, dialect = "sed", modifiers = "") {
|
|
101
103
|
this.ignoreCase = ignoreCase;
|
|
@@ -110,7 +112,11 @@ export class Pattern {
|
|
|
110
112
|
let groups = 0;
|
|
111
113
|
let depth = 0;
|
|
112
114
|
const closedGroups = new Set();
|
|
113
|
-
const characterNode = (character) => ({
|
|
115
|
+
const characterNode = (character) => ({
|
|
116
|
+
type: "character",
|
|
117
|
+
...(ignoreCase ? {} : { literal: character }),
|
|
118
|
+
accepts: candidate => ignoreCase ? candidate.toLowerCase() === character.toLowerCase() : candidate === character,
|
|
119
|
+
});
|
|
114
120
|
const escaped = () => {
|
|
115
121
|
const character = source[offset++];
|
|
116
122
|
if (character === undefined)
|
|
@@ -305,7 +311,7 @@ export class Pattern {
|
|
|
305
311
|
return;
|
|
306
312
|
const { root, counts } = this.parsed;
|
|
307
313
|
budget.step(counts.get(root) + 1);
|
|
308
|
-
await budget.checkpoint();
|
|
314
|
+
await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
309
315
|
// Publish only a finished program. Cancelled or concurrent preparations own
|
|
310
316
|
// separate arrays, so a failed caller cannot leave a partially patched NFA.
|
|
311
317
|
const code = [];
|
|
@@ -318,7 +324,7 @@ export class Pattern {
|
|
|
318
324
|
return;
|
|
319
325
|
yield;
|
|
320
326
|
if (node.type === "character") {
|
|
321
|
-
emit({ kind: "character", accepts: node.accepts });
|
|
327
|
+
emit({ kind: "character", ...(node.literal !== undefined ? { literal: node.literal } : {}), accepts: node.accepts });
|
|
322
328
|
return;
|
|
323
329
|
}
|
|
324
330
|
if (node.type === "backreference") {
|
|
@@ -396,14 +402,97 @@ export class Pattern {
|
|
|
396
402
|
let work = 0;
|
|
397
403
|
for (const ignored of compile(root)) {
|
|
398
404
|
if (++work % 64 === 0) {
|
|
399
|
-
await budget.checkpoint();
|
|
405
|
+
await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
400
406
|
budget.step(0);
|
|
401
407
|
}
|
|
402
408
|
}
|
|
403
409
|
emit({ kind: "match" });
|
|
404
|
-
await budget.checkpoint();
|
|
410
|
+
await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
405
411
|
budget.step(0);
|
|
406
412
|
this.linear = code.every(instruction => instruction.kind === "character" || instruction.kind === "begin" || instruction.kind === "end" || instruction.kind === "match");
|
|
413
|
+
if (this.linear && !this.ignoreCase && this.dialect !== "jq") {
|
|
414
|
+
let validLiteral = true;
|
|
415
|
+
let anchoredStart = false;
|
|
416
|
+
let anchoredEnd = false;
|
|
417
|
+
let literalValue = "";
|
|
418
|
+
for (let i = 0; i < code.length - 1; i++) {
|
|
419
|
+
const inst = code[i];
|
|
420
|
+
if (inst.kind === "begin") {
|
|
421
|
+
if (i === 0)
|
|
422
|
+
anchoredStart = true;
|
|
423
|
+
else {
|
|
424
|
+
validLiteral = false;
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
else if (inst.kind === "end") {
|
|
429
|
+
if (i === code.length - 2)
|
|
430
|
+
anchoredEnd = true;
|
|
431
|
+
else {
|
|
432
|
+
validLiteral = false;
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
else if (inst.kind === "character" && inst.literal !== undefined) {
|
|
437
|
+
literalValue += inst.literal;
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
validLiteral = false;
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
if (validLiteral) {
|
|
445
|
+
this.literalMatch = { value: literalValue, anchoredStart, anchoredEnd, groups: [literalValue] };
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else if (!this.ignoreCase && this.dialect !== "jq" && root.type === "sequence" && this.groupCount <= 1) {
|
|
449
|
+
let startIdx = 0;
|
|
450
|
+
let endIdx = root.nodes.length;
|
|
451
|
+
let anchoredStart = false;
|
|
452
|
+
let anchoredEnd = false;
|
|
453
|
+
if (startIdx < endIdx && root.nodes[startIdx]?.type === "begin") {
|
|
454
|
+
anchoredStart = true;
|
|
455
|
+
startIdx++;
|
|
456
|
+
}
|
|
457
|
+
if (startIdx < endIdx && root.nodes[endIdx - 1]?.type === "end") {
|
|
458
|
+
anchoredEnd = true;
|
|
459
|
+
endIdx--;
|
|
460
|
+
}
|
|
461
|
+
if (startIdx < endIdx) {
|
|
462
|
+
let prefix = "";
|
|
463
|
+
let prefixValid = true;
|
|
464
|
+
for (let i = startIdx; i < endIdx - 1; i++) {
|
|
465
|
+
const n = root.nodes[i];
|
|
466
|
+
if (n.type === "character" && n.literal !== undefined) {
|
|
467
|
+
prefix += n.literal;
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
prefixValid = false;
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
const tail = root.nodes[endIdx - 1];
|
|
475
|
+
const captured = tail.type === "group" && tail.index === 1 && this.groupCount === 1;
|
|
476
|
+
const rawInner = captured ? tail.node : this.groupCount === 0 ? tail : undefined;
|
|
477
|
+
const repeatNode = rawInner?.type === "sequence" && rawInner.nodes.length === 1 ? rawInner.nodes[0] : rawInner;
|
|
478
|
+
if (prefixValid &&
|
|
479
|
+
(anchoredStart || prefix.length > 0) &&
|
|
480
|
+
repeatNode?.type === "repeat" &&
|
|
481
|
+
repeatNode.minimum >= 1 &&
|
|
482
|
+
repeatNode.maximum === Infinity &&
|
|
483
|
+
!repeatNode.lazy &&
|
|
484
|
+
repeatNode.node.type === "character") {
|
|
485
|
+
this.simpleRepeatMatch = {
|
|
486
|
+
prefix,
|
|
487
|
+
anchoredStart,
|
|
488
|
+
anchoredEnd,
|
|
489
|
+
captured,
|
|
490
|
+
minimum: repeatNode.minimum,
|
|
491
|
+
accepts: repeatNode.node.accepts,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
407
496
|
this.backreferences = code.some(instruction => instruction.kind === "backreference");
|
|
408
497
|
this.code = code;
|
|
409
498
|
this.parsed = undefined;
|
|
@@ -417,7 +506,7 @@ export class Pattern {
|
|
|
417
506
|
let checkpoints = 0;
|
|
418
507
|
while (pending.length) {
|
|
419
508
|
if (++checkpoints % 64 === 1)
|
|
420
|
-
await budget.checkpoint();
|
|
509
|
+
await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
421
510
|
budget.step();
|
|
422
511
|
const state = pending.pop();
|
|
423
512
|
if (options.end !== undefined && state.position > options.end)
|
|
@@ -499,12 +588,266 @@ export class Pattern {
|
|
|
499
588
|
}
|
|
500
589
|
return undefined;
|
|
501
590
|
}
|
|
591
|
+
canFindSync() {
|
|
592
|
+
return this.code.length > 0 && this.dialect !== "jq" && Boolean(this.literalMatch || this.simpleRepeatMatch);
|
|
593
|
+
}
|
|
594
|
+
findSyncFast(text, budget, from = 0) {
|
|
595
|
+
if (this.simpleRepeatMatch) {
|
|
596
|
+
const { prefix, anchoredStart, anchoredEnd, captured, minimum, accepts } = this.simpleRepeatMatch;
|
|
597
|
+
if (from > text.length || (anchoredStart && from > 0))
|
|
598
|
+
return undefined;
|
|
599
|
+
let found = -1;
|
|
600
|
+
let matchEnd = -1;
|
|
601
|
+
let groupStart = -1;
|
|
602
|
+
let groupEnd = -1;
|
|
603
|
+
if (anchoredStart) {
|
|
604
|
+
if (text.startsWith(prefix)) {
|
|
605
|
+
const pos = prefix.length;
|
|
606
|
+
let cursor = pos;
|
|
607
|
+
while (cursor < text.length && accepts(text[cursor]))
|
|
608
|
+
cursor++;
|
|
609
|
+
if (cursor - pos >= minimum && (!anchoredEnd || cursor === text.length)) {
|
|
610
|
+
found = 0;
|
|
611
|
+
matchEnd = cursor;
|
|
612
|
+
groupStart = pos;
|
|
613
|
+
groupEnd = cursor;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
let searchFrom = from;
|
|
619
|
+
while (searchFrom <= text.length - prefix.length) {
|
|
620
|
+
const idx = text.indexOf(prefix, searchFrom);
|
|
621
|
+
if (idx < 0)
|
|
622
|
+
break;
|
|
623
|
+
const pos = idx + prefix.length;
|
|
624
|
+
let cursor = pos;
|
|
625
|
+
while (cursor < text.length && accepts(text[cursor]))
|
|
626
|
+
cursor++;
|
|
627
|
+
if (cursor - pos >= minimum && (!anchoredEnd || cursor === text.length)) {
|
|
628
|
+
found = idx;
|
|
629
|
+
matchEnd = cursor;
|
|
630
|
+
groupStart = pos;
|
|
631
|
+
groupEnd = cursor;
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
searchFrom = idx + 1;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
const positionsTried = anchoredStart ? 1 : found >= 0 ? found - from + 1 : text.length - from + 1;
|
|
638
|
+
const len = found >= 0 ? matchEnd - found : 0;
|
|
639
|
+
budget.step(positionsTried * 2 + (found >= 0 ? this.code.length * 2 + len : 0));
|
|
640
|
+
if (found < 0)
|
|
641
|
+
return undefined;
|
|
642
|
+
if (len > budget.maxBufferBytes)
|
|
643
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
644
|
+
const full = text.slice(found, matchEnd);
|
|
645
|
+
const groups = captured ? [full, text.slice(groupStart, groupEnd)] : [full];
|
|
646
|
+
return { start: found, end: matchEnd, groups };
|
|
647
|
+
}
|
|
648
|
+
const { value, anchoredStart, anchoredEnd, groups } = this.literalMatch;
|
|
649
|
+
const len = value.length;
|
|
650
|
+
if (from > text.length || (anchoredStart && from > 0))
|
|
651
|
+
return undefined;
|
|
652
|
+
let found = -1;
|
|
653
|
+
if (anchoredStart && anchoredEnd) {
|
|
654
|
+
if (from === 0 && text.length === len && text === value)
|
|
655
|
+
found = 0;
|
|
656
|
+
}
|
|
657
|
+
else if (anchoredStart) {
|
|
658
|
+
if (from === 0 && text.startsWith(value))
|
|
659
|
+
found = 0;
|
|
660
|
+
}
|
|
661
|
+
else if (anchoredEnd) {
|
|
662
|
+
const candidate = text.length - len;
|
|
663
|
+
if (candidate >= from && text.endsWith(value))
|
|
664
|
+
found = candidate;
|
|
665
|
+
}
|
|
666
|
+
else {
|
|
667
|
+
found = text.indexOf(value, from);
|
|
668
|
+
}
|
|
669
|
+
const positionsTried = anchoredStart ? 1 : found >= 0 ? found - from + 1 : text.length - from + 1;
|
|
670
|
+
budget.step(positionsTried * 2 + (found >= 0 ? this.code.length * 2 + len : 0));
|
|
671
|
+
if (found < 0)
|
|
672
|
+
return undefined;
|
|
673
|
+
if (len > budget.maxBufferBytes)
|
|
674
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
675
|
+
return { start: found, end: found + len, groups };
|
|
676
|
+
}
|
|
677
|
+
tryFindSync(text, budget, from = 0) {
|
|
678
|
+
if (this.code.length && this.simpleRepeatMatch && this.dialect !== "jq") {
|
|
679
|
+
const initialCheck = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
680
|
+
if (initialCheck)
|
|
681
|
+
return initialCheck.then(() => this.find(text, budget, from));
|
|
682
|
+
return this.execSimpleRepeat(text, budget, from);
|
|
683
|
+
}
|
|
684
|
+
if (!this.code.length || !this.literalMatch || this.dialect === "jq") {
|
|
685
|
+
return this.find(text, budget, from);
|
|
686
|
+
}
|
|
687
|
+
const initialCheck = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
688
|
+
if (initialCheck)
|
|
689
|
+
return initialCheck.then(() => this.find(text, budget, from));
|
|
690
|
+
const { value, anchoredStart, anchoredEnd, groups } = this.literalMatch;
|
|
691
|
+
const len = value.length;
|
|
692
|
+
if (from > text.length || (anchoredStart && from > 0))
|
|
693
|
+
return undefined;
|
|
694
|
+
let found = -1;
|
|
695
|
+
if (anchoredStart && anchoredEnd) {
|
|
696
|
+
if (from === 0 && text.length === len && text === value)
|
|
697
|
+
found = 0;
|
|
698
|
+
}
|
|
699
|
+
else if (anchoredStart) {
|
|
700
|
+
if (from === 0 && text.startsWith(value))
|
|
701
|
+
found = 0;
|
|
702
|
+
}
|
|
703
|
+
else if (anchoredEnd) {
|
|
704
|
+
const candidate = text.length - len;
|
|
705
|
+
if (candidate >= from && text.endsWith(value))
|
|
706
|
+
found = candidate;
|
|
707
|
+
}
|
|
708
|
+
else {
|
|
709
|
+
found = text.indexOf(value, from);
|
|
710
|
+
}
|
|
711
|
+
const positionsTried = anchoredStart ? 1 : found >= 0 ? found - from + 1 : text.length - from + 1;
|
|
712
|
+
const stepCount = positionsTried * 2 + (found >= 0 ? this.code.length * 2 + len : 0);
|
|
713
|
+
budget.step(stepCount);
|
|
714
|
+
if (stepCount >= 64) {
|
|
715
|
+
const midCheck = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
716
|
+
if (midCheck) {
|
|
717
|
+
if (found < 0)
|
|
718
|
+
return midCheck.then(() => undefined);
|
|
719
|
+
if (len > budget.maxBufferBytes)
|
|
720
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
721
|
+
return midCheck.then(() => ({ start: found, end: found + len, groups }));
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
if (found < 0)
|
|
725
|
+
return undefined;
|
|
726
|
+
if (len > budget.maxBufferBytes)
|
|
727
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
728
|
+
const endCheck = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
729
|
+
if (endCheck)
|
|
730
|
+
return endCheck.then(() => ({ start: found, end: found + len, groups }));
|
|
731
|
+
return { start: found, end: found + len, groups };
|
|
732
|
+
}
|
|
733
|
+
execSimpleRepeat(text, budget, from) {
|
|
734
|
+
const { prefix, anchoredStart, anchoredEnd, captured, minimum, accepts } = this.simpleRepeatMatch;
|
|
735
|
+
if (from > text.length || (anchoredStart && from > 0))
|
|
736
|
+
return undefined;
|
|
737
|
+
let found = -1;
|
|
738
|
+
let matchEnd = -1;
|
|
739
|
+
let groupStart = -1;
|
|
740
|
+
let groupEnd = -1;
|
|
741
|
+
if (anchoredStart) {
|
|
742
|
+
if (text.startsWith(prefix)) {
|
|
743
|
+
const pos = prefix.length;
|
|
744
|
+
let cursor = pos;
|
|
745
|
+
while (cursor < text.length && accepts(text[cursor]))
|
|
746
|
+
cursor++;
|
|
747
|
+
if (cursor - pos >= minimum && (!anchoredEnd || cursor === text.length)) {
|
|
748
|
+
found = 0;
|
|
749
|
+
matchEnd = cursor;
|
|
750
|
+
groupStart = pos;
|
|
751
|
+
groupEnd = cursor;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
else {
|
|
756
|
+
let searchFrom = from;
|
|
757
|
+
while (searchFrom <= text.length - prefix.length) {
|
|
758
|
+
const idx = text.indexOf(prefix, searchFrom);
|
|
759
|
+
if (idx < 0)
|
|
760
|
+
break;
|
|
761
|
+
const pos = idx + prefix.length;
|
|
762
|
+
let cursor = pos;
|
|
763
|
+
while (cursor < text.length && accepts(text[cursor]))
|
|
764
|
+
cursor++;
|
|
765
|
+
if (cursor - pos >= minimum && (!anchoredEnd || cursor === text.length)) {
|
|
766
|
+
found = idx;
|
|
767
|
+
matchEnd = cursor;
|
|
768
|
+
groupStart = pos;
|
|
769
|
+
groupEnd = cursor;
|
|
770
|
+
break;
|
|
771
|
+
}
|
|
772
|
+
searchFrom = idx + 1;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
const positionsTried = anchoredStart ? 1 : found >= 0 ? found - from + 1 : text.length - from + 1;
|
|
776
|
+
const len = found >= 0 ? matchEnd - found : 0;
|
|
777
|
+
const stepCount = positionsTried * 2 + (found >= 0 ? this.code.length * 2 + len : 0);
|
|
778
|
+
budget.step(stepCount);
|
|
779
|
+
const finish = () => {
|
|
780
|
+
if (found < 0)
|
|
781
|
+
return undefined;
|
|
782
|
+
if (len > budget.maxBufferBytes)
|
|
783
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
784
|
+
const full = text.slice(found, matchEnd);
|
|
785
|
+
const groups = captured ? [full, text.slice(groupStart, groupEnd)] : [full];
|
|
786
|
+
return { start: found, end: matchEnd, groups };
|
|
787
|
+
};
|
|
788
|
+
if (stepCount >= 64) {
|
|
789
|
+
const midCheck = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
790
|
+
if (midCheck)
|
|
791
|
+
return midCheck.then(finish);
|
|
792
|
+
}
|
|
793
|
+
const endCheck = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
794
|
+
if (endCheck)
|
|
795
|
+
return endCheck.then(finish);
|
|
796
|
+
return finish();
|
|
797
|
+
}
|
|
502
798
|
async find(text, budget, from = 0) {
|
|
503
799
|
if (!this.code.length)
|
|
504
800
|
await this.prepare(budget);
|
|
505
801
|
if (this.dialect === "jq")
|
|
506
802
|
return (await this.findJq(text, budget, from))?.match;
|
|
507
|
-
|
|
803
|
+
if (this.simpleRepeatMatch) {
|
|
804
|
+
const initialCheck = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
805
|
+
if (initialCheck)
|
|
806
|
+
await initialCheck;
|
|
807
|
+
return await this.execSimpleRepeat(text, budget, from);
|
|
808
|
+
}
|
|
809
|
+
const initialCheck = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
810
|
+
if (initialCheck)
|
|
811
|
+
await initialCheck;
|
|
812
|
+
if (this.literalMatch) {
|
|
813
|
+
const { value, anchoredStart, anchoredEnd, groups } = this.literalMatch;
|
|
814
|
+
const len = value.length;
|
|
815
|
+
if (from > text.length || (anchoredStart && from > 0))
|
|
816
|
+
return undefined;
|
|
817
|
+
let found = -1;
|
|
818
|
+
if (anchoredStart && anchoredEnd) {
|
|
819
|
+
if (from === 0 && text.length === len && text === value)
|
|
820
|
+
found = 0;
|
|
821
|
+
}
|
|
822
|
+
else if (anchoredStart) {
|
|
823
|
+
if (from === 0 && text.startsWith(value))
|
|
824
|
+
found = 0;
|
|
825
|
+
}
|
|
826
|
+
else if (anchoredEnd) {
|
|
827
|
+
const candidate = text.length - len;
|
|
828
|
+
if (candidate >= from && text.endsWith(value))
|
|
829
|
+
found = candidate;
|
|
830
|
+
}
|
|
831
|
+
else {
|
|
832
|
+
found = text.indexOf(value, from);
|
|
833
|
+
}
|
|
834
|
+
const positionsTried = anchoredStart ? 1 : found >= 0 ? found - from + 1 : text.length - from + 1;
|
|
835
|
+
const stepCount = positionsTried * 2 + (found >= 0 ? this.code.length * 2 + len : 0);
|
|
836
|
+
budget.step(stepCount);
|
|
837
|
+
if (stepCount >= 64) {
|
|
838
|
+
const midCheck = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
839
|
+
if (midCheck)
|
|
840
|
+
await midCheck;
|
|
841
|
+
}
|
|
842
|
+
if (found < 0)
|
|
843
|
+
return undefined;
|
|
844
|
+
if (len > budget.maxBufferBytes)
|
|
845
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
846
|
+
const endCheck = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
847
|
+
if (endCheck)
|
|
848
|
+
await endCheck;
|
|
849
|
+
return { start: found, end: found + len, groups };
|
|
850
|
+
}
|
|
508
851
|
let units = 0;
|
|
509
852
|
const work = (count = 1) => {
|
|
510
853
|
budget.step(count);
|
|
@@ -512,7 +855,7 @@ export class Pattern {
|
|
|
512
855
|
if (units < 64)
|
|
513
856
|
return undefined;
|
|
514
857
|
units %= 64;
|
|
515
|
-
return budget.checkpoint();
|
|
858
|
+
return (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
516
859
|
};
|
|
517
860
|
if (this.linear) {
|
|
518
861
|
for (let start = from; start <= text.length && (!this.anchored || start === 0); start++) {
|
|
@@ -535,7 +878,7 @@ export class Pattern {
|
|
|
535
878
|
if (copied)
|
|
536
879
|
await copied;
|
|
537
880
|
const match = { start, end: position, groups: [text.slice(start, position)] };
|
|
538
|
-
await budget.checkpoint();
|
|
881
|
+
await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
539
882
|
return match;
|
|
540
883
|
}
|
|
541
884
|
}
|
|
@@ -754,7 +1097,7 @@ export class Pattern {
|
|
|
754
1097
|
const end = bestCaptures[index * 2 + 1];
|
|
755
1098
|
groups.push(begin === undefined || end === undefined ? undefined : text.slice(begin, end));
|
|
756
1099
|
}
|
|
757
|
-
await budget.checkpoint();
|
|
1100
|
+
await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
758
1101
|
return { start: bestStart, end: bestEnd, groups };
|
|
759
1102
|
}
|
|
760
1103
|
return undefined;
|
|
@@ -771,7 +1114,7 @@ async function replacementLength(replacement, match, budget, available, syntax)
|
|
|
771
1114
|
let tokens = 0;
|
|
772
1115
|
for (let index = 0; index < replacement.length; index++) {
|
|
773
1116
|
if (tokens++ % 256 === 0)
|
|
774
|
-
await budget.checkpoint();
|
|
1117
|
+
await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
775
1118
|
budget.step();
|
|
776
1119
|
const character = replacement[index];
|
|
777
1120
|
let size = 1;
|
|
@@ -801,7 +1144,7 @@ async function replacementText(replacement, match, buffer, budget, syntax) {
|
|
|
801
1144
|
let tokens = 0;
|
|
802
1145
|
for (let index = 0; index < replacement.length; index++) {
|
|
803
1146
|
if (tokens++ % 256 === 0)
|
|
804
|
-
await budget.checkpoint();
|
|
1147
|
+
await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
805
1148
|
budget.step();
|
|
806
1149
|
const character = replacement[index];
|
|
807
1150
|
if (character !== "&" && (character !== "\\" || index + 1 === replacement.length))
|
|
@@ -828,7 +1171,152 @@ async function replacementText(replacement, match, buffer, budget, syntax) {
|
|
|
828
1171
|
}
|
|
829
1172
|
await buffer.append(replacement, literal);
|
|
830
1173
|
}
|
|
1174
|
+
function expandReplacementSync(replacement, match, budget, available, syntax) {
|
|
1175
|
+
if (!replacement.includes("&") && !replacement.includes("\\")) {
|
|
1176
|
+
budget.step(replacement.length * 2 + 1);
|
|
1177
|
+
if (replacement.length > available)
|
|
1178
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
1179
|
+
return replacement;
|
|
1180
|
+
}
|
|
1181
|
+
let out = "";
|
|
1182
|
+
for (let index = 0; index < replacement.length; index++) {
|
|
1183
|
+
budget.step();
|
|
1184
|
+
const character = replacement[index];
|
|
1185
|
+
let piece = character;
|
|
1186
|
+
if (character === "&") {
|
|
1187
|
+
budget.step();
|
|
1188
|
+
piece = match.groups[0] ?? "";
|
|
1189
|
+
}
|
|
1190
|
+
else if (character === "\\" && index + 1 < replacement.length) {
|
|
1191
|
+
budget.step();
|
|
1192
|
+
const next = replacement[++index];
|
|
1193
|
+
if (syntax === "awk") {
|
|
1194
|
+
piece = next === "&" || next === "\\" ? next : `\\${next}`;
|
|
1195
|
+
}
|
|
1196
|
+
else if (next >= "0" && next <= "9") {
|
|
1197
|
+
budget.step();
|
|
1198
|
+
piece = match.groups[Number(next)] ?? "";
|
|
1199
|
+
}
|
|
1200
|
+
else {
|
|
1201
|
+
piece = next === "n" ? "\n" : next === "t" ? "\t" : next;
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
if (piece.length > available - out.length)
|
|
1205
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
1206
|
+
out += piece;
|
|
1207
|
+
}
|
|
1208
|
+
budget.step(out.length + 1);
|
|
1209
|
+
return out;
|
|
1210
|
+
}
|
|
1211
|
+
export function trySubstituteSync(text, pattern, replacement, budget, global, occurrence = 1, syntax = "sed") {
|
|
1212
|
+
if (pattern.canFindSync() && text.length <= 4096 && replacement.length <= 256) {
|
|
1213
|
+
const check = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
1214
|
+
if (check)
|
|
1215
|
+
return substitute(text, pattern, replacement, budget, global, occurrence, syntax);
|
|
1216
|
+
let search = 0;
|
|
1217
|
+
let consumed = 0;
|
|
1218
|
+
let previousEnd = -1;
|
|
1219
|
+
let encountered = 0;
|
|
1220
|
+
let count = 0;
|
|
1221
|
+
let out = "";
|
|
1222
|
+
while (search <= text.length) {
|
|
1223
|
+
budget.step();
|
|
1224
|
+
const match = pattern.findSyncFast(text, budget, search);
|
|
1225
|
+
if (!match)
|
|
1226
|
+
break;
|
|
1227
|
+
if (match.start === match.end && match.start === previousEnd) {
|
|
1228
|
+
search = match.end + 1;
|
|
1229
|
+
continue;
|
|
1230
|
+
}
|
|
1231
|
+
encountered++;
|
|
1232
|
+
if (encountered >= occurrence) {
|
|
1233
|
+
const prefixLen = match.start - consumed;
|
|
1234
|
+
if (out.length + prefixLen > budget.maxBufferBytes) {
|
|
1235
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
1236
|
+
}
|
|
1237
|
+
if (prefixLen > 0)
|
|
1238
|
+
out += text.slice(consumed, match.start);
|
|
1239
|
+
const rep = expandReplacementSync(replacement, match, budget, budget.maxBufferBytes - out.length, syntax);
|
|
1240
|
+
out += rep;
|
|
1241
|
+
consumed = match.end;
|
|
1242
|
+
count++;
|
|
1243
|
+
if (!global)
|
|
1244
|
+
break;
|
|
1245
|
+
}
|
|
1246
|
+
previousEnd = match.end;
|
|
1247
|
+
search = match.end === match.start ? match.end + 1 : match.end;
|
|
1248
|
+
}
|
|
1249
|
+
if (count > 0) {
|
|
1250
|
+
const tailLen = text.length - consumed;
|
|
1251
|
+
if (out.length + tailLen > budget.maxBufferBytes) {
|
|
1252
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
1253
|
+
}
|
|
1254
|
+
if (tailLen > 0)
|
|
1255
|
+
out += text.slice(consumed);
|
|
1256
|
+
}
|
|
1257
|
+
else {
|
|
1258
|
+
out = budget.check(text);
|
|
1259
|
+
}
|
|
1260
|
+
const postCheck = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
1261
|
+
if (postCheck)
|
|
1262
|
+
return postCheck.then(() => ({ text: out, count }));
|
|
1263
|
+
return { text: out, count };
|
|
1264
|
+
}
|
|
1265
|
+
if (!global && occurrence === 1 && !replacement.includes("&") && !replacement.includes("\\")) {
|
|
1266
|
+
const check = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
1267
|
+
if (check)
|
|
1268
|
+
return substitute(text, pattern, replacement, budget, global, occurrence, syntax);
|
|
1269
|
+
budget.step();
|
|
1270
|
+
const matchOrPromise = pattern.tryFindSync(text, budget, 0);
|
|
1271
|
+
if (matchOrPromise instanceof Promise) {
|
|
1272
|
+
return matchOrPromise.then(match => {
|
|
1273
|
+
if (!match) {
|
|
1274
|
+
budget.step(0);
|
|
1275
|
+
return { text: budget.check(text), count: 0 };
|
|
1276
|
+
}
|
|
1277
|
+
const newLen = text.length - (match.end - match.start) + replacement.length;
|
|
1278
|
+
if (newLen > budget.maxBufferBytes || match.start + replacement.length > budget.maxBufferBytes) {
|
|
1279
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
1280
|
+
}
|
|
1281
|
+
budget.step(replacement.length * 2 + 1);
|
|
1282
|
+
const out = (match.start === 0 ? "" : text.slice(0, match.start)) + replacement + (match.end === text.length ? "" : text.slice(match.end));
|
|
1283
|
+
return { text: budget.check(out), count: 1 };
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
const match = matchOrPromise;
|
|
1287
|
+
if (!match) {
|
|
1288
|
+
budget.step(0);
|
|
1289
|
+
return { text: budget.check(text), count: 0 };
|
|
1290
|
+
}
|
|
1291
|
+
const newLen = text.length - (match.end - match.start) + replacement.length;
|
|
1292
|
+
if (newLen > budget.maxBufferBytes || match.start + replacement.length > budget.maxBufferBytes) {
|
|
1293
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
1294
|
+
}
|
|
1295
|
+
budget.step(replacement.length * 2 + 1);
|
|
1296
|
+
const out = (match.start === 0 ? "" : text.slice(0, match.start)) + replacement + (match.end === text.length ? "" : text.slice(match.end));
|
|
1297
|
+
return { text: budget.check(out), count: 1 };
|
|
1298
|
+
}
|
|
1299
|
+
return substitute(text, pattern, replacement, budget, global, occurrence, syntax);
|
|
1300
|
+
}
|
|
831
1301
|
export async function substitute(text, pattern, replacement, budget, global, occurrence = 1, syntax = "sed") {
|
|
1302
|
+
if (!global && occurrence === 1 && !replacement.includes("&") && !replacement.includes("\\")) {
|
|
1303
|
+
const check = (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
1304
|
+
if (check)
|
|
1305
|
+
await check;
|
|
1306
|
+
budget.step();
|
|
1307
|
+
const match = await pattern.find(text, budget, 0);
|
|
1308
|
+
if (!match) {
|
|
1309
|
+
budget.step(0);
|
|
1310
|
+
return { text: budget.check(text), count: 0 };
|
|
1311
|
+
}
|
|
1312
|
+
const newLen = text.length - (match.end - match.start) + replacement.length;
|
|
1313
|
+
if (newLen > budget.maxBufferBytes || match.start + replacement.length > budget.maxBufferBytes) {
|
|
1314
|
+
throw new ProgramError("text buffer limit exceeded");
|
|
1315
|
+
}
|
|
1316
|
+
budget.step(replacement.length * 2 + 1);
|
|
1317
|
+
const out = (match.start === 0 ? "" : text.slice(0, match.start)) + replacement + (match.end === text.length ? "" : text.slice(match.end));
|
|
1318
|
+
return { text: budget.check(out), count: 1 };
|
|
1319
|
+
}
|
|
832
1320
|
let search = 0;
|
|
833
1321
|
let consumed = 0;
|
|
834
1322
|
let previousEnd = -1;
|
|
@@ -837,7 +1325,7 @@ export async function substitute(text, pattern, replacement, budget, global, occ
|
|
|
837
1325
|
const result = new ReplacementBuffer(budget);
|
|
838
1326
|
try {
|
|
839
1327
|
while (search <= text.length) {
|
|
840
|
-
await budget.checkpoint();
|
|
1328
|
+
await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
|
|
841
1329
|
budget.step();
|
|
842
1330
|
const match = await pattern.find(text, budget, search);
|
|
843
1331
|
if (!match)
|