Merge nucleic/nimble-umber-toad-20h7 into dev
This commit is contained in:
+14
-14
@@ -37,7 +37,7 @@ pub(crate) struct ExpanderOptions {
|
||||
/// Whether to perform pathname expansion (globbing). If disabled, glob patterns
|
||||
/// are returned as literal strings.
|
||||
pub pathname_expand: bool,
|
||||
// nash: whether literal (unquoted, non-expansion) text is also subject to
|
||||
// hydrashell: whether literal (unquoted, non-expansion) text is also subject to
|
||||
// field splitting. Off by default per POSIX/bash (only expansion results
|
||||
// split); enabled by callers whose input string is *data*, e.g. the
|
||||
// `compgen -W` word list.
|
||||
@@ -275,7 +275,7 @@ impl From<String> for WordField {
|
||||
enum ExpansionPiece {
|
||||
Unsplittable(String),
|
||||
Splittable(String),
|
||||
// nash: literal unquoted word text. Bash field-splits only the *results of
|
||||
// hydrashell: literal unquoted word text. Bash field-splits only the *results of
|
||||
// expansions*, never literal text — but glob characters in literal text stay
|
||||
// active. This third state fixes `IFS=,; echo a,b,c` printing `a b c`
|
||||
// (corpus divergence D1) without breaking `echo *.txt`.
|
||||
@@ -297,7 +297,7 @@ impl From<ExpansionPiece> for patterns::PatternPiece {
|
||||
match piece {
|
||||
ExpansionPiece::Unsplittable(s) => Self::Literal(s),
|
||||
ExpansionPiece::Splittable(s) => Self::Pattern(s),
|
||||
// nash: unquoted literal text keeps glob chars active.
|
||||
// hydrashell: unquoted literal text keeps glob chars active.
|
||||
ExpansionPiece::LiteralText(s) => Self::Pattern(s),
|
||||
}
|
||||
}
|
||||
@@ -308,7 +308,7 @@ impl From<ExpansionPiece> for crate::regex::RegexPiece {
|
||||
match piece {
|
||||
ExpansionPiece::Unsplittable(s) => Self::Literal(s),
|
||||
ExpansionPiece::Splittable(s) => Self::Pattern(s),
|
||||
// nash: unquoted literal text keeps pattern chars active.
|
||||
// hydrashell: unquoted literal text keeps pattern chars active.
|
||||
ExpansionPiece::LiteralText(s) => Self::Pattern(s),
|
||||
}
|
||||
}
|
||||
@@ -335,12 +335,12 @@ impl ExpansionPiece {
|
||||
match self {
|
||||
Self::Unsplittable(_) => self,
|
||||
Self::Splittable(s) => Self::Unsplittable(s),
|
||||
// nash: quoting literal text also deactivates its glob chars.
|
||||
// hydrashell: quoting literal text also deactivates its glob chars.
|
||||
Self::LiteralText(s) => Self::Unsplittable(s),
|
||||
}
|
||||
}
|
||||
|
||||
// nash: opt literal text into field splitting (see
|
||||
// hydrashell: opt literal text into field splitting (see
|
||||
// `ExpanderOptions::field_split_literal_text`). Quoted pieces stay intact.
|
||||
fn make_literal_splittable(self) -> Self {
|
||||
match self {
|
||||
@@ -547,7 +547,7 @@ struct WordExpander<'a, SE: extensions::ShellExtensions> {
|
||||
in_double_quotes: bool,
|
||||
/// Whether to use heredoc expansion semantics (literal quotes, no brace expansion).
|
||||
heredoc_mode: bool,
|
||||
// nash: see `ExpanderOptions::field_split_literal_text`.
|
||||
// hydrashell: see `ExpanderOptions::field_split_literal_text`.
|
||||
field_split_literal_text: bool,
|
||||
}
|
||||
|
||||
@@ -684,7 +684,7 @@ impl<'a, SE: extensions::ShellExtensions> WordExpander<'a, SE> {
|
||||
&['$', '`', '\\', '\'', '\"', '~', '{']
|
||||
};
|
||||
if !word.contains(expansion_chars) {
|
||||
// nash: a word with no expansion characters is pure literal text —
|
||||
// hydrashell: a word with no expansion characters is pure literal text —
|
||||
// glob-active but not subject to field splitting.
|
||||
return Ok(Expansion::from(ExpansionPiece::LiteralText(
|
||||
word.to_owned(),
|
||||
@@ -821,7 +821,7 @@ impl<'a, SE: extensions::ShellExtensions> WordExpander<'a, SE> {
|
||||
// Go through the fields we have so far.
|
||||
for existing_field in expansion.fields {
|
||||
for piece in existing_field.0 {
|
||||
// nash: callers whose input is data (e.g. compgen -W) opt
|
||||
// hydrashell: callers whose input is data (e.g. compgen -W) opt
|
||||
// literal text into splitting.
|
||||
let piece = if self.field_split_literal_text {
|
||||
piece.make_literal_splittable()
|
||||
@@ -829,7 +829,7 @@ impl<'a, SE: extensions::ShellExtensions> WordExpander<'a, SE> {
|
||||
piece
|
||||
};
|
||||
match piece {
|
||||
// nash: literal text is never field-split (only expansion
|
||||
// hydrashell: literal text is never field-split (only expansion
|
||||
// results are), but stays a distinct piece so its glob
|
||||
// characters remain active downstream.
|
||||
ExpansionPiece::Unsplittable(_) | ExpansionPiece::LiteralText(_) => {
|
||||
@@ -913,7 +913,7 @@ impl<'a, SE: extensions::ShellExtensions> WordExpander<'a, SE> {
|
||||
) -> Result<Expansion, error::Error> {
|
||||
let expansion: Expansion = match word_piece {
|
||||
brush_parser::word::WordPiece::Text(s) => {
|
||||
// nash: literal word text — not field-split, glob-active.
|
||||
// hydrashell: literal word text — not field-split, glob-active.
|
||||
Expansion::from(ExpansionPiece::LiteralText(s))
|
||||
}
|
||||
brush_parser::word::WordPiece::SingleQuotedText(s) => {
|
||||
@@ -963,7 +963,7 @@ impl<'a, SE: extensions::ShellExtensions> WordExpander<'a, SE> {
|
||||
ExpansionPiece::Unsplittable(self.expand_tilde_expression(&tilde_expr)?),
|
||||
),
|
||||
brush_parser::word::WordPiece::ParameterExpansion(p) => {
|
||||
// nash: whatever a parameter expansion substitutes (including
|
||||
// hydrashell: whatever a parameter expansion substitutes (including
|
||||
// literal text from ${v:-default} / ${v:+alt} words) is an
|
||||
// expansion *result*, so it is subject to field splitting.
|
||||
// Quoted pieces inside remain Unsplittable.
|
||||
@@ -999,7 +999,7 @@ impl<'a, SE: extensions::ShellExtensions> WordExpander<'a, SE> {
|
||||
let trimmed_len = cmd_output.trim_end_matches('\n').len();
|
||||
cmd_output.truncate(trimmed_len);
|
||||
|
||||
// nash: capture command-substitution output (docs/NASH.md §5.3) —
|
||||
// hydrashell: capture command-substitution output (docs/HYDRASHELL.md §5.3) —
|
||||
// invisible to the transcript, often carries decisions/secrets.
|
||||
if !self.disable_command_substitutions {
|
||||
crate::gate::gate().on_cmdsub(cmd_output.as_str());
|
||||
@@ -1012,7 +1012,7 @@ impl<'a, SE: extensions::ShellExtensions> WordExpander<'a, SE> {
|
||||
// If we are *not* in a double-quoted context and we were requested to skip
|
||||
// unquoted backslash removal, then we need to skip removing backslashes here.
|
||||
if !self.in_double_quotes && self.disable_unquoted_backslash_removal {
|
||||
// nash: retained-backslash text is literal, not an
|
||||
// hydrashell: retained-backslash text is literal, not an
|
||||
// expansion result — no field splitting.
|
||||
return Ok(Expansion::from(ExpansionPiece::LiteralText(s)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user