* mdocml: bring back support for sorting
@ 2016-10-18 23:58 schwarze
0 siblings, 0 replies; only message in thread
From: schwarze @ 2016-10-18 23:58 UTC (permalink / raw)
To: source
Log Message:
-----------
bring back support for sorting
Modified Files:
--------------
mdocml:
compat_fts.c
compat_fts.h
Revision Data
-------------
Index: compat_fts.h
===================================================================
RCS file: /home/cvs/mdocml/mdocml/compat_fts.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -Lcompat_fts.h -Lcompat_fts.h -u -p -r1.3 -r1.4
--- compat_fts.h
+++ compat_fts.h
@@ -38,9 +38,12 @@
typedef struct {
struct _ftsent *fts_cur; /* current node */
struct _ftsent *fts_child; /* linked list of children */
+ struct _ftsent **fts_array; /* sort array */
dev_t fts_dev; /* starting device # */
char *fts_path; /* path for this descent */
size_t fts_pathlen; /* sizeof(path) */
+ int fts_nitems; /* elements in the sort array */
+ int (*fts_compar)(); /* compare function */
#define FTS_NOCHDIR 0x0004 /* don't change directories */
#define FTS_PHYSICAL 0x0010 /* physical walk */
@@ -94,7 +97,8 @@ typedef struct _ftsent {
int fts_close(FTS *);
-FTS *fts_open(char * const *, int, void *);
+FTS *fts_open(char * const *, int,
+ int (*)(const FTSENT **, const FTSENT **));
FTSENT *fts_read(FTS *);
int fts_set(FTS *, FTSENT *, int);
Index: compat_fts.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/compat_fts.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -Lcompat_fts.c -Lcompat_fts.c -u -p -r1.11 -r1.12
--- compat_fts.c
+++ compat_fts.c
@@ -59,6 +59,7 @@ static void fts_load(FTS *, FTSENT *);
static size_t fts_maxarglen(char * const *);
static void fts_padjust(FTS *, FTSENT *);
static int fts_palloc(FTS *, size_t);
+static FTSENT *fts_sort(FTS *, FTSENT *, int);
static unsigned short fts_stat(FTS *, FTSENT *);
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
@@ -77,7 +78,8 @@ static unsigned short fts_stat(FTS *, F
#define SET(opt) (sp->fts_options |= (opt))
FTS *
-fts_open(char * const *argv, int options, void *dummy)
+fts_open(char * const *argv, int options,
+ int (*compar)(const FTSENT **, const FTSENT **))
{
FTS *sp;
FTSENT *p, *root;
@@ -99,6 +101,7 @@ fts_open(char * const *argv, int options
/* Allocate/initialize the stream */
if ((sp = calloc(1, sizeof(FTS))) == NULL)
return (NULL);
+ sp->fts_compar = compar;
sp->fts_options = options;
/*
@@ -126,14 +129,25 @@ fts_open(char * const *argv, int options
if (p->fts_info == FTS_DOT)
p->fts_info = FTS_D;
- p->fts_link = NULL;
- if (root == NULL)
- tmp = root = p;
- else {
- tmp->fts_link = p;
- tmp = p;
+ /*
+ * If comparison routine supplied, traverse in sorted
+ * order; otherwise traverse in the order specified.
+ */
+ if (compar) {
+ p->fts_link = root;
+ root = p;
+ } else {
+ p->fts_link = NULL;
+ if (root == NULL)
+ tmp = root = p;
+ else {
+ tmp->fts_link = p;
+ tmp = p;
+ }
}
}
+ if (compar && nitems > 1)
+ root = fts_sort(sp, root, nitems);
/*
* Allocate a dummy pointer and make fts_read think that we've just
@@ -203,6 +217,7 @@ fts_close(FTS *sp)
/* Free up child linked list, sort array, path buffer, stream ptr.*/
if (sp->fts_child)
fts_lfree(sp->fts_child);
+ free(sp->fts_array);
free(sp->fts_path);
free(sp);
@@ -490,6 +505,10 @@ mem1: saved_errno = errno;
cur->fts_info = FTS_DP;
return (NULL);
}
+
+ /* Sort the entries. */
+ if (sp->fts_compar && nitems > 1)
+ head = fts_sort(sp, head, nitems);
return (head);
}
@@ -544,6 +563,40 @@ fts_stat(FTS *sp, FTSENT *p)
if (S_ISREG(sbp->st_mode))
return (FTS_F);
return (FTS_DEFAULT);
+}
+
+static FTSENT *
+fts_sort(FTS *sp, FTSENT *head, int nitems)
+{
+ FTSENT **ap, *p;
+
+ /*
+ * Construct an array of pointers to the structures and call qsort(3).
+ * Reassemble the array in the order returned by qsort. If unable to
+ * sort for memory reasons, return the directory entries in their
+ * current order. Allocate enough space for the current needs plus
+ * 40 so don't realloc one entry at a time.
+ */
+ if (nitems > sp->fts_nitems) {
+ struct _ftsent **a;
+
+ sp->fts_nitems = nitems + 40;
+ if ((a = reallocarray(sp->fts_array,
+ sp->fts_nitems, sizeof(FTSENT *))) == NULL) {
+ free(sp->fts_array);
+ sp->fts_array = NULL;
+ sp->fts_nitems = 0;
+ return (head);
+ }
+ sp->fts_array = a;
+ }
+ for (ap = sp->fts_array, p = head; p; p = p->fts_link)
+ *ap++ = p;
+ qsort(sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
+ for (head = *(ap = sp->fts_array); --nitems; ++ap)
+ ap[0]->fts_link = ap[1];
+ ap[0]->fts_link = NULL;
+ return (head);
}
static FTSENT *
--
To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2016-10-18 23:58 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-18 23:58 mdocml: bring back support for sorting schwarze
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).