# Directives controlling the display of server-generated directory listings.
#
-#
-# FancyIndexing is whether you want fancy directory indexing or standard
-#
-IndexOptions FancyIndexing
+# FancyIndexing is whether you want fancy directory indexing or standard.
+# VersionSort is whether files containing version numbers should be
+# compared in the natural way, so that `apache-1.3.9.tar' is placed before
+# `apache-1.3.12.tar'.
+IndexOptions FancyIndexing VersionSort
#
# AddIcon* directives tell the server which icon to show for different
filename column in bytes. If the keyword value is '<SAMP>*</SAMP>',
then the column is automatically sized to the length of the longest
filename in the display.
+<DT><A NAME="indexoptions:versionsort">VersionSort (<EM>Apache 2.0a3 and later</EM>)</A>
+<DD>
+The VersionSort keyword causes files containing version numbers to
+sort in a natural way. Strings are sorted as usual, except that
+substrings of digits in the name and description are compared
+according to their numeric value.
+
+For example:
+<BLOCKQUOTE><pre>
+foo-1.7
+foo-1.7.2
+foo-1.7.12
+foo-1.8.2
+foo-1.8.2a
+foo-1.12
+</pre></BLOCKQUOTE>
+
+If the number starts with a zero, then it is considered to be a
+ fraction:
+<BLOCKQUOTE><pre>
+foo-1.001
+foo-1.002
+foo-1.030
+foo-1.04
+</pre></BLOCKQUOTE>
<DT><A NAME="indexoptions:scanhtmltitles">ScanHTMLTitles</A>
<DD><!--%plaintext <?INDEX {\tt ScanHTMLTitles} index option> -->
This enables the extraction of the title from HTML documents for fancy
* 3/23/93
*
* Adapted to Apache by rst.
- */
+ *
+ * Version sort added by Martin Pool <mbp@humbug.org.au>. */
#include "ap_config.h"
#include "httpd.h"
#include "http_main.h"
#include "util_script.h"
#include "apr_fnmatch.h"
+#include "apr_strnatcmp.h"
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#define SUPPRESS_PREAMBLE 64
#define SUPPRESS_COLSORT 128
#define NO_OPTIONS 256
+#define VERSION_SORT 512
#define K_PAD 1
#define K_NOPAD 0
else if (!strcasecmp(w, "SuppressColumnSorting")) {
option = SUPPRESS_COLSORT;
}
+ else if (!strcasecmp(w, "VersionSort")) {
+ option = VERSION_SORT;
+ }
else if (!strcasecmp(w, "None")) {
if (action != '\0') {
return "Cannot combine '+' or '-' with 'None' keyword";
off_t size;
ap_time_t lm;
struct ent *next;
- int ascending;
+ int ascending, version_sort;
char key;
};
p->lm = -1;
p->key = ap_toupper(keyid);
p->ascending = (ap_toupper(direction) == D_ASCENDING);
+ p->version_sort = autoindex_opts & VERSION_SORT;
if (autoindex_opts & FANCY_INDEXING) {
request_rec *rr = ap_sub_req_lookup_file(name, r);
c1 = *e2;
c2 = *e1;
}
+
switch (c1->key) {
case K_LAST_MOD:
if (c1->lm > c2->lm) {
}
break;
case K_DESC:
- result = strcmp(c1->desc ? c1->desc : "", c2->desc ? c2->desc : "");
+ if (c1->version_sort)
+ result = strnatcmp(c1->desc ? c1->desc : "", c2->desc ? c2->desc : "");
+ else
+ result = strcmp(c1->desc ? c1->desc : "", c2->desc ? c2->desc : "");
if (result) {
return result;
}
break;
}
- return strcmp(c1->name, c2->name);
+ if (c1->version_sort)
+ return strnatcmp(c1->name, c2->name);
+ else
+ return strcmp(c1->name, c2->name);
}