summaryrefslogtreecommitdiffstats
path: root/makefile.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2022-01-01 12:58:18 +0100
committerMattias Andrée <maandree@kth.se>2022-01-01 12:58:18 +0100
commit8189ba58a436ea0f396a48af48d5ae84f7019cf6 (patch)
tree74369822cf0e39629ac9acf957755460ee2ae58f /makefile.c
parentFix replacement character insertion for invalid UTF-8 (diff)
downloadmakel-8189ba58a436ea0f396a48af48d5ae84f7019cf6.tar.gz
makel-8189ba58a436ea0f396a48af48d5ae84f7019cf6.tar.bz2
makel-8189ba58a436ea0f396a48af48d5ae84f7019cf6.tar.xz
Move some functions into makefile.c
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'makefile.c')
-rw-r--r--makefile.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/makefile.c b/makefile.c
new file mode 100644
index 0000000..ef280b9
--- /dev/null
+++ b/makefile.c
@@ -0,0 +1,89 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+static const char *const default_makefiles[] = {
+ "makefile",
+ "Makefile"
+};
+
+
+int
+open_default_makefile(const char **pathp)
+{
+ int fd;
+ size_t i;
+
+ /* The specification says that the alternatives “shall be
+ * tried”, but it uses the phrase “if neither … are found”,
+ * implying that make(1) shall fail if a file cannot be
+ * opened and only try the next alternative if it failed
+ * becomes the file does not exist.
+ */
+
+ for (i = 0; i < ELEMSOF(default_makefiles); i++) {
+ *pathp = default_makefiles[i];
+ fd = open(*pathp, O_RDONLY);
+ if (fd >= 0) {
+ printinfof(WC_MAKEFILE, "found standard makefile to use: %s", *pathp);
+ goto find_existing_fallbacks;
+ } else if (errno != ENOENT) {
+ eprintf("found standard makefile to use, but failed to open: %s:", *pathp);
+ }
+ }
+
+ printerrorf("couldn't find any makefile to use, portable "
+ "alternatives are ./makefile and ./Makefile");
+
+find_existing_fallbacks:
+ for (i++; i < ELEMSOF(default_makefiles); i++)
+ if (!access(default_makefiles[i], F_OK))
+ warnf_warning(WC_EXTRA_MAKEFILE, "found additional standard makefile: %s",
+ default_makefiles[i]);
+
+ return fd;
+}
+
+
+void
+cmdline_opt_f(const char *arg, const char **makefile_pathp)
+{
+ static int warning_emitted = 0;
+
+ if (*makefile_pathp && !warning_emitted) {
+ warning_emitted = 1;
+ warnf_unspecified(WC_CMDLINE, "the -f option has been specified multiple times, "
+ "they are processed in order, but the behaviour is "
+ "otherwise unspecified");
+ printinfof(WC_CMDLINE, "this implementation will use the last "
+ "option and discard earlier options");
+ }
+
+ *makefile_pathp = arg;
+}
+
+
+struct line *
+load_makefile(const char *path, size_t *nlinesp)
+{
+ struct line *lines;
+ int fd;
+
+ if (!path) {
+ fd = open_default_makefile(&path);
+ } else if (!strcmp(path, "-")) {
+ /* “A pathname of '-' shall denote the standard input” */
+ fd = dup(STDIN_FILENO);
+ if (fd < 0)
+ eprintf("dup <stdin>:");
+ path = "<stdin>";
+ } else {
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ eprintf("open %s O_RDONLY:", path);
+ }
+
+ lines = load_text_file(fd, path, 0, nlinesp);
+ close(fd);
+ return lines;
+}