Skip to content

Instantly share code, notes, and snippets.

@waltarix
Last active January 6, 2018 05:14
Show Gist options
  • Save waltarix/1408362 to your computer and use it in GitHub Desktop.
Save waltarix/1408362 to your computer and use it in GitHub Desktop.
coreutils: "ls" learned -M, --normalize-utf8mac options to normalize MacOSX's hfs encoding.
diff --git a/Makefile.in b/Makefile.in
index 60bb1ed..d8cba0d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -4609,7 +4609,7 @@ src_logname_LDADD = $(LDADD)
# for cap_get_file
src_ls_LDADD = $(LDADD) $(LIB_SELINUX) $(LIB_SMACK) \
- $(LIB_CLOCK_GETTIME) $(LIB_CAP) $(LIB_HAS_ACL)
+ $(LIB_CLOCK_GETTIME) $(LIB_CAP) $(LIB_HAS_ACL) $(LIBICONV)
# This must *not* depend on anything in lib/, since it is used to generate
# src/primes.h. If it depended on libcoreutils.a, that would pull all lib/*.c
diff --git a/src/ls.c b/src/ls.c
index 4becd06..3f33d84 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -114,6 +114,8 @@
#include "c-ctype.h"
#include "canonicalize.h"
+#include <iconv.h>
+
/* Include <sys/capability.h> last to avoid a clash of <sys/types.h>
include guards with some premature versions of libcap.
For more details, see <https://bugzilla.redhat.com/483548>. */
@@ -666,6 +668,10 @@ static bool immediate_dirs;
static bool directories_first;
+/* True means normalize MacOSX's hfs encoding. */
+
+static bool normalize_utf8mac;
+
/* Which files to ignore. */
static enum
@@ -880,6 +886,7 @@ static struct option const long_options[] =
{"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
{"context", no_argument, 0, 'Z'},
{"author", no_argument, NULL, AUTHOR_OPTION},
+ {"normalize-utf8mac", no_argument, NULL, 'M'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -1736,6 +1743,7 @@ decode_switches (int argc, char **argv)
ignore_patterns = NULL;
hide_patterns = NULL;
print_scontext = false;
+ normalize_utf8mac = false;
getenv_quoting_style ();
@@ -1782,7 +1790,7 @@ decode_switches (int argc, char **argv)
{
int oi = -1;
int c = getopt_long (argc, argv,
- "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1",
+ "abcdfghiklmnopqrstuvw:xABCDFGHI:LMNQRST:UXZ1",
long_options, &oi);
if (c == -1)
break;
@@ -1941,6 +1949,10 @@ decode_switches (int argc, char **argv)
dereference = DEREF_ALWAYS;
break;
+ case 'M':
+ normalize_utf8mac = true;
+ break;
+
case 'N':
set_quoting_style (NULL, literal_quoting_style);
break;
@@ -4538,6 +4550,10 @@ print_name_with_quoting (const struct fileinfo *f,
size_t start_col)
{
const char* name = symlink_target ? f->linkname : f->name;
+ static iconv_t conv_ds = (iconv_t)NULL;
+ static char *conv_name = (char *)NULL;
+ char *temp_name_ptr, *orig_name_ptr;
+ size_t temp_name_len, orig_name_len;
const struct bin_str *color = print_with_color ?
get_color_indicator (f, symlink_target) : NULL;
@@ -4545,6 +4561,22 @@ print_name_with_quoting (const struct fileinfo *f,
bool used_color_this_time = (print_with_color
&& (color || is_colored (C_NORM)));
+ if (normalize_utf8mac) {
+ if (!conv_ds)
+ conv_ds = iconv_open("UTF-8", "UTF-8-MAC");
+ if (conv_ds) {
+ orig_name_ptr = name;
+ orig_name_len = strlen(name);
+ conv_name = conv_name ? realloc(conv_name, orig_name_len+1) : malloc(orig_name_len+1);
+ temp_name_ptr = conv_name;
+ temp_name_len = orig_name_len;
+ if (iconv(conv_ds,&orig_name_ptr,&orig_name_len,&temp_name_ptr,&temp_name_len) >= 0) {
+ *temp_name_ptr = '\0';
+ name = conv_name;
+ }
+ }
+ }
+
size_t len = quote_name (name, filename_quoting_options, f->quoted,
color, !symlink_target, stack, f->absolute_name);
@@ -5217,6 +5249,9 @@ Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.\n\
references rather than for the link itself\n\
-m fill width with a comma separated list of entries\
\n\
+"), stdout);
+ fputs (_("\
+ -M, --normalize-utf8mac Normalize MacOSX's hfs encoding\n\
"), stdout);
fputs (_("\
-n, --numeric-uid-gid like -l, but list numeric user and group IDs\n\
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment