aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archival/ar.c4
-rw-r--r--archival/libarchive/Kbuild.src1
-rw-r--r--archival/libarchive/unpack_ar_archive.c8
-rw-r--r--configs/mingw32_defconfig4
-rw-r--r--configs/mingw64_defconfig4
-rw-r--r--miscutils/make.c2621
-rwxr-xr-xtestsuite/make.tests413
-rw-r--r--win32/Kbuild1
-rw-r--r--win32/glob.c343
-rw-r--r--win32/glob.h89
10 files changed, 3482 insertions, 6 deletions
diff --git a/archival/ar.c b/archival/ar.c
index beccab217..b5565c936 100644
--- a/archival/ar.c
+++ b/archival/ar.c
@@ -30,12 +30,12 @@
30//config:config FEATURE_AR_LONG_FILENAMES 30//config:config FEATURE_AR_LONG_FILENAMES
31//config: bool "Support long filenames (not needed for debs)" 31//config: bool "Support long filenames (not needed for debs)"
32//config: default y 32//config: default y
33//config: depends on AR 33//config: depends on AR || MAKE
34//config: help 34//config: help
35//config: By default the ar format can only store the first 15 characters 35//config: By default the ar format can only store the first 15 characters
36//config: of the filename, this option removes that limitation. 36//config: of the filename, this option removes that limitation.
37//config: It supports the GNU ar long filename method which moves multiple long 37//config: It supports the GNU ar long filename method which moves multiple long
38//config: filenames into a the data section of a new ar entry. 38//config: filenames into the data section of a new ar entry.
39//config: 39//config:
40//config:config FEATURE_AR_CREATE 40//config:config FEATURE_AR_CREATE
41//config: bool "Support archive creation" 41//config: bool "Support archive creation"
diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src
index d2f284b08..1c74250a2 100644
--- a/archival/libarchive/Kbuild.src
+++ b/archival/libarchive/Kbuild.src
@@ -47,6 +47,7 @@ lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES)
47 47
48lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o 48lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o
49lib-$(CONFIG_CPIO) += get_header_cpio.o 49lib-$(CONFIG_CPIO) += get_header_cpio.o
50lib-$(CONFIG_MAKE) += get_header_ar.o unpack_ar_archive.o
50lib-$(CONFIG_TAR) += get_header_tar.o unsafe_prefix.o 51lib-$(CONFIG_TAR) += get_header_tar.o unsafe_prefix.o
51lib-$(CONFIG_FEATURE_TAR_TO_COMMAND) += data_extract_to_command.o 52lib-$(CONFIG_FEATURE_TAR_TO_COMMAND) += data_extract_to_command.o
52lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o 53lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o
diff --git a/archival/libarchive/unpack_ar_archive.c b/archival/libarchive/unpack_ar_archive.c
index 125d424c9..923a0b2ab 100644
--- a/archival/libarchive/unpack_ar_archive.c
+++ b/archival/libarchive/unpack_ar_archive.c
@@ -16,6 +16,10 @@ void FAST_FUNC unpack_ar_archive(archive_handle_t *ar_archive)
16 } 16 }
17 ar_archive->offset += AR_MAGIC_LEN; 17 ar_archive->offset += AR_MAGIC_LEN;
18 18
19 while (get_header_ar(ar_archive) == EXIT_SUCCESS) 19 while (get_header_ar(ar_archive) == EXIT_SUCCESS) {
20 continue; 20#if ENABLE_MAKE
21 free(ar_archive->file_header->name);
22 ar_archive->file_header->name = NULL;
23#endif
24 }
21} 25}
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig
index 78e359500..81bbda4dd 100644
--- a/configs/mingw32_defconfig
+++ b/configs/mingw32_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Busybox version: 1.36.0.git 3# Busybox version: 1.36.0.git
4# Thu May 12 08:13:00 2022 4# Thu Jul 7 08:08:14 2022
5# 5#
6CONFIG_HAVE_DOT_CONFIG=y 6CONFIG_HAVE_DOT_CONFIG=y
7# CONFIG_PLATFORM_POSIX is not set 7# CONFIG_PLATFORM_POSIX is not set
@@ -831,6 +831,8 @@ CONFIG_FEATURE_LESS_LINENUMS=y
831CONFIG_FEATURE_LESS_RAW=y 831CONFIG_FEATURE_LESS_RAW=y
832CONFIG_FEATURE_LESS_ENV=y 832CONFIG_FEATURE_LESS_ENV=y
833# CONFIG_LSSCSI is not set 833# CONFIG_LSSCSI is not set
834CONFIG_MAKE=y
835CONFIG_FEATURE_MAKE_POSIX=y
834# CONFIG_MAKEDEVS is not set 836# CONFIG_MAKEDEVS is not set
835# CONFIG_FEATURE_MAKEDEVS_LEAF is not set 837# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
836# CONFIG_FEATURE_MAKEDEVS_TABLE is not set 838# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig
index c88da8007..0e54eb78d 100644
--- a/configs/mingw64_defconfig
+++ b/configs/mingw64_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Busybox version: 1.36.0.git 3# Busybox version: 1.36.0.git
4# Thu May 12 08:13:00 2022 4# Thu Jul 7 08:08:14 2022
5# 5#
6CONFIG_HAVE_DOT_CONFIG=y 6CONFIG_HAVE_DOT_CONFIG=y
7# CONFIG_PLATFORM_POSIX is not set 7# CONFIG_PLATFORM_POSIX is not set
@@ -831,6 +831,8 @@ CONFIG_FEATURE_LESS_LINENUMS=y
831CONFIG_FEATURE_LESS_RAW=y 831CONFIG_FEATURE_LESS_RAW=y
832CONFIG_FEATURE_LESS_ENV=y 832CONFIG_FEATURE_LESS_ENV=y
833# CONFIG_LSSCSI is not set 833# CONFIG_LSSCSI is not set
834CONFIG_MAKE=y
835CONFIG_FEATURE_MAKE_POSIX=y
834# CONFIG_MAKEDEVS is not set 836# CONFIG_MAKEDEVS is not set
835# CONFIG_FEATURE_MAKEDEVS_LEAF is not set 837# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
836# CONFIG_FEATURE_MAKEDEVS_TABLE is not set 838# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
diff --git a/miscutils/make.c b/miscutils/make.c
new file mode 100644
index 000000000..b92819266
--- /dev/null
+++ b/miscutils/make.c
@@ -0,0 +1,2621 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * make implementation for BusyBox
4 *
5 * Based on public domain POSIX make: https://frippery.org/make
6 */
7//config:config MAKE
8//config: bool "make (18 kb)"
9//config: default n
10//config: help
11//config: The make command can be used to maintain files that depend on
12//config: other files. Normally it's used to build programs from source
13//config: code but it can be used in other situations too.
14//config:
15//config:config FEATURE_MAKE_POSIX
16//config: bool "Runtime enforcement of POSIX"
17//config: default n
18//config: depends on MAKE
19//config: help
20//config: Allow strict enforcement of POSIX mode at runtime by:
21//config: - .POSIX special target in makefile
22//config: - '--posix' command line option
23//config: - PDPMAKE_POSIXLY_CORRECT environment variable
24//config: Enable this if you want to check whether your makefiles are
25//config: POSIX compliant. This adds about 500 bytes.
26
27//applet:IF_MAKE(APPLET(make, BB_DIR_USR_BIN, BB_SUID_DROP))
28
29//kbuild:lib-$(CONFIG_MAKE) += make.o
30
31//usage:#define make_trivial_usage
32//usage: IF_FEATURE_MAKE_POSIX(
33//usage: "[--posix] [-C DIR] [-f FILE] [j NUM] [-eiknpqrsSt] [MACRO[::]=VAL]... [TARGET]..."
34//usage: )
35//usage: IF_NOT_FEATURE_MAKE_POSIX(
36//usage: "[-C DIR] [-f FILE] [j NUM] [-eiknpqrsSt] [MACRO[::]=VAL]... [TARGET]..."
37//usage: )
38//usage:#define make_full_usage "\n\n"
39//usage: "Maintain files based on their dependencies\n"
40//usage: IF_FEATURE_MAKE_POSIX(
41//usage: "\n --posix Enforce POSIX mode"
42//usage: )
43//usage: "\n -C DIR Change to DIR"
44//usage: "\n -f FILE Makefile"
45//usage: "\n -j NUM Jobs to run in parallel (not implemented)"
46//usage: "\n -e Environment variables override macros in makefiles"
47//usage: "\n -i Ignore exit status"
48//usage: "\n -k Continue on error"
49//usage: "\n -n Dry run"
50//usage: "\n -p Print macros and targets"
51//usage: "\n -q Query target; exit status 1 if not up to date"
52//usage: "\n -r Don't use built-in rules"
53//usage: "\n -s Make silently"
54//usage: "\n -S Stop on error"
55//usage: "\n -t Touch files instead of making them"
56
57#include "libbb.h"
58#include "bb_archive.h"
59#include "common_bufsiz.h"
60#include <glob.h>
61
62#define OPTSTR1 "eij:+knqrsSt"
63#define OPTSTR2 "pf:*C:*"
64
65enum {
66 OPT_e = (1 << 0),
67 OPT_i = (1 << 1),
68 OPT_j = (1 << 2),
69 OPT_k = (1 << 3),
70 OPT_n = (1 << 4),
71 OPT_q = (1 << 5),
72 OPT_r = (1 << 6),
73 OPT_s = (1 << 7),
74 OPT_S = (1 << 8),
75 OPT_t = (1 << 9),
76 // These options aren't allowed in MAKEFLAGS
77 OPT_p = (1 << 10),
78 OPT_f = (1 << 11),
79 OPT_C = (1 << 12),
80 // The following aren't command line options and must be last
81 OPT_precious = (1 << 13),
82 OPT_phony = (1 << 14),
83 OPT_include = (1 << 15),
84 OPT_make = (1 << 16),
85};
86
87// Options in OPTSTR1 that aren't included in MAKEFLAGS
88#define OPT_MASK (~OPT_S)
89
90#define useenv (opts & OPT_e)
91#define ignore (opts & OPT_i)
92#define errcont (opts & OPT_k)
93#define dryrun (opts & OPT_n)
94#define print (opts & OPT_p)
95#define quest (opts & OPT_q)
96#define norules (opts & OPT_r)
97#define silent (opts & OPT_s)
98#define dotouch (opts & OPT_t)
99#define precious (opts & OPT_precious)
100#define doinclude (opts & OPT_include)
101#define domake (opts & OPT_make)
102
103// A name. This represents a file, either to be made, or pre-existing.
104struct name {
105 struct name *n_next; // Next in the list of names
106 char *n_name; // Called
107 struct rule *n_rule; // Rules to build this (prerequisites/commands)
108 struct timespec n_tim; // Modification time of this name
109 uint16_t n_flag; // Info about the name
110};
111
112#define N_DOING 0x01 // Name in process of being built
113#define N_DONE 0x02 // Name looked at
114#define N_TARGET 0x04 // Name is a target
115#define N_PRECIOUS 0x08 // Target is precious
116#define N_DOUBLE 0x10 // Double-colon target
117#define N_SILENT 0x20 // Build target silently
118#define N_IGNORE 0x40 // Ignore build errors
119#define N_SPECIAL 0x80 // Special target
120#define N_MARK 0x100 // Mark for deduplication
121#define N_PHONY 0x200 // Name is a phony target
122
123// List of rules to build a target
124struct rule {
125 struct rule *r_next; // Next rule
126 struct depend *r_dep; // Prerequisites for this rule
127 struct cmd *r_cmd; // Commands for this rule
128};
129
130// NOTE: the layout of the following two structures must be compatible.
131// Also, their first two members must be compatible with llist_t.
132
133// List of prerequisites for a rule
134struct depend {
135 struct depend *d_next; // Next prerequisite
136 struct name *d_name; // Name of prerequisite
137 int d_refcnt; // Reference count
138};
139
140// List of commands for a rule
141struct cmd {
142 struct cmd *c_next; // Next command line
143 char *c_cmd; // Text of command line
144 int c_refcnt; // Reference count
145};
146
147// Macro storage
148struct macro {
149 struct macro *m_next; // Next variable
150 char *m_name; // Its name
151 char *m_val; // Its value
152 bool m_immediate; // Immediate-expansion macro set using ::=
153 bool m_flag; // Infinite loop check
154 uint8_t m_level; // Level at which macro was created
155};
156
157// Flags passed to setmacro()
158#define M_IMMEDIATE 8 // immediate-expansion macro is being defined
159#define M_VALID 16 // assert macro name is valid
160
161#define HTABSIZE 39
162
163struct globals {
164 uint32_t opts;
165 const char *makefile;
166 llist_t *makefiles;
167 llist_t *dirs;
168 struct name *namehead[HTABSIZE];
169 struct macro *macrohead[HTABSIZE];
170 struct name *firstname;
171 struct name *target;
172 time_t ar_mtime;
173 int lineno; // Physical line number in file
174 int dispno; // Line number for display purposes
175 const char *rulepos;
176#define IF_MAX 10
177 uint8_t clevel;
178 uint8_t cstate[IF_MAX + 1];
179#if ENABLE_FEATURE_MAKE_POSIX
180 bool posix;
181 bool seen_first;
182#endif
183 int numjobs;
184} FIX_ALIASING;
185
186#define G (*(struct globals*)bb_common_bufsiz1)
187#define INIT_G() do { \
188 setup_common_bufsiz(); \
189} while (0)
190
191#define opts (G.opts)
192#define makefile (G.makefile)
193#define makefiles (G.makefiles)
194#define dirs (G.dirs)
195#define namehead (G.namehead)
196#define macrohead (G.macrohead)
197#define firstname (G.firstname)
198#define target (G.target)
199#define ar_mtime (G.ar_mtime)
200#define lineno (G.lineno)
201#define dispno (G.dispno)
202#define rulepos (G.rulepos)
203#define clevel (G.clevel)
204#define cstate (G.cstate)
205#if ENABLE_FEATURE_MAKE_POSIX
206#define posix (G.posix)
207#define seen_first (G.seen_first)
208#else
209#define posix 0
210#endif
211#define numjobs (G.numjobs)
212
213static int make(struct name *np, int level);
214
215// Return TRUE if c is allowed in a POSIX 2017 macro or target name
216#define ispname(c) (isalpha(c) || isdigit(c) || c == '.' || c == '_')
217// Return TRUE if c is in the POSIX 'portable filename character set'
218#define isfname(c) (ispname(c) || c == '-')
219
220/*
221 * Utility functions.
222 */
223
224/*
225 * Error handler. Print message, with line number, and exit.
226 */
227static void error(const char *msg, ...) NORETURN;
228static void
229error(const char *msg, ...)
230{
231 va_list list;
232
233 if (makefile) {
234 const char *num = itoa(dispno);
235 char *s = malloc(strlen(makefile) + strlen(num) + 2);
236 if (s) {
237 sprintf(s, "%s:%s", makefile, num);
238 applet_name = s;
239 }
240 }
241 va_start(list, msg);
242 bb_verror_msg(msg, list, NULL);
243 va_end(list);
244 exit(2);
245}
246
247static void error_unexpected(const char *s) NORETURN;
248static void
249error_unexpected(const char *s)
250{
251 error("unexpected %s", s);
252}
253
254static void error_in_inference_rule(const char *s) NORETURN;
255static void
256error_in_inference_rule(const char *s)
257{
258 error("%s in inference rule", s);
259}
260
261static char *
262auto_concat(const char *s1, const char *s2)
263{
264 return auto_string(xasprintf("%s%s", s1, s2));
265}
266
267/*
268 * Append a word to a space-separated string of words. The first
269 * call should use a NULL pointer for str, subsequent calls should
270 * pass an allocated string which will be freed.
271 */
272static char *
273xappendword(const char *str, const char *word)
274{
275 char *newstr = str ? xasprintf("%s %s", str, word) : xstrdup(word);
276 free((void *)str);
277 return newstr;
278}
279
280static unsigned int
281getbucket(const char *name)
282{
283 unsigned int hashval = 0;
284 const unsigned char *p = (unsigned char *)name;
285
286 while (*p)
287 hashval ^= (hashval << 5) + (hashval >> 2) + *p++;
288 return hashval % HTABSIZE;
289}
290
291/*
292 * Add a prerequisite to the end of the supplied list.
293 */
294static void
295newdep(struct depend **dphead, struct name *np)
296{
297 while (*dphead)
298 dphead = &(*dphead)->d_next;
299 *dphead = xzalloc(sizeof(struct depend));
300 /*(*dphead)->d_next = NULL; - xzalloc did it */
301 (*dphead)->d_name = np;
302 /*(*dphead)->d_refcnt = 0; */
303}
304
305static void
306freedeps(struct depend *dp)
307{
308 if (dp && --dp->d_refcnt <= 0)
309 llist_free((llist_t *)dp, NULL);
310}
311
312/*
313 * Add a command to the end of the supplied list of commands.
314 */
315static void
316newcmd(struct cmd **cphead, char *str)
317{
318 while (isspace(*str))
319 str++;
320
321 if (*str == '\0') // No command, leave current head unchanged
322 return;
323
324 while (*cphead)
325 cphead = &(*cphead)->c_next;
326 *cphead = xzalloc(sizeof(struct cmd));
327 /*(*cphead)->c_next = NULL; - xzalloc did it */
328 (*cphead)->c_cmd = xstrdup(str);
329 /*(*cphead)->c_refcnt = 0; */
330}
331
332static void
333freecmds(struct cmd *cp)
334{
335 if (cp && --cp->c_refcnt <= 0)
336 llist_free((llist_t *)cp, free);
337}
338
339static struct name *
340findname(const char *name)
341{
342 struct name *np = namehead[getbucket(name)];
343 return (struct name *)llist_find_str((llist_t *)np, name);
344}
345
346static int
347is_valid_target(const char *name)
348{
349 const char *s;
350 for (s = name; *s; ++s) {
351 if (posix && !ispname(*s))
352 return FALSE;
353 }
354 return TRUE;
355}
356
357/*
358 * Intern a name. Return a pointer to the name struct
359 */
360static struct name *
361newname(const char *name)
362{
363 struct name *np = findname(name);
364
365 if (np == NULL) {
366 unsigned int bucket;
367
368 if (!is_valid_target(name))
369 error("invalid target name '%s'", name);
370
371 bucket = getbucket(name);
372 np = xzalloc(sizeof(struct name));
373 np->n_next = namehead[bucket];
374 namehead[bucket] = np;
375 np->n_name = xstrdup(name);
376 /*np->n_rule = NULL; - xzalloc did it */
377 /*np->n_tim = (struct timespec){0, 0}; */
378 /*np->n_flag = 0; */
379 }
380 return np;
381}
382
383/*
384 * Return the commands on the first rule that has them or NULL.
385 */
386static struct cmd *
387getcmd(struct name *np)
388{
389 struct rule *rp;
390
391 if (np == NULL)
392 return NULL;
393
394 for (rp = np->n_rule; rp; rp = rp->r_next)
395 if (rp->r_cmd)
396 return rp->r_cmd;
397 return NULL;
398}
399
400#if ENABLE_FEATURE_CLEAN_UP
401static void
402freenames(void)
403{
404 int i;
405 struct name *np, *nextnp;
406
407 for (i = 0; i < HTABSIZE; i++) {
408 for (np = namehead[i]; np; np = nextnp) {
409 nextnp = np->n_next;
410 free(np->n_name);
411 freerules(np->n_rule);
412 free(np);
413 }
414 }
415}
416#endif
417
418static void
419freerules(struct rule *rp)
420{
421 struct rule *nextrp;
422
423 for (; rp; rp = nextrp) {
424 nextrp = rp->r_next;
425 freedeps(rp->r_dep);
426 freecmds(rp->r_cmd);
427 free(rp);
428 }
429}
430
431static void *
432inc_ref(void *vp)
433{
434 if (vp) {
435 struct depend *dp = vp;
436 if (dp->d_refcnt == INT_MAX)
437 bb_die_memory_exhausted();
438 dp->d_refcnt++;
439 }
440 return vp;
441}
442
443/*
444 * Add a new rule to a target. This checks to see if commands already
445 * exist for the target. If flag is TRUE the target can have multiple
446 * rules with commands (double-colon rules).
447 *
448 * i) If the name is a special target and there are no prerequisites
449 * or commands to be added remove all prerequisites and commands.
450 * This is necessary when clearing a built-in inference rule.
451 * ii) If name is a special target and has commands, replace them.
452 * This is for redefining commands for an inference rule.
453 */
454static void
455addrule(struct name *np, struct depend *dp, struct cmd *cp, int flag)
456{
457 struct rule *rp;
458 struct rule **rpp;
459
460 // Can't mix single-colon and double-colon rules
461 if (!posix && (np->n_flag & N_TARGET)) {
462 if (!(np->n_flag & N_DOUBLE) != !flag) // like xor
463 error("inconsistent rules for target %s", np->n_name);
464 }
465
466 // Clear out prerequisites and commands
467 if ((np->n_flag & N_SPECIAL) && !dp && !cp) {
468 if (strcmp(np->n_name, ".PHONY") == 0)
469 return;
470 freerules(np->n_rule);
471 np->n_rule = NULL;
472 return;
473 }
474
475 if (cp && !(np->n_flag & N_DOUBLE) && getcmd(np)) {
476 // Handle the inference rule redefinition case
477 if ((np->n_flag & N_SPECIAL) && !dp) {
478 freerules(np->n_rule);
479 np->n_rule = NULL;
480 } else {
481 error("commands defined twice for target %s", np->n_name);
482 }
483 }
484
485 rpp = &np->n_rule;
486 while (*rpp)
487 rpp = &(*rpp)->r_next;
488
489 *rpp = rp = xzalloc(sizeof(struct rule));
490 /*rp->r_next = NULL; - xzalloc did it */
491 rp->r_dep = inc_ref(dp);
492 rp->r_cmd = inc_ref(cp);
493
494 np->n_flag |= N_TARGET;
495 if (flag)
496 np->n_flag |= N_DOUBLE;
497}
498
499/*
500 * Macro control for make
501 */
502static struct macro *
503getmp(const char *name)
504{
505 struct macro *mp = macrohead[getbucket(name)];
506 return (struct macro *)llist_find_str((llist_t *)mp, name);
507}
508
509static int
510is_valid_macro(const char *name)
511{
512 const char *s;
513 for (s = name; *s; ++s) {
514 // In POSIX mode only a limited set of characters are guaranteed
515 // to be allowed in macro names.
516 if (posix && !isfname(*s))
517 return FALSE;
518 // As an extension allow anything that can get through the
519 // input parser, apart from the following.
520 if (*s == '=' || isblank(*s) || iscntrl(*s))
521 return FALSE;
522 }
523 return TRUE;
524}
525
526static void
527setmacro(const char *name, const char *val, int level)
528{
529 struct macro *mp;
530 bool valid = level & M_VALID;
531 bool immediate = level & M_IMMEDIATE;
532
533 level &= ~(M_IMMEDIATE | M_VALID);
534 mp = getmp(name);
535 if (mp) {
536 // Don't replace existing macro from a lower level
537 if (level > mp->m_level)
538 return;
539
540 // Replace existing macro
541 free(mp->m_val);
542 } else {
543 // If not defined, allocate space for new
544 unsigned int bucket;
545
546 if (!valid && !is_valid_macro(name))
547 error("invalid macro name '%s'", name);
548
549 bucket = getbucket(name);
550 mp = xzalloc(sizeof(struct macro));
551 mp->m_next = macrohead[bucket];
552 macrohead[bucket] = mp;
553 /* mp->m_flag = FALSE; - xzalloc did it */
554 mp->m_name = xstrdup(name);
555 }
556 mp->m_immediate = immediate;
557 mp->m_level = level;
558 mp->m_val = xstrdup(val ? val : "");
559}
560
561#if ENABLE_FEATURE_CLEAN_UP
562static void
563freemacros(void)
564{
565 int i;
566 struct macro *mp, *nextmp;
567
568 for (i = 0; i < HTABSIZE; i++) {
569 for (mp = macrohead[i]; mp; mp = nextmp) {
570 nextmp = mp->m_next;
571 free(mp->m_name);
572 free(mp->m_val);
573 free(mp);
574 }
575 }
576}
577#endif
578
579/*
580 * Get modification time of file or archive member
581 */
582static void FAST_FUNC
583record_mtime(const file_header_t *file_header)
584{
585 ar_mtime = file_header->mtime;
586}
587
588static time_t
589artime(const char *archive, const char *member)
590{
591 archive_handle_t *archive_handle;
592
593 ar_mtime = 0;
594 archive_handle = init_handle();
595 archive_handle->src_fd = open(archive, O_RDONLY);
596 if (archive_handle->src_fd != -1) {
597 archive_handle->action_header = record_mtime;
598 archive_handle->filter = filter_accept_list;
599 llist_add_to_end(&archive_handle->accept, (void *)member);
600 unpack_ar_archive(archive_handle);
601 close(archive_handle->src_fd);
602 }
603
604#if ENABLE_FEATURE_AR_LONG_FILENAMES
605 free(archive_handle->ar__long_names);
606#endif
607 llist_free(archive_handle->accept, NULL);
608 free(archive_handle->file_header);
609 free(archive_handle);
610
611 return ar_mtime;
612}
613
614/*
615 * If the name is of the form 'libname(member.o)' split it into its
616 * name and member parts and set the member pointer to point to the
617 * latter. Otherwise just take a copy of the name and don't alter
618 * the member pointer.
619 *
620 * In either case the return value is an allocated string which must
621 * be freed by the caller.
622 */
623static char *
624splitlib(const char *name, char **member)
625{
626 char *s, *t;
627 size_t len;
628
629 t = xstrdup(name);
630 s = strchr(t, '(');
631 if (s) {
632 // We have 'libname(member.o)'
633 *s++ = '\0';
634 len = strlen(s);
635 if (len <= 1 || s[len - 1] != ')' || *t == '\0')
636 error("invalid name '%s'", name);
637 s[len - 1] = '\0';
638 *member = s;
639 }
640 return t;
641}
642
643/*
644 * Get the modification time of a file. Set it to 0 if the file
645 * doesn't exist.
646 */
647static void
648modtime(struct name *np)
649{
650 char *name, *member = NULL;
651 struct stat info;
652
653 name = splitlib(np->n_name, &member);
654 if (member) {
655 // Looks like library(member)
656 np->n_tim.tv_sec = artime(name, member);
657 np->n_tim.tv_nsec = 0;
658 } else if (stat(name, &info) < 0) {
659 if (errno != ENOENT)
660 bb_perror_msg("can't open %s", name);
661 np->n_tim.tv_sec = 0;
662 np->n_tim.tv_nsec = 0;
663 } else {
664 np->n_tim.tv_sec = info.st_mtim.tv_sec;
665 np->n_tim.tv_nsec = info.st_mtim.tv_nsec;
666 }
667 free(name);
668}
669
670/*
671 * Control of the implicit suffix rules
672 */
673
674/*
675 * Return a pointer to the suffix of a name (which may be the
676 * terminating NUL if there's no suffix).
677 */
678static char *
679suffix(const char *name)
680{
681 char *p = strrchr(name, '.');
682 return p ? p : (char *)name + strlen(name);
683}
684
685/*
686 * Dynamic dependency. This routine applies the suffix rules
687 * to try and find a source and a set of rules for a missing
688 * target. NULL is returned on failure. On success the name of
689 * the implicit prerequisite is returned and the details are
690 * placed in the imprule structure provided by the caller.
691 */
692static struct name *
693dyndep(struct name *np, struct rule *imprule)
694{
695 char *suff, *newsuff;
696 char *base, *name, *member;
697 struct name *xp; // Suffixes
698 struct name *sp; // Suffix rule
699 struct name *pp = NULL; // Implicit prerequisite
700 struct rule *rp;
701 struct depend *dp;
702 bool chain = FALSE;
703
704 member = NULL;
705 name = splitlib(np->n_name, &member);
706
707 suff = xstrdup(suffix(name));
708 base = member ? member : name;
709 *suffix(base) = '\0';
710
711 xp = newname(".SUFFIXES");
712 retry:
713 for (rp = xp->n_rule; rp; rp = rp->r_next) {
714 for (dp = rp->r_dep; dp; dp = dp->d_next) {
715 // Generate new suffix rule to try
716 newsuff = dp->d_name->n_name;
717 sp = findname(auto_concat(newsuff, suff));
718 if (sp && sp->n_rule) {
719 // Generate a name for an implicit prerequisite
720 pp = newname(auto_concat(base, newsuff));
721 if (!pp->n_tim.tv_sec)
722 modtime(pp);
723 if ((!chain && (pp->n_tim.tv_sec || getcmd(pp))) ||
724 (chain && dyndep(pp, NULL))) {
725 // Prerequisite exists or we know how to make it
726 if (imprule) {
727 dp = NULL;
728 newdep(&dp, pp);
729 imprule->r_dep = dp;
730 imprule->r_cmd = sp->n_rule->r_cmd;
731 }
732 goto finish;
733 }
734 pp = NULL;
735 }
736 }
737 }
738 // If we didn't find an existing file or an explicit rule try
739 // again, this time looking for a chained inference rule.
740 if (!posix && !chain) {
741 chain = TRUE;
742 goto retry;
743 }
744 finish:
745 free(suff);
746 free(name);
747 return pp;
748}
749
750#define RULES \
751 ".SUFFIXES:.o .c .y .l .a .sh .f\n" \
752 ".c.o:\n" \
753 " $(CC) $(CFLAGS) -c $<\n" \
754 ".f.o:\n" \
755 " $(FC) $(FFLAGS) -c $<\n" \
756 ".y.o:\n" \
757 " $(YACC) $(YFLAGS) $<\n" \
758 " $(CC) $(CFLAGS) -c y.tab.c\n" \
759 " rm -f y.tab.c\n" \
760 " mv y.tab.o $@\n" \
761 ".y.c:\n" \
762 " $(YACC) $(YFLAGS) $<\n" \
763 " mv y.tab.c $@\n" \
764 ".l.o:\n" \
765 " $(LEX) $(LFLAGS) $<\n" \
766 " $(CC) $(CFLAGS) -c lex.yy.c\n" \
767 " rm -f lex.yy.c\n" \
768 " mv lex.yy.o $@\n" \
769 ".l.c:\n" \
770 " $(LEX) $(LFLAGS) $<\n" \
771 " mv lex.yy.c $@\n" \
772 ".c.a:\n" \
773 " $(CC) -c $(CFLAGS) $<\n" \
774 " $(AR) $(ARFLAGS) $@ $*.o\n" \
775 " rm -f $*.o\n" \
776 ".f.a:\n" \
777 " $(FC) -c $(FFLAGS) $<\n" \
778 " $(AR) $(ARFLAGS) $@ $*.o\n" \
779 " rm -f $*.o\n" \
780 ".c:\n" \
781 " $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<\n" \
782 ".f:\n" \
783 " $(FC) $(FFLAGS) $(LDFLAGS) -o $@ $<\n" \
784 ".sh:\n" \
785 " cp $< $@\n" \
786 " chmod a+x $@\n"
787
788#define MACROS \
789 "CC=c99\n" \
790 "CFLAGS=-O1\n" \
791 "FC=fort77\n" \
792 "FFLAGS=-O1\n" \
793 "YACC=yacc\n" \
794 "YFLAGS=\n" \
795 "LEX=lex\n" \
796 "LFLAGS=\n" \
797 "AR=ar\n" \
798 "ARFLAGS=-rv\n" \
799 "LDFLAGS=\n"
800
801/*
802 * Read the built-in rules using a fake fgets-like interface.
803 */
804static char *
805getrules(char *s, int size)
806{
807 char *r = s;
808
809 if (rulepos == NULL)
810 rulepos = (RULES MACROS) + (norules ? sizeof(RULES) - 1 : 0);
811
812 if (*rulepos == '\0')
813 return NULL;
814
815 while (--size) {
816 if ((*r++ = *rulepos++) == '\n')
817 break;
818 }
819 *r = '\0';
820 return s;
821}
822
823/*
824 * Parse a makefile
825 */
826
827/*
828 * Return a pointer to the next blank-delimited word or NULL if
829 * there are none left.
830 */
831static char *
832gettok(char **ptr)
833{
834 char *p;
835
836 while (isblank(**ptr)) // Skip blanks
837 (*ptr)++;
838
839 if (**ptr == '\0') // Nothing after blanks
840 return NULL;
841
842 p = *ptr; // Word starts here
843
844 while (**ptr != '\0' && !isblank(**ptr))
845 (*ptr)++; // Find end of word
846
847 // Terminate token and move on unless already at end of string
848 if (**ptr != '\0')
849 *(*ptr)++ = '\0';
850
851 return(p);
852}
853
854/*
855 * Skip over (possibly adjacent or nested) macro expansions.
856 */
857static char *
858skip_macro(const char *s)
859{
860 while (*s && s[0] == '$') {
861 if (s[1] == '(' || s[1] == '{') {
862 char end = *++s == '(' ? ')' : '}';
863 while (*s && *s != end)
864 s = skip_macro(s + 1);
865 if (*s == end)
866 ++s;
867 } else if (s[1] != '\0') {
868 s += 2;
869 } else {
870 break;
871 }
872 }
873 return (char *)s;
874}
875
876/*
877 * Process each whitespace-separated word in the input string:
878 *
879 * - replace paths with their directory or filename part
880 * - replace prefixes and suffixes
881 *
882 * Returns an allocated string or NULL if the input is unmodified.
883 */
884static char *
885modify_words(const char *val, int modifier, size_t lenf,
886 const char *find_pref, const char *repl_pref,
887 const char *find_suff, const char *repl_suff)
888{
889 char *s, *copy, *word, *sep, *buf = NULL;
890 size_t find_pref_len = 0, find_suff_len = 0;
891
892 if (!modifier && !lenf)
893 return buf;
894
895 if (find_pref) {
896 // get length of find prefix, e.g: src/
897 find_pref_len = strlen(find_pref);
898 // get length of find suffix, e.g: .c
899 find_suff_len = lenf - find_pref_len - 1;
900 }
901
902 s = copy = xstrdup(val);
903 while ((word = gettok(&s)) != NULL) {
904 if (modifier) {
905 sep = strrchr(word, '/');
906 if (modifier == 'D') {
907 if (!sep) {
908 word[0] = '.'; // no '/', return "."
909 sep = word + 1;
910 } else if (sep == word) {
911 // '/' at start of word, return "/"
912 sep = word + 1;
913 }
914 // else terminate at separator
915 *sep = '\0';
916 } else if (/* modifier == 'F' && */ sep) {
917 word = sep + 1;
918 }
919 }
920 if (lenf) {
921 size_t lenw = strlen(word);
922 // This code implements pattern macro expansions:
923 // https://austingroupbugs.net/view.php?id=519
924 //
925 // find: <prefix>%<suffix>
926 // example: src/%.c
927 if (lenw >= lenf - 1 && find_pref) {
928 // If prefix and suffix of word match find_pref and
929 // find_suff, then do substitution.
930 if (strncmp(word, find_pref, find_pref_len) == 0 &&
931 strcmp(word + lenw - find_suff_len, find_suff) == 0) {
932 // replace: <prefix>[%<suffix>]
933 // example: build/%.o or build/all.o (notice no %)
934 // If repl_suff is NULL, replace whole word with repl_pref.
935 if (!repl_suff) {
936 word = xstrdup(repl_pref);
937 } else {
938 word[lenw - find_suff_len] = '\0';
939 word = xasprintf("%s%s%s", repl_pref,
940 word + find_pref_len, repl_suff);
941 }
942 word = auto_string(word);
943 }
944 } else if (lenw >= lenf &&
945 strcmp(word + lenw - lenf, find_suff) == 0) {
946 word[lenw - lenf] = '\0';
947 word = auto_concat(word, repl_suff);
948 }
949 }
950 buf = xappendword(buf, word);
951 }
952 free(copy);
953 return buf;
954}
955
956/*
957 * Return a pointer to the next instance of a given character. Macro
958 * expansions are skipped so the ':' and '=' in $(VAR:.s1=.s2) aren't
959 * detected as separators for rules or macro definitions.
960 */
961static char *
962find_char(const char *str, int c)
963{
964 const char *s;
965
966 for (s = skip_macro(str); *s; s = skip_macro(s + 1)) {
967 if (*s == c)
968 return (char *)s;
969 }
970 return NULL;
971}
972
973/*
974 * Recursively expand any macros in str to an allocated string.
975 */
976static char *
977expand_macros(const char *str, int except_dollar)
978{
979 char *exp, *newexp, *s, *t, *p, *q, *name;
980 char *find, *replace, *modified;
981 char *expval, *expfind, *find_suff, *repl_suff;
982 char *find_pref = NULL, *repl_pref = NULL;
983 size_t lenf;
984 char modifier;
985 struct macro *mp;
986
987 exp = xstrdup(str);
988 for (t = exp; *t; t++) {
989 if (*t == '$') {
990 if (t[1] == '\0') {
991 break;
992 }
993 if (t[1] == '$' && except_dollar) {
994 t++;
995 continue;
996 }
997 // Need to expand a macro. Find its extent (s to t inclusive)
998 // and take a copy of its content.
999 s = t;
1000 t++;
1001 if (*t == '{' || *t == '(') {
1002 t = find_char(t, *t == '{' ? '}' : ')');
1003 if (t == NULL)
1004 error("unterminated variable '%s'", s);
1005 name = xstrndup(s + 2, t - s - 2);
1006 } else {
1007 name = xzalloc(2);
1008 name[0] = *t;
1009 /*name[1] = '\0'; - xzalloc did it */
1010 }
1011
1012 // Only do suffix replacement or pattern macro expansion
1013 // if both ':' and '=' are found. This is indicated by
1014 // lenf != 0.
1015 expfind = NULL;
1016 find_suff = repl_suff = NULL;
1017 lenf = 0;
1018 if ((find = find_char(name, ':'))) {
1019 *find++ = '\0';
1020 expfind = expand_macros(find, FALSE);
1021 if ((replace = find_char(expfind, '='))) {
1022 *replace++ = '\0';
1023 lenf = strlen(expfind);
1024 if (!posix && (find_suff = strchr(expfind, '%'))) {
1025 find_pref = expfind;
1026 repl_pref = replace;
1027 *find_suff++ = '\0';
1028 if ((repl_suff = strchr(replace, '%')))
1029 *repl_suff++ = '\0';
1030 } else {
1031 find_suff = expfind;
1032 repl_suff = replace;
1033 }
1034 }
1035 }
1036
1037 p = q = name;
1038 // If not in POSIX mode expand macros in the name.
1039 if (!posix) {
1040 char *expname = expand_macros(name, FALSE);
1041 free(name);
1042 name = expname;
1043 } else {
1044 // Skip over nested expansions in name
1045 do {
1046 *q++ = *p;
1047 } while ((p = skip_macro(p + 1)) && *p);
1048 }
1049
1050 // The internal macros support 'D' and 'F' modifiers
1051 modifier = '\0';
1052 switch (name[0]) {
1053 case '^':
1054 if (posix)
1055 break;
1056 // fall through
1057 case '@': case '%': case '?': case '<': case '*':
1058 if ((name[1] == 'D' || name[1] == 'F') && name[2] == '\0') {
1059 modifier = name[1];
1060 name[1] = '\0';
1061 }
1062 break;
1063 }
1064
1065 modified = NULL;
1066 if ((mp = getmp(name))) {
1067 // Recursive expansion
1068 if (mp->m_flag)
1069 error("recursive macro %s", name);
1070 // Note if we've expanded $(MAKE)
1071 if (strcmp(name, "MAKE") == 0)
1072 opts |= OPT_make;
1073 mp->m_flag = TRUE;
1074 expval = expand_macros(mp->m_val, FALSE);
1075 mp->m_flag = FALSE;
1076 modified = modify_words(expval, modifier, lenf,
1077 find_pref, repl_pref, find_suff, repl_suff);
1078 if (modified)
1079 free(expval);
1080 else
1081 modified = expval;
1082 }
1083 free(name);
1084 free(expfind);
1085
1086 if (modified && *modified) {
1087 // The text to be replaced by the macro expansion is
1088 // from s to t inclusive.
1089 *s = '\0';
1090 newexp = xasprintf("%s%s%s", exp, modified, t + 1);
1091 t = newexp + (s - exp) + strlen(modified) - 1;
1092 free(exp);
1093 exp = newexp;
1094 } else {
1095 // Macro wasn't expanded or expanded to nothing.
1096 // Close the space occupied by the macro reference.
1097 q = t + 1;
1098 t = s - 1;
1099 while ((*s++ = *q++))
1100 continue;
1101 }
1102 free(modified);
1103 }
1104 }
1105 return exp;
1106}
1107
1108/*
1109 * Process a non-command line
1110 */
1111static char *
1112process_line(char *s)
1113{
1114 char *r, *t;
1115
1116 // Skip leading blanks
1117 while (isblank(*s))
1118 s++;
1119 r = s;
1120
1121 // Strip comment
1122 t = strchr(s, '#');
1123 if (t)
1124 *t = '\0';
1125
1126 // Replace escaped newline and any leading white space on the
1127 // following line with a single space. Stop processing at a
1128 // non-escaped newline.
1129 for (t = s; *s && *s != '\n'; ) {
1130 if (s[0] == '\\' && s[1] == '\n') {
1131 s += 2;
1132 while (isspace(*s))
1133 ++s;
1134 *t++ = ' ';
1135 } else {
1136 *t++ = *s++;
1137 }
1138 }
1139 *t = '\0';
1140
1141 return r;
1142}
1143
1144enum {
1145 INITIAL = 0,
1146 SKIP_LINE = 1 << 0,
1147 EXPECT_ELSE = 1 << 1,
1148 GOT_MATCH = 1 << 2
1149};
1150
1151#define IFDEF 0
1152#define IFNDEF 1
1153#define ELSE 0
1154#define ENDIF 1
1155
1156/*
1157 * Process conditional directives and return TRUE if the current line
1158 * should be skipped.
1159 */
1160static int
1161skip_line(const char *str1)
1162{
1163 char *copy, *q, *token, *next_token;
1164 bool new_level = TRUE;
1165 // Default is to return skip flag for current level
1166 int ret = cstate[clevel] & SKIP_LINE;
1167 int key;
1168
1169 if (*str1 == '\t')
1170 return ret;
1171
1172 copy = xstrdup(str1);
1173 q = process_line(copy);
1174 if ((token = gettok(&q)) != NULL) {
1175 next_token = gettok(&q);
1176
1177 switch (index_in_strings("else\0endif\0", token)) {
1178 case ENDIF:
1179 if (next_token != NULL)
1180 error_unexpected("text");
1181 if (clevel == 0)
1182 error_unexpected(token);
1183 --clevel;
1184 ret = TRUE;
1185 goto end;
1186 case ELSE:
1187 if (!(cstate[clevel] & EXPECT_ELSE))
1188 error_unexpected(token);
1189
1190 // If an earlier condition matched we'll now skip lines.
1191 // If not we don't, though an 'else if' may override this.
1192 if ((cstate[clevel] & GOT_MATCH))
1193 cstate[clevel] |= SKIP_LINE;
1194 else
1195 cstate[clevel] &= ~SKIP_LINE;
1196
1197 if (next_token == NULL) {
1198 // Simple else with no conditional directive
1199 cstate[clevel] &= ~EXPECT_ELSE;
1200 ret = TRUE;
1201 goto end;
1202 } else {
1203 // A conditional directive is now required ('else if').
1204 token = next_token;
1205 next_token = gettok(&q);
1206 new_level = FALSE;
1207 }
1208 break;
1209 }
1210
1211 key = index_in_strings("ifdef\0ifndef\0", token);
1212 if (key != -1) {
1213 if (next_token != NULL && gettok(&q) == NULL) {
1214 if (new_level) {
1215 // Start a new level.
1216 if (clevel == IF_MAX)
1217 error("nesting too deep");
1218 ++clevel;
1219 cstate[clevel] = EXPECT_ELSE | SKIP_LINE;
1220 // If we were skipping lines at the previous level
1221 // we need to continue doing that unconditionally
1222 // at the new level.
1223 if ((cstate[clevel - 1] & SKIP_LINE))
1224 cstate[clevel] |= GOT_MATCH;
1225 }
1226
1227 if (!(cstate[clevel] & GOT_MATCH)) {
1228 char *t = expand_macros(next_token, FALSE);
1229 struct macro *mp = getmp(t);
1230 int match = mp != NULL && mp->m_val[0] != '\0';
1231
1232 if (key == IFNDEF)
1233 match = !match;
1234 if (match) {
1235 cstate[clevel] &= ~SKIP_LINE;
1236 cstate[clevel] |= GOT_MATCH;
1237 }
1238 free(t);
1239 }
1240 } else {
1241 error("invalid condition");
1242 }
1243 ret = TRUE;
1244 } else if (!new_level) {
1245 error("missing conditional");
1246 }
1247 }
1248 end:
1249 free(copy);
1250 return ret;
1251}
1252
1253/*
1254 * If fd is NULL read the built-in rules. Otherwise read from the
1255 * specified file descriptor.
1256 */
1257static char *
1258make_fgets(char *s, int size, FILE *fd)
1259{
1260 return fd ? fgets(s, size, fd) : getrules(s, size);
1261}
1262
1263/*
1264 * Read a newline-terminated line into an allocated string.
1265 * Backslash-escaped newlines don't terminate the line.
1266 * Ignore comment lines. Return NULL on EOF.
1267 */
1268static char *
1269readline(FILE *fd)
1270{
1271 char *p, *str;
1272 int pos = 0;
1273 int len = 256;
1274
1275 str = xmalloc(len);
1276
1277 for (;;) {
1278 if (make_fgets(str + pos, len - pos, fd) == NULL) {
1279 if (pos)
1280 return str;
1281 free(str);
1282 return NULL; // EOF
1283 }
1284
1285 if ((p = strchr(str + pos, '\n')) == NULL) {
1286 // Need more room
1287 pos = len - 1;
1288 len += 256;
1289 str = xrealloc(str, len);
1290 continue;
1291 }
1292 lineno++;
1293
1294#if ENABLE_PLATFORM_MINGW32
1295 // Remove CR before LF
1296 if (p != str && p[-1] == '\r') {
1297 p[-1] = '\n';
1298 *p-- = '\0';
1299 }
1300#endif
1301 // Keep going if newline has been escaped
1302 if (p != str && p[-1] == '\\') {
1303 pos = p - str + 1;
1304 continue;
1305 }
1306 dispno = lineno;
1307
1308 // Check for comment lines and lines that are conditionally skipped.
1309 p = str;
1310 while (isblank(*p))
1311 p++;
1312
1313 if (*p != '\n' && *str != '#' && (posix || !skip_line(str)))
1314 return str;
1315
1316 pos = 0;
1317 }
1318}
1319
1320/*
1321 * Return TRUE if the argument is a known suffix.
1322 */
1323static int
1324is_suffix(const char *s)
1325{
1326 struct name *np;
1327 struct rule *rp;
1328 struct depend *dp;
1329
1330 np = newname(".SUFFIXES");
1331 for (rp = np->n_rule; rp; rp = rp->r_next) {
1332 for (dp = rp->r_dep; dp; dp = dp->d_next) {
1333 if (strcmp(s, dp->d_name->n_name) == 0) {
1334 return TRUE;
1335 }
1336 }
1337 }
1338 return FALSE;
1339}
1340
1341#define T_NORMAL 0
1342#define T_SPECIAL 1
1343#define T_INFERENCE 2
1344/*
1345 * Determine if the argument is a special target and return a set
1346 * of flags indicating its properties.
1347 */
1348static int
1349target_type(char *s)
1350{
1351 char *sfx;
1352 int ret;
1353 static const char *s_name[] = {
1354 ".DEFAULT",
1355 ".POSIX",
1356 ".IGNORE",
1357 ".PRECIOUS",
1358 ".SILENT",
1359 ".SUFFIXES",
1360 ".PHONY",
1361 };
1362
1363 if (*s != '.')
1364 return T_NORMAL;
1365
1366 // Check for one of the known special targets
1367 for (ret = 0; ret < ARRAY_SIZE(s_name); ret++)
1368 if (strcmp(s_name[ret], s) == 0)
1369 return T_SPECIAL;
1370
1371 // Check for an inference rule
1372 ret = T_NORMAL;
1373 sfx = suffix(s);
1374 if (is_suffix(sfx)) {
1375 if (s == sfx) { // Single suffix rule
1376 ret = T_INFERENCE;
1377 } else {
1378 // Suffix is valid, check that prefix is too
1379 *sfx = '\0';
1380 if (is_suffix(s))
1381 ret = T_INFERENCE;
1382 *sfx = '.';
1383 }
1384 }
1385 return ret;
1386}
1387
1388static int
1389ends_with_bracket(const char *s)
1390{
1391 return last_char_is(s, ')') != NULL;
1392}
1393
1394/*
1395 * Process a command line
1396 */
1397static char *
1398process_command(char *s)
1399{
1400 char *t, *u;
1401
1402 // Remove tab following escaped newline. Stop processing at a
1403 // non-escaped newline.
1404 for (t = u = s; *u && *u != '\n'; u++) {
1405 if (u[0] == '\\' && u[1] == '\n' && u[2] == '\t') {
1406 *t++ = *u++;
1407 *t++ = *u++;
1408 } else {
1409 *t++ = *u;
1410 }
1411 }
1412 *t = '\0';
1413 return s;
1414}
1415
1416static char *
1417run_command(const char *cmd)
1418{
1419 FILE *fd;
1420 char *s, *val = NULL;
1421 char buf[256];
1422 size_t len = 0, nread;
1423
1424 if ((fd = popen(cmd, "r")) == NULL)
1425 return val;
1426
1427 for (;;) {
1428 nread = fread(buf, 1, sizeof(buf), fd);
1429 if (nread == 0)
1430 break;
1431
1432 val = xrealloc(val, len + nread + 1);
1433 memcpy(val + len, buf, nread);
1434 len += nread;
1435 val[len] = '\0';
1436 }
1437 pclose(fd);
1438
1439 if (val) {
1440#if ENABLE_PLATFORM_MINGW32
1441 len = remove_cr(val, len + 1) - 1;
1442 if (len == 0) {
1443 free(val);
1444 return NULL;
1445 }
1446#endif
1447 // Remove one newline from the end (BSD compatibility)
1448 if (val[len - 1] == '\n')
1449 val[len - 1] = '\0';
1450 // Other newlines are changed to spaces
1451 for (s = val; *s; ++s) {
1452 if (*s == '\n')
1453 *s = ' ';
1454 }
1455 }
1456 return val;
1457}
1458
1459/*
1460 * Check for an unescaped wildcard character
1461 */
1462static int wildchar(const char *p)
1463{
1464 while (*p) {
1465 switch (*p) {
1466 case '?':
1467 case '*':
1468 case '[':
1469 return 1;
1470 case '\\':
1471 if (p[1] != '\0')
1472 ++p;
1473 break;
1474 }
1475 ++p;
1476 }
1477 return 0;
1478}
1479
1480/*
1481 * Expand any wildcards in a pattern. Return TRUE if a match is
1482 * found, in which case the caller should call globfree() on the
1483 * glob_t structure.
1484 */
1485static int
1486wildcard(char *p, glob_t *gd)
1487{
1488 int ret;
1489 char *s;
1490
1491 // Don't call glob() if there are no wildcards.
1492 if (!wildchar(p)) {
1493 nomatch:
1494 // Remove backslashes from the name.
1495 for (s = p; *p; ++p) {
1496 if (*p == '\\' && p[1] != '\0')
1497 continue;
1498 *s++ = *p;
1499 }
1500 *s = '\0';
1501 return 0;
1502 }
1503
1504 memset(gd, 0, sizeof(*gd));
1505 ret = glob(p, GLOB_NOSORT, NULL, gd);
1506 if (ret == GLOB_NOMATCH) {
1507 globfree(gd);
1508 goto nomatch;
1509 } else if (ret != 0) {
1510 error("glob error for '%s'", p);
1511 }
1512 return 1;
1513}
1514
1515/*
1516 * Parse input from the makefile and construct a tree structure of it.
1517 */
1518static void
1519input(FILE *fd, int ilevel)
1520{
1521 char *p, *q, *s, *a, *str, *expanded, *copy;
1522 char *str1, *str2;
1523 struct name *np;
1524 struct depend *dp;
1525 struct cmd *cp;
1526 int startno, count;
1527 bool semicolon_cmd, seen_inference;
1528 uint8_t old_clevel = clevel;
1529 bool dbl;
1530 char *lib = NULL;
1531 glob_t gd;
1532 int nfile, i;
1533 char **files;
1534 bool minus;
1535
1536 lineno = 0;
1537 str1 = readline(fd);
1538 while (str1) {
1539 str2 = NULL;
1540 if (*str1 == '\t') // Command without target
1541 error("command not allowed here");
1542
1543 // Newlines and comments are handled differently in command lines
1544 // and other types of line. Take a copy of the current line before
1545 // processing it as a non-command line in case it contains a
1546 // rule with a command line. That is, a line of the form:
1547 //
1548 // target: prereq; command
1549 //
1550 copy = xstrdup(str1);
1551 str = process_line(str1);
1552
1553 // Check for an include line
1554 minus = !posix && *str == '-';
1555 p = str + minus;
1556 if (strncmp(p, "include", 7) == 0 && isblank(p[7])) {
1557 const char *old_makefile = makefile;
1558 int old_lineno = lineno;
1559
1560 if (ilevel > 16)
1561 error("too many includes");
1562
1563 q = expanded = expand_macros(p + 7, FALSE);
1564 while ((p = gettok(&q)) != NULL) {
1565 FILE *ifd;
1566
1567 if (!posix) {
1568 // Try to create include file or bring it up-to-date
1569 opts |= OPT_include;
1570 make(newname(p), 1);
1571 opts &= ~OPT_include;
1572 }
1573 if ((ifd = fopen(p, "r")) == NULL) {
1574 if (!minus)
1575 error("can't open include file '%s'", p);
1576 } else {
1577 makefile = p;
1578 input(ifd, ilevel + 1);
1579 fclose(ifd);
1580 }
1581 if (posix)
1582 break;
1583 }
1584 if (posix && (p == NULL || gettok(&q)))
1585 error("one include file per line");
1586
1587 makefile = old_makefile;
1588 lineno = old_lineno;
1589 goto end_loop;
1590 }
1591
1592 // Check for a macro definition
1593 q = find_char(str, '=');
1594 if (q != NULL) {
1595 int level = (useenv || fd == NULL) ? 4 : 3;
1596 char *newq = NULL;
1597 char eq = '\0';
1598
1599 if (q - 1 > str) {
1600 switch (q[-1]) {
1601 case ':':
1602 // '::=' and ':::=' are from POSIX 202X.
1603 if (!posix && q - 2 > str && q[-2] == ':') {
1604 if (q - 3 > str && q[-3] == ':') {
1605 eq = 'B'; // BSD-style ':='
1606 q[-3] = '\0';
1607 } else {
1608 eq = ':'; // GNU-style ':='
1609 q[-2] = '\0';
1610 }
1611 break;
1612 }
1613 case '!':
1614 // ':=' and '!=' are non-POSIX extensions.
1615 case '+':
1616 case '?':
1617 // '+=' and '?=' are from POSIX 202X.
1618 if (posix)
1619 break;
1620 eq = q[-1];
1621 q[-1] = '\0';
1622 break;
1623 }
1624 }
1625 *q++ = '\0'; // Separate name and value
1626 while (isblank(*q))
1627 q++;
1628 if ((p = strrchr(q, '\n')) != NULL)
1629 *p = '\0';
1630
1631 // Expand left-hand side of assignment
1632 p = expanded = expand_macros(str, FALSE);
1633 if ((a = gettok(&p)) == NULL || gettok(&p))
1634 error("invalid macro assignment");
1635
1636 if (eq == ':') {
1637 // GNU-style ':='. Expand right-hand side of assignment.
1638 // Macro is of type immediate-expansion.
1639 q = newq = expand_macros(q, FALSE);
1640 level |= M_IMMEDIATE;
1641 }
1642 else if (eq == 'B') {
1643 // BSD-style ':='. Expand right-hand side of assignment,
1644 // though not '$$'. Macro is of type delayed-expansion.
1645 q = newq = expand_macros(q, TRUE);
1646 } else if (eq == '?' && getmp(a) != NULL) {
1647 // Skip assignment if macro is already set
1648 goto end_loop;
1649 } else if (eq == '+') {
1650 // Append to current value
1651 struct macro *mp = getmp(a);
1652 char *rhs;
1653 newq = mp && mp->m_val[0] ? xstrdup(mp->m_val) : NULL;
1654 if (mp && mp->m_immediate) {
1655 // Expand right-hand side of assignment (GNU make
1656 // compatibility)
1657 rhs = expand_macros(q, FALSE);
1658 level |= M_IMMEDIATE;
1659 } else {
1660 rhs = q;
1661 }
1662 newq = xappendword(newq, rhs);
1663 if (rhs != q)
1664 free(rhs);
1665 q = newq;
1666 }
1667 else if (eq == '!') {
1668 char *cmd = expand_macros(q, FALSE);
1669 q = newq = run_command(cmd);
1670 free(cmd);
1671 }
1672 setmacro(a, q, level);
1673 free(newq);
1674 goto end_loop;
1675 }
1676
1677 // If we get here it must be a target rule
1678 p = expanded = expand_macros(str, FALSE);
1679
1680 // Look for colon separator
1681 q = find_char(p, ':');
1682 if (q == NULL)
1683 error("expected separator");
1684
1685 *q++ = '\0'; // Separate targets and prerequisites
1686
1687 // Double colon
1688 dbl = !posix && *q == ':';
1689 if (dbl)
1690 q++;
1691
1692 // Look for semicolon separator
1693 cp = NULL;
1694 s = strchr(q, ';');
1695 if (s) {
1696 *s = '\0';
1697 // Retrieve command from copy of line
1698 if ((p = find_char(copy, ':')) && (p = strchr(p, ';')))
1699 newcmd(&cp, process_command(p + 1));
1700 }
1701 semicolon_cmd = cp != NULL;
1702
1703 // Create list of prerequisites
1704 dp = NULL;
1705 while (((p = gettok(&q)) != NULL)) {
1706 char *newp = NULL;
1707
1708 if (!posix) {
1709 // Allow prerequisites of form library(member1 member2).
1710 // Leading and trailing spaces in the brackets are skipped.
1711 if (!lib) {
1712 s = strchr(p, '(');
1713 if (s && !ends_with_bracket(s) && strchr(q, ')')) {
1714 // Looks like an unterminated archive member
1715 // with a terminator later on the line.
1716 lib = p;
1717 if (s[1] != '\0') {
1718 p = newp = auto_concat(lib, ")");
1719 s[1] = '\0';
1720 } else {
1721 continue;
1722 }
1723 }
1724 } else if (ends_with_bracket(p)) {
1725 if (*p != ')')
1726 p = newp = auto_concat(lib, p);
1727 lib = NULL;
1728 if (newp == NULL)
1729 continue;
1730 } else {
1731 p = newp = auto_string(xasprintf("%s%s)", lib, p));
1732 }
1733 }
1734
1735 // If not in POSIX mode expand wildcards in the name.
1736 nfile = 1;
1737 files = &p;
1738 if (!posix && wildcard(p, &gd)) {
1739 nfile = gd.gl_pathc;
1740 files = gd.gl_pathv;
1741 }
1742 for (i = 0; i < nfile; ++i) {
1743 np = newname(files[i]);
1744 newdep(&dp, np);
1745 }
1746 if (files != &p)
1747 globfree(&gd);
1748 free(newp);
1749 }
1750 lib = NULL;
1751
1752 // Create list of commands
1753 startno = dispno;
1754 while ((str2 = readline(fd)) && *str2 == '\t') {
1755 newcmd(&cp, process_command(str2));
1756 free(str2);
1757 }
1758 dispno = startno;
1759
1760 // Create target names and attach rule to them
1761 q = expanded;
1762 count = 0;
1763 seen_inference = FALSE;
1764 while ((p = gettok(&q)) != NULL) {
1765 // If not in POSIX mode expand wildcards in the name.
1766 nfile = 1;
1767 files = &p;
1768 if (!posix && wildcard(p, &gd)) {
1769 nfile = gd.gl_pathc;
1770 files = gd.gl_pathv;
1771 }
1772 for (i = 0; i < nfile; ++i) {
1773 int ttype = target_type(files[i]);
1774
1775 np = newname(files[i]);
1776 if (ttype != T_NORMAL) {
1777 if (ttype == T_INFERENCE && posix) {
1778 if (semicolon_cmd)
1779 error_in_inference_rule("'; command'");
1780 seen_inference = TRUE;
1781 }
1782 np->n_flag |= N_SPECIAL;
1783 } else if (!firstname) {
1784 firstname = np;
1785 }
1786 addrule(np, dp, cp, dbl);
1787 count++;
1788 }
1789 if (files != &p)
1790 globfree(&gd);
1791 }
1792 if (seen_inference && count != 1)
1793 error_in_inference_rule("multiple targets");
1794
1795 // Prerequisites and commands will be unused if there were
1796 // no targets. Avoid leaking memory.
1797 if (count == 0) {
1798 freedeps(dp);
1799 freecmds(cp);
1800 }
1801 end_loop:
1802 free(str1);
1803 dispno = lineno;
1804 str1 = str2 ? str2 : readline(fd);
1805 free(copy);
1806 free(expanded);
1807#if ENABLE_FEATURE_MAKE_POSIX
1808 if (!seen_first && fd) {
1809 if (findname(".POSIX")) {
1810 // The first non-comment line from a real makefile
1811 // defined the .POSIX special target.
1812 setenv("PDPMAKE_POSIXLY_CORRECT", "", 1);
1813 posix = TRUE;
1814 }
1815 seen_first = TRUE;
1816 }
1817#endif
1818 }
1819 // Conditionals aren't allowed to span files
1820 if (clevel != old_clevel)
1821 error("invalid conditional");
1822}
1823
1824static void
1825remove_target(void)
1826{
1827 if (!dryrun && !print && !precious &&
1828 target && !(target->n_flag & (N_PRECIOUS | N_PHONY)) &&
1829 unlink(target->n_name) == 0) {
1830 bb_error_msg("'%s' removed", target->n_name);
1831 }
1832}
1833
1834/*
1835 * Do commands to make a target
1836 */
1837static int
1838docmds(struct name *np, struct cmd *cp)
1839{
1840 int estat = 0; // 0 exit status is success
1841 char *q, *command;
1842
1843 for (; cp; cp = cp->c_next) {
1844 uint8_t ssilent, signore, sdomake;
1845
1846 opts &= ~OPT_make; // We want to know if $(MAKE) is expanded
1847 q = command = expand_macros(cp->c_cmd, FALSE);
1848 ssilent = silent || (np->n_flag & N_SILENT) || dotouch;
1849 signore = ignore || (np->n_flag & N_IGNORE);
1850 sdomake = (!dryrun || doinclude || domake) && !dotouch;
1851 for (;;) {
1852 if (*q == '@') // Specific silent
1853 ssilent = TRUE + 1;
1854 else if (*q == '-') // Specific ignore
1855 signore = TRUE;
1856 else if (*q == '+') // Specific domake
1857 sdomake = TRUE + 1;
1858 else
1859 break;
1860 q++;
1861 }
1862
1863 if (sdomake > TRUE) {
1864 // '+' must not override '@' or .SILENT
1865 if (ssilent != TRUE + 1 && !(np->n_flag & N_SILENT))
1866 ssilent = FALSE;
1867 } else if (!sdomake)
1868 ssilent = dotouch;
1869
1870 if (!ssilent)
1871 puts(q);
1872
1873 if (sdomake) {
1874 // Get the shell to execute it
1875 int status;
1876 char *cmd = !signore ? auto_concat("set -e;", q) : q;
1877
1878 target = np;
1879 status = system(cmd);
1880 target = NULL;
1881 // If this command was being run to create an include file
1882 // or bring it up-to-date errors should be ignored and a
1883 // failure status returned.
1884 if (status == -1 && !doinclude) {
1885 error("couldn't execute '%s'", q);
1886 } else if (status != 0 && !signore) {
1887 if (!doinclude)
1888 bb_error_msg("failed to build '%s'", np->n_name);
1889#if !ENABLE_PLATFORM_MINGW32
1890 if (status == SIGINT || status == SIGQUIT)
1891#endif
1892 remove_target();
1893 if (errcont || doinclude)
1894 estat = 1; // 1 exit status is failure
1895 else
1896 exit(status);
1897 }
1898 }
1899 free(command);
1900 }
1901 return estat;
1902}
1903
1904/*
1905 * Update the modification time of a file to now.
1906 */
1907static void
1908touch(struct name *np)
1909{
1910 if (dryrun || !silent)
1911 printf("touch %s\n", np->n_name);
1912
1913 if (!dryrun) {
1914 const struct timespec timebuf[2] = {{0, UTIME_NOW}, {0, UTIME_NOW}};
1915
1916 if (utimensat(AT_FDCWD, np->n_name, timebuf, 0) < 0) {
1917 if (errno == ENOENT) {
1918 int fd = open(np->n_name, O_RDWR | O_CREAT, 0666);
1919 if (fd >= 0) {
1920 close(fd);
1921 return;
1922 }
1923 }
1924 bb_perror_msg("touch %s failed", np->n_name);
1925 }
1926 }
1927}
1928
1929static int
1930make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc,
1931 struct name *implicit)
1932{
1933 int estat = 0; // 0 exit status is success
1934 char *name, *member = NULL, *base;
1935
1936 name = splitlib(np->n_name, &member);
1937 setmacro("?", oodate, 0 | M_VALID);
1938 if (!posix)
1939 setmacro("^", allsrc, 0 | M_VALID);
1940 setmacro("%", member, 0 | M_VALID);
1941 setmacro("@", name, 0 | M_VALID);
1942 if (implicit) {
1943 setmacro("<", implicit->n_name, 0 | M_VALID);
1944 base = member ? member : name;
1945 *suffix(base) = '\0';
1946 setmacro("*", base, 0 | M_VALID);
1947 }
1948 free(name);
1949
1950 estat = docmds(np, cp);
1951 if (dotouch && !(np->n_flag & N_PHONY))
1952 touch(np);
1953
1954 return estat;
1955}
1956
1957/*
1958 * Determine if the modification time of a target, t, is less than
1959 * that of a prerequisite, p. If the tv_nsec member of either is
1960 * exactly 0 we assume (possibly incorrectly) that the time resolution
1961 * is 1 second and only compare tv_sec values.
1962 */
1963static int
1964timespec_le(const struct timespec *t, const struct timespec *p)
1965{
1966 if (t->tv_nsec == 0 || p->tv_nsec == 0)
1967 return t->tv_sec <= p->tv_sec;
1968 else if (t->tv_sec < p->tv_sec)
1969 return TRUE;
1970 else if (t->tv_sec == p->tv_sec)
1971 return t->tv_nsec <= p->tv_nsec;
1972 return FALSE;
1973}
1974
1975/*
1976 * Return the greater of two struct timespecs
1977 */
1978static const struct timespec *
1979timespec_max(const struct timespec *t, const struct timespec *p)
1980{
1981 return timespec_le(t, p) ? p : t;
1982}
1983
1984/*
1985 * Recursive routine to make a target.
1986 */
1987static int
1988make(struct name *np, int level)
1989{
1990 struct depend *dp;
1991 struct rule *rp;
1992 struct name *impdep = NULL; // implicit prerequisite
1993 struct rule imprule;
1994 struct cmd *sc_cmd = NULL; // commands for single-colon rule
1995 char *oodate = NULL;
1996 char *allsrc = NULL;
1997 struct timespec dtim = {1, 0};
1998 bool didsomething = 0;
1999 bool estat = 0; // 0 exit status is success
2000
2001 if (np->n_flag & N_DONE)
2002 return 0;
2003 if (np->n_flag & N_DOING)
2004 error("circular dependency for %s", np->n_name);
2005 np->n_flag |= N_DOING;
2006
2007 if (!np->n_tim.tv_sec)
2008 modtime(np); // Get modtime of this file
2009
2010 if (!(np->n_flag & N_DOUBLE)) {
2011 // Find the commands needed for a single-colon rule, using
2012 // an inference rule or .DEFAULT rule if necessary
2013 sc_cmd = getcmd(np);
2014 if (!sc_cmd) {
2015 impdep = dyndep(np, &imprule);
2016 if (impdep) {
2017 sc_cmd = imprule.r_cmd;
2018 addrule(np, imprule.r_dep, NULL, FALSE);
2019 }
2020 }
2021
2022 // As a last resort check for a default rule
2023 if (!(np->n_flag & N_TARGET) && np->n_tim.tv_sec == 0) {
2024 sc_cmd = getcmd(findname(".DEFAULT"));
2025 if (!sc_cmd) {
2026 if (doinclude)
2027 return 1;
2028 error("don't know how to make %s", np->n_name);
2029 }
2030 impdep = np;
2031 }
2032 }
2033 else {
2034 // If any double-colon rule has no commands we need
2035 // an inference rule
2036 for (rp = np->n_rule; rp; rp = rp->r_next) {
2037 if (!rp->r_cmd) {
2038 impdep = dyndep(np, &imprule);
2039 if (!impdep) {
2040 if (doinclude)
2041 return 1;
2042 error("don't know how to make %s", np->n_name);
2043 }
2044 break;
2045 }
2046 }
2047 }
2048
2049 // Reset flag to detect duplicate prerequisites
2050 if (!quest && !(np->n_flag & N_DOUBLE)) {
2051 for (rp = np->n_rule; rp; rp = rp->r_next) {
2052 for (dp = rp->r_dep; dp; dp = dp->d_next) {
2053 dp->d_name->n_flag &= ~N_MARK;
2054 }
2055 }
2056 }
2057
2058 for (rp = np->n_rule; rp; rp = rp->r_next) {
2059 struct name *locdep = NULL;
2060
2061 // Each double-colon rule is handled separately.
2062 if ((np->n_flag & N_DOUBLE)) {
2063 // If the rule has no commands use the inference rule.
2064 if (!rp->r_cmd) {
2065 locdep = impdep;
2066 imprule.r_dep->d_next = rp->r_dep;
2067 rp->r_dep = imprule.r_dep;
2068 rp->r_cmd = imprule.r_cmd;
2069 }
2070 // A rule with no prerequisities is executed unconditionally.
2071 if (!rp->r_dep)
2072 dtim = np->n_tim;
2073 // Reset flag to detect duplicate prerequisites
2074 if (!quest) {
2075 for (dp = rp->r_dep; dp; dp = dp->d_next) {
2076 dp->d_name->n_flag &= ~N_MARK;
2077 }
2078 }
2079 }
2080 for (dp = rp->r_dep; dp; dp = dp->d_next) {
2081 // Make prerequisite
2082 estat |= make(dp->d_name, level + 1);
2083
2084 // Make strings of out-of-date prerequisites (for $?)
2085 // and all prerequisites (for $^). But not if we were
2086 // invoked with -q.
2087 if (!quest
2088 // Skip duplicate entries.
2089 && (posix || !(dp->d_name->n_flag & N_MARK))
2090 ) {
2091 if (timespec_le(&np->n_tim, &dp->d_name->n_tim)) {
2092 oodate = xappendword(oodate, dp->d_name->n_name);
2093 }
2094 allsrc = xappendword(allsrc, dp->d_name->n_name);
2095 dp->d_name->n_flag |= N_MARK;
2096 }
2097 dtim = *timespec_max(&dtim, &dp->d_name->n_tim);
2098 }
2099 if ((np->n_flag & N_DOUBLE)) {
2100 if (!quest && ((np->n_flag & N_PHONY) ||
2101 timespec_le(&np->n_tim, &dtim))) {
2102 if (estat == 0) {
2103 estat = make1(np, rp->r_cmd, oodate, allsrc, locdep);
2104 dtim = (struct timespec){1, 0};
2105 didsomething = 1;
2106 }
2107 free(oodate);
2108 oodate = NULL;
2109 }
2110 free(allsrc);
2111 allsrc = NULL;
2112 if (locdep) {
2113 rp->r_dep = rp->r_dep->d_next;
2114 rp->r_cmd = NULL;
2115 }
2116 }
2117 }
2118 if ((np->n_flag & N_DOUBLE) && impdep)
2119 free(imprule.r_dep);
2120
2121 np->n_flag |= N_DONE;
2122 np->n_flag &= ~N_DOING;
2123
2124 if (quest) {
2125 if (timespec_le(&np->n_tim, &dtim)) {
2126 clock_gettime(CLOCK_REALTIME, &np->n_tim);
2127 return 1; // 1 means rebuild is needed
2128 }
2129 } else if (!(np->n_flag & N_DOUBLE) &&
2130 ((np->n_flag & N_PHONY) || (timespec_le(&np->n_tim, &dtim)))) {
2131 if (estat == 0) {
2132 if (!sc_cmd) {
2133 if (!doinclude)
2134 bb_error_msg("nothing to be done for %s", np->n_name);
2135 } else {
2136 estat = make1(np, sc_cmd, oodate, allsrc, impdep);
2137 clock_gettime(CLOCK_REALTIME, &np->n_tim);
2138 }
2139 } else if (!doinclude) {
2140 bb_error_msg("'%s' not built due to errors", np->n_name);
2141 }
2142 free(oodate);
2143 } else if (didsomething) {
2144 clock_gettime(CLOCK_REALTIME, &np->n_tim);
2145 } else if (level == 0) {
2146 printf("%s: '%s' is up to date\n", applet_name, np->n_name);
2147 }
2148 free(allsrc);
2149 return estat;
2150}
2151
2152/*
2153 * Check structures for make.
2154 */
2155
2156static void
2157print_name(struct name *np)
2158{
2159 if (np == firstname)
2160 printf("# default target\n");
2161 printf("%s:", np->n_name);
2162 if ((np->n_flag & N_DOUBLE))
2163 putchar(':');
2164}
2165
2166static void
2167print_prerequisites(struct rule *rp)
2168{
2169 struct depend *dp;
2170
2171 for (dp = rp->r_dep; dp; dp = dp->d_next)
2172 printf(" %s", dp->d_name->n_name);
2173}
2174
2175static void
2176print_commands(struct rule *rp)
2177{
2178 struct cmd *cp;
2179
2180 for (cp = rp->r_cmd; cp; cp = cp->c_next)
2181 printf("\t%s\n", cp->c_cmd);
2182}
2183
2184static void
2185print_details(void)
2186{
2187 int i;
2188 struct macro *mp;
2189 struct name *np;
2190 struct rule *rp;
2191
2192 for (i = 0; i < HTABSIZE; i++)
2193 for (mp = macrohead[i]; mp; mp = mp->m_next)
2194 printf("%s = %s\n", mp->m_name, mp->m_val);
2195 putchar('\n');
2196
2197 for (i = 0; i < HTABSIZE; i++) {
2198 for (np = namehead[i]; np; np = np->n_next) {
2199 if (!(np->n_flag & N_DOUBLE)) {
2200 print_name(np);
2201 for (rp = np->n_rule; rp; rp = rp->r_next) {
2202 print_prerequisites(rp);
2203 }
2204 putchar('\n');
2205
2206 for (rp = np->n_rule; rp; rp = rp->r_next) {
2207 print_commands(rp);
2208 }
2209 putchar('\n');
2210 } else {
2211 for (rp = np->n_rule; rp; rp = rp->r_next) {
2212 print_name(np);
2213 print_prerequisites(rp);
2214 putchar('\n');
2215
2216 print_commands(rp);
2217 putchar('\n');
2218 }
2219 }
2220 }
2221 }
2222}
2223
2224/*
2225 * Process options from an argv array. If from_env is non-zero we're
2226 * handling options from MAKEFLAGS so skip '-C', '-f' and '-p'.
2227 */
2228static uint32_t
2229process_options(char **argv, int from_env)
2230{
2231 uint32_t flags;
2232
2233 flags = getopt32(argv, "^" OPTSTR1 OPTSTR2 "\0k-S:S-k",
2234 &numjobs, &makefiles, &dirs);
2235 if (from_env && (flags & (OPT_C | OPT_f | OPT_p)))
2236 error("invalid MAKEFLAGS");
2237 if (posix && (flags & OPT_C))
2238 error("-C not allowed");
2239
2240 return flags;
2241}
2242
2243/*
2244 * Split the contents of MAKEFLAGS into an argv array. If the return
2245 * value (call it fargv) isn't NULL the caller should free fargv[1] and
2246 * fargv.
2247 */
2248static char **
2249expand_makeflags(void)
2250{
2251 const char *m, *makeflags = getenv("MAKEFLAGS");
2252 char *p, *argstr;
2253 int argc;
2254 char **argv;
2255
2256 if (makeflags == NULL)
2257 return NULL;
2258
2259 while (isblank(*makeflags))
2260 makeflags++;
2261
2262 if (*makeflags == '\0')
2263 return NULL;
2264
2265 p = argstr = xzalloc(strlen(makeflags) + 2);
2266
2267 // If MAKEFLAGS doesn't start with a hyphen, doesn't look like
2268 // a macro definition and only contains valid option characters,
2269 // add a hyphen.
2270 argc = 3;
2271 if (makeflags[0] != '-' && strchr(makeflags, '=') == NULL) {
2272 if (strspn(makeflags, OPTSTR1) != strlen(makeflags))
2273 error("invalid MAKEFLAGS");
2274 *p++ = '-';
2275 } else {
2276 // MAKEFLAGS may need to be split, estimate size of argv array.
2277 for (m = makeflags; *m; ++m) {
2278 if (isblank(*m))
2279 argc++;
2280 }
2281 }
2282
2283 argv = xzalloc(argc * sizeof(char *));
2284 argc = 0;
2285 argv[argc++] = (char *)applet_name;
2286 argv[argc++] = argstr;
2287
2288 // Copy MAKEFLAGS into argstr, splitting at non-escaped blanks.
2289 m = makeflags;
2290 do {
2291 if (*m == '\\' && m[1] != '\0')
2292 m++; // Skip backslash, copy next character unconditionally.
2293 else if (isblank(*m)) {
2294 // Terminate current argument and start a new one.
2295 /* *p = '\0'; - xzalloc did it */
2296 argv[argc++] = ++p;
2297 do {
2298 m++;
2299 } while (isblank(*m));
2300 continue;
2301 }
2302 *p++ = *m++;
2303 } while (*m != '\0');
2304 /* *p = '\0'; - xzalloc did it */
2305 /* argv[argc] = NULL; - and this */
2306
2307 return argv;
2308}
2309
2310// These macros require special treatment
2311#define MAKEFLAGS_SHELL "MAKEFLAGS\0SHELL\0"
2312#define MAKEFLAGS 0
2313#define SHELL 1
2314
2315/*
2316 * Instantiate all macros in an argv-style array of pointers. Stop
2317 * processing at the first string that doesn't contain an equal sign.
2318 */
2319static char **
2320process_macros(char **argv, int level)
2321{
2322 char *p;
2323
2324 while (*argv && (p = strchr(*argv, '=')) != NULL) {
2325 int immediate = 0;
2326
2327 if (p - 2 > *argv && p[-1] == ':' && p[-2] == ':') {
2328 if (posix)
2329 error("invalid macro assignment");
2330 immediate = M_IMMEDIATE;
2331 p[-2] = '\0';
2332 } else
2333 *p = '\0';
2334 if (level != 3 || index_in_strings(MAKEFLAGS_SHELL, *argv) < 0) {
2335 if (immediate) {
2336 char *exp = expand_macros(p + 1, FALSE);
2337 setmacro(*argv, exp, level | immediate);
2338 free(exp);
2339 } else {
2340 setmacro(*argv, p + 1, level);
2341 }
2342 }
2343 *p = '=';
2344 if (immediate)
2345 p[-2] = ':';
2346
2347 argv++;
2348 }
2349 return argv;
2350}
2351
2352/*
2353 * Update the MAKEFLAGS macro and environment variable to include any
2354 * command line options that don't have their default value (apart from
2355 * -f, -p and -S). Also add any macros defined on the command line or
2356 * by the MAKEFLAGS environment variable (apart from MAKEFLAGS itself).
2357 * Add macros that were defined on the command line to the environment.
2358 */
2359static void
2360update_makeflags(void)
2361{
2362 int i;
2363 char optbuf[] = "-?";
2364 char *makeflags = NULL;
2365 char *macro, *s;
2366 const char *t;
2367 struct macro *mp;
2368
2369 t = OPTSTR1;
2370 for (i = 0; *t; t++) {
2371 if (*t == ':' || *t == '+')
2372 continue;
2373 if ((opts & OPT_MASK & (1 << i))) {
2374 optbuf[1] = *t;
2375 makeflags = xappendword(makeflags, optbuf);
2376 if (*t == 'j') {
2377 s = auto_string(xasprintf("%d", numjobs));
2378 makeflags = xappendword(makeflags, s);
2379 }
2380 }
2381 i++;
2382 }
2383
2384 for (i = 0; i < HTABSIZE; ++i) {
2385 for (mp = macrohead[i]; mp; mp = mp->m_next) {
2386 if (mp->m_level == 1 || mp->m_level == 2) {
2387 int idx = index_in_strings(MAKEFLAGS_SHELL, mp->m_name);
2388 if (idx == MAKEFLAGS)
2389 continue;
2390 macro = xzalloc(strlen(mp->m_name) + 2 * strlen(mp->m_val) + 1);
2391 s = stpcpy(macro, mp->m_name);
2392 *s++ = '=';
2393 for (t = mp->m_val; *t; t++) {
2394 if (*t == '\\' || isblank(*t))
2395 *s++ = '\\';
2396 *s++ = *t;
2397 }
2398 /* *s = '\0'; - xzalloc did it */
2399
2400 makeflags = xappendword(makeflags, macro);
2401 free(macro);
2402
2403 // Add command line macro definitions to the environment
2404 if (mp->m_level == 1 && idx != SHELL)
2405 setenv(mp->m_name, mp->m_val, 1);
2406 }
2407 }
2408 }
2409
2410 if (makeflags) {
2411 setmacro("MAKEFLAGS", makeflags, 0);
2412 setenv("MAKEFLAGS", makeflags, 1);
2413 free(makeflags);
2414 }
2415}
2416
2417#if !ENABLE_PLATFORM_MINGW32
2418static void
2419make_handler(int sig)
2420{
2421 signal(sig, SIG_DFL);
2422 remove_target();
2423 kill(getpid(), sig);
2424}
2425
2426static void
2427init_signal(int sig)
2428{
2429 struct sigaction sa, new_action;
2430
2431 sigemptyset(&new_action.sa_mask);
2432 new_action.sa_flags = 0;
2433 new_action.sa_handler = make_handler;
2434
2435 sigaction(sig, NULL, &sa);
2436 if (sa.sa_handler != SIG_IGN)
2437 sigaction_set(sig, &new_action);
2438}
2439#endif
2440
2441/*
2442 * If the global option flag associated with a special target hasn't
2443 * been set mark all prerequisites of the target with a flag. If the
2444 * target had no prerequisites set the global option flag.
2445 */
2446static void
2447mark_special(const char *special, uint32_t oflag, uint16_t nflag)
2448{
2449 struct name *np;
2450 struct rule *rp;
2451 struct depend *dp;
2452 int marked = FALSE;
2453
2454 if (!(opts & oflag) && (np = findname(special))) {
2455 for (rp = np->n_rule; rp; rp = rp->r_next) {
2456 for (dp = rp->r_dep; dp; dp = dp->d_next) {
2457 dp->d_name->n_flag |= nflag;
2458 marked = TRUE;
2459 }
2460 }
2461
2462 if (!marked)
2463 opts |= oflag;
2464 }
2465}
2466
2467int make_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
2468int make_main(int argc UNUSED_PARAM, char **argv)
2469{
2470 const char *path, *newpath = NULL;
2471 char **fargv, **fargv0;
2472 const char *dir, *file;
2473 char def_make[] = "makefile";
2474 int estat;
2475 FILE *ifd;
2476
2477 INIT_G();
2478
2479#if ENABLE_FEATURE_MAKE_POSIX
2480 if (argv[1] && strcmp(argv[1], "--posix") == 0) {
2481 argv[1] = argv[0];
2482 ++argv;
2483 --argc;
2484 setenv("PDPMAKE_POSIXLY_CORRECT", "", 1);
2485 posix = TRUE;
2486 } else {
2487 posix = getenv("PDPMAKE_POSIXLY_CORRECT") != NULL;
2488 }
2489#endif
2490
2491 if (!posix) {
2492 path = argv[0];
2493#if ENABLE_PLATFORM_MINGW32
2494 if (has_path(argv[0])) {
2495 // Add extension if necessary, else realpath() will fail
2496 char *p = xmalloc(strlen(argv[0]) + 5);
2497 add_win32_extension(strcpy(p, argv[0]));
2498 path = newpath = xmalloc_realpath(p);
2499 free(p);
2500 if (!path) {
2501 bb_perror_msg("can't resolve path for %s", argv[0]);
2502 }
2503 }
2504#else
2505 if (argv[0][0] != '/' && strchr(argv[0], '/')) {
2506 // Make relative path absolute
2507 path = newpath = realpath(argv[0], NULL);
2508 if (!path) {
2509 bb_perror_msg("can't resolve path for %s", argv[0]);
2510 }
2511 }
2512#endif
2513 } else {
2514 path = "make";
2515 }
2516
2517 // Process options from MAKEFLAGS
2518 fargv = fargv0 = expand_makeflags();
2519 if (fargv0) {
2520 opts = process_options(fargv, TRUE);
2521 fargv = fargv0 + optind;
2522 }
2523 // Reset getopt(3) so we can call it again
2524 GETOPT_RESET();
2525
2526 // Process options from the command line
2527 opts |= process_options(argv, FALSE);
2528 argv += optind;
2529
2530 while ((dir = llist_pop(&dirs))) {
2531 if (chdir(dir) == -1) {
2532 bb_perror_msg("can't chdir to %s", dir);
2533 }
2534 }
2535
2536#if !ENABLE_PLATFORM_MINGW32
2537 init_signal(SIGHUP);
2538 init_signal(SIGTERM);
2539#endif
2540
2541 setmacro("$", "$", 0 | M_VALID);
2542
2543 // Process macro definitions from the command line
2544 argv = process_macros(argv, 1);
2545
2546 // Process macro definitions from MAKEFLAGS
2547 if (fargv) {
2548 process_macros(fargv, 2);
2549 free(fargv0[1]);
2550 free(fargv0);
2551 }
2552
2553 // Process macro definitions from the environment
2554 process_macros(environ, 3 | M_VALID);
2555
2556 // Update MAKEFLAGS and environment
2557 update_makeflags();
2558
2559 // Read built-in rules
2560 input(NULL, 0);
2561
2562 setmacro("SHELL", "/bin/sh", 4);
2563 setmacro("MAKE", path, 4);
2564 free((void *)newpath);
2565
2566 if (!makefiles) { // Look for a default Makefile
2567#if !ENABLE_PLATFORM_MINGW32
2568 for (; def_make[0] >= 'M'; def_make[0] -= 0x20) {
2569#else
2570 {
2571#endif
2572 if ((ifd = fopen(def_make, "r")) != NULL) {
2573 makefile = def_make;
2574 goto read_makefile;
2575 }
2576 }
2577 error("no makefile found");
2578 }
2579
2580 while ((file = llist_pop(&makefiles))) {
2581 if (strcmp(file, "-") == 0) { // Can use stdin as makefile
2582 ifd = stdin;
2583 makefile = "stdin";
2584 } else {
2585 ifd = xfopen_for_read(file);
2586 makefile = file;
2587 }
2588 read_makefile:
2589 input(ifd, 0);
2590 fclose(ifd);
2591 makefile = NULL;
2592 }
2593
2594 if (print)
2595 print_details();
2596
2597 mark_special(".SILENT", OPT_s, N_SILENT);
2598 mark_special(".IGNORE", OPT_i, N_IGNORE);
2599 mark_special(".PRECIOUS", OPT_precious, N_PRECIOUS);
2600 if (!posix)
2601 mark_special(".PHONY", OPT_phony, N_PHONY);
2602
2603 estat = 0;
2604 if (*argv == NULL) {
2605 if (!firstname)
2606 error("no targets defined");
2607 estat = make(firstname, 0);
2608 } else {
2609 while (*argv != NULL)
2610 estat |= make(newname(*argv++), 0);
2611 }
2612
2613#if ENABLE_FEATURE_CLEAN_UP
2614 freenames();
2615 freemacros();
2616 llist_free(makefiles, NULL);
2617 llist_free(dirs, NULL);
2618#endif
2619
2620 return estat;
2621}
diff --git a/testsuite/make.tests b/testsuite/make.tests
new file mode 100755
index 000000000..75091b0f7
--- /dev/null
+++ b/testsuite/make.tests
@@ -0,0 +1,413 @@
1#!/bin/sh
2
3. ./testing.sh
4
5# testing "test name" "command" "expected result" "file input" "stdin"
6
7testing "Basic makefile" \
8 "make -f -" "target\n" "" '
9target:
10 @echo target
11'
12
13# .DEFAULT rules with no commands or some prerequisites are ignored.
14# .DEFAULT rules with commands can be redefined.
15testing ".DEFAULT rule" \
16 "make -f - default" "default2\n" "" '
17.DEFAULT: ignored
18.DEFAULT:
19 @echo default1
20.DEFAULT:
21 @echo default2
22target:
23'
24
25# Macros should be expanded before suffix substitution. The suffixes
26# can be obtained by macro expansion.
27testing "Macro expansion and suffix substitution" \
28 "make -f -" "src1.o src2.o\n" "" '
29DOTC = .c
30DOTO = .o
31SRC1 = src1.c
32SRCS = $(SRC1) src2.c
33target:
34 @echo $(SRCS:$(DOTC)=$(DOTO))
35'
36
37# Indeed, everything after the <colon> can be obtained by macro
38# macro expansion.
39testing "Macro expansion and suffix substitution 2" \
40 "make -f -" "src1.o src2.o\n" "" '
41DOTS = .c=.o
42SRC1 = src1.c
43SRCS = $(SRC1) src2.c
44target:
45 @echo $(SRCS:$(DOTS))
46'
47
48# It should be possible for an inference rule to determine that a
49# prerequisite can be created using an explicit rule.
50mkdir make.tempdir && cd make.tempdir || exit 1
51testing "Inference rule with explicit rule for prerequisite" \
52 "make -f -" "touch x.p\ncat x.p >x.q\n" "" '
53.SUFFIXES: .p .q
54x.q:
55x.p:
56 touch $@
57.p.q:
58 cat $< >$@
59'
60cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
61
62# A macro created using ::= remembers it's of type immediate-expansion.
63# Immediate expansion also occurs when += is used to append to such a macro.
64testing "Appending to immediate-expansion macro" \
65 "make -f -" \
66 "hello 1 2 3\nhello 4 4\n" "" '
67world = 1
68hello ::= hello $(world)
69world = 2
70hello += $(world)
71world = 3
72hello += $(world)
73world = 4
74
75world = 1
76reset ::= hello $(world)
77world = 2
78# No longer immediate-expansion
79reset = hello $(world)
80world = 3
81reset += $(world)
82world = 4
83
84target:
85 @echo $(hello)
86 @echo $(reset)
87'
88
89# basic pattern macro expansion
90testing "Basic pattern macro expansion" \
91 "make -f -" \
92 "obj/util.o obj/main.o\n" "" '
93SRC = src/util.c src/main.c
94OBJ = $(SRC:src/%.c=obj/%.o)
95
96target:
97 @echo $(OBJ)
98'
99
100# pattern macro expansion; match any value
101testing "Pattern macro expansion; match any value" \
102 "make -f -" \
103 "any_value.o\n" "" '
104SRC = any_value
105OBJ = $(SRC:%=%.o)
106
107target:
108 @echo $(OBJ)
109'
110
111# pattern macro expansion with empty rvalue
112testing "Pattern macro expansion with empty rvalue" \
113 "make -f -" \
114 "\n" "" '
115SRC = util.c main.c
116OBJ = $(SRC:%.c=)
117
118target:
119 @echo $(OBJ)
120'
121
122# pattern macro expansion with multiple <percent> in rvalue
123# POSIX requires the first <percent> to be expanded, others
124# may or may not be expanded. Permit either case.
125testing "Pattern macro expansion with multiple <percent> in rvalue" \
126 "make -f - | sed 's/mainmainmain/main%%/'" \
127 "main%%\n" "" '
128SRC = main.c
129OBJ = $(SRC:%.c=%%%)
130
131target:
132 @echo $(OBJ)
133'
134
135# pattern macro expansion; zero match
136testing "Pattern macro expansion; zero match" \
137 "make -f -" \
138 "nsnp\n" "" '
139WORD = osop
140REPL = $(WORD:os%op=ns%np)
141
142target:
143 @echo $(REPL)
144'
145
146# Check that MAKE will contain argv[0], e.g make in this case
147testing "Basic MAKE macro expansion" \
148 "make -f -" \
149 "make\n" "" '
150target:
151 @echo $(MAKE)
152'
153
154# Check that MAKE defined as environment variable will overwrite default MAKE
155testing "MAKE macro expansion; overwrite with env macro" \
156 "MAKE=hello make -f -" \
157 "hello\n" "" '
158target:
159 @echo $(MAKE)
160'
161
162# Check that MAKE defined on the command-line will overwrite MAKE defined in
163# Makefile
164testing "MAKE macro expansion; overwrite with command-line macro" \
165 "make -f - MAKE=hello" \
166 "hello\n" "" '
167MAKE = test
168
169target:
170 @echo $(MAKE)
171'
172
173# POSIX draft states that if make was invoked using relative path, MAKE must
174# contain absolute path, not just argv[0]
175testing "MAKE macro expansion; turn relative path into absolute" \
176 "../runtest-tempdir-links/make -f -" \
177 "ok\n" "" '
178target:
179 @test -e "$(MAKE)" && test "$(MAKE)" = "$$(env which make)" && echo ok
180'
181
182# $? contains prerequisites newer than target, file2 in this case
183# $^ has all prerequisites, file1 and file2
184touch -t 202206171200 file1
185touch -t 202206171201 target
186touch -t 202206171202 file2
187testing "Compare \$? and \$^ internal macros" \
188 "make -f -" \
189 "file2\nfile1 file2\n" "" '
190target: file1 file2
191 @echo $?
192 @echo $^
193'
194rm -f target file1 file2
195
196# Phony targets are executed (once) even if a matching file exists.
197# A .PHONY target with no prerequisites is ignored.
198touch -t 202206171201 target
199testing "Phony target" \
200 "make -f -" \
201 "phony\n" "" '
202.PHONY: target
203.PHONY:
204target:
205 @echo phony
206'
207rm -f target
208
209# Phony targets aren't touched with -t
210testing "Phony target not touched" \
211 "make -t -f - >/dev/null && test -f target && echo target" \
212 "" "" '
213.PHONY: target
214target:
215 @:
216'
217rm -f target
218
219# Include files are created or brought up-to-date
220mkdir make.tempdir && cd make.tempdir || exit 1
221testing "Create include file" \
222 "make -f -" \
223 "made\n" "" '
224target:
225 @echo $(VAR)
226mk:
227 @echo "VAR = made" >mk
228include mk
229'
230cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
231
232# Include files are created or brought up-to-date even when the -n
233# option is given.
234mkdir make.tempdir && cd make.tempdir || exit 1
235testing "Create include file even with -n" \
236 "make -n -f -" \
237 "echo made\n" "" '
238target:
239 @echo $(VAR)
240mk:
241 @echo "VAR = made" >mk
242include mk
243'
244cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
245
246# Failure to create an include file isn't an error. (Provided the
247# include line is ignoring non-existent files.)
248testing "Failure to create include file is OK" \
249 "make -f -" \
250 "OK\n" "" '
251target:
252 @echo OK
253mk:
254 @:
255-include mk
256'
257
258# Nested macro expansion is allowed. This should be compatible
259# with other implementations.
260testing "Nested macro expansion" \
261 "make -f -" "0 bc\n1 d\n2\n3\n4 bcd\n5 bcd\n" "" '
262a = b
263b = c
264c = d
265$(a:.q=.v)$(b:.z=.v) = bc
266bcd = bcd
267target:
268 @echo 0 $(bc)
269 @echo 1 $($($(a)))
270 @echo 2 $($(a) $(b) $(c))
271 @echo 3 $($a $b $c)
272 @echo 4 $($(a)$(b)$(c))
273 @echo 5 $($a$b$c)
274'
275
276testing "Double-colon rule" \
277 "make -f -" "target1\ntarget2\n" "" '
278target::
279 @echo target1
280target::
281 @echo target2
282'
283
284# There was a bug whereby the modification time of a file created by
285# double-colon rules wasn't correctly updated. This test checks that
286# the bug is now fixed.
287mkdir make.tempdir && cd make.tempdir || exit 1
288touch -t 202206171200 file1
289touch -t 202206171201 intermediate
290touch -t 202206171202 target
291touch -t 202206171203 file2
292testing "Target depends on prerequisite updated by double-colon rule" \
293 "make -f -" \
294 "file2\n" "" '
295target: intermediate
296 @cat intermediate
297intermediate:: file1
298 @echo file1 >>intermediate
299intermediate:: file2
300 @echo file2 >>intermediate
301'
302cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
303
304# Use chained inference rules to determine prerequisites.
305mkdir make.tempdir && cd make.tempdir || exit 1
306touch target.p
307testing "Chained inference rules" \
308 "make -s -f - target.s" \
309 "target.q\ntarget.r\ntarget.s\n" "" '
310.SUFFIXES: .p .q .r .s
311.p.q:
312 @cp $< $*.q
313 @echo $*.q
314.q.r:
315 @cp $< $*.r
316 @echo $*.r
317.r.s:
318 @cp $< $*.s
319 @echo $*.s
320'
321cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
322
323# Assign the output of a shell command to a macro.
324testing "Shell assignment" \
325 "make -f -" \
326 "1 2 3 4\n" "" '
327hello != echo 1; echo 2; echo 3; echo; echo
328
329target:
330 @echo "$(hello) 4"
331'
332
333cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
334# make supports *, ? and [] wildcards in targets and prerequisites
335mkdir make.tempdir && cd make.tempdir || exit 1
336touch -t 202206171201 t1a t2aa t3b
337touch s1a s2aa s3b
338testing "Expand wildcards in filenames" \
339 "make -f - t1a t2aa t3b" \
340 "t1a s1a s2aa s3b\nt2aa s1a s2aa s3b\nt3b s1a s2aa s3b\n" "" '
341t1? t2* t3[abc]: s1? s2* s3[abc]
342 @echo $@ $?
343'
344cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
345
346# Skip duplicate entries in $? and $^
347mkdir make.tempdir && cd make.tempdir || exit 1
348touch -t 202206171200 file1 file3
349touch -t 202206171201 target
350touch -t 202206171202 file2
351testing "Skip duplicate entries in \$? and \$^" \
352 "make -f -" \
353 "file2\nfile1 file2 file3\n" "" '
354target: file1 file2 file2 file3 file3
355 @echo $?
356 @echo $^
357'
358cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
359
360# Skip duplicate entries in $? and $^, with each double-colon rule
361# handled separately
362mkdir make.tempdir && cd make.tempdir || exit 1
363touch -t 202206171200 file1 file3
364touch -t 202206171201 target
365touch -t 202206171202 file2
366testing "Skip duplicate entries: double-colon rules" \
367 "make -f -" \
368 "file2\nfile1 file3 file2\nfile2\nfile2 file3\n" "" '
369target:: file1 file3 file1 file2 file3
370 @echo $?
371 @echo $^
372target:: file2 file3 file3
373 @echo $?
374 @echo $^
375'
376cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
377
378# Skip duplicate entries in $? and $^, with each double-colon rule
379# handled separately. No prerequisites out-of-date in the first.
380mkdir make.tempdir && cd make.tempdir || exit 1
381touch -t 202206171200 file1 file3
382touch -t 202206171201 target
383touch -t 202206171202 file2
384testing "Skip duplicate entries: double-colon rules, only second invoked" \
385 "make -f -" \
386 "file2\nfile2 file3\n" "" '
387target:: file1 file3 file1 file3
388 @echo $?
389 @echo $^
390target:: file2 file3 file3
391 @echo $?
392 @echo $^
393'
394cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
395
396# Double-colon rules didn't work properly if their target was phony:
397# - they didn't ignore the presence of a file matching the target name;
398# - they were also invoked as if they were a single-colon rule.
399mkdir make.tempdir && cd make.tempdir || exit 1
400touch -t 202206171200 file1
401touch -t 202206171201 target
402testing "Phony target of double-colon rule" \
403 "make -f - 2>&1" \
404 "unconditional\nconditional\n" "" '
405.PHONY: target
406target::
407 @echo unconditional
408target:: file1
409 @echo conditional
410file1:
411 @touch file1
412'
413cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
diff --git a/win32/Kbuild b/win32/Kbuild
index 9f486d5e9..10614461a 100644
--- a/win32/Kbuild
+++ b/win32/Kbuild
@@ -8,6 +8,7 @@ lib-$(CONFIG_PLATFORM_MINGW32) += dirent.o
8lib-$(CONFIG_PLATFORM_MINGW32) += env.o 8lib-$(CONFIG_PLATFORM_MINGW32) += env.o
9lib-$(CONFIG_PLATFORM_MINGW32) += fnmatch.o 9lib-$(CONFIG_PLATFORM_MINGW32) += fnmatch.o
10lib-$(CONFIG_PLATFORM_MINGW32) += fsync.o 10lib-$(CONFIG_PLATFORM_MINGW32) += fsync.o
11lib-$(CONFIG_MAKE) += glob.o
11lib-$(CONFIG_PLATFORM_MINGW32) += inet_pton.o 12lib-$(CONFIG_PLATFORM_MINGW32) += inet_pton.o
12lib-$(CONFIG_PLATFORM_MINGW32) += ioctl.o 13lib-$(CONFIG_PLATFORM_MINGW32) += ioctl.o
13lib-$(CONFIG_FEATURE_PRNG_ISAAC) += isaac.o 14lib-$(CONFIG_FEATURE_PRNG_ISAAC) += isaac.o
diff --git a/win32/glob.c b/win32/glob.c
new file mode 100644
index 000000000..1cc6483e7
--- /dev/null
+++ b/win32/glob.c
@@ -0,0 +1,343 @@
1/*
2 glob from musl (https://www.musl-libc.org/).
3
4 MIT licensed:
5
6----------------------------------------------------------------------
7Copyright © 2005-2020 Rich Felker, et al.
8
9Permission is hereby granted, free of charge, to any person obtaining
10a copy of this software and associated documentation files (the
11"Software"), to deal in the Software without restriction, including
12without limitation the rights to use, copy, modify, merge, publish,
13distribute, sublicense, and/or sell copies of the Software, and to
14permit persons to whom the Software is furnished to do so, subject to
15the following conditions:
16
17The above copyright notice and this permission notice shall be
18included in all copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27----------------------------------------------------------------------
28*/
29#include "libbb.h"
30#include <glob.h>
31#include <fnmatch.h>
32
33struct match
34{
35 struct match *next;
36 char name[];
37};
38
39static int append(struct match **tail, const char *name, size_t len, int mark)
40{
41 struct match *new = malloc(sizeof(struct match) + len + 2);
42 if (!new) return -1;
43 (*tail)->next = new;
44 new->next = NULL;
45 memcpy(new->name, name, len+1);
46 if (mark && len && name[len-1]!='/') {
47 new->name[len] = '/';
48 new->name[len+1] = 0;
49 }
50 *tail = new;
51 return 0;
52}
53
54static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (*errfunc)(const char *path, int err), struct match **tail)
55{
56 ptrdiff_t i, j;
57 int in_bracket, overflow;
58 char *p2, saved_sep;
59 int readerr, old_errno;
60 DIR *dir;
61 struct dirent *de;
62
63 /* If GLOB_MARK is unused, we don't care about type. */
64 if (!type && !(flags & GLOB_MARK)) type = DT_REG;
65
66 /* Special-case the remaining pattern being all slashes, in
67 * which case we can use caller-passed type if it's a dir. */
68 if (*pat && type!=DT_DIR) type = 0;
69 while (pos+1 < PATH_MAX && *pat=='/') buf[pos++] = *pat++;
70
71 /* Consume maximal [escaped-]literal prefix of pattern, copying
72 * and un-escaping it to the running buffer as we go. */
73 i=0; j=0;
74 in_bracket = 0; overflow = 0;
75 for (; pat[i]!='*' && pat[i]!='?' && (!in_bracket || pat[i]!=']'); i++) {
76 if (!pat[i]) {
77 if (overflow) return 0;
78 pat += i;
79 pos += j;
80 i = j = 0;
81 break;
82 } else if (pat[i] == '[') {
83 in_bracket = 1;
84 } else if (pat[i] == '\\' && !(flags & GLOB_NOESCAPE)) {
85 /* Backslashes inside a bracket are (at least by
86 * our interpretation) non-special, so if next
87 * char is ']' we have a complete expression. */
88 if (in_bracket && pat[i+1]==']') break;
89 /* Unpaired final backslash never matches. */
90 if (!pat[i+1]) return 0;
91 i++;
92 }
93 if (pat[i] == '/') {
94 if (overflow) return 0;
95 in_bracket = 0;
96 pat += i+1;
97 i = -1;
98 pos += j+1;
99 j = -1;
100 }
101 /* Only store a character if it fits in the buffer, but if
102 * a potential bracket expression is open, the overflow
103 * must be remembered and handled later only if the bracket
104 * is unterminated (and thereby a literal), so as not to
105 * disallow long bracket expressions with short matches. */
106 if (pos+(j+1) < PATH_MAX) {
107 buf[pos+j++] = pat[i];
108 } else if (in_bracket) {
109 overflow = 1;
110 } else {
111 return 0;
112 }
113 /* If we consume any new components, the caller-passed type
114 * or dummy type from above is no longer valid. */
115 type = 0;
116 }
117 buf[pos] = 0;
118 if (!*pat) {
119 /* If we consumed any components above, or if GLOB_MARK is
120 * requested and we don't yet know if the match is a dir,
121 * we must confirm the file exists and/or determine its type.
122 *
123 * If marking dirs, symlink type is inconclusive; we need the
124 * type for the symlink target, and therefore must try stat
125 * first unless type is known not to be a symlink. Otherwise,
126 * or if that fails, use lstat for determining existence to
127 * avoid false negatives in the case of broken symlinks. */
128 struct stat st;
129 if ((flags & GLOB_MARK) && (!type||type==DT_LNK) && !stat(buf, &st)) {
130 if (S_ISDIR(st.st_mode)) type = DT_DIR;
131 else type = DT_REG;
132 }
133 if (!type && lstat(buf, &st)) {
134 if (errno!=ENOENT && (errfunc(buf, errno) || (flags & GLOB_ERR)))
135 return GLOB_ABORTED;
136 return 0;
137 }
138 if (append(tail, buf, pos, (flags & GLOB_MARK) && type==DT_DIR))
139 return GLOB_NOSPACE;
140 return 0;
141 }
142 p2 = strchr(pat, '/');
143 saved_sep = '/';
144 /* Check if the '/' was escaped and, if so, remove the escape char
145 * so that it will not be unpaired when passed to fnmatch. */
146 if (p2 && !(flags & GLOB_NOESCAPE)) {
147 char *p;
148 for (p=p2; p>pat && p[-1]=='\\'; p--);
149 if ((p2-p)%2) {
150 p2--;
151 saved_sep = '\\';
152 }
153 }
154 dir = opendir(pos ? buf : ".");
155 if (!dir) {
156 if (errfunc(buf, errno) || (flags & GLOB_ERR))
157 return GLOB_ABORTED;
158 return 0;
159 }
160 old_errno = errno;
161 while (errno=0, de=readdir(dir)) {
162 size_t l;
163 int fnm_flags, r;
164
165 /* Quickly skip non-directories when there's pattern left. */
166 if (p2 && de->d_type && de->d_type!=DT_DIR && de->d_type!=DT_LNK)
167 continue;
168
169 l = strlen(de->d_name);
170 if (l >= PATH_MAX-pos) continue;
171
172 if (p2) *p2 = 0;
173
174 fnm_flags= ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
175 | ((!(flags & GLOB_PERIOD)) ? FNM_PERIOD : 0);
176
177 if (fnmatch(pat, de->d_name, fnm_flags))
178 continue;
179
180 /* With GLOB_PERIOD, don't allow matching . or .. unless
181 * fnmatch would match them with FNM_PERIOD rules in effect. */
182 if (p2 && (flags & GLOB_PERIOD) && de->d_name[0]=='.'
183 && (!de->d_name[1] || (de->d_name[1]=='.' && !de->d_name[2]))
184 && fnmatch(pat, de->d_name, fnm_flags | FNM_PERIOD))
185 continue;
186
187 memcpy(buf+pos, de->d_name, l+1);
188 if (p2) *p2 = saved_sep;
189 r = do_glob(buf, pos+l, de->d_type, p2 ? p2 : (char *)"", flags, errfunc, tail);
190 if (r) {
191 closedir(dir);
192 return r;
193 }
194 }
195 readerr = errno;
196 if (p2) *p2 = saved_sep;
197 closedir(dir);
198 if (readerr && (errfunc(buf, errno) || (flags & GLOB_ERR)))
199 return GLOB_ABORTED;
200 errno = old_errno;
201 return 0;
202}
203
204static int ignore_err(const char *path UNUSED_PARAM, int err UNUSED_PARAM)
205{
206 return 0;
207}
208
209static void freelist(struct match *head)
210{
211 struct match *match, *next;
212 for (match=head->next; match; match=next) {
213 next = match->next;
214 free(match);
215 }
216}
217
218#if !ENABLE_PLATFORM_MINGW32
219static int sort(const void *a, const void *b)
220{
221 return strcmp(*(const char **)a, *(const char **)b);
222}
223
224static int expand_tilde(char **pat, char *buf, size_t *pos)
225{
226 char *p = *pat + 1;
227 size_t i = 0;
228
229 char delim, *name_end = __strchrnul(p, '/');
230 if ((delim = *name_end)) *name_end++ = 0;
231 *pat = name_end;
232
233 char *home = *p ? NULL : getenv("HOME");
234 if (!home) {
235 struct passwd pw, *res;
236 switch (*p ? getpwnam_r(p, &pw, buf, PATH_MAX, &res)
237 : getpwuid_r(getuid(), &pw, buf, PATH_MAX, &res)) {
238 case ENOMEM:
239 return GLOB_NOSPACE;
240 case 0:
241 if (!res)
242 default:
243 return GLOB_NOMATCH;
244 }
245 home = pw.pw_dir;
246 }
247 while (i < PATH_MAX - 2 && *home)
248 buf[i++] = *home++;
249 if (*home)
250 return GLOB_NOMATCH;
251 if ((buf[i] = delim))
252 buf[++i] = 0;
253 *pos = i;
254 return 0;
255}
256#endif
257
258int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, int err), glob_t *restrict g)
259{
260 struct match head = { .next = NULL }, *tail = &head;
261 size_t cnt, i;
262 size_t offs = (flags & GLOB_DOOFFS) ? g->gl_offs : 0;
263 int error = 0;
264 char buf[PATH_MAX];
265
266 if (!errfunc) errfunc = ignore_err;
267
268 if (!(flags & GLOB_APPEND)) {
269 g->gl_offs = offs;
270 g->gl_pathc = 0;
271 g->gl_pathv = NULL;
272 }
273
274 if (*pat) {
275 char *p = strdup(pat);
276 size_t pos = 0;
277 char *s = p;
278 if (!p) return GLOB_NOSPACE;
279 buf[0] = 0;
280#if !ENABLE_PLATFORM_MINGW32
281 if ((flags & (GLOB_TILDE | GLOB_TILDE_CHECK)) && *p == '~')
282 error = expand_tilde(&s, buf, &pos);
283 if (!error)
284#endif
285 error = do_glob(buf, pos, 0, s, flags, errfunc, &tail);
286 free(p);
287 }
288
289 if (error == GLOB_NOSPACE) {
290 freelist(&head);
291 return error;
292 }
293
294 for (cnt=0, tail=head.next; tail; tail=tail->next, cnt++);
295 if (!cnt) {
296 if (flags & GLOB_NOCHECK) {
297 tail = &head;
298 if (append(&tail, pat, strlen(pat), 0))
299 return GLOB_NOSPACE;
300 cnt++;
301 } else
302 return GLOB_NOMATCH;
303 }
304
305 if (flags & GLOB_APPEND) {
306 char **pathv = realloc(g->gl_pathv, (offs + g->gl_pathc + cnt + 1) * sizeof(char *));
307 if (!pathv) {
308 freelist(&head);
309 return GLOB_NOSPACE;
310 }
311 g->gl_pathv = pathv;
312 offs += g->gl_pathc;
313 } else {
314 g->gl_pathv = malloc((offs + cnt + 1) * sizeof(char *));
315 if (!g->gl_pathv) {
316 freelist(&head);
317 return GLOB_NOSPACE;
318 }
319 for (i=0; i<offs; i++)
320 g->gl_pathv[i] = NULL;
321 }
322 for (i=0, tail=head.next; i<cnt; tail=tail->next, i++)
323 g->gl_pathv[offs + i] = tail->name;
324 g->gl_pathv[offs + i] = NULL;
325 g->gl_pathc += cnt;
326
327#if !ENABLE_PLATFORM_MINGW32
328 if (!(flags & GLOB_NOSORT))
329 qsort(g->gl_pathv+offs, cnt, sizeof(char *), sort);
330#endif
331
332 return error;
333}
334
335void globfree(glob_t *g)
336{
337 size_t i;
338 for (i=0; i<g->gl_pathc; i++)
339 free(g->gl_pathv[g->gl_offs + i] - offsetof(struct match, name));
340 free(g->gl_pathv);
341 g->gl_pathc = 0;
342 g->gl_pathv = NULL;
343}
diff --git a/win32/glob.h b/win32/glob.h
new file mode 100644
index 000000000..a8141b8bf
--- /dev/null
+++ b/win32/glob.h
@@ -0,0 +1,89 @@
1/*
2 glob from musl (https://www.musl-libc.org/).
3
4 MIT licensed:
5
6----------------------------------------------------------------------
7Copyright © 2005-2020 Rich Felker, et al.
8
9Permission is hereby granted, free of charge, to any person obtaining
10a copy of this software and associated documentation files (the
11"Software"), to deal in the Software without restriction, including
12without limitation the rights to use, copy, modify, merge, publish,
13distribute, sublicense, and/or sell copies of the Software, and to
14permit persons to whom the Software is furnished to do so, subject to
15the following conditions:
16
17The above copyright notice and this permission notice shall be
18included in all copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27----------------------------------------------------------------------
28*/
29#ifndef _GLOB_H
30#define _GLOB_H
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36typedef struct {
37 size_t gl_pathc;
38 char **gl_pathv;
39 size_t gl_offs;
40 int __dummy1;
41 void *__dummy2[5];
42} glob_t;
43
44int glob(const char *__restrict, int, int (*)(const char *, int), glob_t *__restrict);
45void globfree(glob_t *);
46
47#if ENABLE_PLATFORM_MINGW32
48// Set some flags to zero so the compiler can exclude unused code.
49#define GLOB_ERR 0
50#define GLOB_MARK 0
51#define GLOB_NOSORT 0x04
52#define GLOB_DOOFFS 0
53#define GLOB_NOCHECK 0x10
54#define GLOB_APPEND 0
55#define GLOB_NOESCAPE 0x40
56#define GLOB_PERIOD 0
57
58#define GLOB_TILDE 0
59#define GLOB_TILDE_CHECK 0
60#else
61#define GLOB_ERR 0x01
62#define GLOB_MARK 0x02
63#define GLOB_NOSORT 0x04
64#define GLOB_DOOFFS 0x08
65#define GLOB_NOCHECK 0x10
66#define GLOB_APPEND 0x20
67#define GLOB_NOESCAPE 0x40
68#define GLOB_PERIOD 0x80
69
70#define GLOB_TILDE 0x1000
71#define GLOB_TILDE_CHECK 0x4000
72#endif
73
74#define GLOB_NOSPACE 1
75#define GLOB_ABORTED 2
76#define GLOB_NOMATCH 3
77#define GLOB_NOSYS 4
78
79#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
80#define glob64 glob
81#define globfree64 globfree
82#define glob64_t glob_t
83#endif
84
85#ifdef __cplusplus
86}
87#endif
88
89#endif