Print this page
make: unifdef for SUNOS4_AND_AFTER (defined)


  77  *      cd $(DIR); $(MAKE)
  78  * where DIR is imported from the shell environment.
  79  * However it well not find:
  80  *      CD = cd
  81  *              $(CD) $(DIR); $(MAKE)
  82  * or
  83  *      CD = cd $(DIR)
  84  *              $(CD); $(MAKE)
  85  *
  86  * This routine also checks for recursion to the same
  87  * directory.
  88  */
  89 void
  90 nse_check_cd(Property prop)
  91 {
  92         wchar_t         tok[512];
  93         wchar_t         *p;
  94         wchar_t         *our_template;
  95         int             len;
  96         Boolean         cd;
  97 #ifdef SUNOS4_AND_AFTER
  98         String_rec      string;
  99 #else
 100         String          string;
 101 #endif
 102         Name            name;
 103         Name            target;
 104         struct  Line    *line;
 105         struct  Recursive *r;
 106         Property        recurse;
 107         wchar_t         strbuf[STRING_BUFFER_LENGTH];
 108         wchar_t         tmpbuf[STRING_BUFFER_LENGTH];
 109 
 110 #ifdef LTEST
 111         printf("In nse_check_cd, nse = %d, nse_did_recursion = %d\n", nse, nse_did_recursion);
 112 #endif
 113 #ifdef SUNOS4_AND_AFTER
 114         if (!nse_did_recursion || !nse) {
 115 #else
 116         if (is_false(nse_did_recursion) || is_false(flag.nse)) {
 117 #endif
 118 #ifdef LTEST
 119                 printf ("returning,  nse = %d,  nse_did_recursion = %d\n", nse, nse_did_recursion);
 120 #endif
 121                 return;
 122         }
 123         line = &prop->body.line;
 124 #ifdef LTEST
 125         printf("string = %s\n", line->command_template->command_line->string_mb);
 126 #endif
 127 
 128         wscpy(tmpbuf, line->command_template->command_line->string);
 129         our_template = tmpbuf;
 130         cd = false;
 131         while (nse_gettoken(&our_template, tok)) {
 132 #ifdef LTEST
 133                 printf("in gettoken loop\n");
 134 #endif
 135 #ifdef SUNOS4_AND_AFTER
 136                 if (IS_WEQUAL(tok, (wchar_t *) "cd")) {
 137 #else
 138                 if (is_equal(tok, "cd")) {
 139 #endif
 140                         cd = true;
 141                 } else if (cd && tok[0] == '$') {
 142                         nse_backquote_seen = NULL;
 143                         nse_shell_var_used = NULL;
 144                         nse_watch_vars = true;
 145 #ifdef SUNOS4_AND_AFTER
 146                         INIT_STRING_FROM_STACK(string, strbuf);
 147                         name = GETNAME(tok, FIND_LENGTH);
 148 #else
 149                         init_string_from_stack(string, strbuf);
 150                         name = getname(tok, FIND_LENGTH);
 151 #endif
 152                         expand_value(name, &string, false);
 153                         nse_watch_vars = false;
 154 
 155 #ifdef LTEST
 156                         printf("cd = %d, tok = $\n", cd);
 157 #endif
 158                         /*
 159                          * Try to trim tok to just
 160                          * the variable.
 161                          */
 162                         if (nse_shell_var_used != NULL) {
 163                                 nse_warning();
 164                                 fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tdefined by the shell environment variable %s\n\tCommand line: %s\n",
 165                                     nse_shell_var_used->string_mb,
 166                                     line->command_template->command_line->string_mb);
 167                         }
 168                         if (nse_backquote_seen != NULL) {
 169                                 nse_warning();
 170                                 fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tdefined by a variable (%s) with backquotes in it\n\tCommand line: %s\n",
 171                                     nse_backquote_seen->string_mb,


 173                         }
 174                         cd = false;
 175                 } else if (cd && nse_backquotes(tok)) {
 176                         nse_warning();
 177                         fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tspecified by a command in backquotes\n\tCommand line: %s\n",
 178                             line->command_template->command_line->string_mb);
 179                         cd = false;
 180                 } else {
 181                         cd = false;
 182                 }
 183         }
 184 
 185         /*
 186          * Now check for recursion to ".".
 187          */
 188         if (primary_makefile != NULL) {
 189                 target = prop->body.line.target;
 190                 recurse = get_prop(target->prop, recursive_prop);
 191                 while (recurse != NULL) {
 192                         r = &recurse->body.recursive;
 193 #ifdef SUNOS4_AND_AFTER
 194                         if (IS_WEQUAL(r->directory->string, (wchar_t *) ".") &&
 195                             !IS_WEQUAL(r->makefiles->name->string, 
 196                             primary_makefile->string)) {
 197 #else
 198                         if (is_equal(r->directory->string, ".") &&
 199                             !is_equal(r->makefiles->name->string, 
 200                             primary_makefile->string)) {
 201 #endif
 202                                 nse_warning();
 203                                 fprintf(stderr, "\tRecursion to makefile `%s' in the same directory\n\tCommand line: %s\n",
 204                                     r->makefiles->name->string_mb,
 205                                     line->command_template->command_line->string_mb);
 206                         }
 207                         recurse = get_prop(recurse->next, recursive_prop);
 208                 }
 209         }
 210 }
 211 
 212 /*
 213  * Print an NSE make warning line.
 214  * If the -P flag was given then consider this a fatal
 215  * error, otherwise, just a warning.
 216  */
 217 static void
 218 nse_warning(void)
 219 {
 220 #ifdef SUNOS4_AND_AFTER
 221         if (report_dependencies_level > 0) {
 222 #else
 223         if (is_true(flag.report_dependencies)) {
 224 #endif
 225                 our_exit_status = 1;
 226         }
 227         if (primary_makefile != NULL) {
 228                 fprintf(stderr, "make: NSE warning from makefile %s/%s:\n",
 229                         get_current_path(), primary_makefile->string_mb);
 230         } else {
 231                 fprintf(stderr, "make: NSE warning from directory %s:\n",
 232                         get_current_path());
 233         }
 234 }
 235 
 236 /*
 237  * Get the next whitespace delimited token pointed to by *cp.
 238  * Return it in tok.
 239  */
 240 static Boolean
 241 nse_gettoken(wchar_t **cp, wchar_t *tok)
 242 {
 243         wchar_t         *to;
 244         wchar_t         *p;


 258                 return false;
 259         }
 260         *to = '\0';
 261         *cp = p;
 262         return true;
 263 }
 264 
 265 /*
 266  * Given a dependency and a target, see if the dependency
 267  * is an SCCS file.  Check for the last component of its name
 268  * beginning with "s." and the component before that being "SCCS".
 269  * The NSE does not consider a source file to be derived from
 270  * an SCCS file.
 271  */
 272 void
 273 nse_check_sccs(wchar_t *targ, wchar_t *dep)
 274 {
 275         wchar_t         *slash;
 276         wchar_t         *p;
 277 
 278 #ifdef SUNOS4_AND_AFTER
 279         if (!nse) {
 280 #else
 281         if (is_false(flag.nse)) {
 282 #endif
 283                 return;
 284         }
 285 #ifdef SUNOS4_AND_AFTER
 286         slash = wsrchr(dep, (int) slash_char); 
 287 #else
 288         slash = rindex(dep, '/');
 289 #endif
 290         if (slash == NULL) {
 291                 return;
 292         }
 293         if (slash[1] != 's' || slash[2] != '.') {
 294                 return;
 295         }
 296 
 297         /*
 298          * Find the next to last filename component.
 299          */
 300         for (p = slash - 1; p >= dep; p--) {
 301                 if (*p == '/') {
 302                         break;
 303                 }
 304         }
 305         p++;
 306 #ifdef SUNOS4_AND_AFTER
 307         MBSTOWCS(wcs_buffer, "SCCS/");
 308         if (IS_WEQUALN(p, wcs_buffer, wslen(wcs_buffer))) {
 309 #else
 310         if (is_equaln(p, "SCCS/", 5)) {
 311 #endif
 312                 nse_warning();
 313                 WCSTOMBS(mbs_buffer, targ);
 314                 WCSTOMBS(mbs_buffer2, dep);
 315                 fprintf(stderr, "\tFile `%s' depends upon SCCS file `%s'\n",
 316                         mbs_buffer, mbs_buffer2);
 317         }
 318         return;
 319 }
 320 
 321 /*
 322  * Given a filename check to see if it has 2 backquotes in it.
 323  * Complain about this because the shell expands the backquotes
 324  * but make does not so the files always appear to be out of date.
 325  */
 326 void
 327 nse_check_file_backquotes(wchar_t *file)
 328 {
 329 #ifdef SUNOS4_AND_AFTER
 330         if (!nse) {
 331 #else
 332         if (is_false(flag.nse)) {
 333 #endif
 334                 return;
 335         }
 336         if (nse_backquotes(file)) {
 337                 nse_warning();
 338                 WCSTOMBS(mbs_buffer, file);
 339                 fprintf(stderr, "\tFilename \"%s\" has backquotes in it\n",
 340                         mbs_buffer);
 341         }
 342 }
 343 
 344 /*
 345  * Return true if the string has two backquotes in it.
 346  */
 347 Boolean
 348 nse_backquotes(wchar_t *str)
 349 {
 350         wchar_t         *bq;
 351 
 352 #ifdef SUNOS4_AND_AFTER
 353         bq = wschr(str, (int) backquote_char);
 354         if (bq) {
 355                 bq = wschr(&bq[1], (int) backquote_char);
 356 #else
 357         bq = index(str, '`');
 358         if (bq) {
 359                 bq = index(&bq[1], '`');
 360 #endif
 361                 if (bq) {
 362                         return true;
 363                 }
 364         }
 365         return false;
 366 }
 367 
 368 /*
 369  * A macro that was defined on the command-line was found to affect the
 370  * set of dependencies.  The NSE "target explode" will not know about
 371  * this and will not get the same set of dependencies.
 372  */
 373 void
 374 nse_dep_cmdmacro(wchar_t *macro)
 375 {
 376 #ifdef SUNOS4_AND_AFTER
 377         if (!nse) {
 378 #else
 379         if (is_false(flag.nse)) {
 380 #endif
 381                 return;
 382         }
 383         nse_warning();
 384         WCSTOMBS(mbs_buffer, macro);
 385         fprintf(stderr, "\tVariable `%s' is defined on the command-line and\n\taffects dependencies\n",
 386                 mbs_buffer);
 387 }
 388 
 389 /*
 390  * A macro that was defined on the command-line was found to
 391  * be part of the argument to a cd before a recursive make.
 392  * This make cause the make to recurse to different places
 393  * depending upon how it is invoked.
 394  */
 395 void
 396 nse_rule_cmdmacro(wchar_t *macro)
 397 {
 398 #ifdef SUNOS4_AND_AFTER
 399         if (!nse) {
 400 #else
 401         if (is_false(flag.nse)) {
 402 #endif
 403                 return;
 404         }
 405         nse_warning();
 406         WCSTOMBS(mbs_buffer, macro);
 407         fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tspecified by a variable (%s) defined on the command-line\n",
 408                 mbs_buffer);
 409 }
 410 
 411 /*
 412  * A dependency has been found with a wildcard in it.
 413  * This causes the NSE problems because the set of dependencies
 414  * can change without changing the Makefile.
 415  */
 416 void
 417 nse_wildcard(wchar_t *targ, wchar_t *dep)
 418 {
 419 #ifdef SUNOS4_AND_AFTER
 420         if (!nse) {
 421 #else
 422         if (is_false(flag.nse)) {
 423 #endif
 424                 return;
 425         }
 426         nse_warning();
 427         WCSTOMBS(mbs_buffer, targ);
 428         WCSTOMBS(mbs_buffer2, dep);
 429         fprintf(stderr, "\tFile `%s' has a wildcard in dependency `%s'\n",
 430                 mbs_buffer, mbs_buffer2);
 431 }
 432 
 433 /*
 434  * Read in the list of suffixes that are interpreted as source
 435  * files.
 436  */
 437 void
 438 nse_init_source_suffixes(void)
 439 {
 440         FILE            *fp;
 441         wchar_t         suffix[100];
 442         Nse_suffix      sufx;
 443         Nse_suffix      *bpatch;
 444 
 445         fp = fopen(TARG_SUFX, "r");
 446         if (fp == NULL) {
 447                 return;
 448         }
 449         bpatch = &sufx_hdr;
 450         while (fscanf(fp, "%s %*s", suffix) == 1) {
 451 #ifdef SUNOS4_AND_AFTER
 452                 sufx = ALLOC(Nse_suffix);  
 453                 sufx->suffix = wscpy(ALLOC_WC(wslen(suffix) + 1), suffix);
 454 #else
 455                 sufx = alloc(Nse_suffix);
 456                 sufx->suffix = strcpy(malloc(strlen(suffix) + 1), suffix);
 457 #endif
 458                 sufx->next = NULL;
 459                 *bpatch = sufx;
 460                 bpatch = &sufx->next;
 461         }
 462         fclose(fp);
 463 }
 464 
 465 /*
 466  * Check if a derived file (something with a dependency) appears
 467  * to be a source file (by its suffix) but has no rule to build it.
 468  * If so, complain.
 469  *
 470  * This generally arises from the old-style of make-depend that
 471  * produces:
 472  *      foo.c:  foo.h
 473  */
 474 void
 475 nse_check_derived_src(Name target, wchar_t *dep, Cmd_line command_template)
 476 {
 477         Nse_suffix      sufx;
 478         wchar_t         *suffix;
 479         wchar_t         *depsufx;
 480 
 481 #ifdef SUNOS4_AND_AFTER
 482         if (!nse) {
 483 #else
 484         if (is_false(flag.nse)) {
 485 #endif
 486                 return;
 487         }
 488 #ifdef SUNOS4_AND_AFTER
 489         if (target->stat.is_derived_src) {
 490 #else
 491         if (is_true(target->stat.is_derived_src)) {
 492 #endif
 493                 return;
 494         }
 495         if (command_template != NULL) {
 496                 return;
 497         }
 498 #ifdef SUNOS4_AND_AFTER
 499         suffix = wsrchr(target->string, (int) period_char ); 
 500 #else
 501         suffix = rindex(target->string, '.');
 502 #endif
 503         if (suffix != NULL) {
 504                 for (sufx = sufx_hdr; sufx != NULL; sufx = sufx->next) {
 505 #ifdef SUNOS4_AND_AFTER
 506                         if (IS_WEQUAL(sufx->suffix, suffix)) {
 507 #else
 508                         if (is_equal(sufx->suffix, suffix)) {
 509 #endif
 510                                 nse_warning();
 511                                 WCSTOMBS(mbs_buffer, dep);
 512                                 fprintf(stderr, "\tProbable source file `%s' appears as a derived file\n\tas it depends upon file `%s', but there is\n\tno rule to build it\n",
 513                                         target->string_mb, mbs_buffer);
 514                                 break;
 515                         }
 516                 }
 517         }
 518 }
 519 
 520 /*
 521  * See if a target is a potential source file and has no
 522  * dependencies and no rule but shows up on the right-hand
 523  * side.  This tends to occur from old "make depend" output.
 524  */
 525 void
 526 nse_check_no_deps_no_rule(Name target, Property line, Property command)
 527 {
 528         Nse_suffix      sufx;
 529         wchar_t         *suffix;
 530 
 531 #ifdef SUNOS4_AND_AFTER
 532         if (!nse) {
 533 #else
 534         if (is_false(flag.nse)) {
 535 #endif
 536                 return;
 537         }
 538 #ifdef SUNOS4_AND_AFTER
 539         if (target->stat.is_derived_src) {
 540 #else
 541         if (is_true(target->stat.is_derived_src)) {
 542 #endif
 543                 return;
 544         }
 545         if (line != NULL && line->body.line.dependencies != NULL) {
 546                 return;
 547         }
 548 #ifdef SUNOS4_AND_AFTER
 549         if (command->body.line.sccs_command) {
 550 #else
 551         if (is_true(command->body.line.sccs_command)) {
 552 #endif
 553                 return;
 554         }
 555 #ifdef SUNOS4_AND_AFTER
 556         suffix = wsrchr(target->string, (int) period_char); 
 557 #else
 558         suffix = rindex(target->string, '.');
 559 #endif
 560         if (suffix != NULL) {
 561                 for (sufx = sufx_hdr; sufx != NULL; sufx = sufx->next) {
 562 #ifdef SUNOS4_AND_AFTER
 563                         if (IS_WEQUAL(sufx->suffix, suffix)) {
 564 #else
 565                         if (is_equal(sufx->suffix, suffix)) {
 566 #endif
 567                                 if (command->body.line.command_template == NULL) {
 568                                         nse_warning();
 569                                         fprintf(stderr, "\tProbable source file `%s' appears as a derived file because\n\tit is on the left-hand side, but it has no dependencies and\n\tno rule to build it\n",
 570                                                 target->string_mb);
 571                                 }
 572                         }
 573                 }
 574         } 
 575 } 
 576 
 577 /*
 578  * Detected a situation where a recursive make derived a file
 579  * without using a makefile.
 580  */
 581 void
 582 nse_no_makefile(Name target)
 583 {
 584 #ifdef SUNOS4_AND_AFTER
 585         if (!nse) {
 586 #else
 587         if (is_false(flag.nse)) {
 588 #endif
 589                 return;
 590         }
 591         nse_warning();
 592         fprintf(stderr, "Recursive make to derive %s did not use a makefile\n",
 593                 target->string_mb);
 594 }
 595 
 596 /*
 597  * Return the NSE exit status.
 598  * If the -P flag was given then a warning is considered fatal
 599  */
 600 int
 601 nse_exit_status(void)
 602 {
 603         return our_exit_status;
 604 }
 605 #endif


  77  *      cd $(DIR); $(MAKE)
  78  * where DIR is imported from the shell environment.
  79  * However it well not find:
  80  *      CD = cd
  81  *              $(CD) $(DIR); $(MAKE)
  82  * or
  83  *      CD = cd $(DIR)
  84  *              $(CD); $(MAKE)
  85  *
  86  * This routine also checks for recursion to the same
  87  * directory.
  88  */
  89 void
  90 nse_check_cd(Property prop)
  91 {
  92         wchar_t         tok[512];
  93         wchar_t         *p;
  94         wchar_t         *our_template;
  95         int             len;
  96         Boolean         cd;

  97         String_rec      string;



  98         Name            name;
  99         Name            target;
 100         struct  Line    *line;
 101         struct  Recursive *r;
 102         Property        recurse;
 103         wchar_t         strbuf[STRING_BUFFER_LENGTH];
 104         wchar_t         tmpbuf[STRING_BUFFER_LENGTH];
 105 
 106 #ifdef LTEST
 107         printf("In nse_check_cd, nse = %d, nse_did_recursion = %d\n", nse, nse_did_recursion);
 108 #endif

 109         if (!nse_did_recursion || !nse) {



 110 #ifdef LTEST
 111                 printf ("returning,  nse = %d,  nse_did_recursion = %d\n", nse, nse_did_recursion);
 112 #endif
 113                 return;
 114         }
 115         line = &prop->body.line;
 116 #ifdef LTEST
 117         printf("string = %s\n", line->command_template->command_line->string_mb);
 118 #endif
 119 
 120         wscpy(tmpbuf, line->command_template->command_line->string);
 121         our_template = tmpbuf;
 122         cd = false;
 123         while (nse_gettoken(&our_template, tok)) {
 124 #ifdef LTEST
 125                 printf("in gettoken loop\n");
 126 #endif

 127                 if (IS_WEQUAL(tok, (wchar_t *) "cd")) {



 128                         cd = true;
 129                 } else if (cd && tok[0] == '$') {
 130                         nse_backquote_seen = NULL;
 131                         nse_shell_var_used = NULL;
 132                         nse_watch_vars = true;

 133                         INIT_STRING_FROM_STACK(string, strbuf);
 134                         name = GETNAME(tok, FIND_LENGTH);




 135                         expand_value(name, &string, false);
 136                         nse_watch_vars = false;
 137 
 138 #ifdef LTEST
 139                         printf("cd = %d, tok = $\n", cd);
 140 #endif
 141                         /*
 142                          * Try to trim tok to just
 143                          * the variable.
 144                          */
 145                         if (nse_shell_var_used != NULL) {
 146                                 nse_warning();
 147                                 fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tdefined by the shell environment variable %s\n\tCommand line: %s\n",
 148                                     nse_shell_var_used->string_mb,
 149                                     line->command_template->command_line->string_mb);
 150                         }
 151                         if (nse_backquote_seen != NULL) {
 152                                 nse_warning();
 153                                 fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tdefined by a variable (%s) with backquotes in it\n\tCommand line: %s\n",
 154                                     nse_backquote_seen->string_mb,


 156                         }
 157                         cd = false;
 158                 } else if (cd && nse_backquotes(tok)) {
 159                         nse_warning();
 160                         fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tspecified by a command in backquotes\n\tCommand line: %s\n",
 161                             line->command_template->command_line->string_mb);
 162                         cd = false;
 163                 } else {
 164                         cd = false;
 165                 }
 166         }
 167 
 168         /*
 169          * Now check for recursion to ".".
 170          */
 171         if (primary_makefile != NULL) {
 172                 target = prop->body.line.target;
 173                 recurse = get_prop(target->prop, recursive_prop);
 174                 while (recurse != NULL) {
 175                         r = &recurse->body.recursive;

 176                         if (IS_WEQUAL(r->directory->string, (wchar_t *) ".") &&
 177                             !IS_WEQUAL(r->makefiles->name->string, 
 178                             primary_makefile->string)) {





 179                                 nse_warning();
 180                                 fprintf(stderr, "\tRecursion to makefile `%s' in the same directory\n\tCommand line: %s\n",
 181                                     r->makefiles->name->string_mb,
 182                                     line->command_template->command_line->string_mb);
 183                         }
 184                         recurse = get_prop(recurse->next, recursive_prop);
 185                 }
 186         }
 187 }
 188 
 189 /*
 190  * Print an NSE make warning line.
 191  * If the -P flag was given then consider this a fatal
 192  * error, otherwise, just a warning.
 193  */
 194 static void
 195 nse_warning(void)
 196 {

 197         if (report_dependencies_level > 0) {



 198                 our_exit_status = 1;
 199         }
 200         if (primary_makefile != NULL) {
 201                 fprintf(stderr, "make: NSE warning from makefile %s/%s:\n",
 202                         get_current_path(), primary_makefile->string_mb);
 203         } else {
 204                 fprintf(stderr, "make: NSE warning from directory %s:\n",
 205                         get_current_path());
 206         }
 207 }
 208 
 209 /*
 210  * Get the next whitespace delimited token pointed to by *cp.
 211  * Return it in tok.
 212  */
 213 static Boolean
 214 nse_gettoken(wchar_t **cp, wchar_t *tok)
 215 {
 216         wchar_t         *to;
 217         wchar_t         *p;


 231                 return false;
 232         }
 233         *to = '\0';
 234         *cp = p;
 235         return true;
 236 }
 237 
 238 /*
 239  * Given a dependency and a target, see if the dependency
 240  * is an SCCS file.  Check for the last component of its name
 241  * beginning with "s." and the component before that being "SCCS".
 242  * The NSE does not consider a source file to be derived from
 243  * an SCCS file.
 244  */
 245 void
 246 nse_check_sccs(wchar_t *targ, wchar_t *dep)
 247 {
 248         wchar_t         *slash;
 249         wchar_t         *p;
 250 

 251         if (!nse) {



 252                 return;
 253         }

 254         slash = wsrchr(dep, (int) slash_char); 



 255         if (slash == NULL) {
 256                 return;
 257         }
 258         if (slash[1] != 's' || slash[2] != '.') {
 259                 return;
 260         }
 261 
 262         /*
 263          * Find the next to last filename component.
 264          */
 265         for (p = slash - 1; p >= dep; p--) {
 266                 if (*p == '/') {
 267                         break;
 268                 }
 269         }
 270         p++;

 271         MBSTOWCS(wcs_buffer, "SCCS/");
 272         if (IS_WEQUALN(p, wcs_buffer, wslen(wcs_buffer))) {



 273                 nse_warning();
 274                 WCSTOMBS(mbs_buffer, targ);
 275                 WCSTOMBS(mbs_buffer2, dep);
 276                 fprintf(stderr, "\tFile `%s' depends upon SCCS file `%s'\n",
 277                         mbs_buffer, mbs_buffer2);
 278         }
 279         return;
 280 }
 281 
 282 /*
 283  * Given a filename check to see if it has 2 backquotes in it.
 284  * Complain about this because the shell expands the backquotes
 285  * but make does not so the files always appear to be out of date.
 286  */
 287 void
 288 nse_check_file_backquotes(wchar_t *file)
 289 {

 290         if (!nse) {



 291                 return;
 292         }
 293         if (nse_backquotes(file)) {
 294                 nse_warning();
 295                 WCSTOMBS(mbs_buffer, file);
 296                 fprintf(stderr, "\tFilename \"%s\" has backquotes in it\n",
 297                         mbs_buffer);
 298         }
 299 }
 300 
 301 /*
 302  * Return true if the string has two backquotes in it.
 303  */
 304 Boolean
 305 nse_backquotes(wchar_t *str)
 306 {
 307         wchar_t         *bq;
 308 

 309         bq = wschr(str, (int) backquote_char);
 310         if (bq) {
 311                 bq = wschr(&bq[1], (int) backquote_char);





 312                 if (bq) {
 313                         return true;
 314                 }
 315         }
 316         return false;
 317 }
 318 
 319 /*
 320  * A macro that was defined on the command-line was found to affect the
 321  * set of dependencies.  The NSE "target explode" will not know about
 322  * this and will not get the same set of dependencies.
 323  */
 324 void
 325 nse_dep_cmdmacro(wchar_t *macro)
 326 {

 327         if (!nse) {



 328                 return;
 329         }
 330         nse_warning();
 331         WCSTOMBS(mbs_buffer, macro);
 332         fprintf(stderr, "\tVariable `%s' is defined on the command-line and\n\taffects dependencies\n",
 333                 mbs_buffer);
 334 }
 335 
 336 /*
 337  * A macro that was defined on the command-line was found to
 338  * be part of the argument to a cd before a recursive make.
 339  * This make cause the make to recurse to different places
 340  * depending upon how it is invoked.
 341  */
 342 void
 343 nse_rule_cmdmacro(wchar_t *macro)
 344 {

 345         if (!nse) {



 346                 return;
 347         }
 348         nse_warning();
 349         WCSTOMBS(mbs_buffer, macro);
 350         fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tspecified by a variable (%s) defined on the command-line\n",
 351                 mbs_buffer);
 352 }
 353 
 354 /*
 355  * A dependency has been found with a wildcard in it.
 356  * This causes the NSE problems because the set of dependencies
 357  * can change without changing the Makefile.
 358  */
 359 void
 360 nse_wildcard(wchar_t *targ, wchar_t *dep)
 361 {

 362         if (!nse) {



 363                 return;
 364         }
 365         nse_warning();
 366         WCSTOMBS(mbs_buffer, targ);
 367         WCSTOMBS(mbs_buffer2, dep);
 368         fprintf(stderr, "\tFile `%s' has a wildcard in dependency `%s'\n",
 369                 mbs_buffer, mbs_buffer2);
 370 }
 371 
 372 /*
 373  * Read in the list of suffixes that are interpreted as source
 374  * files.
 375  */
 376 void
 377 nse_init_source_suffixes(void)
 378 {
 379         FILE            *fp;
 380         wchar_t         suffix[100];
 381         Nse_suffix      sufx;
 382         Nse_suffix      *bpatch;
 383 
 384         fp = fopen(TARG_SUFX, "r");
 385         if (fp == NULL) {
 386                 return;
 387         }
 388         bpatch = &sufx_hdr;
 389         while (fscanf(fp, "%s %*s", suffix) == 1) {

 390                 sufx = ALLOC(Nse_suffix);  
 391                 sufx->suffix = wscpy(ALLOC_WC(wslen(suffix) + 1), suffix);




 392                 sufx->next = NULL;
 393                 *bpatch = sufx;
 394                 bpatch = &sufx->next;
 395         }
 396         fclose(fp);
 397 }
 398 
 399 /*
 400  * Check if a derived file (something with a dependency) appears
 401  * to be a source file (by its suffix) but has no rule to build it.
 402  * If so, complain.
 403  *
 404  * This generally arises from the old-style of make-depend that
 405  * produces:
 406  *      foo.c:  foo.h
 407  */
 408 void
 409 nse_check_derived_src(Name target, wchar_t *dep, Cmd_line command_template)
 410 {
 411         Nse_suffix      sufx;
 412         wchar_t         *suffix;
 413         wchar_t         *depsufx;
 414 

 415         if (!nse) {



 416                 return;
 417         }

 418         if (target->stat.is_derived_src) {



 419                 return;
 420         }
 421         if (command_template != NULL) {
 422                 return;
 423         }

 424         suffix = wsrchr(target->string, (int) period_char ); 



 425         if (suffix != NULL) {
 426                 for (sufx = sufx_hdr; sufx != NULL; sufx = sufx->next) {

 427                         if (IS_WEQUAL(sufx->suffix, suffix)) {



 428                                 nse_warning();
 429                                 WCSTOMBS(mbs_buffer, dep);
 430                                 fprintf(stderr, "\tProbable source file `%s' appears as a derived file\n\tas it depends upon file `%s', but there is\n\tno rule to build it\n",
 431                                         target->string_mb, mbs_buffer);
 432                                 break;
 433                         }
 434                 }
 435         }
 436 }
 437 
 438 /*
 439  * See if a target is a potential source file and has no
 440  * dependencies and no rule but shows up on the right-hand
 441  * side.  This tends to occur from old "make depend" output.
 442  */
 443 void
 444 nse_check_no_deps_no_rule(Name target, Property line, Property command)
 445 {
 446         Nse_suffix      sufx;
 447         wchar_t         *suffix;
 448 

 449         if (!nse) {



 450                 return;
 451         }

 452         if (target->stat.is_derived_src) {



 453                 return;
 454         }
 455         if (line != NULL && line->body.line.dependencies != NULL) {
 456                 return;
 457         }

 458         if (command->body.line.sccs_command) {



 459                 return;
 460         }

 461         suffix = wsrchr(target->string, (int) period_char); 



 462         if (suffix != NULL) {
 463                 for (sufx = sufx_hdr; sufx != NULL; sufx = sufx->next) {

 464                         if (IS_WEQUAL(sufx->suffix, suffix)) {



 465                                 if (command->body.line.command_template == NULL) {
 466                                         nse_warning();
 467                                         fprintf(stderr, "\tProbable source file `%s' appears as a derived file because\n\tit is on the left-hand side, but it has no dependencies and\n\tno rule to build it\n",
 468                                                 target->string_mb);
 469                                 }
 470                         }
 471                 }
 472         } 
 473 } 
 474 
 475 /*
 476  * Detected a situation where a recursive make derived a file
 477  * without using a makefile.
 478  */
 479 void
 480 nse_no_makefile(Name target)
 481 {

 482         if (!nse) {



 483                 return;
 484         }
 485         nse_warning();
 486         fprintf(stderr, "Recursive make to derive %s did not use a makefile\n",
 487                 target->string_mb);
 488 }
 489 
 490 /*
 491  * Return the NSE exit status.
 492  * If the -P flag was given then a warning is considered fatal
 493  */
 494 int
 495 nse_exit_status(void)
 496 {
 497         return our_exit_status;
 498 }
 499 #endif