/* Get the list */
if(fn(dcgi_client, dir, re, &tracks, &ntracks))
return 0;
- /* Sort it. NB trackname_transform() does not go to the server. */
- tsd = tracksort_init(ntracks, tracks, type);
- /* Expand the subsiduary templates. We chuck in @sort and @display because
- * it is particularly easy to do so. */
- for(n = 0; n < ntracks; ++n)
- if((rc = mx_expand(mx_rewritel(m,
- "index", make_index(n),
- "parity", n % 2 ? "odd" : "even",
- "track", tsd[n].track,
- "first", n == 0 ? "true" : "false",
- "last", n + 1 == ntracks ? "false" : "true",
- "sort", tsd[n].sort,
- "display", tsd[n].display,
- (char *)0),
- output, u)))
- return rc;
+ if(type) {
+ /* Sort it. NB trackname_transform() does not go to the server. */
+ tsd = tracksort_init(ntracks, tracks, type);
+ /* Expand the subsiduary templates. We chuck in @sort and @display because
+ * it is particularly easy to do so. */
+ for(n = 0; n < ntracks; ++n)
+ if((rc = mx_expand(mx_rewritel(m,
+ "index", make_index(n),
+ "parity", n % 2 ? "odd" : "even",
+ "track", tsd[n].track,
+ "first", n == 0 ? "true" : "false",
+ "last", n + 1 == ntracks ? "false" : "true",
+ "sort", tsd[n].sort,
+ "display", tsd[n].display,
+ (char *)0),
+ output, u)))
+ return rc;
+ } else {
+ for(n = 0; n < ntracks; ++n)
+ if((rc = mx_expand(mx_rewritel(m,
+ "index", make_index(n),
+ "parity", n % 2 ? "odd" : "even",
+ "track", tracks[n],
+ "first", n == 0 ? "true" : "false",
+ "last", n + 1 == ntracks ? "false" : "true",
+ (char *)0),
+ output, u)))
+ return rc;
+ }
return 0;
-
}
/*$ @tracks{DIR}{RE}{TEMPLATE}
* - @parity: "even" or "odd" alternately
* - @first: "true" on the first directory and "false" otherwise
* - @last: "true" on the last directory and "false" otherwise
- * - @sort: the sort key for this track
- * - @display: the UNQUOTED display string for this track
*/
static int exp_search(int nargs,
const struct mx_node **args,
struct sink *output,
void *u) {
- return exp__files_dirs(nargs, args, output, u, "track", exp__search_shim);
+ return exp__files_dirs(nargs, args, output, u, NULL, exp__search_shim);
}
/*$ @label{NAME}
/* Comparison function for path names that groups all entries in a directory
* together */
-/* Convenient wrapper for compare_path_raw */
+/** @brief Compare two paths
+ * @param ap First path
+ * @param bp Second path
+ * @return -ve, 0 or +ve for ap <, = or > bp
+ *
+ * Sorts files within a directory together.
+ * A wrapper around compare_path_raw().
+ */
static inline int compare_path(const char *ap, const char *bp) {
return compare_path_raw((const unsigned char *)ap, strlen(ap),
(const unsigned char *)bp, strlen(bp));
#include "log.h"
#include "unicode.h"
+/** @brief Compare two tracks
+ * @param sa First sort key
+ * @param sb Second sort key
+ * @param da First display string
+ * @param db Second display string
+ * @param ta First raw track
+ * @param tb Second raw track
+ * @return -ve, 0 or +ve for a <, = or > b
+ *
+ * Tries the following comparisons until a difference is found:
+ * - case-independent comparison of sort keys
+ * - case-dependent comparison of sort keys
+ * - case-independent comparison of display strings
+ * - case-dependent comparison of display strings
+ * - case-dependent comparison of paths (see compare_path())
+ */
int compare_tracks(const char *sa, const char *sb,
const char *da, const char *db,
const char *ta, const char *tb) {
return compare_path(ta, tb);
}
+/** @brief Compare two paths
+ * @param ap First path
+ * @param an Length of @p ap
+ * @param bp Second path
+ * @param bn Length @p bp
+ * @return -ve, 0 or +ve for ap <, = or > bp
+ *
+ * Sorts files within a directory together.
+ *
+ * See also compare_path().
+ */
int compare_path_raw(const unsigned char *ap, size_t an,
const unsigned char *bp, size_t bn) {
/* Don't change this function! The database sort order depends on it */