aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2000-08-11 18:10:21 +0000
committerEric Andersen <andersen@codepoet.org>2000-08-11 18:10:21 +0000
commit79565b6c910e76c19cd5c0729659d6e96472c785 (patch)
tree407c3e6c7d6e36403397e04149524a998a9bf57e
parentf9ca653faa5ee3a56409221d4627679d6a9304a9 (diff)
downloadbusybox-w32-79565b6c910e76c19cd5c0729659d6e96472c785.tar.gz
busybox-w32-79565b6c910e76c19cd5c0729659d6e96472c785.tar.bz2
busybox-w32-79565b6c910e76c19cd5c0729659d6e96472c785.zip
Add optional ls file sorting, thanks to a patch from
Sterling Huxley <sterling@europa.com> -Erik
-rw-r--r--Changelog6
-rw-r--r--busybox.def.h3
-rw-r--r--coreutils/ls.c86
-rw-r--r--ls.c86
4 files changed, 179 insertions, 2 deletions
diff --git a/Changelog b/Changelog
index f415e5d43..62db63bd2 100644
--- a/Changelog
+++ b/Changelog
@@ -7,8 +7,10 @@
7 * syslogd can now log messages to a remote host -- patch thanks 7 * syslogd can now log messages to a remote host -- patch thanks
8 to Gyepi Sam <gyepi@praxis-sw.com> 8 to Gyepi Sam <gyepi@praxis-sw.com>
9 * Rewrite of 'tail' to make it simpler, smaller, and more robust. 9 * Rewrite of 'tail' to make it simpler, smaller, and more robust.
10 It now weighs only 2.25k (3k when full featured). The code it 10 It now weighs only 2.25k (3k when full featured). The code is
11 much cleaner, thanks to "Allen Soard" <esp-software@mail.hypermart.net> 11 cleaner too, thanks to Allen Soard <esp-software@mail.hypermart.net>
12 * Add optional ls file sorting, thanks to a patch from
13 Sterling Huxley <sterling@europa.com>
12 14
13 15
14 -Erik Andersen 16 -Erik Andersen
diff --git a/busybox.def.h b/busybox.def.h
index 5adc3e57f..474c3c368 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -161,6 +161,9 @@
161// enable ls -p and -F 161// enable ls -p and -F
162#define BB_FEATURE_LS_FILETYPES 162#define BB_FEATURE_LS_FILETYPES
163// 163//
164// sort the file names
165#define BB_FEATURE_LS_SORTFILES
166//
164// enable ls -R 167// enable ls -R
165#define BB_FEATURE_LS_RECURSIVE 168#define BB_FEATURE_LS_RECURSIVE
166// 169//
diff --git a/coreutils/ls.c b/coreutils/ls.c
index d7455f427..20373eaaa 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -90,6 +90,14 @@
90#define MINOR(dev) ((dev)&0xff) 90#define MINOR(dev) ((dev)&0xff)
91#endif 91#endif
92 92
93#ifdef BB_FEATURE_LS_SORTFILES
94struct dnode { /* the basic node */
95 char *name; /* the dir entry name */
96 char *fullname; /* the dir entry name */
97 struct stat dstat; /* the file stat info */
98};
99typedef struct dnode dnode_t;
100#endif
93static unsigned char display_fmt = FMT_AUTO; 101static unsigned char display_fmt = FMT_AUTO;
94static unsigned short opts = 0; 102static unsigned short opts = 0;
95static unsigned short column = 0; 103static unsigned short column = 0;
@@ -328,6 +336,48 @@ static void list_single(const char *name, struct stat *info,
328 } 336 }
329} 337}
330 338
339#ifdef BB_FEATURE_LS_SORTFILES
340void shellsort(struct dnode *dn[], int size)
341{
342 struct dnode *temp;
343 int gap, i, j;
344
345 /* shell short the array */
346 for (gap= size/2; gap>0; gap /=2) {
347 for (i=gap; i<size; i++) {
348 for (j= i-gap; j>=0; j-=gap) {
349 if (strcmp(dn[j]->name, dn[j+gap]->name) <= 0)
350 break;
351 temp= dn[j];
352 dn[j]= dn[j+gap];
353 dn[j+gap]= temp;
354 }
355 }
356 }
357}
358
359void showdnodes(struct dnode *dn[], int nfiles)
360{
361 int nf, nc;
362 int ncols, fpc, i;
363
364 ncols= (int)(terminal_width / (column_width + COLUMN_GAP));
365 /* files per column. The +1 means the last col is shorter than others */
366 fpc= (nfiles / ncols) + 1;
367 for (nf=0; nf<fpc; nf++) {
368 for (nc=0; nc<ncols; nc++) {
369 /* reach into the array based on the column and row */
370 i= (nc * fpc) + nf;
371 if (i >= nfiles) {
372 newline();
373 } else {
374 list_single(dn[i]->name, &dn[i]->dstat, dn[i]->fullname);
375 }
376 }
377 }
378}
379#endif
380
331/** 381/**
332 ** 382 **
333 ** List the given file or directory, expanding a directory 383 ** List the given file or directory, expanding a directory
@@ -341,6 +391,11 @@ static int list_item(const char *name)
341 DIR *dir; 391 DIR *dir;
342 struct dirent *entry; 392 struct dirent *entry;
343 char fullname[BUFSIZ + 1], *fnend; 393 char fullname[BUFSIZ + 1], *fnend;
394#ifdef BB_FEATURE_LS_SORTFILES
395 int ni=0, nfiles=0;
396 struct dnode **dnp;
397 dnode_t *cur;
398#endif
344 399
345 if (lstat(name, &info)) 400 if (lstat(name, &info))
346 goto listerr; 401 goto listerr;
@@ -369,6 +424,18 @@ static int list_item(const char *name)
369 column_width = 0; 424 column_width = 0;
370 while ((entry = readdir(dir)) != NULL) { 425 while ((entry = readdir(dir)) != NULL) {
371 short w = strlen(entry->d_name); 426 short w = strlen(entry->d_name);
427#ifdef BB_FEATURE_LS_SORTFILES
428 const char *en = entry->d_name;
429
430 if (en[0] == '.') {
431 if (!en[1] || (en[1] == '.' && !en[2])) { /* . or .. */
432 if (!(opts & DISP_DOT))
433 continue;
434 } else if (!(opts & DISP_HIDDEN))
435 continue;
436 }
437 nfiles++; /* count how many files there will be */
438#endif
372 439
373 if (column_width < w) 440 if (column_width < w)
374 column_width = w; 441 column_width = w;
@@ -382,6 +449,12 @@ static int list_item(const char *name)
382 goto listerr; 449 goto listerr;
383#endif 450#endif
384#endif 451#endif
452#ifdef BB_FEATURE_LS_SORTFILES
453 /* now that we know how many files there are
454 * allocate memory for an array to hold dnode pointers
455 */
456 dnp= (struct dnode **)calloc((size_t)nfiles, (size_t)(sizeof(struct dnode *)));
457#endif
385 458
386 /* List the contents */ 459 /* List the contents */
387 460
@@ -402,11 +475,24 @@ static int list_item(const char *name)
402 } 475 }
403 /* FIXME: avoid stat if not required */ 476 /* FIXME: avoid stat if not required */
404 strcpy(fnend, entry->d_name); 477 strcpy(fnend, entry->d_name);
478#ifdef BB_FEATURE_LS_SORTFILES
479 /* allocate memory for a node and memory for the file name */
480 cur= (struct dnode *)malloc(sizeof(struct dnode));
481 cur->fullname= strcpy((char *)malloc(strlen(fullname)+1), fullname);
482 cur->name= cur->fullname + (int)(fnend - fullname) ;
483 lstat(fullname, &cur->dstat); /* get file stat info into node */
484 dnp[ni++]= cur; /* save pointer to node in array */
485#else
405 if (lstat(fullname, &info)) 486 if (lstat(fullname, &info))
406 goto direrr; /* (shouldn't fail) */ 487 goto direrr; /* (shouldn't fail) */
407 list_single(entry->d_name, &info, fullname); 488 list_single(entry->d_name, &info, fullname);
489#endif
408 } 490 }
409 closedir(dir); 491 closedir(dir);
492#ifdef BB_FEATURE_LS_SORTFILES
493 shellsort(dnp, nfiles);
494 showdnodes(dnp, nfiles);
495#endif
410 496
411 if (opts & DISP_DIRNAME) { /* separate the directory */ 497 if (opts & DISP_DIRNAME) { /* separate the directory */
412 if (column) { 498 if (column) {
diff --git a/ls.c b/ls.c
index d7455f427..20373eaaa 100644
--- a/ls.c
+++ b/ls.c
@@ -90,6 +90,14 @@
90#define MINOR(dev) ((dev)&0xff) 90#define MINOR(dev) ((dev)&0xff)
91#endif 91#endif
92 92
93#ifdef BB_FEATURE_LS_SORTFILES
94struct dnode { /* the basic node */
95 char *name; /* the dir entry name */
96 char *fullname; /* the dir entry name */
97 struct stat dstat; /* the file stat info */
98};
99typedef struct dnode dnode_t;
100#endif
93static unsigned char display_fmt = FMT_AUTO; 101static unsigned char display_fmt = FMT_AUTO;
94static unsigned short opts = 0; 102static unsigned short opts = 0;
95static unsigned short column = 0; 103static unsigned short column = 0;
@@ -328,6 +336,48 @@ static void list_single(const char *name, struct stat *info,
328 } 336 }
329} 337}
330 338
339#ifdef BB_FEATURE_LS_SORTFILES
340void shellsort(struct dnode *dn[], int size)
341{
342 struct dnode *temp;
343 int gap, i, j;
344
345 /* shell short the array */
346 for (gap= size/2; gap>0; gap /=2) {
347 for (i=gap; i<size; i++) {
348 for (j= i-gap; j>=0; j-=gap) {
349 if (strcmp(dn[j]->name, dn[j+gap]->name) <= 0)
350 break;
351 temp= dn[j];
352 dn[j]= dn[j+gap];
353 dn[j+gap]= temp;
354 }
355 }
356 }
357}
358
359void showdnodes(struct dnode *dn[], int nfiles)
360{
361 int nf, nc;
362 int ncols, fpc, i;
363
364 ncols= (int)(terminal_width / (column_width + COLUMN_GAP));
365 /* files per column. The +1 means the last col is shorter than others */
366 fpc= (nfiles / ncols) + 1;
367 for (nf=0; nf<fpc; nf++) {
368 for (nc=0; nc<ncols; nc++) {
369 /* reach into the array based on the column and row */
370 i= (nc * fpc) + nf;
371 if (i >= nfiles) {
372 newline();
373 } else {
374 list_single(dn[i]->name, &dn[i]->dstat, dn[i]->fullname);
375 }
376 }
377 }
378}
379#endif
380
331/** 381/**
332 ** 382 **
333 ** List the given file or directory, expanding a directory 383 ** List the given file or directory, expanding a directory
@@ -341,6 +391,11 @@ static int list_item(const char *name)
341 DIR *dir; 391 DIR *dir;
342 struct dirent *entry; 392 struct dirent *entry;
343 char fullname[BUFSIZ + 1], *fnend; 393 char fullname[BUFSIZ + 1], *fnend;
394#ifdef BB_FEATURE_LS_SORTFILES
395 int ni=0, nfiles=0;
396 struct dnode **dnp;
397 dnode_t *cur;
398#endif
344 399
345 if (lstat(name, &info)) 400 if (lstat(name, &info))
346 goto listerr; 401 goto listerr;
@@ -369,6 +424,18 @@ static int list_item(const char *name)
369 column_width = 0; 424 column_width = 0;
370 while ((entry = readdir(dir)) != NULL) { 425 while ((entry = readdir(dir)) != NULL) {
371 short w = strlen(entry->d_name); 426 short w = strlen(entry->d_name);
427#ifdef BB_FEATURE_LS_SORTFILES
428 const char *en = entry->d_name;
429
430 if (en[0] == '.') {
431 if (!en[1] || (en[1] == '.' && !en[2])) { /* . or .. */
432 if (!(opts & DISP_DOT))
433 continue;
434 } else if (!(opts & DISP_HIDDEN))
435 continue;
436 }
437 nfiles++; /* count how many files there will be */
438#endif
372 439
373 if (column_width < w) 440 if (column_width < w)
374 column_width = w; 441 column_width = w;
@@ -382,6 +449,12 @@ static int list_item(const char *name)
382 goto listerr; 449 goto listerr;
383#endif 450#endif
384#endif 451#endif
452#ifdef BB_FEATURE_LS_SORTFILES
453 /* now that we know how many files there are
454 * allocate memory for an array to hold dnode pointers
455 */
456 dnp= (struct dnode **)calloc((size_t)nfiles, (size_t)(sizeof(struct dnode *)));
457#endif
385 458
386 /* List the contents */ 459 /* List the contents */
387 460
@@ -402,11 +475,24 @@ static int list_item(const char *name)
402 } 475 }
403 /* FIXME: avoid stat if not required */ 476 /* FIXME: avoid stat if not required */
404 strcpy(fnend, entry->d_name); 477 strcpy(fnend, entry->d_name);
478#ifdef BB_FEATURE_LS_SORTFILES
479 /* allocate memory for a node and memory for the file name */
480 cur= (struct dnode *)malloc(sizeof(struct dnode));
481 cur->fullname= strcpy((char *)malloc(strlen(fullname)+1), fullname);
482 cur->name= cur->fullname + (int)(fnend - fullname) ;
483 lstat(fullname, &cur->dstat); /* get file stat info into node */
484 dnp[ni++]= cur; /* save pointer to node in array */
485#else
405 if (lstat(fullname, &info)) 486 if (lstat(fullname, &info))
406 goto direrr; /* (shouldn't fail) */ 487 goto direrr; /* (shouldn't fail) */
407 list_single(entry->d_name, &info, fullname); 488 list_single(entry->d_name, &info, fullname);
489#endif
408 } 490 }
409 closedir(dir); 491 closedir(dir);
492#ifdef BB_FEATURE_LS_SORTFILES
493 shellsort(dnp, nfiles);
494 showdnodes(dnp, nfiles);
495#endif
410 496
411 if (opts & DISP_DIRNAME) { /* separate the directory */ 497 if (opts & DISP_DIRNAME) { /* separate the directory */
412 if (column) { 498 if (column) {