fix(highlight): env -S payload is a full arg list, not a bare interpreter
The attached split-string payload (`-Spython3`, `--split-string=...`) can itself begin with env options or VAR=value assignments before the interpreter: `-S-i python3`, `-SFOO=bar python3`, `--split-string=-u FOO python3`. Rather than taking the payload's first word as the interpreter, re-inject the attached payload into the token stream so it flows through the same option / operand / assignment state machine as a separated payload. Adds the three cases as resolver tests.
This commit is contained in:
parent
558d00020f
commit
7479213c3f
|
|
@ -98,13 +98,21 @@ function pmacs.parse.language_from_shebang(buf)
|
||||||
base = nil
|
base = nil
|
||||||
local seen_env = false
|
local seen_env = false
|
||||||
local skip_next = false
|
local skip_next = false
|
||||||
|
local tokens = {}
|
||||||
for tok in rest:gmatch("%S+") do
|
for tok in rest:gmatch("%S+") do
|
||||||
-- `-S`/`--split-string` introduces a string whose FIRST word is the
|
tokens[#tokens + 1] = tok
|
||||||
-- interpreter. GNU env accepts that value ATTACHED — `-Spython3`,
|
end
|
||||||
-- `-vSpython3` (after no-operand short flags i/v/0), or
|
local i = 1
|
||||||
-- `--split-string=python3` — where the interpreter rides inside the
|
while i <= #tokens do
|
||||||
-- option token. Extract it; the separated forms (`-S python3`) are
|
local tok = tokens[i]
|
||||||
-- handled by simply walking on to the next token.
|
i = i + 1
|
||||||
|
-- `-S`/`--split-string` introduces a complete env argument list,
|
||||||
|
-- not necessarily an interpreter first: it may begin with more env
|
||||||
|
-- options or `VAR=value` assignments. GNU env accepts that value
|
||||||
|
-- ATTACHED — `-Spython3`, `-vSpython3` (after no-operand short flags
|
||||||
|
-- i/v/0), or `--split-string=python3`. Put an attached payload back
|
||||||
|
-- into this token stream so it goes through the same option/operand/
|
||||||
|
-- assignment state machine as a separated payload.
|
||||||
local split_attached =
|
local split_attached =
|
||||||
tok:match("^%-[iv0]*S(.+)$") or tok:match("^%-%-split%-string=(.+)$")
|
tok:match("^%-[iv0]*S(.+)$") or tok:match("^%-%-split%-string=(.+)$")
|
||||||
if not seen_env then
|
if not seen_env then
|
||||||
|
|
@ -112,12 +120,10 @@ function pmacs.parse.language_from_shebang(buf)
|
||||||
elseif skip_next then
|
elseif skip_next then
|
||||||
skip_next = false -- the operand consumed by the previous option
|
skip_next = false -- the operand consumed by the previous option
|
||||||
elseif split_attached then
|
elseif split_attached then
|
||||||
local word = split_attached:match("^(%S+)")
|
table.insert(tokens, i, split_attached)
|
||||||
base = word and (word:match("([^/]+)$") or word)
|
|
||||||
break
|
|
||||||
elseif tok == "-S" or tok == "--split-string" then
|
elseif tok == "-S" or tok == "--split-string" then
|
||||||
-- Separated split-string: the next token starts the string, i.e.
|
-- Separated split-string: the next token starts the string, i.e.
|
||||||
-- the interpreter — keep walking.
|
-- another env argument — keep walking.
|
||||||
elseif tok:find("=", 1, true) then
|
elseif tok:find("=", 1, true) then
|
||||||
-- `VAR=value` env assignment, or another `--long=value` option:
|
-- `VAR=value` env assignment, or another `--long=value` option:
|
||||||
-- self-contained, skip.
|
-- self-contained, skip.
|
||||||
|
|
|
||||||
|
|
@ -5883,6 +5883,11 @@ fn m4_shebang_resolver_maps_interpreters() {
|
||||||
("#!/usr/bin/env -Spython3 -u\n", "python"),
|
("#!/usr/bin/env -Spython3 -u\n", "python"),
|
||||||
("#!/usr/bin/env --split-string=python3 -u\n", "python"),
|
("#!/usr/bin/env --split-string=python3 -u\n", "python"),
|
||||||
("#!/usr/bin/env -vSpython3 -u\n", "python"),
|
("#!/usr/bin/env -vSpython3 -u\n", "python"),
|
||||||
|
// The attached split string is a complete env argument list, so
|
||||||
|
// options and assignments may precede the interpreter within it.
|
||||||
|
("#!/usr/bin/env -S-i python3 -u\n", "python"),
|
||||||
|
("#!/usr/bin/env -SFOO=bar python3 -u\n", "python"),
|
||||||
|
("#!/usr/bin/env --split-string=-u FOO python3\n", "python"),
|
||||||
// GNU-env options that consume an operand must not have the
|
// GNU-env options that consume an operand must not have the
|
||||||
// operand mistaken for the interpreter.
|
// operand mistaken for the interpreter.
|
||||||
("#!/usr/bin/env -u FOO python3\n", "python"),
|
("#!/usr/bin/env -u FOO python3\n", "python"),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue