Print this page
make: unifdef for SUNOS4_AND_AFTER (defined)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/bin/nse.cc
+++ new/usr/src/cmd/make/bin/nse.cc
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 1994 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #ifdef NSE
27 27
28 28 /*
29 29 * Included files
30 30 */
31 31 #include <mk/defs.h>
32 32 #include <mksh/macro.h> /* expand_value() */
33 33 #include <mksh/misc.h> /* get_prop() */
34 34
35 35 /*
36 36 * This file does some extra checking on behalf of the NSE.
37 37 * It does some stuff that is analogous to lint in that it
38 38 * looks for things which may be legal but that give the NSE
39 39 * trouble. Currently it looks for:
40 40 * 1) recursion by cd'ing to a directory specified by a
41 41 * make variable that is defined from the shell environment.
42 42 * 2) recursion by cd'ing to a directory specified by a
43 43 * make variable that has backquotes in it.
44 44 * 3) recursion to another makefile in the same directory.
45 45 * 4) a dependency upon an SCCS file (SCCS/s.*)
46 46 * 5) backquotes in a file name
47 47 * 6) a make variable being defined on the command-line that
48 48 * ends up affecting dependencies
49 49 * 7) wildcards (*[) in dependencies
50 50 * 8) recursion to the same directory
51 51 * 9) potential source files on the left-hand-side so
52 52 * that they appear as derived files
53 53 *
54 54 * Things it should look for:
55 55 * 1) makefiles that are symlinks (why are these a problem?)
56 56 */
57 57
58 58 #define TARG_SUFX "/usr/nse/lib/nse_targ.sufx"
59 59
60 60 typedef struct _Nse_suffix *Nse_suffix, Nse_suffix_rec;
61 61 struct _Nse_suffix {
62 62 wchar_t *suffix; /* The suffix */
63 63 struct _Nse_suffix *next; /* Linked list */
64 64 };
65 65 static Nse_suffix sufx_hdr;
66 66 static int our_exit_status;
67 67
68 68 static void nse_warning(void);
69 69 static Boolean nse_gettoken(wchar_t **, wchar_t *);
70 70
71 71 /*
72 72 * Given a command that has just recursed to a sub make
73 73 * try to determine if it cd'ed to a directory that was
74 74 * defined by a make variable imported from the shell
75 75 * environment or a variable with backquotes in it.
76 76 * This routine will find something like:
77 77 * cd $(DIR); $(MAKE)
78 78 * where DIR is imported from the shell environment.
79 79 * However it well not find:
80 80 * CD = cd
81 81 * $(CD) $(DIR); $(MAKE)
82 82 * or
83 83 * CD = cd $(DIR)
84 84 * $(CD); $(MAKE)
85 85 *
86 86 * This routine also checks for recursion to the same
↓ open down ↓ |
86 lines elided |
↑ open up ↑ |
87 87 * directory.
88 88 */
89 89 void
90 90 nse_check_cd(Property prop)
91 91 {
92 92 wchar_t tok[512];
93 93 wchar_t *p;
94 94 wchar_t *our_template;
95 95 int len;
96 96 Boolean cd;
97 -#ifdef SUNOS4_AND_AFTER
98 97 String_rec string;
99 -#else
100 - String string;
101 -#endif
102 98 Name name;
103 99 Name target;
104 100 struct Line *line;
105 101 struct Recursive *r;
106 102 Property recurse;
107 103 wchar_t strbuf[STRING_BUFFER_LENGTH];
108 104 wchar_t tmpbuf[STRING_BUFFER_LENGTH];
109 105
110 106 #ifdef LTEST
111 107 printf("In nse_check_cd, nse = %d, nse_did_recursion = %d\n", nse, nse_did_recursion);
112 108 #endif
113 -#ifdef SUNOS4_AND_AFTER
114 109 if (!nse_did_recursion || !nse) {
115 -#else
116 - if (is_false(nse_did_recursion) || is_false(flag.nse)) {
117 -#endif
118 110 #ifdef LTEST
119 111 printf ("returning, nse = %d, nse_did_recursion = %d\n", nse, nse_did_recursion);
120 112 #endif
121 113 return;
122 114 }
123 115 line = &prop->body.line;
124 116 #ifdef LTEST
125 117 printf("string = %s\n", line->command_template->command_line->string_mb);
126 118 #endif
127 119
128 120 wscpy(tmpbuf, line->command_template->command_line->string);
129 121 our_template = tmpbuf;
130 122 cd = false;
131 123 while (nse_gettoken(&our_template, tok)) {
132 124 #ifdef LTEST
133 125 printf("in gettoken loop\n");
134 126 #endif
135 -#ifdef SUNOS4_AND_AFTER
136 127 if (IS_WEQUAL(tok, (wchar_t *) "cd")) {
137 -#else
138 - if (is_equal(tok, "cd")) {
139 -#endif
140 128 cd = true;
141 129 } else if (cd && tok[0] == '$') {
142 130 nse_backquote_seen = NULL;
143 131 nse_shell_var_used = NULL;
144 132 nse_watch_vars = true;
145 -#ifdef SUNOS4_AND_AFTER
146 133 INIT_STRING_FROM_STACK(string, strbuf);
147 134 name = GETNAME(tok, FIND_LENGTH);
148 -#else
149 - init_string_from_stack(string, strbuf);
150 - name = getname(tok, FIND_LENGTH);
151 -#endif
152 135 expand_value(name, &string, false);
153 136 nse_watch_vars = false;
154 137
155 138 #ifdef LTEST
156 139 printf("cd = %d, tok = $\n", cd);
157 140 #endif
158 141 /*
159 142 * Try to trim tok to just
160 143 * the variable.
161 144 */
162 145 if (nse_shell_var_used != NULL) {
163 146 nse_warning();
164 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",
165 148 nse_shell_var_used->string_mb,
166 149 line->command_template->command_line->string_mb);
167 150 }
168 151 if (nse_backquote_seen != NULL) {
169 152 nse_warning();
170 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",
171 154 nse_backquote_seen->string_mb,
172 155 line->command_template->command_line->string_mb);
173 156 }
174 157 cd = false;
175 158 } else if (cd && nse_backquotes(tok)) {
176 159 nse_warning();
177 160 fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tspecified by a command in backquotes\n\tCommand line: %s\n",
178 161 line->command_template->command_line->string_mb);
179 162 cd = false;
180 163 } else {
181 164 cd = false;
182 165 }
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
183 166 }
184 167
185 168 /*
186 169 * Now check for recursion to ".".
187 170 */
188 171 if (primary_makefile != NULL) {
189 172 target = prop->body.line.target;
190 173 recurse = get_prop(target->prop, recursive_prop);
191 174 while (recurse != NULL) {
192 175 r = &recurse->body.recursive;
193 -#ifdef SUNOS4_AND_AFTER
194 176 if (IS_WEQUAL(r->directory->string, (wchar_t *) ".") &&
195 177 !IS_WEQUAL(r->makefiles->name->string,
196 178 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 179 nse_warning();
203 180 fprintf(stderr, "\tRecursion to makefile `%s' in the same directory\n\tCommand line: %s\n",
204 181 r->makefiles->name->string_mb,
205 182 line->command_template->command_line->string_mb);
206 183 }
207 184 recurse = get_prop(recurse->next, recursive_prop);
208 185 }
209 186 }
210 187 }
211 188
212 189 /*
213 190 * Print an NSE make warning line.
214 191 * If the -P flag was given then consider this a fatal
215 192 * error, otherwise, just a warning.
216 193 */
217 194 static void
218 195 nse_warning(void)
219 196 {
220 -#ifdef SUNOS4_AND_AFTER
221 197 if (report_dependencies_level > 0) {
222 -#else
223 - if (is_true(flag.report_dependencies)) {
224 -#endif
225 198 our_exit_status = 1;
226 199 }
227 200 if (primary_makefile != NULL) {
228 201 fprintf(stderr, "make: NSE warning from makefile %s/%s:\n",
229 202 get_current_path(), primary_makefile->string_mb);
230 203 } else {
231 204 fprintf(stderr, "make: NSE warning from directory %s:\n",
232 205 get_current_path());
233 206 }
234 207 }
235 208
236 209 /*
237 210 * Get the next whitespace delimited token pointed to by *cp.
238 211 * Return it in tok.
239 212 */
240 213 static Boolean
241 214 nse_gettoken(wchar_t **cp, wchar_t *tok)
242 215 {
243 216 wchar_t *to;
244 217 wchar_t *p;
245 218
246 219 p = *cp;
247 220 while (*p && iswspace(*p)) {
248 221 p++;
249 222 }
250 223 if (*p == '\0') {
251 224 return false;
252 225 }
253 226 to = tok;
254 227 while (*p && !iswspace(*p)) {
255 228 *to++ = *p++;
256 229 }
257 230 if (*p == '\0') {
258 231 return false;
259 232 }
260 233 *to = '\0';
261 234 *cp = p;
262 235 return true;
263 236 }
264 237
265 238 /*
266 239 * Given a dependency and a target, see if the dependency
267 240 * is an SCCS file. Check for the last component of its name
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
268 241 * beginning with "s." and the component before that being "SCCS".
269 242 * The NSE does not consider a source file to be derived from
270 243 * an SCCS file.
271 244 */
272 245 void
273 246 nse_check_sccs(wchar_t *targ, wchar_t *dep)
274 247 {
275 248 wchar_t *slash;
276 249 wchar_t *p;
277 250
278 -#ifdef SUNOS4_AND_AFTER
279 251 if (!nse) {
280 -#else
281 - if (is_false(flag.nse)) {
282 -#endif
283 252 return;
284 253 }
285 -#ifdef SUNOS4_AND_AFTER
286 254 slash = wsrchr(dep, (int) slash_char);
287 -#else
288 - slash = rindex(dep, '/');
289 -#endif
290 255 if (slash == NULL) {
291 256 return;
292 257 }
293 258 if (slash[1] != 's' || slash[2] != '.') {
294 259 return;
295 260 }
296 261
297 262 /*
298 263 * Find the next to last filename component.
299 264 */
300 265 for (p = slash - 1; p >= dep; p--) {
301 266 if (*p == '/') {
302 267 break;
303 268 }
304 269 }
305 270 p++;
306 -#ifdef SUNOS4_AND_AFTER
307 271 MBSTOWCS(wcs_buffer, "SCCS/");
308 272 if (IS_WEQUALN(p, wcs_buffer, wslen(wcs_buffer))) {
309 -#else
310 - if (is_equaln(p, "SCCS/", 5)) {
311 -#endif
312 273 nse_warning();
313 274 WCSTOMBS(mbs_buffer, targ);
314 275 WCSTOMBS(mbs_buffer2, dep);
315 276 fprintf(stderr, "\tFile `%s' depends upon SCCS file `%s'\n",
316 277 mbs_buffer, mbs_buffer2);
317 278 }
318 279 return;
319 280 }
320 281
321 282 /*
322 283 * Given a filename check to see if it has 2 backquotes in it.
323 284 * Complain about this because the shell expands the backquotes
324 285 * but make does not so the files always appear to be out of date.
325 286 */
326 287 void
327 288 nse_check_file_backquotes(wchar_t *file)
328 289 {
329 -#ifdef SUNOS4_AND_AFTER
330 290 if (!nse) {
331 -#else
332 - if (is_false(flag.nse)) {
333 -#endif
334 291 return;
335 292 }
336 293 if (nse_backquotes(file)) {
337 294 nse_warning();
338 295 WCSTOMBS(mbs_buffer, file);
339 296 fprintf(stderr, "\tFilename \"%s\" has backquotes in it\n",
340 297 mbs_buffer);
341 298 }
342 299 }
343 300
344 301 /*
345 302 * Return true if the string has two backquotes in it.
346 303 */
347 304 Boolean
348 305 nse_backquotes(wchar_t *str)
349 306 {
350 307 wchar_t *bq;
351 308
352 -#ifdef SUNOS4_AND_AFTER
353 309 bq = wschr(str, (int) backquote_char);
354 310 if (bq) {
355 311 bq = wschr(&bq[1], (int) backquote_char);
356 -#else
357 - bq = index(str, '`');
358 - if (bq) {
359 - bq = index(&bq[1], '`');
360 -#endif
361 312 if (bq) {
362 313 return true;
363 314 }
364 315 }
365 316 return false;
366 317 }
367 318
368 319 /*
369 320 * A macro that was defined on the command-line was found to affect the
370 321 * set of dependencies. The NSE "target explode" will not know about
371 322 * this and will not get the same set of dependencies.
372 323 */
373 324 void
374 325 nse_dep_cmdmacro(wchar_t *macro)
375 326 {
376 -#ifdef SUNOS4_AND_AFTER
377 327 if (!nse) {
378 -#else
379 - if (is_false(flag.nse)) {
380 -#endif
381 328 return;
382 329 }
383 330 nse_warning();
384 331 WCSTOMBS(mbs_buffer, macro);
385 332 fprintf(stderr, "\tVariable `%s' is defined on the command-line and\n\taffects dependencies\n",
386 333 mbs_buffer);
387 334 }
388 335
389 336 /*
390 337 * A macro that was defined on the command-line was found to
391 338 * be part of the argument to a cd before a recursive make.
392 339 * This make cause the make to recurse to different places
393 340 * depending upon how it is invoked.
394 341 */
395 342 void
396 343 nse_rule_cmdmacro(wchar_t *macro)
397 344 {
398 -#ifdef SUNOS4_AND_AFTER
399 345 if (!nse) {
400 -#else
401 - if (is_false(flag.nse)) {
402 -#endif
403 346 return;
404 347 }
405 348 nse_warning();
406 349 WCSTOMBS(mbs_buffer, macro);
407 350 fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tspecified by a variable (%s) defined on the command-line\n",
408 351 mbs_buffer);
409 352 }
410 353
411 354 /*
412 355 * A dependency has been found with a wildcard in it.
413 356 * This causes the NSE problems because the set of dependencies
414 357 * can change without changing the Makefile.
415 358 */
416 359 void
417 360 nse_wildcard(wchar_t *targ, wchar_t *dep)
418 361 {
419 -#ifdef SUNOS4_AND_AFTER
420 362 if (!nse) {
421 -#else
422 - if (is_false(flag.nse)) {
423 -#endif
424 363 return;
425 364 }
426 365 nse_warning();
427 366 WCSTOMBS(mbs_buffer, targ);
428 367 WCSTOMBS(mbs_buffer2, dep);
429 368 fprintf(stderr, "\tFile `%s' has a wildcard in dependency `%s'\n",
430 369 mbs_buffer, mbs_buffer2);
431 370 }
432 371
433 372 /*
434 373 * Read in the list of suffixes that are interpreted as source
435 374 * files.
436 375 */
437 376 void
438 377 nse_init_source_suffixes(void)
439 378 {
440 379 FILE *fp;
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
441 380 wchar_t suffix[100];
442 381 Nse_suffix sufx;
443 382 Nse_suffix *bpatch;
444 383
445 384 fp = fopen(TARG_SUFX, "r");
446 385 if (fp == NULL) {
447 386 return;
448 387 }
449 388 bpatch = &sufx_hdr;
450 389 while (fscanf(fp, "%s %*s", suffix) == 1) {
451 -#ifdef SUNOS4_AND_AFTER
452 390 sufx = ALLOC(Nse_suffix);
453 391 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 392 sufx->next = NULL;
459 393 *bpatch = sufx;
460 394 bpatch = &sufx->next;
461 395 }
462 396 fclose(fp);
463 397 }
464 398
465 399 /*
466 400 * Check if a derived file (something with a dependency) appears
467 401 * to be a source file (by its suffix) but has no rule to build it.
468 402 * If so, complain.
469 403 *
470 404 * This generally arises from the old-style of make-depend that
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
471 405 * produces:
472 406 * foo.c: foo.h
473 407 */
474 408 void
475 409 nse_check_derived_src(Name target, wchar_t *dep, Cmd_line command_template)
476 410 {
477 411 Nse_suffix sufx;
478 412 wchar_t *suffix;
479 413 wchar_t *depsufx;
480 414
481 -#ifdef SUNOS4_AND_AFTER
482 415 if (!nse) {
483 -#else
484 - if (is_false(flag.nse)) {
485 -#endif
486 416 return;
487 417 }
488 -#ifdef SUNOS4_AND_AFTER
489 418 if (target->stat.is_derived_src) {
490 -#else
491 - if (is_true(target->stat.is_derived_src)) {
492 -#endif
493 419 return;
494 420 }
495 421 if (command_template != NULL) {
496 422 return;
497 423 }
498 -#ifdef SUNOS4_AND_AFTER
499 424 suffix = wsrchr(target->string, (int) period_char );
500 -#else
501 - suffix = rindex(target->string, '.');
502 -#endif
503 425 if (suffix != NULL) {
504 426 for (sufx = sufx_hdr; sufx != NULL; sufx = sufx->next) {
505 -#ifdef SUNOS4_AND_AFTER
506 427 if (IS_WEQUAL(sufx->suffix, suffix)) {
507 -#else
508 - if (is_equal(sufx->suffix, suffix)) {
509 -#endif
510 428 nse_warning();
511 429 WCSTOMBS(mbs_buffer, dep);
512 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",
513 431 target->string_mb, mbs_buffer);
514 432 break;
515 433 }
516 434 }
517 435 }
518 436 }
519 437
520 438 /*
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
521 439 * See if a target is a potential source file and has no
522 440 * dependencies and no rule but shows up on the right-hand
523 441 * side. This tends to occur from old "make depend" output.
524 442 */
525 443 void
526 444 nse_check_no_deps_no_rule(Name target, Property line, Property command)
527 445 {
528 446 Nse_suffix sufx;
529 447 wchar_t *suffix;
530 448
531 -#ifdef SUNOS4_AND_AFTER
532 449 if (!nse) {
533 -#else
534 - if (is_false(flag.nse)) {
535 -#endif
536 450 return;
537 451 }
538 -#ifdef SUNOS4_AND_AFTER
539 452 if (target->stat.is_derived_src) {
540 -#else
541 - if (is_true(target->stat.is_derived_src)) {
542 -#endif
543 453 return;
544 454 }
545 455 if (line != NULL && line->body.line.dependencies != NULL) {
546 456 return;
547 457 }
548 -#ifdef SUNOS4_AND_AFTER
549 458 if (command->body.line.sccs_command) {
550 -#else
551 - if (is_true(command->body.line.sccs_command)) {
552 -#endif
553 459 return;
554 460 }
555 -#ifdef SUNOS4_AND_AFTER
556 461 suffix = wsrchr(target->string, (int) period_char);
557 -#else
558 - suffix = rindex(target->string, '.');
559 -#endif
560 462 if (suffix != NULL) {
561 463 for (sufx = sufx_hdr; sufx != NULL; sufx = sufx->next) {
562 -#ifdef SUNOS4_AND_AFTER
563 464 if (IS_WEQUAL(sufx->suffix, suffix)) {
564 -#else
565 - if (is_equal(sufx->suffix, suffix)) {
566 -#endif
567 465 if (command->body.line.command_template == NULL) {
568 466 nse_warning();
569 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",
570 468 target->string_mb);
571 469 }
572 470 }
573 471 }
574 472 }
575 473 }
576 474
577 475 /*
578 476 * Detected a situation where a recursive make derived a file
579 477 * without using a makefile.
580 478 */
581 479 void
582 480 nse_no_makefile(Name target)
583 481 {
584 -#ifdef SUNOS4_AND_AFTER
585 482 if (!nse) {
586 -#else
587 - if (is_false(flag.nse)) {
588 -#endif
589 483 return;
590 484 }
591 485 nse_warning();
592 486 fprintf(stderr, "Recursive make to derive %s did not use a makefile\n",
593 487 target->string_mb);
594 488 }
595 489
596 490 /*
597 491 * Return the NSE exit status.
598 492 * If the -P flag was given then a warning is considered fatal
599 493 */
600 494 int
601 495 nse_exit_status(void)
602 496 {
603 497 return our_exit_status;
604 498 }
605 499 #endif
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX