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 | |
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>
-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 | } |