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