--- ls.c.orig Fri May 19 00:02:20 2006 +++ ls.c Wed Nov 22 16:07:39 2006 @@ -105,6 +105,7 @@ /* flags */ int f_accesstime; /* use time of last access */ int f_birthtime; /* use time of birth */ + int f_digitsep; /* display sizes with thousands separators */ int f_flags; /* show flags associated with a file */ int f_humanval; /* show human-readable file sizes */ int f_inode; /* print inode */ @@ -148,6 +149,7 @@ int main(int argc, char *argv[]) { + struct lconv *loco; static char dot[] = ".", *dotav[] = {dot, NULL}; struct winsize win; int ch, fts_options, notused; @@ -179,9 +181,17 @@ fts_options = FTS_PHYSICAL; while ((ch = getopt(argc, argv, - "1ABCFGHILPRSTUWZabcdfghiklmnopqrstuwx")) != -1) { + ",1ABCFGHILPRSTUWZabcdfghiklmnopqrstuwx")) != -1) { switch (ch) { /* + * Note that f_humanval and f_digitsep override each other so + * shell aliasing works right. + */ + case ',': + f_digitsep = 1; + f_humanval = 0; + break; + /* * The -1, -C, -x and -l options all override each other so * shell aliasing works right. */ @@ -267,6 +277,7 @@ break; case 'h': f_humanval = 1; + f_digitsep = 0; break; case 'i': f_inode = 1; @@ -376,6 +387,29 @@ #endif /* + * Enforce thousands separators if the user wants them and the + * native locale doesn't have them. Set "," as the separator + * unless the locale's decimal point is also a comma (in that + * case we set "."). If the locale doesn't specify grouping, + * then set it to "3;3". + * + * Note that it is OK to overwrite pointers in the struct lconv + * (but we must not overwrite any targets of existing pointers!). + * See localeconv(3) for details. + */ + if (f_digitsep) { + loco = localeconv(); + if (*loco->thousands_sep == 0) { + if (*loco->decimal_point != ',') + loco->thousands_sep = strdup(","); + else + loco->thousands_sep = strdup("."); + } + if (*loco->grouping <= 0 || *loco->grouping >= CHAR_MAX) + loco->grouping = strdup("\003\003\0"); + } + + /* * If not -F, -i, -l, -s, -S or -t options, don't require stat * information, unless in color mode in which case we do * need this to determine which colors to display. @@ -560,7 +594,7 @@ int entries, needstats; const char *user, *group; char *flags, *labelstr = NULL; - char buf[STRBUF_SIZEOF(u_quad_t) + 1]; + char buf[STRBUF_SIZEOF(u_quad_t) * 2 + 1]; char ngroup[STRBUF_SIZEOF(uid_t) + 1]; char nuser[STRBUF_SIZEOF(gid_t) + 1]; @@ -829,7 +863,10 @@ d.s_inode = strlen(buf); (void)snprintf(buf, sizeof(buf), "%lu", maxnlink); d.s_nlink = strlen(buf); - (void)snprintf(buf, sizeof(buf), "%ju", maxsize); + if (f_digitsep) + (void)snprintf(buf, sizeof(buf), "%'ju", maxsize); + else + (void)snprintf(buf, sizeof(buf), "%ju", maxsize); d.s_size = strlen(buf); d.s_user = maxuser; } --- ls.h.orig Fri May 19 00:02:20 2006 +++ ls.h Wed Nov 22 16:07:13 2006 @@ -38,8 +38,9 @@ extern long blocksize; /* block size units */ extern int f_accesstime; /* use time of last access */ -extern int f_birthtime; /* use time of file creation */ +extern int f_birthtime; /* use time of file creation */ extern int f_flags; /* show flags associated with a file */ +extern int f_digitsep; /* display sizes with thousands separators */ extern int f_humanval; /* show human-readable file sizes */ extern int f_label; /* show MAC label */ extern int f_inode; /* print inode */ --- print.c.orig Fri May 19 00:02:20 2006 +++ print.c Wed Nov 22 16:07:13 2006 @@ -605,7 +605,9 @@ humanize_number(buf, sizeof(buf), (int64_t)bytes, "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); (void)printf("%5s ", buf); - } else + } else if (f_digitsep) + (void)printf("%'*jd ", (u_int)width, bytes); + else (void)printf("%*jd ", (u_int)width, bytes); }