1        -:    0:Source:sort.c
2        -:    1:/* sort.c -- functions used to sort files */
3        -:    2:
4        -:    3:/*
5        -:    4: * This file is part of CliFM
6        -:    5: *
7        -:    6: * Copyright (C) 2016-2021, L. Abramovich <johndoe.arch@outlook.com>
8        -:    7: * All rights reserved.
9        -:    8:
10        -:    9: * CliFM is free software; you can redistribute it and/or modify
11        -:   10: * it under the terms of the GNU General Public License as published by
12        -:   11: * the Free Software Foundation; either version 2 of the License, or
13        -:   12: * (at your option) any later version.
14        -:   13: *
15        -:   14: * CliFM is distributed in the hope that it will be useful,
16        -:   15: * but WITHOUT ANY WARRANTY; without even the implied warranty of
17        -:   16: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18        -:   17: * GNU General Public License for more details.
19        -:   18: *
20        -:   19: * You should have received a copy of the GNU General Public License
21        -:   20: * along with this program; if not, write to the Free Software
22        -:   21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23        -:   22: * MA 02110-1301, USA.
24        -:   23:*/
25        -:   24:
26        -:   25:#include "helpers.h"
27        -:   26:
28        -:   27:#include <dirent.h>
29        -:   28:#include <fcntl.h>
30        -:   29:#include <stdio.h>
31        -:   30:#include <string.h>
32        -:   31:#include <unistd.h>
33        -:   32:#ifdef __OpenBSD__
34        -:   33:#include <strings.h>
35        -:   34:#endif
36        -:   35://#include <sys/stat.h>
37        -:   36:
38        -:   37:#include "checks.h"
39        -:   38:#include "listing.h"
40        -:   39:#include "messages.h"
41        -:   40:
42        -:   41:int
43function skip_nonexec called 73420 returned 100% blocks executed 100%
44    73420:   42:skip_nonexec(const struct dirent *ent)
45        -:   43:{
46    73420:   44:	if (access(ent->d_name, X_OK) == -1)
47    73420:   44-block  0
48call    0 returned 73420
49branch  1 taken 137 (fallthrough)
50branch  2 taken 73283
51      137:   45:		return 0;
52      137:   45-block  0
53unconditional  0 taken 137
54    73283:   46:	return 1;
55    73283:   46-block  0
56unconditional  0 taken 73283
57        -:   47:
58        -:   48:/*	int f = 0; // Hold file ownership flags
59        -:   49:
60        -:   50:	struct stat a;
61        -:   51:	if (stat(ent->d_name, &a) == -1)
62        -:   52:		return 0;
63        -:   53:
64        -:   54:	mode_t val = (a.st_mode & (mode_t)~S_IFMT);
65        -:   55:	if (val & S_IXUSR) f |= X_USR;
66        -:   56:	if (val & S_IXGRP) f |= X_GRP;
67        -:   57:	if (val & S_IXOTH) f |= X_OTH;
68        -:   58:
69        -:   59:	if ((f & X_USR) && a.st_uid == user.uid)
70        -:   60:		return 1;
71        -:   61:	if ((f & X_GRP) && a.st_gid == user.gid)
72        -:   62:		return 1;
73        -:   63:	if (f & X_OTH)
74        -:   64:		return 1;
75        -:   65:
76        -:   66:	return 0; */
77        -:   67:}
78        -:   68:
79        -:   69:int
80function skip_files called 33 returned 100% blocks executed 64%
81       33:   70:skip_files(const struct dirent *ent)
82        -:   71:{
83        -:   72:	/* In case a directory isn't reacheable, like a failed
84        -:   73:	 * mountpoint... */
85        -:   74:	/*  struct stat file_attrib;
86        -:   75:
87        -:   76:	if (lstat(entry->d_name, &file_attrib) == -1) {
88        -:   77:		fprintf(stderr, _("stat: cannot access '%s': %s\n"),
89        -:   78:				entry->d_name, strerror(errno));
90        -:   79:		return 0;
91        -:   80:	} */
92        -:   81:
93        -:   82:	/* Skip "." and ".." */
94       33:   83:	if (*ent->d_name == '.' && (!ent->d_name[1] || (ent->d_name[1] == '.' && !ent->d_name[2])))
95       33:   83-block  0
96branch  0 taken 14 (fallthrough)
97branch  1 taken 19
98       14:   83-block  1
99branch  2 taken 7 (fallthrough)
100branch  3 taken 7
101        7:   83-block  2
102branch  4 taken 7 (fallthrough)
103branch  5 taken 0
104        7:   83-block  3
105branch  6 taken 7 (fallthrough)
106branch  7 taken 0
107       14:   84:		return 0;
108       14:   84-block  0
109unconditional  0 taken 14
110        -:   85:
111        -:   86:	/* Skip files matching FILTER */
112      19*:   87:	if (filter && regexec(&regex_exp, ent->d_name, 0, NULL, 0) == EXIT_SUCCESS)
113       19:   87-block  0
114branch  0 taken 0 (fallthrough)
115branch  1 taken 19
116    %%%%%:   87-block  1
117call    2 never executed
118branch  3 never executed
119branch  4 never executed
120    #####:   88:		return 0;
121    %%%%%:   88-block  0
122unconditional  0 never executed
123        -:   89:
124        -:   90:	/* If not hidden files */
125      19*:   91:	if (!show_hidden && *ent->d_name == '.')
126       19:   91-block  0
127branch  0 taken 0 (fallthrough)
128branch  1 taken 19
129    %%%%%:   91-block  1
130branch  2 never executed
131branch  3 never executed
132    #####:   92:		return 0;
133    %%%%%:   92-block  0
134unconditional  0 never executed
135        -:   93:
136       19:   94:	return 1;
137       19:   94-block  0
138unconditional  0 taken 19
139        -:   95:}
140        -:   96:
141        -:   97:int
142function namecmp called 370705 returned 100% blocks executed 95%
143   370705:   98:namecmp(const char *s1, const char *s2)
144        -:   99:{
145        -:  100:	/* Do not take initial dot into account */
146   370705:  101:	if (*s1 == '.')
147   370705:  101-block  0
148branch  0 taken 7465 (fallthrough)
149branch  1 taken 363240
150     7465:  102:		s1++;
151     7465:  102-block  0
152unconditional  0 taken 7465
153        -:  103:
154   370705:  104:	if (*s2 == '.')
155   370705:  104-block  0
156branch  0 taken 8015 (fallthrough)
157branch  1 taken 362690
158     8015:  105:		s2++;
159     8015:  105-block  0
160unconditional  0 taken 8015
161        -:  106:
162   370705:  107:	char ac = *s1, bc = *s2;
163        -:  108:
164   370705:  109:	if (!case_sensitive) {
165   370705:  109-block  0
166branch  0 taken 370705 (fallthrough)
167branch  1 taken 0
168   370705:  110:		ac = (char)TOUPPER(*s1);
169   370705:  110-block  0
170branch  0 taken 365644 (fallthrough)
171branch  1 taken 5061
172   365644:  110-block  1
173branch  2 taken 365644 (fallthrough)
174branch  3 taken 0
175   365644:  110-block  2
176unconditional  4 taken 365644
177     5061:  110-block  3
178unconditional  5 taken 5061
179   370705:  111:		bc = (char)TOUPPER(*s2);
180   370705:  111-block  0
181branch  0 taken 365935 (fallthrough)
182branch  1 taken 4770
183   365935:  111-block  1
184branch  2 taken 365935 (fallthrough)
185branch  3 taken 0
186   365935:  111-block  2
187unconditional  4 taken 365935
188     4770:  111-block  3
189unconditional  5 taken 4770
190   370705:  111-block  4
191unconditional  6 taken 370705
192        -:  112:	}
193        -:  113:
194   370705:  114:	if (bc > ac)
195   370705:  114-block  0
196branch  0 taken 76140 (fallthrough)
197branch  1 taken 294565
198    76140:  115:		return -1;
199    76140:  115-block  0
200unconditional  0 taken 76140
201        -:  116:
202   294565:  117:	if (bc < ac)
203   294565:  117-block  0
204branch  0 taken 81327 (fallthrough)
205branch  1 taken 213238
206    81327:  118:		return 1;
207    81327:  118-block  0
208unconditional  0 taken 81327
209        -:  119:
210   213238:  120:	if (!case_sensitive)
211   213238:  120-block  0
212branch  0 taken 213238 (fallthrough)
213branch  1 taken 0
214   213238:  121:		return strcasecmp(s1, s2);
215   213238:  121-block  0
216unconditional  0 taken 213238
217        -:  122:
218    #####:  123:	return strcmp(s1, s2);
219    %%%%%:  123-block  0
220unconditional  0 never executed
221        -:  124:}
222        -:  125:
223        -:  126:int
224function entrycmp called 376432 returned 100% blocks executed 91%
225   376432:  127:entrycmp(const void *a, const void *b)
226        -:  128:{
227   376432:  129:	const struct fileinfo *pa = (struct fileinfo *)a;
228   376432:  130:	const struct fileinfo *pb = (struct fileinfo *)b;
229        -:  131:
230   376432:  132:	if (list_folders_first) {
231   376432:  132-block  0
232branch  0 taken 376136 (fallthrough)
233branch  1 taken 296
234   376136:  133:		if (pb->dir != pa->dir) {
235   376136:  133-block  0
236branch  0 taken 4206 (fallthrough)
237branch  1 taken 371930
238     4206:  134:			if (pb->dir)
239     4206:  134-block  0
240branch  0 taken 2234 (fallthrough)
241branch  1 taken 1972
242     2234:  135:				return 1;
243     2234:  135-block  0
244unconditional  0 taken 2234
245        -:  136:
246     1972:  137:			return -1;
247     1972:  137-block  0
248unconditional  0 taken 1972
249        -:  138:		}
250        -:  139:	}
251        -:  140:
252   372226:  141:	int ret = 0, st = sort;
253        -:  142:
254        -:  143:#ifndef _GNU_SOURCE
255        -:  144:	if (st == SVER)
256        -:  145:		st = SNAME;
257        -:  146:#endif
258        -:  147:
259   372226:  148:	if (light_mode && (st == SOWN || st == SGRP))
260   372226:  148-block  0
261branch  0 taken 12 (fallthrough)
262branch  1 taken 372214
263       12:  148-block  1
264branch  2 taken 12 (fallthrough)
265branch  3 taken 0
266       12:  148-block  2
267branch  4 taken 0 (fallthrough)
268branch  5 taken 12
269    #####:  149:		st = SNAME;
270    %%%%%:  149-block  0
271unconditional  0 never executed
272        -:  150:
273   372226:  151:	switch (st) {
274   372226:  151-block  0
275branch  0 taken 456
276branch  1 taken 917
277branch  2 taken 236
278branch  3 taken 237
279branch  4 taken 233
280branch  5 taken 233
281branch  6 taken 233
282branch  7 taken 369681
283        -:  152:
284      456:  153:	case SSIZE:
285      456:  154:		if (pa->size > pb->size)
286      456:  154-block  0
287branch  0 taken 70 (fallthrough)
288branch  1 taken 386
289       70:  155:			ret = 1;
290       70:  155-block  0
291unconditional  0 taken 70
292      386:  156:		else if (pa->size < pb->size)
293      386:  156-block  0
294branch  0 taken 75 (fallthrough)
295branch  1 taken 311
296       75:  157:			ret = -1;
297       75:  157-block  0
298unconditional  0 taken 75
299      456:  158:		break;
300      456:  158-block  0
301unconditional  0 taken 456
302        -:  159:
303      917:  160:	case SATIME: /* fallthrough */
304        -:  161:	case SBTIME: /* fallthrough */
305        -:  162:	case SCTIME: /* fallthrough */
306        -:  163:	case SMTIME:
307      917:  164:		if (pa->time > pb->time)
308      917:  164-block  0
309branch  0 taken 448 (fallthrough)
310branch  1 taken 469
311      448:  165:			ret = 1;
312      448:  165-block  0
313unconditional  0 taken 448
314      469:  166:		else if (pa->time < pb->time)
315      469:  166-block  0
316branch  0 taken 432 (fallthrough)
317branch  1 taken 37
318      432:  167:			ret = -1;
319      432:  167-block  0
320unconditional  0 taken 432
321      917:  168:		break;
322      917:  168-block  0
323unconditional  0 taken 917
324        -:  169:
325        -:  170:#ifdef _GNU_SOURCE
326      236:  171:	case SVER:
327      236:  172:		ret = strverscmp(pa->name, pb->name);
328      236:  173:		break;
329      236:  173-block  0
330unconditional  0 taken 236
331        -:  174:#endif
332        -:  175:
333      237:  176:	case SEXT: {
334      237:  177:		char *aext = (char *)NULL, *bext = (char *)NULL, *val;
335      237:  178:		val = strrchr(pa->name, '.');
336      237:  179:		if (val && val != pa->name)
337      237:  179-block  0
338branch  0 taken 181 (fallthrough)
339branch  1 taken 56
340      181:  179-block  1
341branch  2 taken 10 (fallthrough)
342branch  3 taken 171
343       10:  180:			aext = val + 1;
344       10:  180-block  0
345unconditional  0 taken 10
346        -:  181:
347      237:  182:		val = strrchr(pb->name, '.');
348      237:  183:		if (val && val != pb->name)
349      237:  183-block  0
350branch  0 taken 200 (fallthrough)
351branch  1 taken 37
352      200:  183-block  1
353branch  2 taken 22 (fallthrough)
354branch  3 taken 178
355       22:  184:			bext = val + 1;
356       22:  184-block  0
357unconditional  0 taken 22
358        -:  185:
359      237:  186:		if (aext || bext) {
360      237:  186-block  0
361branch  0 taken 227 (fallthrough)
362branch  1 taken 10
363      227:  186-block  1
364branch  2 taken 17 (fallthrough)
365branch  3 taken 210
366       27:  187:			if (!aext)
367       27:  187-block  0
368branch  0 taken 17 (fallthrough)
369branch  1 taken 10
370       17:  188:				ret = -1;
371       17:  188-block  0
372unconditional  0 taken 17
373       10:  189:			else if (!bext)
374       10:  189-block  0
375branch  0 taken 5 (fallthrough)
376branch  1 taken 5
377        5:  190:				ret = 1;
378        5:  190-block  0
379unconditional  0 taken 5
380        -:  191:
381        -:  192:			else
382        5:  193:				ret = strcasecmp(aext, bext);
383        5:  193-block  0
384unconditional  0 taken 5
385        -:  194:		}
386      237:  195:	} break;
387      237:  195-block  0
388unconditional  0 taken 237
389        -:  196:
390      233:  197:	case SINO:
391      233:  198:		if (pa->inode > pb->inode)
392      233:  198-block  0
393branch  0 taken 115 (fallthrough)
394branch  1 taken 118
395      115:  199:			ret = 1;
396      115:  199-block  0
397unconditional  0 taken 115
398      118:  200:		else if (pa->inode < pb->inode)
399      118:  200-block  0
400branch  0 taken 118 (fallthrough)
401branch  1 taken 0
402      118:  201:			ret = -1;
403      118:  201-block  0
404unconditional  0 taken 118
405      233:  202:		break;
406      233:  202-block  0
407unconditional  0 taken 233
408        -:  203:
409      233:  204:	case SOWN:
410      233:  205:		if (pa->uid > pb->uid)
411      233:  205-block  0
412branch  0 taken 0 (fallthrough)
413branch  1 taken 233
414    #####:  206:			ret = 1;
415    %%%%%:  206-block  0
416unconditional  0 never executed
417      233:  207:		else if (pa->uid < pb->uid)
418      233:  207-block  0
419branch  0 taken 0 (fallthrough)
420branch  1 taken 233
421    #####:  208:			ret = -1;
422    %%%%%:  208-block  0
423unconditional  0 never executed
424      233:  209:		break;
425      233:  209-block  0
426unconditional  0 taken 233
427        -:  210:
428      233:  211:	case SGRP:
429      233:  212:		if (pa->gid > pb->gid)
430      233:  212-block  0
431branch  0 taken 0 (fallthrough)
432branch  1 taken 233
433    #####:  213:			ret = 1;
434    %%%%%:  213-block  0
435unconditional  0 never executed
436      233:  214:		else if (pa->gid < pb->gid)
437      233:  214-block  0
438branch  0 taken 0 (fallthrough)
439branch  1 taken 233
440    #####:  215:			ret = -1;
441    %%%%%:  215-block  0
442unconditional  0 never executed
443      233:  216:		break;
444      233:  216-block  0
445unconditional  0 taken 233
446        -:  217:	}
447        -:  218:
448   372226:  219:	if (!ret)
449   372226:  219-block  0
450branch  0 taken 370705 (fallthrough)
451branch  1 taken 1521
452   370705:  220:		ret = namecmp(pa->name, pb->name);
453   370705:  220-block  0
454call    0 returned 370705
455unconditional  1 taken 370705
456        -:  221:
457   372226:  222:	if (!sort_reverse)
458   372226:  222-block  0
459branch  0 taken 371986 (fallthrough)
460branch  1 taken 240
461   371986:  223:		return ret;
462   371986:  223-block  0
463unconditional  0 taken 371986
464        -:  224:
465      240:  225:	return (ret - (ret * 2));
466      240:  225-block  0
467unconditional  0 taken 240
468        -:  226:}
469        -:  227:
470        -:  228:/* Same as alphasort, but is uses strcmp instead of sctroll, which is
471        -:  229: * slower. However, bear in mind that, unlike strcmp(), strcoll() is locale
472        -:  230: * aware. Use only with C and english locales */
473        -:  231:int
474function xalphasort called 759605 returned 100% blocks executed 89%
475   759605:  232:xalphasort(const struct dirent **a, const struct dirent **b)
476        -:  233:{
477   759605:  234:	int ret = 0;
478        -:  235:
479        -:  236:	/* The if statements prevent strcmp from running in every
480        -:  237:	 * call to the function (it will be called only if the first
481        -:  238:	 * character of the two strings is the same), which makes the
482        -:  239:	 * function faster */
483   759605:  240:	if ((*a)->d_name[0] > (*b)->d_name[0])
484   759605:  240-block  0
485branch  0 taken 160941 (fallthrough)
486branch  1 taken 598664
487   160941:  241:		ret = 1;
488   160941:  241-block  0
489unconditional  0 taken 160941
490   598664:  242:	else if ((*a)->d_name[0] < (*b)->d_name[0])
491   598664:  242-block  0
492branch  0 taken 151411 (fallthrough)
493branch  1 taken 447253
494   151411:  243:		ret = -1;
495   151411:  243-block  0
496unconditional  0 taken 151411
497        -:  244:	else
498   447253:  245:		ret = strcmp((*a)->d_name, (*b)->d_name);
499   447253:  245-block  0
500unconditional  0 taken 447253
501        -:  246:
502   759605:  247:	if (!sort_reverse)
503   759605:  247-block  0
504branch  0 taken 759605 (fallthrough)
505branch  1 taken 0
506   759605:  248:		return ret;
507   759605:  248-block  0
508unconditional  0 taken 759605
509        -:  249:
510        -:  250:	/* If sort_reverse, return the opposite value */
511    #####:  251:	return (ret - (ret * 2));
512    %%%%%:  251-block  0
513unconditional  0 never executed
514        -:  252:}
515        -:  253:
516        -:  254:int
517function sort_function called 9 returned 100% blocks executed 32%
518        9:  255:sort_function(char **arg)
519        -:  256:{
520        9:  257:	int exit_status = EXIT_FAILURE;
521        -:  258:
522        -:  259:	/* No argument: Just print current sorting method */
523        9:  260:	if (!arg[1]) {
524        9:  260-block  0
525branch  0 taken 3 (fallthrough)
526branch  1 taken 6
527        -:  261:
528        3:  262:		printf(_("Sorting method: "));
529        3:  262-block  0
530call    0 returned 3
531call    1 returned 3
532        -:  263:
533        3:  264:		switch (sort) {
534branch  0 taken 0
535branch  1 taken 3
536branch  2 taken 0
537branch  3 taken 0
538branch  4 taken 0
539branch  5 taken 0
540branch  6 taken 0
541branch  7 taken 0
542branch  8 taken 0
543branch  9 taken 0
544branch 10 taken 0
545branch 11 taken 0
546branch 12 taken 0
547    #####:  265:		case SNONE:
548    #####:  266:			printf(_("none %s\n"), (sort_reverse) ? "[rev]" : "");
549    %%%%%:  266-block  0
550branch  0 never executed
551branch  1 never executed
552    %%%%%:  266-block  1
553unconditional  2 never executed
554    %%%%%:  266-block  2
555unconditional  3 never executed
556    %%%%%:  266-block  3
557call    4 never executed
558call    5 never executed
559    #####:  267:			break;
560unconditional  0 never executed
561        3:  268:		case SNAME:
562        3:  269:			printf(_("name %s\n"), (sort_reverse) ? "[rev]" : "");
563        3:  269-block  0
564branch  0 taken 1 (fallthrough)
565branch  1 taken 2
566        1:  269-block  1
567unconditional  2 taken 1
568        2:  269-block  2
569unconditional  3 taken 2
570        3:  269-block  3
571call    4 returned 3
572call    5 returned 3
573        3:  270:			break;
574unconditional  0 taken 3
575    #####:  271:		case SSIZE:
576    #####:  272:			printf(_("size %s\n"), (sort_reverse) ? "[rev]" : "");
577    %%%%%:  272-block  0
578branch  0 never executed
579branch  1 never executed
580    %%%%%:  272-block  1
581unconditional  2 never executed
582    %%%%%:  272-block  2
583unconditional  3 never executed
584    %%%%%:  272-block  3
585call    4 never executed
586call    5 never executed
587    #####:  273:			break;
588unconditional  0 never executed
589    #####:  274:		case SATIME:
590    #####:  275:			printf(_("atime %s\n"), (sort_reverse) ? "[rev]" : "");
591    %%%%%:  275-block  0
592branch  0 never executed
593branch  1 never executed
594    %%%%%:  275-block  1
595unconditional  2 never executed
596    %%%%%:  275-block  2
597unconditional  3 never executed
598    %%%%%:  275-block  3
599call    4 never executed
600call    5 never executed
601    #####:  276:			break;
602unconditional  0 never executed
603    #####:  277:		case SBTIME:
604        -:  278:#if defined(HAVE_ST_BIRTHTIME) || defined(__BSD_VISIBLE) || defined(_STATX)
605    #####:  279:			printf(_("btime %s\n"), (sort_reverse) ? "[rev]" : "");
606    %%%%%:  279-block  0
607branch  0 never executed
608branch  1 never executed
609    %%%%%:  279-block  1
610unconditional  2 never executed
611    %%%%%:  279-block  2
612unconditional  3 never executed
613    %%%%%:  279-block  3
614call    4 never executed
615call    5 never executed
616        -:  280:#else
617        -:  281:			printf(_("ctime %s\n"), (sort_reverse) ? "[rev]" : "");
618        -:  282:#endif
619    #####:  283:			break;
620unconditional  0 never executed
621    #####:  284:		case SCTIME:
622    #####:  285:			printf(_("ctime %s\n"), (sort_reverse) ? "[rev]" : "");
623    %%%%%:  285-block  0
624branch  0 never executed
625branch  1 never executed
626    %%%%%:  285-block  1
627unconditional  2 never executed
628    %%%%%:  285-block  2
629unconditional  3 never executed
630    %%%%%:  285-block  3
631call    4 never executed
632call    5 never executed
633    #####:  286:			break;
634unconditional  0 never executed
635    #####:  287:		case SMTIME:
636    #####:  288:			printf(_("mtime %s\n"), (sort_reverse) ? "[rev]" : "");
637    %%%%%:  288-block  0
638branch  0 never executed
639branch  1 never executed
640    %%%%%:  288-block  1
641unconditional  2 never executed
642    %%%%%:  288-block  2
643unconditional  3 never executed
644    %%%%%:  288-block  3
645call    4 never executed
646call    5 never executed
647    #####:  289:			break;
648unconditional  0 never executed
649    #####:  290:		case SVER:
650        -:  291:#if __FreeBSD__ || __NetBSD__ || __OpenBSD__ || _BE_POSIX
651        -:  292:			printf(_("name %s\n"), (sort_reverse) ? "[rev]" : "");
652        -:  293:#else
653    #####:  294:			printf(_("version %s\n"), (sort_reverse) ? "[rev]" : "");
654    %%%%%:  294-block  0
655branch  0 never executed
656branch  1 never executed
657    %%%%%:  294-block  1
658unconditional  2 never executed
659    %%%%%:  294-block  2
660unconditional  3 never executed
661    %%%%%:  294-block  3
662call    4 never executed
663call    5 never executed
664        -:  295:#endif
665    #####:  296:			break;
666unconditional  0 never executed
667    #####:  297:		case SEXT:
668    #####:  298:			printf(_("extension %s\n"), (sort_reverse) ? "[rev]" : "");
669    %%%%%:  298-block  0
670branch  0 never executed
671branch  1 never executed
672    %%%%%:  298-block  1
673unconditional  2 never executed
674    %%%%%:  298-block  2
675unconditional  3 never executed
676    %%%%%:  298-block  3
677call    4 never executed
678call    5 never executed
679    #####:  299:			break;
680unconditional  0 never executed
681    #####:  300:		case SINO:
682    #####:  301:			printf(_("inode %s\n"), (sort_reverse) ? "[rev]" : "");
683    %%%%%:  301-block  0
684branch  0 never executed
685branch  1 never executed
686    %%%%%:  301-block  1
687unconditional  2 never executed
688    %%%%%:  301-block  2
689unconditional  3 never executed
690    %%%%%:  301-block  3
691call    4 never executed
692call    5 never executed
693    #####:  302:			break;
694unconditional  0 never executed
695    #####:  303:		case SOWN:
696    #####:  304:			printf(_("owner %s\n"), (sort_reverse) ? "[rev]" : "");
697    %%%%%:  304-block  0
698branch  0 never executed
699branch  1 never executed
700    %%%%%:  304-block  1
701unconditional  2 never executed
702    %%%%%:  304-block  2
703unconditional  3 never executed
704    %%%%%:  304-block  3
705call    4 never executed
706call    5 never executed
707    #####:  305:			break;
708unconditional  0 never executed
709    #####:  306:		case SGRP:
710    #####:  307:			printf(_("group %s\n"), (sort_reverse) ? "[rev]" : "");
711    %%%%%:  307-block  0
712branch  0 never executed
713branch  1 never executed
714    %%%%%:  307-block  1
715unconditional  2 never executed
716    %%%%%:  307-block  2
717unconditional  3 never executed
718    %%%%%:  307-block  3
719call    4 never executed
720call    5 never executed
721    #####:  308:			break;
722unconditional  0 never executed
723        -:  309:		}
724        -:  310:
725        3:  311:		return EXIT_SUCCESS;
726        3:  311-block  0
727unconditional  0 taken 3
728        -:  312:	}
729        -:  313:
730        -:  314:	/* Argument is alphanumerical string */
731        6:  315:	if (!is_number(arg[1])) {
732        6:  315-block  0
733call    0 returned 6
734branch  1 taken 4 (fallthrough)
735branch  2 taken 2
736        -:  316:
737        -:  317:		struct sort_t {
738        -:  318:			const char *name;
739        -:  319:			int num;
740        -:  320:			int padding; /* Used only to properly align the struct */
741        -:  321:		};
742        -:  322:
743        -:  323:		static struct sort_t sorts[] = {
744        -:  324:		    {"none", 0, 0},
745        -:  325:		    {"name", 1, 0},
746        -:  326:		    {"size", 2, 0},
747        -:  327:		    {"atime", 3, 0},
748        -:  328:		    {"btime", 4, 0},
749        -:  329:		    {"ctime", 5, 0},
750        -:  330:		    {"mtime", 6, 0},
751        -:  331:		    {"version", 7, 0},
752        -:  332:		    {"extension", 8, 0},
753        -:  333:		    {"inode", 9, 0},
754        -:  334:		    {"owner", 10, 0},
755        -:  335:		    {"group", 11, 0},
756        -:  336:		};
757        -:  337:
758        -:  338:		size_t i;
759       52:  339:		for (i = 0; i < sizeof(sorts) / sizeof(struct sort_t); i++) {
760        4:  339-block  0
761unconditional  0 taken 4
762       48:  339-block  1
763unconditional  1 taken 48
764       52:  339-block  2
765branch  2 taken 48
766branch  3 taken 4 (fallthrough)
767       48:  340:			if (strcmp(arg[1], sorts[i].name) == 0) {
768       48:  340-block  0
769branch  0 taken 0 (fallthrough)
770branch  1 taken 48
771    #####:  341:				sprintf(arg[1], "%d", sorts[i].num);
772    #####:  342:				break;
773    %%%%%:  342-block  0
774unconditional  0 never executed
775        -:  343:			}
776        -:  344:		}
777        -:  345:
778        4:  346:		if (strcmp(arg[1], "rev") == 0) {
779        4:  346-block  0
780branch  0 taken 4 (fallthrough)
781branch  1 taken 0
782        -:  347:
783        4:  348:			if (sort_reverse)
784        4:  348-block  0
785branch  0 taken 2 (fallthrough)
786branch  1 taken 2
787        2:  349:				sort_reverse = 0;
788        2:  349-block  0
789unconditional  0 taken 2
790        -:  350:			else
791        2:  351:				sort_reverse = 1;
792        2:  351-block  0
793unconditional  0 taken 2
794        -:  352:
795        4:  353:			if (cd_lists_on_the_fly) {
796        4:  353-block  0
797branch  0 taken 4 (fallthrough)
798branch  1 taken 0
799        -:  354:				/* sort_switch just tells list_dir() to print a line
800        -:  355:				 * with the current sorting method at the end of the
801        -:  356:				 * files list */
802        4:  357:				sort_switch = 1;
803        4:  358:				free_dirlist();
804        4:  358-block  0
805call    0 returned 4
806        4:  359:				exit_status = list_dir();
807call    0 returned 4
808        4:  360:				sort_switch = 0;
809unconditional  0 taken 4
810        -:  361:			}
811        -:  362:
812        4:  363:			return exit_status;
813        4:  363-block  0
814unconditional  0 taken 4
815        -:  364:		}
816        -:  365:
817        -:  366:		/* If arg1 is not a number and is not "rev", the fputs()
818        -:  367:		 * above is executed */
819        -:  368:	}
820        -:  369:
821        -:  370:	/* Argument is a number */
822        2:  371:	int int_arg = atoi(arg[1]);
823        -:  372:
824        2:  373:	if (int_arg >= 0 && int_arg <= SORT_TYPES) {
825        2:  373-block  0
826branch  0 taken 2 (fallthrough)
827branch  1 taken 0
828        2:  373-block  1
829branch  2 taken 2 (fallthrough)
830branch  3 taken 0
831        2:  374:		sort = int_arg;
832        -:  375:
833       2*:  376:		if (arg[2] && strcmp(arg[2], "rev") == 0) {
834        2:  376-block  0
835branch  0 taken 0 (fallthrough)
836branch  1 taken 2
837    %%%%%:  376-block  1
838branch  2 never executed
839branch  3 never executed
840    #####:  377:			if (sort_reverse)
841    %%%%%:  377-block  0
842branch  0 never executed
843branch  1 never executed
844    #####:  378:				sort_reverse = 0;
845    %%%%%:  378-block  0
846unconditional  0 never executed
847        -:  379:			else
848    #####:  380:				sort_reverse = 1;
849    %%%%%:  380-block  0
850unconditional  0 never executed
851        -:  381:		}
852        -:  382:
853        2:  383:		if (cd_lists_on_the_fly) {
854        2:  383-block  0
855branch  0 taken 2 (fallthrough)
856branch  1 taken 0
857        2:  384:			sort_switch = 1;
858        2:  385:			free_dirlist();
859        2:  385-block  0
860call    0 returned 2
861        2:  386:			exit_status = list_dir();
862call    0 returned 2
863        2:  387:			sort_switch = 0;
864unconditional  0 taken 2
865        -:  388:		}
866        -:  389:
867        2:  390:		return exit_status;
868        2:  390-block  0
869unconditional  0 taken 2
870        -:  391:	}
871        -:  392:
872        -:  393:	/* If arg1 is a number but is not in the range 0-SORT_TYPES,
873        -:  394:	 * error */
874    #####:  395:	fprintf(stderr, "%s\n", _(SORT_USAGE));
875    %%%%%:  395-block  0
876call    0 never executed
877call    1 never executed
878        -:  396:
879    #####:  397:	return EXIT_FAILURE;
880unconditional  0 never executed
881        -:  398:}
882        -:  399:
883        -:  400:/* This is a modification of the alphasort function that makes it case
884        -:  401: * insensitive. It also sorts without taking the initial dot of hidden
885        -:  402: * files into account. Note that strcasecmp() isn't locale aware. Use
886        -:  403: * only with C and english locales */
887        -:  404:int
888function alphasort_insensitive called 0 returned 0% blocks executed 0%
889    #####:  405:alphasort_insensitive(const struct dirent **a, const struct dirent **b)
890        -:  406:{
891    #####:  407:	int ret = strcasecmp(((*a)->d_name[0] == '.') ? (*a)->d_name + 1
892    %%%%%:  407-block  0
893branch  0 never executed
894branch  1 never executed
895    %%%%%:  407-block  1
896unconditional  2 never executed
897    #####:  408:	: (*a)->d_name, ((*b)->d_name[0] == '.') ? (*b)->d_name + 1 : (*b)->d_name);
898    %%%%%:  408-block  0
899branch  0 never executed
900branch  1 never executed
901    %%%%%:  408-block  1
902unconditional  2 never executed
903    %%%%%:  408-block  2
904unconditional  3 never executed
905    %%%%%:  408-block  3
906unconditional  4 never executed
907        -:  409:
908    #####:  410:	if (!sort_reverse)
909    %%%%%:  410-block  0
910branch  0 never executed
911branch  1 never executed
912    #####:  411:		return ret;
913    %%%%%:  411-block  0
914unconditional  0 never executed
915        -:  412:
916    #####:  413:	return (ret - (ret * 2));
917    %%%%%:  413-block  0
918unconditional  0 never executed
919        -:  414:}
920