diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-01 01:02:43 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-01 01:02:43 +0200 |
| commit | 4f3a56dc12a2126bdacff73f1cfe586d06e800c0 (patch) | |
| tree | 863d23f2fc3d2bf6b77213ef729a6ebda7101244 /coreutils/ls.c | |
| parent | bb18473216253b8602ce081dd944f854aad9e572 (diff) | |
ls: fix -Q to match GNU
function old new delta
print_name 137 229 +92
display_files 375 402 +27
c_escape_conv_str00 - 24 +24
display 1476 1485 +9
conv_str 33 - -33
------------------------------------------------------------------------------
(add/remove: 2/1 grow/shrink: 3/0 up/down: 152/-33) Total: 119 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils/ls.c')
| -rw-r--r-- | coreutils/ls.c | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index c725be92d..9e4b83032 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -457,19 +457,29 @@ static unsigned calc_name_len(const char *name) if (!(option_mask32 & (OPT_q|OPT_Q))) return strlen(name); - name = printable_string2(&uni_stat, name); - if (!(option_mask32 & OPT_Q)) { + printable_string2(&uni_stat, name); return uni_stat.unicode_width; } - // TODO: quote chars 7..13 as \a,b,t,n,v,f,r - // other chars <32 or >127 as \ooo octal - len = 2 + uni_stat.unicode_width; + len = 2 + strlen(name); while (*name) { + unsigned char ch = (unsigned char)*name; + if (ch < ' ' || ch > 0x7e) { + ch -= 7; + if ((signed char)ch >= 0 && ch <= 6) { + // quote chars 7..13 as \a,b,t,n,v,f,r + len++; + goto next; + } + // other chars <32 or >126 as \ooo octal + len += 3; + goto next; + } if (*name == '"' || *name == '\\') { len++; } + next: name++; } return len; @@ -492,23 +502,39 @@ static unsigned print_name(const char *name) return strlen(name); } - name = printable_string2(&uni_stat, name); - if (!(option_mask32 & OPT_Q)) { + name = printable_string2(&uni_stat, name); fputs_stdout(name); return uni_stat.unicode_width; } - // TODO: quote chars 7..13 as \a,b,t,n,v,f,r - // other chars <32 or >127 as \ooo octal - len = 2 + uni_stat.unicode_width; + len = 2 + strlen(name); putchar('"'); while (*name) { - if (*name == '"' || *name == '\\') { + unsigned char ch = (unsigned char)*name; + if (ch < ' ' || ch > 0x7e) { + putchar('\\'); + ch -= 7; + if ((signed char)ch >= 0 && ch <= 6) { + // quote chars 7..13 as \a,b,t,n,v,f,r + ch = c_escape_conv_str07[1 + 3 * ch]; + len++; + goto put_ch; + } + // other chars <32 or >126 as \ooo octal + ch = (unsigned char)*name; + putchar('0' + ((ch>>6) & 7)); + putchar('0' + ((ch>>3) & 7)); + ch = '0' + (ch & 7); + len += 3; + goto put_ch; + } + if (ch == '"' || ch == '\\') { putchar('\\'); len++; } - putchar(*name); + put_ch: + putchar(ch); name++; } putchar('"'); |
