Commit Diff


commit - 91e38034af0bfa13e6110b0afee1fa5e30942545
commit + e2b738536f63b2e6c945915fcda4e35ec3a0ae15
blob - 1d884824f5873fef9afa97ed1297c246a3eae8b7
blob + cee2108024a52034fa39f930cd96db0e6fcb714a
--- make/TODO
+++ make/TODO
@@ -1,5 +1,4 @@
 - write a useful README about how this make differs from all the other makes
-- first read parent, before reading current directory
 - options: -q, -k
 - make this work:
 	=== MyMakefile
blob - 5a83adee644ecf76e74016cf73704c86c5311905
blob + 4add2fee39fba65f68ce2481140f8918aa809d78
--- make/make.c
+++ make/make.c
@@ -835,47 +835,57 @@ struct path *dir;
 }
 
 struct scope *
-parse_recursive (path)
-char *path;
+parse_recursive (dir)
+struct path *dir;
 {
-	struct scope *sc, *entry, *parent;
-	struct path *dir;
+	struct path *mfpath, *ppath;
+	struct scope *sc, *parent;
+	char *path, *name;
 
-	dir = parse_path (path);
+	tmppath.name = MAKEFILE;
+	mfpath = path_cat (dir, &tmppath);
+	path = path_to_str (mfpath);
+	if (access (path, F_OK) != 0) {
+		sc = NULL;
+		goto ret;
+	}
 
-	sc = new (struct scope);
-	sc->next = NULL;
-	sc->type = SC_DIR;
-	sc->name = path_basename (dir);
-	sc->parent = NULL;
-	entry = sc;
+	ppath = path_cat (dir, &path_super);
+	parent = parse_recursive (ppath);
+	free (ppath);
 
-	asprintf (&path, "%s/" MAKEFILE, path_to_str (dir));
+	name = path_basename (dir);
+
+	if (parent != NULL) {
+		if (parent->type != SC_DIR)
+			errx (1, "%s: invalid parent type", path_to_str (mfpath));
+
+		for (sc = parent->dir->subdirs; sc != NULL; sc = sc->next) {
+			if (sc->name == name) {
+				if (sc->type != SC_DIR)
+					errx (1, "%s: invalid type", path_to_str (mfpath));
+				goto parse;
+			}
+		}
+
+		goto create;
+	} else {
+	create:
+		sc = new (struct scope);
+		sc->type = SC_DIR;
+		sc->name = name;
+		sc->parent = NULL;
+		sc->dir = NULL;
+	}
+
+parse:
+	path = strdup (path_to_str (mfpath));
 	parse (sc, dir, path);
 	free (path);
 
-	while (1) {
-		dir = path_cat (dir, &path_super);
-		asprintf (&path, "%s/" MAKEFILE, path_to_str (dir));
-		if (access (path, F_OK) == -1)
-			break;
-
-		parent = new (struct scope);
-		parent->next = NULL;
-		parent->type = SC_DIR;
-		parent->name = path_basename (dir);
-		parent->parent = NULL;
-		parent->dir = new (struct directory);
-		parent->dir->subdirs = sc;
-		parent->dir->files = NULL;
-		sc->parent = parent;
-		sc = parent;
-
-		parse (sc, dir, path);
-		free (path);
-	}
-
-	return entry;
+ret:
+	free (mfpath);
+	return sc;
 }
 
 /* RUN COMMANDS */
@@ -1368,7 +1378,9 @@ char **argv;
 		argv[i] = NULL;
 	}
 
-	sc = parse_recursive (".");
+	path = parse_path (".");
+	sc = parse_recursive (path);
+	free (path);
 
 	if (pr) {
 		print_sc (sc);
@@ -1381,6 +1393,7 @@ char **argv;
 
 		path = parse_path (argv[i]);
 		build (sc, path);
+		free (path);
 		++n;
 	}