about summary refs log tree commit diff
path: root/lr.c
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2015-11-26 15:13:26 +0100
committerChristian Neukirchen <chneukirchen@gmail.com>2015-11-26 15:13:26 +0100
commit823fe1390a57a54fb595578de86c72a9d4c59f38 (patch)
treee4f764876d75b08c1af6975d72abc07036adfd8e /lr.c
parentf573a2e70c00b3decca4bf1a85537f78d45b3680 (diff)
downloadlr-823fe1390a57a54fb595578de86c72a9d4c59f38.tar.gz
lr-823fe1390a57a54fb595578de86c72a9d4c59f38.tar.xz
lr-823fe1390a57a54fb595578de86c72a9d4c59f38.zip
-o p: sort/group by directory name
Diffstat (limited to 'lr.c')
-rw-r--r--lr.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/lr.c b/lr.c
index 178ddca..26c5888 100644
--- a/lr.c
+++ b/lr.c
@@ -891,8 +891,33 @@ eval(struct expr *e, struct fileinfo *fi)
 	return 0;
 }
 
+int
+dircmp(char *a, char *b)
+{
+	char *ea = strrchr(a, '/');
+	char *eb = strrchr(b, '/');
+	if (!ea)
+		ea = a + strlen(a);
+	if (!eb)
+		eb = b + strlen(b);
+
+	while (a != ea && b != eb && *a == *b) {
+		a++;
+		b++;
+	}
+
+	if (a == ea && b == eb)
+		return 0;
+	if (a == ea)
+		return -1;
+	if (b == eb)
+		return 1;
+	return *a - *b;
+}
+
 #define CMP(a, b) if ((a) == (b)) break; else if ((a) < (b)) return -1; else return 1
 #define STRCMP(a, b) if (strcmp(a, b) == 0) break; else return (strcmp(a, b));
+#define DIRCMP(a, b) { int r = dircmp(a, b); if (r == 0) break; else return r; };
 
 int
 order(const void *a, const void *b)
@@ -924,6 +949,8 @@ order(const void *a, const void *b)
 		case 'N': STRCMP(fb->fpath, fa->fpath);
 		case 'e': STRCMP(extnam(fa->fpath), extnam(fb->fpath));
 		case 'E': STRCMP(extnam(fb->fpath), extnam(fa->fpath));
+		case 'p': DIRCMP(fa->fpath, fb->fpath);
+		case 'P': DIRCMP(fb->fpath, fa->fpath);
 		default: STRCMP(fa->fpath, fb->fpath);
 		}
 	}