Skip to content

Commit a701296

Browse files
committed
perf(printf): optimize shell metacharacter lookup with O(1) lookup table
Replace linear search through SHELL_META_CHARS string with a const lookup table for O(1) character classification. This improves performance for the printf %q implementation without changing behavior. - Add SHELL_META_LOOKUP static array initialized at compile time - Add is_shell_meta() helper using the lookup table - Remove unused SHELL_META_CHARS constant
1 parent ee02b5e commit a701296

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

src/uucore/src/lib/features/quoting_style/printf_quoter.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,31 @@
1414
1515
use super::Quoter;
1616

17-
/// Characters that need escaping in shell context
17+
/// Lookup table for shell metacharacters (for O(1) lookup)
1818
/// Note: Tilde (~) is NOT escaped by bash printf %q
19-
const SHELL_META_CHARS: &str = " \t\n'\"\\`$&|;()<>[]{}*?!#";
19+
static SHELL_META_LOOKUP: [bool; 256] = const {
20+
let mut lookup = [false; 256];
21+
let meta = b" \t\n'\"\\`$&|;()<>[]{}*?!#";
22+
let mut i = 0;
23+
while i < meta.len() {
24+
lookup[meta[i] as usize] = true;
25+
i += 1;
26+
}
27+
lookup
28+
};
2029

2130
/// Check if a byte is a control character
2231
#[inline]
2332
fn is_control(b: u8) -> bool {
2433
b < 0x20 || b == 0x7F
2534
}
2635

36+
/// Check if a byte is a shell metacharacter
37+
#[inline]
38+
fn is_shell_meta(b: u8) -> bool {
39+
SHELL_META_LOOKUP[b as usize]
40+
}
41+
2742
/// Check if string contains any control characters
2843
fn has_control_chars(s: &[u8]) -> bool {
2944
s.iter().any(|&b| is_control(b))
@@ -33,7 +48,7 @@ fn has_control_chars(s: &[u8]) -> bool {
3348
fn needs_quoting(s: &[u8]) -> bool {
3449
s.is_empty()
3550
|| s.iter()
36-
.any(|&b| SHELL_META_CHARS.as_bytes().contains(&b) || is_control(b))
51+
.any(|&b| is_shell_meta(b) || is_control(b))
3752
}
3853

3954
pub(super) struct PrintfQuoter;
@@ -65,7 +80,7 @@ impl PrintfQuoter {
6580
let mut result = Vec::with_capacity(input.len() * 2);
6681

6782
for &b in input {
68-
if SHELL_META_CHARS.as_bytes().contains(&b) {
83+
if is_shell_meta(b) {
6984
result.push(b'\\');
7085
}
7186
result.push(b);

0 commit comments

Comments
 (0)