Commit Diff


commit - 2534b579b7fcf1f22729331399e0898ff4f52dd7
commit + fefb7e82bdf96801d513e26c28d0679cd10bd3b4
blob - 2916fcba96c1bcd5647ad72330d64fbb0e0ba87a
blob + 99c3670c513201155710170e9e69e008121a368d
--- make/make.c
+++ make/make.c
@@ -5,6 +5,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
+#include <fnmatch.h>
 #include <assert.h>
 #include <unistd.h>
 #include <limits.h>
@@ -904,9 +905,10 @@ struct expand_ctx *ctx;
  * ${name:H}		replace each word with its dirname() equvialent
  * ${name:T}		replace each word with its basename() equvialent
  * ${name:m1:m2...}	multiple modifiers can be combined
- * TODO:
  * ${name:Mpattern}	select only words that match pattern
  * ${name:Npattern}	opposite of :Mpattern
+ * TODO:
+ * somehow make this function shorter
  */
 subst2 (out, sc, prefix, s, ctx)
 str_t *out;
@@ -920,7 +922,7 @@ struct expand_ctx *ctx;
 	extern subst ();
 	struct macro *m;
 	struct filetime ft;
-	char *orig = *s, *t, *u, *v, *w;
+	char *orig = *s, *t, *u, *v, *w, *pattern;
 	str_t name, old, new;
 
 	/* parse macro name */
@@ -1086,12 +1088,50 @@ struct expand_ctx *ctx;
 					continue;
 
 				str_puts (&new, basename (w));
+				str_putc (&new, ' ');
+			}
+
+			str_pop (&new);
+			free (v);
+			v = str_release (&new);
+		} else if (str_get (&old)[0] == 'M') {
+			str_new (&new);
+
+			pattern = str_get (&old) + 1;
+
+			for (t = v; (w = strsep (&t, " \t")) != NULL; ) {
+				if (*w == '\0')
+					continue;
+
+				if (fnmatch (pattern, w, 0) != 0)
+					continue;
+
+				str_puts (&new, w);
 				str_putc (&new, ' ');
 			}
 
 			str_pop (&new);
 			free (v);
 			v = str_release (&new);
+		} else if (str_get (&old)[0] == 'N') {
+			str_new (&new);
+
+			pattern = str_get (&old) + 1;
+
+			for (t = v; (w = strsep (&t, " \t")) != NULL; ) {
+				if (*w == '\0')
+					continue;
+
+				if (fnmatch (pattern, w, 0) == 0)
+					continue;
+
+				str_puts (&new, w);
+				str_putc (&new, ' ');
+			}
+
+			str_pop (&new);
+			free (v);
+			v = str_release (&new);
 		} else {
 			errx (1, "%s: invalid modifier: ':%s' in '${%s'", sc_path_str (sc), str_get (&old), orig);
 		}