diff options
Diffstat (limited to 'miscutils/make.c')
-rw-r--r-- | miscutils/make.c | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/miscutils/make.c b/miscutils/make.c index df810677f..bf1cfe226 100644 --- a/miscutils/make.c +++ b/miscutils/make.c | |||
@@ -386,6 +386,12 @@ error_in_inference_rule(const char *s) | |||
386 | } | 386 | } |
387 | 387 | ||
388 | static void | 388 | static void |
389 | error_not_allowed(const char *s, const char *t) | ||
390 | { | ||
391 | error("%s not allowed for %s", s, t); | ||
392 | } | ||
393 | |||
394 | static void | ||
389 | warning(const char *msg, ...) | 395 | warning(const char *msg, ...) |
390 | { | 396 | { |
391 | va_list list; | 397 | va_list list; |
@@ -1803,9 +1809,14 @@ is_suffix(const char *s) | |||
1803 | return FALSE; | 1809 | return FALSE; |
1804 | } | 1810 | } |
1805 | 1811 | ||
1806 | #define T_NORMAL 0 | 1812 | enum { |
1807 | #define T_SPECIAL 1 | 1813 | T_NORMAL = 0, |
1808 | #define T_INFERENCE 2 | 1814 | T_SPECIAL = (1 << 0), |
1815 | T_INFERENCE = (1 << 1), // Inference rule | ||
1816 | T_NOPREREQ = (1 << 2), // If set must not have prerequisites | ||
1817 | T_COMMAND = (1 << 3), // If set must have commands, if unset must not | ||
1818 | }; | ||
1819 | |||
1809 | /* | 1820 | /* |
1810 | * Determine if the argument is a special target and return a set | 1821 | * Determine if the argument is a special target and return a set |
1811 | * of flags indicating its properties. | 1822 | * of flags indicating its properties. |
@@ -1830,24 +1841,38 @@ target_type(char *s) | |||
1830 | #endif | 1841 | #endif |
1831 | ; | 1842 | ; |
1832 | 1843 | ||
1844 | static const uint8_t s_type[] = { | ||
1845 | T_SPECIAL | T_NOPREREQ | T_COMMAND, | ||
1846 | T_SPECIAL | T_NOPREREQ, | ||
1847 | T_SPECIAL, | ||
1848 | T_SPECIAL, | ||
1849 | T_SPECIAL, | ||
1850 | T_SPECIAL, | ||
1851 | T_SPECIAL, | ||
1852 | T_SPECIAL | T_NOPREREQ, | ||
1853 | T_SPECIAL, | ||
1854 | T_SPECIAL, | ||
1855 | }; | ||
1856 | |||
1833 | if (*s != '.') | 1857 | if (*s != '.') |
1834 | return T_NORMAL; | 1858 | return T_NORMAL; |
1835 | 1859 | ||
1836 | // Check for one of the known special targets | 1860 | // Check for one of the known special targets |
1837 | if (index_in_strings(s_name, s) >= 0) | 1861 | ret = index_in_strings(s_name, s); |
1838 | return T_SPECIAL; | 1862 | if (ret >= 0) |
1863 | return s_type[ret]; | ||
1839 | 1864 | ||
1840 | // Check for an inference rule | 1865 | // Check for an inference rule |
1841 | ret = T_NORMAL; | 1866 | ret = T_NORMAL; |
1842 | sfx = suffix(s); | 1867 | sfx = suffix(s); |
1843 | if (is_suffix(sfx)) { | 1868 | if (is_suffix(sfx)) { |
1844 | if (s == sfx) { // Single suffix rule | 1869 | if (s == sfx) { // Single suffix rule |
1845 | ret = T_INFERENCE; | 1870 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; |
1846 | } else { | 1871 | } else { |
1847 | // Suffix is valid, check that prefix is too | 1872 | // Suffix is valid, check that prefix is too |
1848 | *sfx = '\0'; | 1873 | *sfx = '\0'; |
1849 | if (is_suffix(s)) | 1874 | if (is_suffix(s)) |
1850 | ret = T_INFERENCE; | 1875 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; |
1851 | *sfx = '.'; | 1876 | *sfx = '.'; |
1852 | } | 1877 | } |
1853 | } | 1878 | } |
@@ -2347,12 +2372,23 @@ input(FILE *fd, int ilevel) | |||
2347 | 2372 | ||
2348 | np = newname(files[i]); | 2373 | np = newname(files[i]); |
2349 | if (ttype != T_NORMAL) { | 2374 | if (ttype != T_NORMAL) { |
2350 | if (ttype == T_INFERENCE) { | 2375 | // Enforce prerequisites/commands in POSIX mode |
2351 | if (posix) { | 2376 | if (posix) { |
2377 | if ((ttype & T_NOPREREQ) && dp) | ||
2378 | error_not_allowed("prerequisites", p); | ||
2379 | if ((ttype & T_INFERENCE)) { | ||
2352 | if (semicolon_cmd) | 2380 | if (semicolon_cmd) |
2353 | error_in_inference_rule("'; command'"); | 2381 | error_in_inference_rule("'; command'"); |
2354 | seen_inference = TRUE; | 2382 | seen_inference = TRUE; |
2355 | } | 2383 | } |
2384 | if ((ttype & T_COMMAND) && !cp && | ||
2385 | !((ttype & T_INFERENCE) && !semicolon_cmd)) | ||
2386 | error("commands required for %s", p); | ||
2387 | if (!(ttype & T_COMMAND) && cp) | ||
2388 | error_not_allowed("commands", p); | ||
2389 | } | ||
2390 | |||
2391 | if ((ttype & T_INFERENCE)) { | ||
2356 | np->n_flag |= N_INFERENCE; | 2392 | np->n_flag |= N_INFERENCE; |
2357 | } else if (strcmp(p, ".DEFAULT") == 0) { | 2393 | } else if (strcmp(p, ".DEFAULT") == 0) { |
2358 | // .DEFAULT rule is a special case | 2394 | // .DEFAULT rule is a special case |