diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-23 18:01:48 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-23 18:01:48 +0100 |
| commit | 11540a8da47318e34267f6ff033825ebabbd9181 (patch) | |
| tree | 345dda466fdd11ddbaeb5afed24c660b44b252d6 /coreutils | |
| parent | 7a18b9502aedbd6a9201c7c7603ded997a401f53 (diff) | |
| download | busybox-w32-11540a8da47318e34267f6ff033825ebabbd9181.tar.gz busybox-w32-11540a8da47318e34267f6ff033825ebabbd9181.tar.bz2 busybox-w32-11540a8da47318e34267f6ff033825ebabbd9181.zip | |
ls: handle all sort options through option_mask32
function old new delta
packed_usage 31007 31024 +17
my_stat 318 324 +6
sort_and_display_files 419 420 +1
print_name 216 217 +1
sortcmp 228 216 -12
opt_flags 96 64 -32
ls_main 732 685 -47
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/3 up/down: 25/-91) Total: -66 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
| -rw-r--r-- | coreutils/ls.c | 113 |
1 files changed, 42 insertions, 71 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index b48df8bf5..eb14a34e4 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
| @@ -137,7 +137,7 @@ | |||
| 137 | //usage: "\n --full-time List full date and time" | 137 | //usage: "\n --full-time List full date and time" |
| 138 | //usage: )) | 138 | //usage: )) |
| 139 | //usage: IF_FEATURE_HUMAN_READABLE( | 139 | //usage: IF_FEATURE_HUMAN_READABLE( |
| 140 | //usage: "\n -h List sizes in human readable format (1K 243M 2G)" | 140 | //usage: "\n -h Human readable sizes (1K 243M 2G)" |
| 141 | //usage: ) | 141 | //usage: ) |
| 142 | //usage: IF_FEATURE_LS_SORTFILES( | 142 | //usage: IF_FEATURE_LS_SORTFILES( |
| 143 | //usage: IF_LONG_OPTS( | 143 | //usage: IF_LONG_OPTS( |
| @@ -158,7 +158,7 @@ | |||
| 158 | //usage: "\n -Z List security context and permission" | 158 | //usage: "\n -Z List security context and permission" |
| 159 | //usage: ) | 159 | //usage: ) |
| 160 | //usage: IF_FEATURE_LS_WIDTH( | 160 | //usage: IF_FEATURE_LS_WIDTH( |
| 161 | //usage: "\n -w N Assume the terminal is N columns wide" | 161 | //usage: "\n -w N Format N columns wide" |
| 162 | //usage: ) | 162 | //usage: ) |
| 163 | //usage: IF_FEATURE_LS_COLOR( | 163 | //usage: IF_FEATURE_LS_COLOR( |
| 164 | //usage: "\n --color[={always,never,auto}] Control coloring" | 164 | //usage: "\n --color[={always,never,auto}] Control coloring" |
| @@ -228,17 +228,6 @@ STYLE_LONG = 2 << 19, /* one record per line, extended info */ | |||
| 228 | STYLE_SINGLE = 3 << 19, /* one record per line */ | 228 | STYLE_SINGLE = 3 << 19, /* one record per line */ |
| 229 | STYLE_MASK = STYLE_SINGLE, | 229 | STYLE_MASK = STYLE_SINGLE, |
| 230 | 230 | ||
| 231 | /* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */ | ||
| 232 | SORT_REVERSE = 1 << 23, | ||
| 233 | SORT_DIRS_FIRST = 1 << 24, | ||
| 234 | |||
| 235 | SORT_NAME = 0, /* sort by file name */ | ||
| 236 | SORT_SIZE = 1 << 25, /* sort by file size */ | ||
| 237 | SORT_TIME = 2 << 25, /* sort by {a,m,c}time */ | ||
| 238 | SORT_VERSION = 3 << 25, /* sort by version */ | ||
| 239 | SORT_EXT = 4 << 25, /* sort by file name extension */ | ||
| 240 | SORT_MASK = (7 << 25) * ENABLE_FEATURE_LS_SORTFILES, | ||
| 241 | |||
| 242 | LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ | 231 | LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ |
| 243 | LIST_DATE_TIME | LIST_SYMLINK, | 232 | LIST_DATE_TIME | LIST_SYMLINK, |
| 244 | }; | 233 | }; |
| @@ -256,12 +245,13 @@ LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ | |||
| 256 | /* -T WIDTH Ignored (we don't use tabs on output) */ | 245 | /* -T WIDTH Ignored (we don't use tabs on output) */ |
| 257 | /* -Z SELinux mandated option, busybox optionally supports */ | 246 | /* -Z SELinux mandated option, busybox optionally supports */ |
| 258 | static const char ls_options[] ALIGN1 = | 247 | static const char ls_options[] ALIGN1 = |
| 259 | "Cadi1lgnsxQAk" /* 13 opts, total 13 */ | 248 | "Cadi1lgnsxAk" /* 12 opts, total 12 */ |
| 260 | IF_FEATURE_LS_TIMESTAMPS("ctu") /* 3, 16 */ | 249 | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 14 */ |
| 261 | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 20 */ | 250 | IF_FEATURE_LS_RECURSIVE("R") /* 1, 15 */ |
| 262 | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 22 */ | 251 | IF_SELINUX("Z") /* 1, 16 */ |
| 263 | IF_FEATURE_LS_RECURSIVE("R") /* 1, 23 */ | 252 | "Q" /* 1, 17 */ |
| 264 | IF_SELINUX("Z") /* 1, 24 */ | 253 | IF_FEATURE_LS_TIMESTAMPS("ctu") /* 3, 20 */ |
| 254 | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 24 */ | ||
| 265 | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 26 */ | 255 | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 26 */ |
| 266 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 27 */ | 256 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 27 */ |
| 267 | IF_FEATURE_LS_WIDTH("T:w:") /* 2, 29 */ | 257 | IF_FEATURE_LS_WIDTH("T:w:") /* 2, 29 */ |
| @@ -277,22 +267,22 @@ enum { | |||
| 277 | //OPT_n = (1 << 7), | 267 | //OPT_n = (1 << 7), |
| 278 | //OPT_s = (1 << 8), | 268 | //OPT_s = (1 << 8), |
| 279 | //OPT_x = (1 << 9), | 269 | //OPT_x = (1 << 9), |
| 280 | OPT_Q = (1 << 10), | 270 | //OPT_A = (1 << 10), |
| 281 | //OPT_A = (1 << 11), | 271 | //OPT_k = (1 << 11), |
| 282 | //OPT_k = (1 << 12), | ||
| 283 | 272 | ||
| 284 | OPTBIT_c = 13, | 273 | OPTBIT_F = 12, |
| 285 | OPTBIT_t, | 274 | OPTBIT_p, /* 13 */ |
| 286 | OPTBIT_u, | ||
| 287 | OPTBIT_S = OPTBIT_c + 3 * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
| 288 | OPTBIT_X, /* 17 */ | ||
| 289 | OPTBIT_r, | ||
| 290 | OPTBIT_v, | ||
| 291 | OPTBIT_F = OPTBIT_S + 4 * ENABLE_FEATURE_LS_SORTFILES, | ||
| 292 | OPTBIT_p, /* 21 */ | ||
| 293 | OPTBIT_R = OPTBIT_F + 2 * ENABLE_FEATURE_LS_FILETYPES, | 275 | OPTBIT_R = OPTBIT_F + 2 * ENABLE_FEATURE_LS_FILETYPES, |
| 294 | OPTBIT_Z = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE, | 276 | OPTBIT_Z = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE, |
| 295 | OPTBIT_L = OPTBIT_Z + 2 * ENABLE_SELINUX, | 277 | OPTBIT_Q = OPTBIT_Z + 1 * ENABLE_SELINUX, |
| 278 | OPTBIT_c, /* 17 */ | ||
| 279 | OPTBIT_t, /* 18 */ | ||
| 280 | OPTBIT_u, /* 19 */ | ||
| 281 | OPTBIT_S = OPTBIT_c + 3 * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
| 282 | OPTBIT_X, /* 21 */ | ||
| 283 | OPTBIT_r, /* 22 */ | ||
| 284 | OPTBIT_v, /* 23 */ | ||
| 285 | OPTBIT_L = OPTBIT_S + 4 * ENABLE_FEATURE_LS_SORTFILES, | ||
| 296 | OPTBIT_H, /* 25 */ | 286 | OPTBIT_H, /* 25 */ |
| 297 | OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS, | 287 | OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS, |
| 298 | OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE, | 288 | OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE, |
| @@ -302,6 +292,11 @@ enum { | |||
| 302 | OPTBIT_color, /* 31 */ | 292 | OPTBIT_color, /* 31 */ |
| 303 | /* with long opts, we use all 32 bits */ | 293 | /* with long opts, we use all 32 bits */ |
| 304 | 294 | ||
| 295 | OPT_F = (1 << OPTBIT_F) * ENABLE_FEATURE_LS_FILETYPES, | ||
| 296 | OPT_p = (1 << OPTBIT_p) * ENABLE_FEATURE_LS_FILETYPES, | ||
| 297 | OPT_R = (1 << OPTBIT_R) * ENABLE_FEATURE_LS_RECURSIVE, | ||
| 298 | OPT_Z = (1 << OPTBIT_Z) * ENABLE_SELINUX, | ||
| 299 | OPT_Q = (1 << OPTBIT_Q), | ||
| 305 | OPT_c = (1 << OPTBIT_c) * ENABLE_FEATURE_LS_TIMESTAMPS, | 300 | OPT_c = (1 << OPTBIT_c) * ENABLE_FEATURE_LS_TIMESTAMPS, |
| 306 | OPT_t = (1 << OPTBIT_t) * ENABLE_FEATURE_LS_TIMESTAMPS, | 301 | OPT_t = (1 << OPTBIT_t) * ENABLE_FEATURE_LS_TIMESTAMPS, |
| 307 | OPT_u = (1 << OPTBIT_u) * ENABLE_FEATURE_LS_TIMESTAMPS, | 302 | OPT_u = (1 << OPTBIT_u) * ENABLE_FEATURE_LS_TIMESTAMPS, |
| @@ -309,10 +304,6 @@ enum { | |||
| 309 | OPT_X = (1 << OPTBIT_X) * ENABLE_FEATURE_LS_SORTFILES, | 304 | OPT_X = (1 << OPTBIT_X) * ENABLE_FEATURE_LS_SORTFILES, |
| 310 | OPT_r = (1 << OPTBIT_r) * ENABLE_FEATURE_LS_SORTFILES, | 305 | OPT_r = (1 << OPTBIT_r) * ENABLE_FEATURE_LS_SORTFILES, |
| 311 | OPT_v = (1 << OPTBIT_v) * ENABLE_FEATURE_LS_SORTFILES, | 306 | OPT_v = (1 << OPTBIT_v) * ENABLE_FEATURE_LS_SORTFILES, |
| 312 | OPT_F = (1 << OPTBIT_F) * ENABLE_FEATURE_LS_FILETYPES, | ||
| 313 | OPT_p = (1 << OPTBIT_p) * ENABLE_FEATURE_LS_FILETYPES, | ||
| 314 | OPT_R = (1 << OPTBIT_R) * ENABLE_FEATURE_LS_RECURSIVE, | ||
| 315 | OPT_Z = (1 << OPTBIT_Z) * ENABLE_SELINUX, | ||
| 316 | OPT_L = (1 << OPTBIT_L) * ENABLE_FEATURE_LS_FOLLOWLINKS, | 307 | OPT_L = (1 << OPTBIT_L) * ENABLE_FEATURE_LS_FOLLOWLINKS, |
| 317 | OPT_H = (1 << OPTBIT_H) * ENABLE_FEATURE_LS_FOLLOWLINKS, | 308 | OPT_H = (1 << OPTBIT_H) * ENABLE_FEATURE_LS_FOLLOWLINKS, |
| 318 | OPT_h = (1 << OPTBIT_h) * ENABLE_FEATURE_HUMAN_READABLE, | 309 | OPT_h = (1 << OPTBIT_h) * ENABLE_FEATURE_HUMAN_READABLE, |
| @@ -335,20 +326,8 @@ static const uint32_t opt_flags[] = { | |||
| 335 | LIST_LONG | STYLE_LONG | LIST_ID_NUMERIC, /* n (assumes l) */ | 326 | LIST_LONG | STYLE_LONG | LIST_ID_NUMERIC, /* n (assumes l) */ |
| 336 | LIST_BLOCKS, /* s */ | 327 | LIST_BLOCKS, /* s */ |
| 337 | DISP_ROWS | STYLE_COLUMNAR, /* x */ | 328 | DISP_ROWS | STYLE_COLUMNAR, /* x */ |
| 338 | 0, /* Q (quote filename) - handled via OPT_Q */ | ||
| 339 | DISP_HIDDEN, /* A */ | 329 | DISP_HIDDEN, /* A */ |
| 340 | ENABLE_SELINUX * (LIST_CONTEXT|STYLE_SINGLE), /* k (ignored if !SELINUX) */ | 330 | ENABLE_SELINUX * (LIST_CONTEXT|STYLE_SINGLE), /* k (ignored if !SELINUX) */ |
| 341 | #if ENABLE_FEATURE_LS_TIMESTAMPS | ||
| 342 | 0, /* c - handled via OPT_c */ | ||
| 343 | (ENABLE_FEATURE_LS_SORTFILES * SORT_TIME), /* t */ | ||
| 344 | 0, /* u - handled via OPT_u */ | ||
| 345 | #endif | ||
| 346 | #if ENABLE_FEATURE_LS_SORTFILES | ||
| 347 | SORT_SIZE, /* S */ | ||
| 348 | SORT_EXT, /* X */ | ||
| 349 | SORT_REVERSE, /* r */ | ||
| 350 | SORT_VERSION, /* v */ | ||
| 351 | #endif | ||
| 352 | #if ENABLE_FEATURE_LS_FILETYPES | 331 | #if ENABLE_FEATURE_LS_FILETYPES |
| 353 | LIST_FILETYPE | LIST_CLASSIFY, /* F */ | 332 | LIST_FILETYPE | LIST_CLASSIFY, /* F */ |
| 354 | LIST_FILETYPE, /* p */ | 333 | LIST_FILETYPE, /* p */ |
| @@ -930,30 +909,30 @@ static int sortcmp(const void *a, const void *b) | |||
| 930 | { | 909 | { |
| 931 | struct dnode *d1 = *(struct dnode **)a; | 910 | struct dnode *d1 = *(struct dnode **)a; |
| 932 | struct dnode *d2 = *(struct dnode **)b; | 911 | struct dnode *d2 = *(struct dnode **)b; |
| 933 | unsigned sort_opts = G.all_fmt & SORT_MASK; | 912 | unsigned opt = option_mask32; |
| 934 | off_t dif; | 913 | off_t dif; |
| 935 | 914 | ||
| 936 | dif = 0; /* assume SORT_NAME */ | 915 | dif = 0; /* assume sort by name */ |
| 937 | // TODO: use pre-initialized function pointer | 916 | // TODO: use pre-initialized function pointer |
| 938 | // instead of branch forest | 917 | // instead of branch forest |
| 939 | if (G.all_fmt & SORT_DIRS_FIRST) { | 918 | if (opt & OPT_dirs_first) { |
| 940 | dif = S_ISDIR(d2->dn_mode) - S_ISDIR(d1->dn_mode); | 919 | dif = S_ISDIR(d2->dn_mode) - S_ISDIR(d1->dn_mode); |
| 941 | if (dif != 0) | 920 | if (dif != 0) |
| 942 | goto maybe_invert_and_ret; | 921 | goto maybe_invert_and_ret; |
| 943 | } | 922 | } |
| 944 | 923 | ||
| 945 | if (sort_opts == SORT_SIZE) { | 924 | if (opt & OPT_S) { /* sort by size */ |
| 946 | dif = (d2->dn_size - d1->dn_size); | 925 | dif = (d2->dn_size - d1->dn_size); |
| 947 | } else | 926 | } else |
| 948 | if (sort_opts == SORT_TIME) { | 927 | if (opt & OPT_t) { /* sort by time */ |
| 949 | dif = (d2->dn_time - d1->dn_time); | 928 | dif = (d2->dn_time - d1->dn_time); |
| 950 | } else | 929 | } else |
| 951 | #if defined(HAVE_STRVERSCMP) && HAVE_STRVERSCMP == 1 | 930 | #if defined(HAVE_STRVERSCMP) && HAVE_STRVERSCMP == 1 |
| 952 | if (sort_opts == SORT_VERSION) { | 931 | if (opt & OPT_v) { /* sort by version */ |
| 953 | dif = strverscmp(d1->name, d2->name); | 932 | dif = strverscmp(d1->name, d2->name); |
| 954 | } else | 933 | } else |
| 955 | #endif | 934 | #endif |
| 956 | if (sort_opts == SORT_EXT) { | 935 | if (opt & OPT_X) { /* sort by extension */ |
| 957 | dif = strcmp(strchrnul(d1->name, '.'), strchrnul(d2->name, '.')); | 936 | dif = strcmp(strchrnul(d1->name, '.'), strchrnul(d2->name, '.')); |
| 958 | } | 937 | } |
| 959 | if (dif == 0) { | 938 | if (dif == 0) { |
| @@ -962,18 +941,17 @@ static int sortcmp(const void *a, const void *b) | |||
| 962 | dif = strcoll(d1->name, d2->name); | 941 | dif = strcoll(d1->name, d2->name); |
| 963 | else | 942 | else |
| 964 | dif = strcmp(d1->name, d2->name); | 943 | dif = strcmp(d1->name, d2->name); |
| 965 | } | 944 | } else { |
| 966 | 945 | /* Make dif fit into an int */ | |
| 967 | /* Make dif fit into an int */ | 946 | if (sizeof(dif) > sizeof(int)) { |
| 968 | if (sizeof(dif) > sizeof(int)) { | 947 | enum { BITS_TO_SHIFT = 8 * (sizeof(dif) - sizeof(int)) }; |
| 969 | enum { BITS_TO_SHIFT = 8 * (sizeof(dif) - sizeof(int)) }; | 948 | /* shift leaving only "int" worth of bits */ |
| 970 | /* shift leaving only "int" worth of bits */ | 949 | /* (this requires dif != 0, and here it is nonzero) */ |
| 971 | if (dif != 0) { | ||
| 972 | dif = 1 | (int)((uoff_t)dif >> BITS_TO_SHIFT); | 950 | dif = 1 | (int)((uoff_t)dif >> BITS_TO_SHIFT); |
| 973 | } | 951 | } |
| 974 | } | 952 | } |
| 975 | maybe_invert_and_ret: | 953 | maybe_invert_and_ret: |
| 976 | return (G.all_fmt & SORT_REVERSE) ? -(int)dif : (int)dif; | 954 | return (opt & OPT_r) ? -(int)dif : (int)dif; |
| 977 | } | 955 | } |
| 978 | 956 | ||
| 979 | static void dnsort(struct dnode **dn, int size) | 957 | static void dnsort(struct dnode **dn, int size) |
| @@ -1162,9 +1140,6 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
| 1162 | 1140 | ||
| 1163 | init_unicode(); | 1141 | init_unicode(); |
| 1164 | 1142 | ||
| 1165 | if (ENABLE_FEATURE_LS_SORTFILES) | ||
| 1166 | G.all_fmt = SORT_NAME; | ||
| 1167 | |||
| 1168 | #if ENABLE_FEATURE_LS_WIDTH | 1143 | #if ENABLE_FEATURE_LS_WIDTH |
| 1169 | /* obtain the terminal width */ | 1144 | /* obtain the terminal width */ |
| 1170 | G_terminal_width = get_terminal_width(STDIN_FILENO); | 1145 | G_terminal_width = get_terminal_width(STDIN_FILENO); |
| @@ -1209,14 +1184,10 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
| 1209 | 1184 | ||
| 1210 | if (flags & STYLE_MASK) | 1185 | if (flags & STYLE_MASK) |
| 1211 | G.all_fmt &= ~STYLE_MASK; | 1186 | G.all_fmt &= ~STYLE_MASK; |
| 1212 | if (flags & SORT_MASK) | ||
| 1213 | G.all_fmt &= ~SORT_MASK; | ||
| 1214 | 1187 | ||
| 1215 | G.all_fmt |= flags; | 1188 | G.all_fmt |= flags; |
| 1216 | } | 1189 | } |
| 1217 | } | 1190 | } |
| 1218 | if (opt & OPT_dirs_first) | ||
| 1219 | G.all_fmt |= SORT_DIRS_FIRST; | ||
| 1220 | if (opt & OPT_full_time) | 1191 | if (opt & OPT_full_time) |
| 1221 | G.all_fmt |= LIST_FULLTIME; | 1192 | G.all_fmt |= LIST_FULLTIME; |
| 1222 | 1193 | ||
| @@ -1256,7 +1227,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
| 1256 | /* without -l, bare -c or -u enable sort too */ | 1227 | /* without -l, bare -c or -u enable sort too */ |
| 1257 | /* (with -l, bare -c or -u just select which time to show) */ | 1228 | /* (with -l, bare -c or -u just select which time to show) */ |
| 1258 | if (opt & (OPT_c|OPT_u)) { | 1229 | if (opt & (OPT_c|OPT_u)) { |
| 1259 | G.all_fmt = (G.all_fmt & ~SORT_MASK) | SORT_TIME; | 1230 | option_mask32 |= OPT_t; |
| 1260 | } | 1231 | } |
| 1261 | } | 1232 | } |
| 1262 | } | 1233 | } |
