input.c (30410B)
1 /* 2 * Parse a makefile and build the target/rule/macro graph. Ported from pdpmake 3 * input.c. The read path no longer uses FILE*: a MakeSource iterates either an 4 * in-memory makefile buffer or the built-in rules generator; included makefiles 5 * are read through KitContext.file_io; `!=` / $(shell) run through host->capture. 6 * 7 * v1 limitation: shell-glob wildcards in prerequisites/targets are not expanded 8 * (pdpmake used <glob.h>). Names are taken literally, with backslash escapes 9 * removed, which matches the non-wildcard path exactly. Part of the 10 * src/api/make.c amalgamation. 11 */ 12 #include "make.h" 13 14 #define mk_find_colon(p) strchr((p), ':') 15 16 /* Defined below; used by mk_expand_macros for the $(shell ...) function. */ 17 static char* mk_run_command(MakeCtx* mc, const char* cmd); 18 19 /* 20 * Return a pointer to the next blank-delimited word or NULL if none are left. 21 */ 22 static char* mk_gettok(char** ptr) { 23 char* p; 24 25 while (isblank((unsigned char)**ptr)) /* Skip blanks. */ 26 (*ptr)++; 27 28 if (**ptr == '\0') /* Nothing after blanks. */ 29 return NULL; 30 31 p = *ptr; /* Word starts here. */ 32 33 while (**ptr != '\0' && !isblank((unsigned char)**ptr)) 34 (*ptr)++; /* Find end of word. */ 35 36 if (**ptr != '\0') *(*ptr)++ = '\0'; 37 38 return p; 39 } 40 41 /* 42 * Skip over (possibly adjacent or nested) macro expansions. 43 */ 44 static char* mk_skip_macro(const char* s) { 45 while (*s && s[0] == '$') { 46 if (s[1] == '(' || s[1] == '{') { 47 char end = *++s == '(' ? ')' : '}'; 48 while (*s && *s != end) s = mk_skip_macro(s + 1); 49 if (*s == end) ++s; 50 } else if (s[1] != '\0') { 51 s += 2; 52 } else { 53 break; 54 } 55 } 56 return (char*)s; 57 } 58 59 /* 60 * Process each whitespace-separated word: replace paths with their directory or 61 * filename part, and replace prefixes/suffixes. Returns an arena string, or 62 * NULL if the input is unmodified. 63 */ 64 static char* mk_modify_words(MakeCtx* mc, const char* val, int modifier, 65 size_t lenf, size_t lenr, const char* find_pref, 66 const char* repl_pref, const char* find_suff, 67 const char* repl_suff) { 68 char *s, *copy, *word, *sep, *newword, *buf = NULL; 69 size_t find_pref_len = 0, find_suff_len = 0; 70 71 if (!modifier && lenf == 0 && lenr == 0) return buf; 72 73 if (find_pref) { 74 find_pref_len = strlen(find_pref); 75 find_suff_len = lenf - find_pref_len - 1; 76 } 77 78 s = copy = mk_strdup(mc, val); 79 while ((word = mk_gettok(&s)) != NULL) { 80 newword = NULL; 81 if (modifier) { 82 sep = strrchr(word, '/'); 83 if (modifier == 'D') { 84 if (!sep) { 85 word[0] = '.'; 86 sep = word + 1; 87 } else if (sep == word) { 88 sep = word + 1; 89 } 90 *sep = '\0'; 91 } else if (/* modifier == 'F' && */ sep) { 92 word = sep + 1; 93 } 94 } 95 if (find_pref != NULL || lenf != 0 || lenr != 0) { 96 size_t lenw = strlen(word); 97 /* Pattern macro expansions: <prefix>%<suffix>, e.g. src/%.c. */ 98 if (find_pref != NULL && lenw + 1 >= lenf) { 99 if (strncmp(word, find_pref, find_pref_len) == 0 && 100 strcmp(word + lenw - find_suff_len, find_suff) == 0) { 101 if (!repl_suff) { 102 word = newword = mk_strdup(mc, repl_pref); 103 } else { 104 word[lenw - find_suff_len] = '\0'; 105 word = newword = 106 mk_concat3(mc, repl_pref, word + find_pref_len, repl_suff); 107 } 108 } 109 } else if (lenw >= lenf && strcmp(word + lenw - lenf, find_suff) == 0) { 110 word[lenw - lenf] = '\0'; 111 word = newword = mk_concat3(mc, word, repl_suff, ""); 112 } 113 } 114 buf = mk_appendword(mc, buf, word); 115 } 116 return buf; 117 } 118 119 /* 120 * Return a pointer to the next instance of a character, skipping over macro 121 * expansions so ':' and '=' inside $(VAR:.s1=.s2) aren't seen as separators. 122 */ 123 static char* mk_find_char(const char* str, int c) { 124 const char* s; 125 126 for (s = mk_skip_macro(str); *s; s = mk_skip_macro(s + 1)) { 127 if (*s == c) return (char*)s; 128 } 129 return NULL; 130 } 131 132 /* 133 * Recursively expand any macros in str to an arena string. 134 */ 135 static char* mk_expand_macros(MakeCtx* mc, const char* str, int except_dollar) { 136 char *exp, *newexp, *s, *t, *p, *q, *name; 137 char *find, *replace, *modified; 138 char *expval, *expfind, *find_suff, *repl_suff; 139 char *find_pref = NULL, *repl_pref = NULL; 140 size_t lenf, lenr; 141 char modifier; 142 struct macro* mp; 143 144 exp = mk_strdup(mc, str); 145 for (t = exp; *t; t++) { 146 if (*t == '$') { 147 if (t[1] == '\0') { 148 break; 149 } 150 if (t[1] == '$' && except_dollar) { 151 t++; 152 continue; 153 } 154 /* Need to expand a macro. Find its extent (s to t inclusive) and copy. */ 155 s = t; 156 t++; 157 if (*t == '{' || *t == '(') { 158 t = mk_find_char(t, *t == '{' ? '}' : ')'); 159 if (t == NULL) mk_error(mc, "unterminated variable '%s'", s); 160 name = mk_strndup(mc, s + 2, t - s - 2); 161 } else { 162 name = mk_alloc(mc, 2); 163 name[0] = *t; 164 name[1] = '\0'; 165 } 166 167 modified = NULL; 168 /* $(shell command): a non-POSIX function; run it and substitute its 169 * stdout. Detected before the ':'/'=' parsing below, which would 170 * otherwise mangle a command containing those characters. */ 171 if (!mc->posix && strncmp(name, "shell", 5) == 0 && 172 isblank((unsigned char)name[5])) { 173 char* scmd = mk_expand_macros(mc, name + 6, FALSE); 174 modified = mk_run_command(mc, scmd); 175 goto mk_expanded; 176 } 177 178 /* Only do suffix replacement or pattern macro expansion if both ':' and 179 * '=' are found, plus a '%' for the latter. */ 180 expfind = NULL; 181 find_suff = repl_suff = NULL; 182 lenf = lenr = 0; 183 if ((find = mk_find_char(name, ':'))) { 184 *find++ = '\0'; 185 expfind = mk_expand_macros(mc, find, FALSE); 186 if ((replace = mk_find_char(expfind, '='))) { 187 *replace++ = '\0'; 188 lenf = strlen(expfind); 189 if (!POSIX_2017 && (find_suff = strchr(expfind, '%'))) { 190 find_pref = expfind; 191 repl_pref = replace; 192 *find_suff++ = '\0'; 193 if ((repl_suff = strchr(replace, '%'))) *repl_suff++ = '\0'; 194 } else { 195 if (mc->posix && !(mc->pragma & P_EMPTY_SUFFIX) && lenf == 0) 196 mk_error(mc, "empty suffix%s", 197 ": allow with pragma empty_suffix"); 198 find_suff = expfind; 199 repl_suff = replace; 200 lenr = strlen(repl_suff); 201 } 202 } 203 } 204 205 p = q = name; 206 /* If not in POSIX mode expand macros in the name. */ 207 if (!POSIX_2017) { 208 char* expname = mk_expand_macros(mc, name, FALSE); 209 name = expname; 210 } else 211 /* Skip over nested expansions in name. */ 212 do { 213 *q++ = *p; 214 } while ((p = mk_skip_macro(p + 1)) && *p); 215 216 /* The internal macros support 'D' and 'F' modifiers. */ 217 modifier = '\0'; 218 switch (name[0]) { 219 case '^': 220 case '+': 221 if (POSIX_2017) break; 222 /* fall through */ 223 case '@': 224 case '%': 225 case '?': 226 case '<': 227 case '*': 228 if ((name[1] == 'D' || name[1] == 'F') && name[2] == '\0') { 229 modifier = name[1]; 230 name[1] = '\0'; 231 } 232 break; 233 } 234 235 modified = NULL; 236 if ((mp = mk_getmp(mc, name))) { 237 /* Recursive expansion. */ 238 if (mp->m_flag) mk_error(mc, "recursive macro %s", name); 239 /* Note if we've expanded $(MAKE). */ 240 if (strcmp(name, "MAKE") == 0) mc->opts |= OPT_make; 241 mp->m_flag = TRUE; 242 /* Immediate-expansion macros aren't recursively expanded. */ 243 if (mp->m_immediate) 244 expval = mk_strdup(mc, mp->m_val); 245 else 246 expval = mk_expand_macros(mc, mp->m_val, FALSE); 247 mp->m_flag = FALSE; 248 modified = mk_modify_words(mc, expval, modifier, lenf, lenr, find_pref, 249 repl_pref, find_suff, repl_suff); 250 if (!modified) modified = expval; 251 } 252 253 mk_expanded: 254 if (modified && *modified) { 255 /* Text replaced by the expansion is s to t inclusive. */ 256 *s = '\0'; 257 newexp = mk_concat3(mc, exp, modified, t + 1); 258 t = newexp + (s - exp) + strlen(modified) - 1; 259 exp = newexp; 260 } else { 261 /* Macro wasn't expanded or expanded to nothing. Close the gap. */ 262 q = t + 1; 263 t = s - 1; 264 while ((*s++ = *q++)) continue; 265 } 266 } 267 } 268 return exp; 269 } 270 271 /* 272 * Process a non-command line: strip comment, join escaped newlines. 273 */ 274 static void mk_process_line(MakeCtx* mc, char* s) { 275 char* t; 276 277 /* Strip comment. In non-POSIX mode don't treat '#' inside a macro expansion 278 * as a comment, nor a backslash-escaped '#'. */ 279 if (!mc->posix) { 280 char* u = s; 281 while ((t = mk_find_char(u, '#')) && t > u && t[-1] == '\\') { 282 for (u = t; *u; ++u) u[-1] = u[0]; 283 *u = '\0'; 284 u = t; 285 } 286 } else 287 t = strchr(s, '#'); 288 if (t) *t = '\0'; 289 290 /* Replace escaped newline + leading whitespace on the next line with a single 291 * space. Stop at a non-escaped newline. */ 292 for (t = s; *s && *s != '\n';) { 293 if (s[0] == '\\' && s[1] == '\n') { 294 s += 2; 295 while (isspace((unsigned char)*s)) ++s; 296 *t++ = ' '; 297 } else { 298 *t++ = *s++; 299 } 300 } 301 *t = '\0'; 302 } 303 304 enum { MK_INITIAL = 0, MK_SKIP_LINE = 1 << 0, MK_EXPECT_ELSE = 1 << 1, 305 MK_GOT_MATCH = 1 << 2 }; 306 307 /* 308 * Extract strings following ifeq/ifneq and compare them. Return -1 on error. 309 */ 310 static int mk_compare_strings(MakeCtx* mc, char* arg1) { 311 char *arg2, *end, term, *t1, *t2; 312 int ret; 313 314 if (arg1[0] == '(') 315 term = ','; 316 else if (arg1[0] == '"' || arg1[0] == '\'') 317 term = arg1[0]; 318 else 319 return -1; 320 321 arg2 = mk_find_char(++arg1, term); 322 if (arg2 == NULL) return -1; 323 *arg2++ = '\0'; 324 325 if (term == ',') { 326 term = ')'; 327 } else { 328 while (isspace((unsigned char)arg2[0])) arg2++; 329 if (arg2[0] == '"' || arg2[0] == '\'') 330 term = arg2[0]; 331 else 332 return -1; 333 ++arg2; 334 } 335 336 end = mk_find_char(arg2, term); 337 if (end == NULL) return -1; 338 *end++ = '\0'; 339 340 if (mk_gettok(&end) != NULL) mk_warning(mc, "unexpected text"); 341 342 t1 = mk_expand_macros(mc, arg1, FALSE); 343 t2 = mk_expand_macros(mc, arg2, FALSE); 344 ret = strcmp(t1, t2) == 0; 345 return ret; 346 } 347 348 /* 349 * Process conditional directives; return TRUE if the current line is skipped. 350 */ 351 static int mk_skip_line(MakeCtx* mc, const char* str1) { 352 char *copy, *q, *token; 353 bool new_level = TRUE; 354 int ret = mc->cstate[mc->clevel] & MK_SKIP_LINE; 355 356 q = copy = mk_strdup(mc, str1); 357 mk_process_line(mc, copy); 358 if ((token = mk_gettok(&q)) != NULL) { 359 if (strcmp(token, "endif") == 0) { 360 if (mk_gettok(&q) != NULL) mk_error_unexpected(mc, "text"); 361 if (mc->clevel == 0) mk_error_unexpected(mc, token); 362 --mc->clevel; 363 ret = TRUE; 364 goto end; 365 } else if (strcmp(token, "else") == 0) { 366 if (!(mc->cstate[mc->clevel] & MK_EXPECT_ELSE)) 367 mk_error_unexpected(mc, token); 368 369 if ((mc->cstate[mc->clevel] & MK_GOT_MATCH)) 370 mc->cstate[mc->clevel] |= MK_SKIP_LINE; 371 else 372 mc->cstate[mc->clevel] &= ~MK_SKIP_LINE; 373 374 token = mk_gettok(&q); 375 if (token == NULL) { 376 mc->cstate[mc->clevel] &= ~MK_EXPECT_ELSE; 377 ret = TRUE; 378 goto end; 379 } else { 380 new_level = FALSE; 381 } 382 } 383 384 if (strcmp(token, "ifdef") == 0 || strcmp(token, "ifndef") == 0 || 385 strcmp(token, "ifeq") == 0 || strcmp(token, "ifneq") == 0) { 386 int match; 387 388 if (token[2] == 'd' || token[3] == 'd') { 389 char* name = mk_gettok(&q); 390 if (name != NULL && mk_gettok(&q) == NULL) { 391 char* t = mk_expand_macros(mc, name, FALSE); 392 struct macro* mp = mk_getmp(mc, t); 393 match = mp != NULL && mp->m_val[0] != '\0'; 394 } else { 395 match = -1; 396 } 397 } else { 398 match = mk_compare_strings(mc, q); 399 } 400 401 if (match >= 0) { 402 if (new_level) { 403 if (mc->clevel == MK_IF_MAX) mk_error(mc, "nesting too deep"); 404 ++mc->clevel; 405 mc->cstate[mc->clevel] = MK_EXPECT_ELSE | MK_SKIP_LINE; 406 if ((mc->cstate[mc->clevel - 1] & MK_SKIP_LINE)) 407 mc->cstate[mc->clevel] |= MK_GOT_MATCH; 408 } 409 410 if (!(mc->cstate[mc->clevel] & MK_GOT_MATCH)) { 411 if (token[2] == 'n') match = !match; 412 if (match) { 413 mc->cstate[mc->clevel] &= ~MK_SKIP_LINE; 414 mc->cstate[mc->clevel] |= MK_GOT_MATCH; 415 } 416 } 417 } else { 418 mk_error(mc, "invalid condition"); 419 } 420 ret = TRUE; 421 } else if (!new_level) { 422 mk_error(mc, "missing conditional"); 423 } 424 } 425 end: 426 return ret; 427 } 428 429 /* 430 * fgets-style reader over a MakeSource: the built-in rules (data == NULL) or an 431 * in-memory makefile buffer. 432 */ 433 static char* mk_src_fgets(MakeCtx* mc, char* s, int size, MakeSource* src) { 434 int i = 0; 435 436 if (src->data == NULL) return mk_getrules(mc, s, size); 437 if (src->pos >= src->len) return NULL; 438 while (i < size - 1 && src->pos < src->len) { 439 char c = (char)src->data[src->pos++]; 440 s[i++] = c; 441 if (c == '\n') break; 442 } 443 s[i] = '\0'; 444 return i ? s : NULL; 445 } 446 447 /* 448 * Read a newline-terminated logical line into an arena string. Backslash-escaped 449 * newlines don't terminate it; comment lines are skipped. Return NULL on EOF. 450 */ 451 static char* mk_readline(MakeCtx* mc, MakeSource* src, int want_command) { 452 char *p, *str = NULL; 453 int pos = 0; 454 int len = 0; 455 456 for (;;) { 457 if (len - pos > 1 && mk_src_fgets(mc, str + pos, len - pos, src) == NULL) { 458 if (pos) return str; 459 return NULL; /* EOF */ 460 } 461 462 if (len - pos < 2 || (p = strchr(str + pos, '\n')) == NULL) { 463 int oldlen = len; 464 if (len) pos = len - 1; 465 len += 256; 466 str = mk_realloc(mc, str, (size_t)oldlen, (size_t)len); 467 continue; 468 } 469 mc->lineno++; 470 471 if (p != str && p[-1] == '\r') { 472 p[-1] = '\n'; 473 *p-- = '\0'; 474 } 475 476 if (p != str && p[-1] == '\\') { 477 pos = p - str + 1; 478 continue; 479 } 480 mc->dispno = mc->lineno; 481 482 if (mc->posix || !mk_skip_line(mc, str)) { 483 if (want_command && *str == '\t') return str; 484 485 p = str; 486 while (isblank((unsigned char)*p)) p++; 487 488 if (*p != '\n' && (mc->posix ? *str != '#' : *p != '#')) return str; 489 } 490 491 pos = 0; 492 } 493 } 494 495 /* 496 * Return the suffix name if the argument is a known suffix, else NULL. 497 */ 498 static const char* mk_is_suffix(MakeCtx* mc, const char* s) { 499 struct name* np; 500 struct rule* rp; 501 struct depend* dp; 502 503 np = mk_newname(mc, ".SUFFIXES"); 504 for (rp = np->n_rule; rp; rp = rp->r_next) { 505 for (dp = rp->r_dep; dp; dp = dp->d_next) { 506 if (strcmp(s, dp->d_name->n_name) == 0) return dp->d_name->n_name; 507 } 508 } 509 return NULL; 510 } 511 512 /* 513 * Return TRUE if s is formed by concatenating two known suffixes. 514 */ 515 static int mk_is_inference_target(MakeCtx* mc, const char* s) { 516 struct name* np; 517 struct rule *rp1, *rp2; 518 struct depend *dp1, *dp2; 519 520 np = mk_newname(mc, ".SUFFIXES"); 521 for (rp1 = np->n_rule; rp1; rp1 = rp1->r_next) { 522 for (dp1 = rp1->r_dep; dp1; dp1 = dp1->d_next) { 523 const char* suff1 = dp1->d_name->n_name; 524 size_t len = strlen(suff1); 525 526 if (strncmp(s, suff1, len) == 0) { 527 for (rp2 = np->n_rule; rp2; rp2 = rp2->r_next) { 528 for (dp2 = rp2->r_dep; dp2; dp2 = dp2->d_next) { 529 const char* suff2 = dp2->d_name->n_name; 530 if (strcmp(s + len, suff2) == 0) return TRUE; 531 } 532 } 533 } 534 } 535 } 536 return FALSE; 537 } 538 539 enum { 540 T_NORMAL = 0, 541 T_SPECIAL = (1 << 0), 542 T_INFERENCE = (1 << 1), 543 T_NOPREREQ = (1 << 2), 544 T_COMMAND = (1 << 3), 545 }; 546 547 /* 548 * Determine if s is a special target and return flags describing it. 549 */ 550 static int mk_target_type(MakeCtx* mc, char* s) { 551 int ret; 552 static const char* s_name[] = { 553 ".DEFAULT", ".POSIX", ".IGNORE", ".PRECIOUS", 554 ".SILENT", ".SUFFIXES", ".PHONY", ".NOTPARALLEL", 555 ".WAIT", ".PRAGMA", 556 }; 557 static const uint8_t s_type[] = { 558 T_SPECIAL | T_NOPREREQ | T_COMMAND, 559 T_SPECIAL | T_NOPREREQ, 560 T_SPECIAL, 561 T_SPECIAL, 562 T_SPECIAL, 563 T_SPECIAL, 564 T_SPECIAL, 565 T_SPECIAL | T_NOPREREQ, 566 T_SPECIAL | T_NOPREREQ, 567 T_SPECIAL, 568 }; 569 570 for (ret = 0; (size_t)ret < sizeof(s_name) / sizeof(s_name[0]); ret++) 571 if (strcmp(s_name[ret], s) == 0) return s_type[ret]; 572 573 ret = T_NORMAL; 574 if (!mc->posix) { 575 if (mk_is_suffix(mc, s) || mk_is_inference_target(mc, s)) 576 ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; 577 } else { 578 /* In POSIX inference rule targets must contain one or two dots. */ 579 char* sfx = mk_suffix(s); 580 if (*s == '.' && mk_is_suffix(mc, sfx)) { 581 if (s == sfx) { 582 ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; 583 } else { 584 *sfx = '\0'; 585 if (mk_is_suffix(mc, s)) ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; 586 *sfx = '.'; 587 } 588 } 589 } 590 return ret; 591 } 592 593 static int mk_ends_with_bracket(const char* s) { 594 const char* t = strrchr(s, ')'); 595 return t && t[1] == '\0'; 596 } 597 598 /* 599 * Process a command line: strip POSIX comments, collapse escaped newlines. 600 */ 601 static char* mk_process_command(MakeCtx* mc, char* s) { 602 char *t, *u; 603 int len; 604 char* outside; 605 606 if (!(mc->pragma & P_COMMAND_COMMENT) && mc->posix) { 607 /* POSIX strips comments from command lines. */ 608 t = strchr(s, '#'); 609 if (t) { 610 *t = '\0'; 611 mk_warning(mc, 612 "comment in command removed: keep with pragma command_comment"); 613 } 614 } 615 616 len = (int)strlen(s) + 1; 617 outside = mk_alloc(mc, (size_t)len); 618 memset(outside, 0, (size_t)len); 619 for (t = mk_skip_macro(s); *t; t = mk_skip_macro(t + 1)) outside[t - s] = 1; 620 621 /* Process escaped newlines. Stop at first non-escaped newline. */ 622 for (t = u = s; *u && *u != '\n';) { 623 if (u[0] == '\\' && u[1] == '\n') { 624 if (POSIX_2017 || outside[u - s]) { 625 /* Outside macro: remove tab following escaped newline. */ 626 *t++ = *u++; 627 *t++ = *u++; 628 u += (*u == '\t'); 629 } else { 630 /* Inside macro: replace escaped newline + leading whitespace with a 631 * single space. */ 632 u += 2; 633 while (isspace((unsigned char)*u)) ++u; 634 *t++ = ' '; 635 } 636 } else { 637 *t++ = *u++; 638 } 639 } 640 *t = '\0'; 641 return s; 642 } 643 644 /* 645 * Run a command and capture its stdout for `!=` / $(shell). Returns an arena 646 * string or NULL. 647 */ 648 static char* mk_run_command(MakeCtx* mc, const char* cmd) { 649 uint8_t* out = NULL; 650 size_t out_len = 0; 651 int status = 0; 652 char* val; 653 char* s; 654 size_t len; 655 const KitExec* ex = mc->host->exec; 656 KitExecProc* proc = NULL; 657 KitSlice av[3]; 658 KitExecOpts eo; 659 660 av[0] = kit_slice_cstr(mc->shell); 661 av[1] = KIT_SLICE_LIT("-c"); 662 av[2] = kit_slice_cstr(cmd); 663 memset(&eo, 0, sizeof eo); 664 eo.argv = av; 665 eo.argc = 3; 666 eo.env = mc->env; 667 eo.nenv = mc->nenv; 668 eo.cwd = mc->root ? kit_slice_cstr(mc->root) : KIT_SLICE_NULL; 669 eo.search_path = 1; 670 eo.capture_stdout = 1; 671 if (ex->spawn(ex->user, &eo, &proc) != 0) return NULL; 672 /* Like pdpmake's run_command, use the captured output regardless of status. */ 673 (void)ex->wait(ex->user, proc, &status, &out, &out_len); 674 if (out == NULL || out_len == 0) { 675 if (out) mc->ctx->heap->free(mc->ctx->heap, out, out_len); 676 return NULL; 677 } 678 679 val = mk_alloc(mc, out_len + 1); 680 memcpy(val, out, out_len); 681 val[out_len] = '\0'; 682 len = out_len; 683 mc->ctx->heap->free(mc->ctx->heap, out, out_len); 684 685 /* Strip leading whitespace in POSIX mode. */ 686 if (mc->posix) { 687 s = val; 688 while (isspace((unsigned char)*s)) { 689 ++s; 690 --len; 691 } 692 if (len == 0) return NULL; 693 memmove(val, s, len + 1); 694 } 695 696 /* Remove one trailing newline (BSD compatibility); others become spaces. */ 697 if (val[len - 1] == '\n') val[len - 1] = '\0'; 698 for (s = val; *s; ++s) { 699 if (*s == '\n') *s = ' '; 700 } 701 return val; 702 } 703 704 /* 705 * Remove backslash escapes from a name (the non-wildcard path of pdpmake's 706 * wildcard()); v1 does not expand shell globs. 707 */ 708 static void mk_deglob(char* p) { 709 char* s; 710 for (s = p; *p; ++p) { 711 if (*p == '\\' && p[1] != '\0') continue; 712 *s++ = *p; 713 } 714 *s = '\0'; 715 } 716 717 /* 718 * Determine if a line is a target rule with an inline command; return a pointer 719 * to the semicolon separator if so, else NULL. 720 */ 721 static char* mk_inline_command(char* line) { 722 char* p = mk_find_char(line, ':'); 723 if (p) p = strchr(p, ';'); 724 return p; 725 } 726 727 /* 728 * Parse input from a makefile source and construct the tree structure. 729 */ 730 static void mk_input(MakeCtx* mc, MakeSource* src, int ilevel) { 731 char *p, *q, *s, *a, *str, *expanded, *copy; 732 char *str1, *str2; 733 struct name* np; 734 struct depend* dp; 735 struct cmd* cp; 736 int startno, count; 737 bool semicolon_cmd, seen_inference; 738 uint8_t old_clevel = mc->clevel; 739 bool dbl; 740 char* lib = NULL; 741 int nfile, i; 742 char** files; 743 bool minus; 744 745 mc->lineno = 0; 746 str1 = mk_readline(mc, src, FALSE); 747 while (str1) { 748 str2 = NULL; 749 750 /* Take a copy before non-command processing in case this is a rule with an 751 * inline command (target: prereq; command). */ 752 copy = mk_strdup(mc, str1); 753 mk_process_line(mc, str1); 754 str = str1; 755 756 /* Check for an include line. */ 757 if (!mc->posix) 758 while (isblank((unsigned char)*str)) ++str; 759 minus = !POSIX_2017 && *str == '-'; 760 p = str + minus; 761 if (strncmp(p, "include", 7) == 0 && isblank((unsigned char)p[7])) { 762 const char* old_makefile = mc->makefile; 763 int old_lineno = mc->lineno; 764 765 if (ilevel > 16) mk_error(mc, "too many includes"); 766 767 count = 0; 768 q = expanded = mk_expand_macros(mc, p + 7, FALSE); 769 while ((p = mk_gettok(&q)) != NULL) { 770 KitFileData ifd; 771 772 ++count; 773 if (!POSIX_2017) { 774 /* Try to create the include file or bring it up-to-date. */ 775 mc->opts |= OPT_include; 776 mk_make(mc, mk_newname(mc, p), 1); 777 mc->opts &= ~OPT_include; 778 } 779 ifd.data = NULL; 780 ifd.size = 0; 781 ifd.token = NULL; 782 if (!mc->ctx->file_io || 783 mc->ctx->file_io->read_all(mc->ctx->file_io->user, mk_path(mc, p), 784 &ifd) != KIT_OK) { 785 if (!minus) mk_error(mc, "can't open include file '%s'", p); 786 } else { 787 MakeSource subsrc = {(const char*)ifd.data, ifd.size, 0}; 788 mc->makefile = p; 789 mk_input(mc, &subsrc, ilevel + 1); 790 if (mc->ctx->file_io->release) 791 mc->ctx->file_io->release(mc->ctx->file_io->user, &ifd); 792 mc->makefile = old_makefile; 793 mc->lineno = old_lineno; 794 } 795 if (POSIX_2017) break; 796 } 797 if (POSIX_2017) { 798 if (p == NULL || mk_gettok(&q)) mk_error(mc, "one include file per line"); 799 } else if (count == 0) { 800 if (mc->posix) mk_error(mc, "no include file"); 801 } 802 goto end_loop; 803 } 804 805 /* Check for a macro definition. */ 806 str = str1; 807 if (POSIX_2017 && *str == '\t') mk_error(mc, "command not allowed here"); 808 if (mk_find_char(str, '=') != NULL) { 809 int level = (useenv || src->data == NULL) ? 4 : 3; 810 char* copy2 = mk_strdup(mc, str); 811 char* newq = NULL; 812 char eq = '\0'; 813 q = mk_find_char(copy2, '='); /* q can't be NULL */ 814 815 if (q - 1 > copy2) { 816 switch (q[-1]) { 817 case ':': 818 /* '::=' and ':::=' are from POSIX 2024. */ 819 if (!POSIX_2017 && q - 2 > copy2 && q[-2] == ':') { 820 if (q - 3 > copy2 && q[-3] == ':') { 821 eq = 'B'; /* BSD-style ':=' */ 822 q[-3] = '\0'; 823 } else { 824 eq = ':'; /* GNU-style ':=' */ 825 q[-2] = '\0'; 826 } 827 break; 828 } 829 /* ':=' is a non-POSIX extension. */ 830 if (mc->posix) break; 831 goto set_eq; 832 case '+': 833 case '?': 834 case '!': 835 /* '+=', '?=' and '!=' are from POSIX 2024. */ 836 if (POSIX_2017) break; 837 set_eq: 838 eq = q[-1]; 839 q[-1] = '\0'; 840 break; 841 } 842 } 843 *q++ = '\0'; /* Separate name and value. */ 844 while (isblank((unsigned char)*q)) q++; 845 if ((p = strrchr(q, '\n')) != NULL) *p = '\0'; 846 847 /* Expand LHS of the assignment. */ 848 p = expanded = mk_expand_macros(mc, copy2, FALSE); 849 if ((a = mk_gettok(&p)) == NULL) mk_error(mc, "invalid macro assignment"); 850 851 /* If the expanded LHS contains ':' and ';' it might be a target rule. */ 852 if ((s = strchr(a, ':')) != NULL && strchr(s, ';') != NULL) { 853 goto try_target; 854 } 855 856 if (mk_gettok(&p)) mk_error(mc, "invalid macro assignment"); 857 858 if (eq == ':') { 859 /* GNU-style ':='. Expand RHS; immediate-expansion macro. */ 860 q = newq = mk_expand_macros(mc, q, FALSE); 861 level |= M_IMMEDIATE; 862 } else if (eq == 'B') { 863 /* BSD-style ':='. Expand RHS but not '$$'; delayed-expansion. */ 864 q = newq = mk_expand_macros(mc, q, TRUE); 865 } else if (eq == '?' && mk_getmp(mc, a) != NULL) { 866 goto end_loop; /* Skip; macro already set. */ 867 } else if (eq == '+') { 868 /* Append to current value. */ 869 struct macro* mp = mk_getmp(mc, a); 870 char* rhs; 871 newq = mp && mp->m_val[0] ? mk_strdup(mc, mp->m_val) : NULL; 872 if (mp && mp->m_immediate) { 873 rhs = mk_expand_macros(mc, q, FALSE); 874 level |= M_IMMEDIATE; 875 } else { 876 rhs = q; 877 } 878 newq = mk_appendword(mc, newq, rhs); 879 q = newq; 880 } else if (eq == '!') { 881 char* cmd = mk_expand_macros(mc, q, FALSE); 882 q = newq = mk_run_command(mc, cmd); 883 } 884 mk_setmacro(mc, a, q, level); 885 (void)newq; 886 goto end_loop; 887 } 888 889 /* If we get here it must be a target rule. */ 890 try_target: 891 if (*str == '\t') /* Command without target. */ 892 mk_error(mc, "command not allowed here"); 893 p = expanded = mk_expand_macros(mc, str, FALSE); 894 895 /* Look for colon separator. */ 896 q = mk_find_colon(p); 897 if (q == NULL) mk_error(mc, "expected separator"); 898 899 *q++ = '\0'; /* Separate targets and prerequisites. */ 900 901 /* Double colon. */ 902 dbl = !mc->posix && *q == ':'; 903 if (dbl) q++; 904 905 /* Look for semicolon separator. */ 906 cp = NULL; 907 s = strchr(q, ';'); 908 if (s) { 909 /* Retrieve command from the original or expanded copy of the line. */ 910 char* copy3 = mk_expand_macros(mc, copy, FALSE); 911 if ((p = mk_inline_command(copy)) || (p = mk_inline_command(copy3))) 912 cp = mk_newcmd(mc, mk_process_command(mc, p + 1), cp); 913 *s = '\0'; 914 } 915 semicolon_cmd = cp != NULL && cp->c_cmd[0] != '\0'; 916 917 /* Create list of prerequisites. */ 918 dp = NULL; 919 while (((p = mk_gettok(&q)) != NULL)) { 920 char* newp = NULL; 921 922 if (!mc->posix) { 923 /* Allow prerequisites of form library(member1 member2). */ 924 if (!lib) { 925 s = strchr(p, '('); 926 if (s && !mk_ends_with_bracket(s) && strchr(q, ')')) { 927 lib = p; 928 if (s[1] != '\0') { 929 p = newp = mk_concat3(mc, lib, ")", ""); 930 s[1] = '\0'; 931 } else { 932 continue; 933 } 934 } 935 } else if (mk_ends_with_bracket(p)) { 936 if (*p != ')') p = newp = mk_concat3(mc, lib, p, ""); 937 lib = NULL; 938 if (newp == NULL) continue; 939 } else { 940 p = newp = mk_concat3(mc, lib, p, ")"); 941 } 942 } 943 944 /* v1: names are literal (no glob); strip backslash escapes. */ 945 nfile = 1; 946 files = &p; 947 if (!mc->posix) mk_deglob(p); 948 for (i = 0; i < nfile; ++i) { 949 if (!POSIX_2017 && strcmp(files[i], ".WAIT") == 0) continue; 950 np = mk_newname(mc, files[i]); 951 dp = mk_newdep(mc, np, dp); 952 } 953 } 954 lib = NULL; 955 956 /* Create list of commands. */ 957 startno = mc->dispno; 958 while ((str2 = mk_readline(mc, src, TRUE)) && *str2 == '\t') { 959 cp = mk_newcmd(mc, mk_process_command(mc, str2), cp); 960 } 961 mc->dispno = startno; 962 963 /* Create target names and attach the rule to them. */ 964 q = expanded; 965 count = 0; 966 seen_inference = FALSE; 967 while ((p = mk_gettok(&q)) != NULL) { 968 nfile = 1; 969 files = &p; 970 if (!mc->posix) mk_deglob(p); 971 for (i = 0; i < nfile; ++i) 972 #define p files[i] 973 { 974 int ttype = mk_target_type(mc, p); 975 976 np = mk_newname(mc, p); 977 if (ttype != T_NORMAL) { 978 /* Enforce prerequisites/commands. */ 979 if ((ttype & T_NOPREREQ) && dp) mk_error_not_allowed(mc, 980 "prerequisites", 981 p); 982 if ((ttype & T_INFERENCE)) { 983 if (semicolon_cmd) mk_error_in_inference_rule(mc, "'; command'"); 984 seen_inference = TRUE; 985 } 986 if ((ttype & T_COMMAND) && !cp && 987 !((ttype & T_INFERENCE) && !semicolon_cmd)) 988 mk_error(mc, "commands required for %s", p); 989 if (!(ttype & T_COMMAND) && cp) mk_error_not_allowed(mc, "commands", 990 p); 991 992 if ((ttype & T_INFERENCE)) { 993 np->n_flag |= N_INFERENCE; 994 } else if (strcmp(p, ".DEFAULT") == 0) { 995 np->n_flag |= N_SPECIAL | N_INFERENCE; 996 } else { 997 np->n_flag |= N_SPECIAL; 998 } 999 } else if (!mc->firstname) { 1000 mc->firstname = np; 1001 } 1002 mk_addrule(mc, np, dp, cp, dbl); 1003 count++; 1004 } 1005 #undef p 1006 } 1007 if (seen_inference && count != 1) 1008 mk_error_in_inference_rule(mc, "multiple targets"); 1009 1010 /* Prerequisites/commands are unused if there were no targets. */ 1011 if (count == 0) { 1012 (void)dp; 1013 (void)cp; 1014 } 1015 1016 end_loop: 1017 mc->dispno = mc->lineno; 1018 str1 = str2 ? str2 : mk_readline(mc, src, FALSE); 1019 (void)copy; 1020 (void)expanded; 1021 if (!mc->seen_first && src->data) { 1022 if (mk_findname(mc, ".POSIX")) { 1023 /* The first non-comment line defined .POSIX. */ 1024 mc->posix = TRUE; 1025 } 1026 mc->seen_first = TRUE; 1027 } 1028 } 1029 /* Conditionals aren't allowed to span files. */ 1030 if (mc->clevel != old_clevel) mk_error(mc, "invalid conditional"); 1031 }