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
|