diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-22 17:32:20 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-22 17:32:20 +0100 |
commit | 194b2ebd2a0cfc1d27744dea10ef706975c61317 (patch) | |
tree | 4f3734da5abd3795cf7fca7fbb84429b7b2b635c /coreutils | |
parent | 12389889c052cf7bf494bd7cabc0819f6fe9888f (diff) | |
download | busybox-w32-194b2ebd2a0cfc1d27744dea10ef706975c61317.tar.gz busybox-w32-194b2ebd2a0cfc1d27744dea10ef706975c61317.tar.bz2 busybox-w32-194b2ebd2a0cfc1d27744dea10ef706975c61317.zip |
ls: replace -e with --full-time, add --group-directories-first, delete -K
-K and -e were non-standard
function old new delta
static.ls_longopts 9 47 +38
ls_main 748 776 +28
display_single 901 928 +27
sortcmp 254 258 +4
ls_options 32 31 -1
opt_flags 100 96 -4
packed_usage 31032 30977 -55
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/3 up/down: 97/-60) Total: 37 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/ls.c | 130 |
1 files changed, 74 insertions, 56 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index 13df77410..0774a9a45 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -130,17 +130,20 @@ | |||
130 | //usage: "\n -i List inode numbers" | 130 | //usage: "\n -i List inode numbers" |
131 | //usage: "\n -n List numeric UIDs and GIDs instead of names" | 131 | //usage: "\n -n List numeric UIDs and GIDs instead of names" |
132 | //usage: "\n -s List allocated blocks" | 132 | //usage: "\n -s List allocated blocks" |
133 | //usage: IF_FEATURE_LS_TIMESTAMPS( | 133 | //usage: IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS( |
134 | //usage: "\n -e List full date and time" | 134 | //usage: "\n --full-time List full date and time" |
135 | //usage: ) | 135 | //usage: )) |
136 | //usage: IF_FEATURE_HUMAN_READABLE( | 136 | //usage: IF_FEATURE_HUMAN_READABLE( |
137 | //usage: "\n -h List sizes in human readable format (1K 243M 2G)" | 137 | //usage: "\n -h List sizes in human readable format (1K 243M 2G)" |
138 | //usage: ) | 138 | //usage: ) |
139 | //usage: IF_FEATURE_LS_SORTFILES( | 139 | //usage: IF_FEATURE_LS_SORTFILES( |
140 | //usage: "\n -r Sort in reverse order" | 140 | //usage: IF_LONG_OPTS( |
141 | //usage: "\n --group-directories-first" | ||
142 | //usage: ) | ||
141 | //usage: "\n -S Sort by size" | 143 | //usage: "\n -S Sort by size" |
142 | //usage: "\n -X Sort by extension" | 144 | //usage: "\n -X Sort by extension" |
143 | //usage: "\n -v Sort by version" | 145 | //usage: "\n -v Sort by version" |
146 | //usage: "\n -r Reverse sort order" | ||
144 | //usage: ) | 147 | //usage: ) |
145 | //usage: IF_FEATURE_LS_TIMESTAMPS( | 148 | //usage: IF_FEATURE_LS_TIMESTAMPS( |
146 | //usage: "\n -c With -l: sort by ctime" | 149 | //usage: "\n -c With -l: sort by ctime" |
@@ -149,7 +152,6 @@ | |||
149 | //usage: ) | 152 | //usage: ) |
150 | //usage: IF_SELINUX( | 153 | //usage: IF_SELINUX( |
151 | //usage: "\n -k List security context" | 154 | //usage: "\n -k List security context" |
152 | //usage: "\n -K List security context in long format" | ||
153 | //usage: "\n -Z List security context and permission" | 155 | //usage: "\n -Z List security context and permission" |
154 | //usage: ) | 156 | //usage: ) |
155 | //usage: IF_FEATURE_LS_WIDTH( | 157 | //usage: IF_FEATURE_LS_WIDTH( |
@@ -230,16 +232,16 @@ TIME_MASK = (3 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, | |||
230 | 232 | ||
231 | /* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */ | 233 | /* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */ |
232 | SORT_REVERSE = 1 << 23, | 234 | SORT_REVERSE = 1 << 23, |
235 | SORT_DIRS_FIRST = 1 << 24, | ||
233 | 236 | ||
234 | SORT_NAME = 0, /* sort by file name */ | 237 | SORT_NAME = 0, /* sort by file name */ |
235 | SORT_SIZE = 1 << 24, /* sort by file size */ | 238 | SORT_SIZE = 1 << 25, /* sort by file size */ |
236 | SORT_ATIME = 2 << 24, /* sort by last access time */ | 239 | SORT_ATIME = 2 << 25, /* sort by last access time */ |
237 | SORT_CTIME = 3 << 24, /* sort by last change time */ | 240 | SORT_CTIME = 3 << 25, /* sort by last change time */ |
238 | SORT_MTIME = 4 << 24, /* sort by last modification time */ | 241 | SORT_MTIME = 4 << 25, /* sort by last modification time */ |
239 | SORT_VERSION = 5 << 24, /* sort by version */ | 242 | SORT_VERSION = 5 << 25, /* sort by version */ |
240 | SORT_EXT = 6 << 24, /* sort by file name extension */ | 243 | SORT_EXT = 6 << 25, /* sort by file name extension */ |
241 | SORT_DIR = 7 << 24, /* sort by file or directory */ | 244 | SORT_MASK = (7 << 25) * ENABLE_FEATURE_LS_SORTFILES, |
242 | SORT_MASK = (7 << 24) * ENABLE_FEATURE_LS_SORTFILES, | ||
243 | 245 | ||
244 | LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ | 246 | LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ |
245 | LIST_DATE_TIME | LIST_SYMLINK, | 247 | LIST_DATE_TIME | LIST_SYMLINK, |
@@ -249,26 +251,24 @@ LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ | |||
249 | /* -gnsxA Std options, busybox always supports */ | 251 | /* -gnsxA Std options, busybox always supports */ |
250 | /* -Q GNU option, busybox always supports */ | 252 | /* -Q GNU option, busybox always supports */ |
251 | /* -k SELinux option, busybox always supports (ignores if !SELinux) */ | 253 | /* -k SELinux option, busybox always supports (ignores if !SELinux) */ |
252 | /* Std has -k which means "show sizes in kbytes" */ | 254 | /* Std has -k which means "for -s, show sizes in kbytes" */ |
255 | /* Seems to only affect "POSIXLY_CORRECT=1 ls -sk" */ | ||
256 | /* since otherwise -s shows kbytes anyway */ | ||
253 | /* -LHRctur Std options, busybox optionally supports */ | 257 | /* -LHRctur Std options, busybox optionally supports */ |
254 | /* -Fp Std options, busybox optionally supports */ | 258 | /* -Fp Std options, busybox optionally supports */ |
255 | /* -SXvhTw GNU options, busybox optionally supports */ | 259 | /* -SXvhTw GNU options, busybox optionally supports */ |
256 | /* -T WIDTH Ignored (we don't use tabs on output) */ | 260 | /* -T WIDTH Ignored (we don't use tabs on output) */ |
257 | /* -KZ SELinux mandated options, busybox optionally supports */ | 261 | /* -Z SELinux mandated option, busybox optionally supports */ |
258 | /* (coreutils 8.4 has no -K, remove it?) */ | ||
259 | /* -e I think we made this one up (looks similar to GNU --full-time) */ | ||
260 | /* We already used up all 32 bits, if we need to add more, candidates for removal: */ | ||
261 | /* -K, -T, -e (add --full-time instead) */ | ||
262 | static const char ls_options[] ALIGN1 = | 262 | static const char ls_options[] ALIGN1 = |
263 | "Cadil1gnsxQAk" /* 13 opts, total 13 */ | 263 | "Cadil1gnsxQAk" /* 13 opts, total 13 */ |
264 | IF_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */ | 264 | IF_FEATURE_LS_TIMESTAMPS("ctu") /* 3, 16 */ |
265 | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 21 */ | 265 | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 20 */ |
266 | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 23 */ | 266 | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 22 */ |
267 | IF_FEATURE_LS_RECURSIVE("R") /* 1, 24 */ | 267 | IF_FEATURE_LS_RECURSIVE("R") /* 1, 23 */ |
268 | IF_SELINUX("KZ") /* 2, 26 */ | 268 | IF_SELINUX("Z") /* 1, 24 */ |
269 | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 28 */ | 269 | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 26 */ |
270 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 29 */ | 270 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 27 */ |
271 | IF_FEATURE_LS_WIDTH("T:w:") /* 2, 31 */ | 271 | IF_FEATURE_LS_WIDTH("T:w:") /* 2, 29 */ |
272 | /* with --color, we use all 32 bits */; | 272 | /* with --color, we use all 32 bits */; |
273 | enum { | 273 | enum { |
274 | //OPT_C = (1 << 0), | 274 | //OPT_C = (1 << 0), |
@@ -286,27 +286,26 @@ enum { | |||
286 | //OPT_k = (1 << 12), | 286 | //OPT_k = (1 << 12), |
287 | 287 | ||
288 | OPTBIT_c = 13, | 288 | OPTBIT_c = 13, |
289 | OPTBIT_e, | ||
290 | OPTBIT_t, | 289 | OPTBIT_t, |
291 | OPTBIT_u, | 290 | OPTBIT_u, |
292 | OPTBIT_S = OPTBIT_c + 4 * ENABLE_FEATURE_LS_TIMESTAMPS, | 291 | OPTBIT_S = OPTBIT_c + 3 * ENABLE_FEATURE_LS_TIMESTAMPS, |
293 | OPTBIT_X, /* 18 */ | 292 | OPTBIT_X, /* 17 */ |
294 | OPTBIT_r, | 293 | OPTBIT_r, |
295 | OPTBIT_v, | 294 | OPTBIT_v, |
296 | OPTBIT_F = OPTBIT_S + 4 * ENABLE_FEATURE_LS_SORTFILES, | 295 | OPTBIT_F = OPTBIT_S + 4 * ENABLE_FEATURE_LS_SORTFILES, |
297 | OPTBIT_p, /* 22 */ | 296 | OPTBIT_p, /* 21 */ |
298 | OPTBIT_R = OPTBIT_F + 2 * ENABLE_FEATURE_LS_FILETYPES, | 297 | OPTBIT_R = OPTBIT_F + 2 * ENABLE_FEATURE_LS_FILETYPES, |
299 | OPTBIT_K = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE, | 298 | OPTBIT_Z = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE, |
300 | OPTBIT_Z, /* 25 */ | 299 | OPTBIT_L = OPTBIT_Z + 2 * ENABLE_SELINUX, |
301 | OPTBIT_L = OPTBIT_K + 2 * ENABLE_SELINUX, | 300 | OPTBIT_H, /* 25 */ |
302 | OPTBIT_H, /* 27 */ | ||
303 | OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS, | 301 | OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS, |
304 | OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE, | 302 | OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE, |
305 | OPTBIT_w, /* 30 */ | 303 | OPTBIT_w, /* 28 */ |
306 | OPTBIT_color = OPTBIT_T + 2 * ENABLE_FEATURE_LS_WIDTH, | 304 | OPTBIT_color = OPTBIT_T + 2 * ENABLE_FEATURE_LS_WIDTH, |
305 | OPTBIT_dirs_first = OPTBIT_color + 1 * ENABLE_FEATURE_LS_COLOR, | ||
306 | OPTBIT_full_time, | ||
307 | 307 | ||
308 | OPT_c = (1 << OPTBIT_c) * ENABLE_FEATURE_LS_TIMESTAMPS, | 308 | OPT_c = (1 << OPTBIT_c) * ENABLE_FEATURE_LS_TIMESTAMPS, |
309 | OPT_e = (1 << OPTBIT_e) * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
310 | OPT_t = (1 << OPTBIT_t) * ENABLE_FEATURE_LS_TIMESTAMPS, | 309 | OPT_t = (1 << OPTBIT_t) * ENABLE_FEATURE_LS_TIMESTAMPS, |
311 | OPT_u = (1 << OPTBIT_u) * ENABLE_FEATURE_LS_TIMESTAMPS, | 310 | OPT_u = (1 << OPTBIT_u) * ENABLE_FEATURE_LS_TIMESTAMPS, |
312 | OPT_S = (1 << OPTBIT_S) * ENABLE_FEATURE_LS_SORTFILES, | 311 | OPT_S = (1 << OPTBIT_S) * ENABLE_FEATURE_LS_SORTFILES, |
@@ -316,14 +315,15 @@ enum { | |||
316 | OPT_F = (1 << OPTBIT_F) * ENABLE_FEATURE_LS_FILETYPES, | 315 | OPT_F = (1 << OPTBIT_F) * ENABLE_FEATURE_LS_FILETYPES, |
317 | OPT_p = (1 << OPTBIT_p) * ENABLE_FEATURE_LS_FILETYPES, | 316 | OPT_p = (1 << OPTBIT_p) * ENABLE_FEATURE_LS_FILETYPES, |
318 | OPT_R = (1 << OPTBIT_R) * ENABLE_FEATURE_LS_RECURSIVE, | 317 | OPT_R = (1 << OPTBIT_R) * ENABLE_FEATURE_LS_RECURSIVE, |
319 | OPT_K = (1 << OPTBIT_K) * ENABLE_SELINUX, | ||
320 | OPT_Z = (1 << OPTBIT_Z) * ENABLE_SELINUX, | 318 | OPT_Z = (1 << OPTBIT_Z) * ENABLE_SELINUX, |
321 | OPT_L = (1 << OPTBIT_L) * ENABLE_FEATURE_LS_FOLLOWLINKS, | 319 | OPT_L = (1 << OPTBIT_L) * ENABLE_FEATURE_LS_FOLLOWLINKS, |
322 | OPT_H = (1 << OPTBIT_H) * ENABLE_FEATURE_LS_FOLLOWLINKS, | 320 | OPT_H = (1 << OPTBIT_H) * ENABLE_FEATURE_LS_FOLLOWLINKS, |
323 | OPT_h = (1 << OPTBIT_h) * ENABLE_FEATURE_HUMAN_READABLE, | 321 | OPT_h = (1 << OPTBIT_h) * ENABLE_FEATURE_HUMAN_READABLE, |
324 | OPT_T = (1 << OPTBIT_T) * ENABLE_FEATURE_LS_WIDTH, | 322 | OPT_T = (1 << OPTBIT_T) * ENABLE_FEATURE_LS_WIDTH, |
325 | OPT_w = (1 << OPTBIT_w) * ENABLE_FEATURE_LS_WIDTH, | 323 | OPT_w = (1 << OPTBIT_w) * ENABLE_FEATURE_LS_WIDTH, |
326 | OPT_color = (1 << OPTBIT_color) * ENABLE_FEATURE_LS_COLOR, | 324 | OPT_color = (1 << OPTBIT_color ) * ENABLE_FEATURE_LS_COLOR, |
325 | OPT_dirs_first = (1 << OPTBIT_dirs_first) * ENABLE_LONG_OPTS, | ||
326 | OPT_full_time = (1 << OPTBIT_full_time ) * ENABLE_LONG_OPTS, | ||
327 | }; | 327 | }; |
328 | 328 | ||
329 | /* TODO: simple toggles may be stored as OPT_xxx bits instead */ | 329 | /* TODO: simple toggles may be stored as OPT_xxx bits instead */ |
@@ -343,7 +343,6 @@ static const uint32_t opt_flags[] = { | |||
343 | ENABLE_SELINUX * (LIST_CONTEXT|STYLE_SINGLE), /* k (ignored if !SELINUX) */ | 343 | ENABLE_SELINUX * (LIST_CONTEXT|STYLE_SINGLE), /* k (ignored if !SELINUX) */ |
344 | #if ENABLE_FEATURE_LS_TIMESTAMPS | 344 | #if ENABLE_FEATURE_LS_TIMESTAMPS |
345 | TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ | 345 | TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ |
346 | LIST_FULLTIME, /* e */ | ||
347 | ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */ | 346 | ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */ |
348 | TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */ | 347 | TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */ |
349 | #endif | 348 | #endif |
@@ -361,7 +360,6 @@ static const uint32_t opt_flags[] = { | |||
361 | DISP_RECURSIVE, /* R */ | 360 | DISP_RECURSIVE, /* R */ |
362 | #endif | 361 | #endif |
363 | #if ENABLE_SELINUX | 362 | #if ENABLE_SELINUX |
364 | LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME|STYLE_SINGLE, /* K */ | ||
365 | LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT|STYLE_SINGLE, /* Z */ | 363 | LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT|STYLE_SINGLE, /* Z */ |
366 | #endif | 364 | #endif |
367 | (1U << 31) | 365 | (1U << 31) |
@@ -634,21 +632,22 @@ static NOINLINE unsigned display_single(const struct dnode *dn) | |||
634 | } | 632 | } |
635 | #if ENABLE_FEATURE_LS_TIMESTAMPS | 633 | #if ENABLE_FEATURE_LS_TIMESTAMPS |
636 | if (G.all_fmt & (LIST_FULLTIME|LIST_DATE_TIME)) { | 634 | if (G.all_fmt & (LIST_FULLTIME|LIST_DATE_TIME)) { |
637 | char *filetime; | ||
638 | const time_t *ttime = &dn->dn_mtime; | 635 | const time_t *ttime = &dn->dn_mtime; |
639 | if (G.all_fmt & TIME_ACCESS) | 636 | if (G.all_fmt & TIME_ACCESS) |
640 | ttime = &dn->dn_atime; | 637 | ttime = &dn->dn_atime; |
641 | if (G.all_fmt & TIME_CHANGE) | 638 | if (G.all_fmt & TIME_CHANGE) |
642 | ttime = &dn->dn_ctime; | 639 | ttime = &dn->dn_ctime; |
643 | filetime = ctime(ttime); | 640 | if (G.all_fmt & LIST_FULLTIME) { /* --full-time */ |
644 | /* filetime's format: "Wed Jun 30 21:49:08 1993\n" */ | 641 | /* coreutils 8.4 ls --full-time prints: |
645 | if (G.all_fmt & LIST_FULLTIME) { /* -e */ | ||
646 | /* Note: coreutils 8.4 ls --full-time prints: | ||
647 | * 2009-07-13 17:49:27.000000000 +0200 | 642 | * 2009-07-13 17:49:27.000000000 +0200 |
648 | */ | 643 | */ |
649 | column += printf("%.24s ", filetime); | 644 | char buf[sizeof("YYYY-mm-dd HH:MM:SS TIMEZONE")]; |
645 | strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", localtime(ttime)); | ||
646 | column += printf("%s ", buf); | ||
650 | } else { /* LIST_DATE_TIME */ | 647 | } else { /* LIST_DATE_TIME */ |
651 | /* G.current_time_t ~== time(NULL) */ | 648 | /* G.current_time_t is ~== time(NULL) */ |
649 | char *filetime = ctime(ttime); | ||
650 | /* filetime's format: "Wed Jun 30 21:49:08 1993\n" */ | ||
652 | time_t age = G.current_time_t - *ttime; | 651 | time_t age = G.current_time_t - *ttime; |
653 | if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) { | 652 | if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) { |
654 | /* less than 6 months old */ | 653 | /* less than 6 months old */ |
@@ -943,6 +942,12 @@ static int sortcmp(const void *a, const void *b) | |||
943 | dif = 0; /* assume SORT_NAME */ | 942 | dif = 0; /* assume SORT_NAME */ |
944 | // TODO: use pre-initialized function pointer | 943 | // TODO: use pre-initialized function pointer |
945 | // instead of branch forest | 944 | // instead of branch forest |
945 | if (G.all_fmt & SORT_DIRS_FIRST) { | ||
946 | dif = S_ISDIR(d2->dn_mode) - S_ISDIR(d1->dn_mode); | ||
947 | if (dif != 0) | ||
948 | goto maybe_invert_and_ret; | ||
949 | } | ||
950 | |||
946 | if (sort_opts == SORT_SIZE) { | 951 | if (sort_opts == SORT_SIZE) { |
947 | dif = (d2->dn_size - d1->dn_size); | 952 | dif = (d2->dn_size - d1->dn_size); |
948 | } else | 953 | } else |
@@ -955,9 +960,6 @@ static int sortcmp(const void *a, const void *b) | |||
955 | if (sort_opts == SORT_MTIME) { | 960 | if (sort_opts == SORT_MTIME) { |
956 | dif = (d2->dn_mtime - d1->dn_mtime); | 961 | dif = (d2->dn_mtime - d1->dn_mtime); |
957 | } else | 962 | } else |
958 | if (sort_opts == SORT_DIR) { | ||
959 | dif = S_ISDIR(d2->dn_mode) - S_ISDIR(d1->dn_mode); | ||
960 | } else | ||
961 | #if defined(HAVE_STRVERSCMP) && HAVE_STRVERSCMP == 1 | 963 | #if defined(HAVE_STRVERSCMP) && HAVE_STRVERSCMP == 1 |
962 | if (sort_opts == SORT_VERSION) { | 964 | if (sort_opts == SORT_VERSION) { |
963 | dif = strverscmp(d1->name, d2->name); | 965 | dif = strverscmp(d1->name, d2->name); |
@@ -982,7 +984,7 @@ static int sortcmp(const void *a, const void *b) | |||
982 | dif = 1 | (int)((uoff_t)dif >> BITS_TO_SHIFT); | 984 | dif = 1 | (int)((uoff_t)dif >> BITS_TO_SHIFT); |
983 | } | 985 | } |
984 | } | 986 | } |
985 | 987 | maybe_invert_and_ret: | |
986 | return (G.all_fmt & SORT_REVERSE) ? -(int)dif : (int)dif; | 988 | return (G.all_fmt & SORT_REVERSE) ? -(int)dif : (int)dif; |
987 | } | 989 | } |
988 | 990 | ||
@@ -1157,7 +1159,10 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1157 | * (and substrings: "--color=alwa" work too) | 1159 | * (and substrings: "--color=alwa" work too) |
1158 | */ | 1160 | */ |
1159 | static const char ls_longopts[] ALIGN1 = | 1161 | static const char ls_longopts[] ALIGN1 = |
1160 | "color\0" Optional_argument "\xff"; /* no short equivalent */ | 1162 | "color\0" Optional_argument "\xff" /* no short equivalent */ |
1163 | "group-directories-first\0" No_argument "\xfe" | ||
1164 | "full-time\0" No_argument "\xfd" | ||
1165 | ; | ||
1161 | static const char color_str[] ALIGN1 = | 1166 | static const char color_str[] ALIGN1 = |
1162 | "always\0""yes\0""force\0" | 1167 | "always\0""yes\0""force\0" |
1163 | "auto\0""tty\0""if-tty\0"; | 1168 | "auto\0""tty\0""if-tty\0"; |
@@ -1182,8 +1187,8 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1182 | /* process options */ | 1187 | /* process options */ |
1183 | IF_FEATURE_LS_COLOR(applet_long_options = ls_longopts;) | 1188 | IF_FEATURE_LS_COLOR(applet_long_options = ls_longopts;) |
1184 | opt_complementary = | 1189 | opt_complementary = |
1185 | /* -e implies -l */ | 1190 | /* --full-time implies -l */ |
1186 | IF_FEATURE_LS_TIMESTAMPS("el") | 1191 | IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS("\xfd""l")) |
1187 | /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html: | 1192 | /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html: |
1188 | * in some pairs of opts, only last one takes effect: | 1193 | * in some pairs of opts, only last one takes effect: |
1189 | */ | 1194 | */ |
@@ -1200,6 +1205,15 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1200 | IF_FEATURE_LS_WIDTH(, NULL, &G_terminal_width) | 1205 | IF_FEATURE_LS_WIDTH(, NULL, &G_terminal_width) |
1201 | IF_FEATURE_LS_COLOR(, &color_opt) | 1206 | IF_FEATURE_LS_COLOR(, &color_opt) |
1202 | ); | 1207 | ); |
1208 | #if 0 /* option bits debug */ | ||
1209 | bb_error_msg("opt:0x%08x H:%x color:%x dirs:%x", opt, OPT_H, OPT_color, OPT_dirs_first); | ||
1210 | if (opt & OPT_c ) bb_error_msg("-c"); | ||
1211 | if (opt & OPT_H ) bb_error_msg("-H"); | ||
1212 | if (opt & OPT_color ) bb_error_msg("--color"); | ||
1213 | if (opt & OPT_dirs_first) bb_error_msg("--group-directories-first"); | ||
1214 | if (opt & OPT_full_time ) bb_error_msg("--full-time"); | ||
1215 | exit(0); | ||
1216 | #endif | ||
1203 | for (i = 0; opt_flags[i] != (1U << 31); i++) { | 1217 | for (i = 0; opt_flags[i] != (1U << 31); i++) { |
1204 | if (opt & (1 << i)) { | 1218 | if (opt & (1 << i)) { |
1205 | uint32_t flags = opt_flags[i]; | 1219 | uint32_t flags = opt_flags[i]; |
@@ -1239,6 +1253,10 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1239 | } | 1253 | } |
1240 | } | 1254 | } |
1241 | #endif | 1255 | #endif |
1256 | if (opt & OPT_dirs_first) | ||
1257 | G.all_fmt |= SORT_DIRS_FIRST; | ||
1258 | if (opt & OPT_full_time) | ||
1259 | G.all_fmt |= LIST_FULLTIME; | ||
1242 | 1260 | ||
1243 | /* sort out which command line options take precedence */ | 1261 | /* sort out which command line options take precedence */ |
1244 | if (ENABLE_FEATURE_LS_RECURSIVE && (G.all_fmt & DISP_NOLIST)) | 1262 | if (ENABLE_FEATURE_LS_RECURSIVE && (G.all_fmt & DISP_NOLIST)) |