aboutsummaryrefslogtreecommitdiff
path: root/miscutils/make.c
diff options
context:
space:
mode:
Diffstat (limited to 'miscutils/make.c')
-rw-r--r--miscutils/make.c54
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
388static void 388static void
389error_not_allowed(const char *s, const char *t)
390{
391 error("%s not allowed for %s", s, t);
392}
393
394static void
389warning(const char *msg, ...) 395warning(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 1812enum {
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