Print this page
make: unifdef for _CHECK_UPDATE_H (undefined)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/bin/main.cc
+++ new/usr/src/cmd/make/bin/main.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 2006 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * main.cc
28 28 *
29 29 * make program main routine plus some helper routines
30 30 */
31 31
32 32 /*
33 33 * Included files
34 34 */
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
35 35 #if defined(TEAMWARE_MAKE_CMN)
36 36 # include <avo/intl.h>
37 37 # include <avo/libcli.h> /* libcli_init() */
38 38 # include <avo/cli_license.h> /* avo_cli_get_license() */
39 39 # include <avo/find_dir.h> /* avo_find_run_dir() */
40 40 # include <avo/version_string.h>
41 41 # include <avo/util.h> /* avo_init() */
42 42 # include <avo/cleanup.h>
43 43 #endif
44 44
45 -#if defined(TEAMWARE_MAKE_CMN)
46 -/* This is for dmake only (not for Solaris make).
47 - * Include code to check updates (dmake patches)
48 - */
49 -#ifdef _CHECK_UPDATE_H
50 -#include <libAU.h>
51 -#endif
52 -#endif
53 -
54 45 #include <bsd/bsd.h> /* bsd_signal() */
55 46
56 47 #ifdef DISTRIBUTED
57 48 # include <dm/Avo_AcknowledgeMsg.h>
58 49 # include <rw/xdrstrea.h>
59 50 # include <dmrc/dmrc.h> /* dmakerc file processing */
60 51 #endif
61 52
62 53 #include <locale.h> /* setlocale() */
63 54 #include <mk/defs.h>
64 55 #include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
65 56 #include <mksh/macro.h> /* getvar() */
66 57 #include <mksh/misc.h> /* getmem(), setup_char_semantics() */
67 58
68 59 #if defined(TEAMWARE_MAKE_CMN)
69 60 #endif
70 61
71 62 #include <pwd.h> /* getpwnam() */
72 63 #include <setjmp.h>
73 64 #include <signal.h>
74 65 #include <stdlib.h>
75 66 #include <sys/errno.h> /* ENOENT */
76 67 #include <sys/stat.h> /* fstat() */
77 68 #include <fcntl.h> /* open() */
78 69
79 70 # include <sys/systeminfo.h> /* sysinfo() */
80 71
81 72 #include <sys/types.h> /* stat() */
82 73 #include <sys/wait.h> /* wait() */
83 74 #include <unistd.h> /* execv(), unlink(), access() */
84 75 #include <vroot/report.h> /* report_dependency(), get_report_file() */
85 76
86 77 // From read2.cc
87 78 extern Name normalize_name(register wchar_t *name_string, register int length);
88 79
89 80 // From parallel.cc
90 81 #if defined(TEAMWARE_MAKE_CMN)
91 82 #define MAXJOBS_ADJUST_RFE4694000
92 83
93 84 #ifdef MAXJOBS_ADJUST_RFE4694000
94 85 extern void job_adjust_fini();
95 86 #endif /* MAXJOBS_ADJUST_RFE4694000 */
96 87 #endif /* TEAMWARE_MAKE_CMN */
97 88
98 89
99 90 /*
100 91 * Defined macros
101 92 */
102 93 #define LD_SUPPORT_ENV_VAR NOCATGETS("SGS_SUPPORT")
103 94 #define LD_SUPPORT_MAKE_LIB NOCATGETS("libmakestate.so.1")
104 95
105 96 /*
106 97 * typedefs & structs
107 98 */
108 99
109 100 /*
110 101 * Static variables
111 102 */
112 103 static char *argv_zero_string;
113 104 static Boolean build_failed_ever_seen;
114 105 static Boolean continue_after_error_ever_seen; /* `-k' */
115 106 static Boolean dmake_group_specified; /* `-g' */
116 107 static Boolean dmake_max_jobs_specified; /* `-j' */
117 108 static Boolean dmake_mode_specified; /* `-m' */
118 109 static Boolean dmake_add_mode_specified; /* `-x' */
119 110 static Boolean dmake_output_mode_specified; /* `-x DMAKE_OUTPUT_MODE=' */
120 111 static Boolean dmake_compat_mode_specified; /* `-x SUN_MAKE_COMPAT_MODE=' */
121 112 static Boolean dmake_odir_specified; /* `-o' */
122 113 static Boolean dmake_rcfile_specified; /* `-c' */
123 114 static Boolean env_wins; /* `-e' */
124 115 static Boolean ignore_default_mk; /* `-r' */
125 116 static Boolean list_all_targets; /* `-T' */
126 117 static int mf_argc;
127 118 static char **mf_argv;
128 119 static Dependency_rec not_auto_depen_struct;
129 120 static Dependency not_auto_depen = ¬_auto_depen_struct;
130 121 static Boolean pmake_cap_r_specified; /* `-R' */
131 122 static Boolean pmake_machinesfile_specified; /* `-M' */
132 123 static Boolean stop_after_error_ever_seen; /* `-S' */
133 124 static Boolean trace_status; /* `-p' */
134 125
135 126 #ifdef DMAKE_STATISTICS
136 127 static Boolean getname_stat = false;
137 128 #endif
138 129
139 130 #if defined(TEAMWARE_MAKE_CMN)
140 131 static time_t start_time;
141 132 static int g_argc;
142 133 static char **g_argv;
143 134 static Avo_cleanup *cleanup = NULL;
144 135 #endif
145 136
146 137 /*
147 138 * File table of contents
148 139 */
149 140 extern "C" void cleanup_after_exit(void);
150 141
151 142 #ifdef TEAMWARE_MAKE_CMN
152 143 extern "C" {
153 144 extern void dmake_exit_callback(void);
154 145 extern void dmake_message_callback(char *);
155 146 }
156 147 #endif
157 148
158 149 extern Name normalize_name(register wchar_t *name_string, register int length);
159 150
160 151 extern int main(int, char * []);
161 152
162 153 static void append_makeflags_string(Name, String);
163 154 static void doalarm(int);
164 155 static void enter_argv_values(int , char **, ASCII_Dyn_Array *);
165 156 static void make_targets(int, char **, Boolean);
166 157 static int parse_command_option(char);
167 158 static void read_command_options(int, char **);
168 159 static void read_environment(Boolean);
169 160 static void read_files_and_state(int, char **);
170 161 static Boolean read_makefile(Name, Boolean, Boolean, Boolean);
171 162 static void report_recursion(Name);
172 163 static void set_sgs_support(void);
173 164 static void setup_for_projectdir(void);
174 165 static void setup_makeflags_argv(void);
175 166 static void report_dir_enter_leave(Boolean entering);
176 167
177 168 extern void expand_value(Name, register String , Boolean);
178 169
179 170 #ifdef DISTRIBUTED
180 171 extern int dmake_ofd;
181 172 extern FILE* dmake_ofp;
182 173 extern int rxmPid;
183 174 extern XDR xdrs_out;
184 175 #endif
185 176 #ifdef TEAMWARE_MAKE_CMN
186 177 extern char verstring[];
187 178 #endif
188 179
189 180 jmp_buf jmpbuffer;
190 181 extern nl_catd catd;
191 182
192 183 /*
193 184 * main(argc, argv)
194 185 *
195 186 * Parameters:
196 187 * argc You know what this is
197 188 * argv You know what this is
198 189 *
199 190 * Static variables used:
200 191 * list_all_targets make -T seen
201 192 * trace_status make -p seen
202 193 *
203 194 * Global variables used:
204 195 * debug_level Should we trace make actions?
205 196 * keep_state Set if .KEEP_STATE seen
206 197 * makeflags The Name "MAKEFLAGS", used to get macro
207 198 * remote_command_name Name of remote invocation cmd ("on")
208 199 * running_list List of parallel running processes
209 200 * stdout_stderr_same true if stdout and stderr are the same
210 201 * auto_dependencies The Name "SUNPRO_DEPENDENCIES"
211 202 * temp_file_directory Set to the dir where we create tmp file
212 203 * trace_reader Set to reflect tracing status
213 204 * working_on_targets Set when building user targets
214 205 */
215 206 int
216 207 main(int argc, char *argv[])
217 208 {
218 209 /*
219 210 * cp is a -> to the value of the MAKEFLAGS env var,
220 211 * which has to be regular chars.
221 212 */
222 213 register char *cp;
223 214 char make_state_dir[MAXPATHLEN];
224 215 Boolean parallel_flag = false;
225 216 char *prognameptr;
226 217 char *slash_ptr;
227 218 mode_t um;
228 219 int i;
229 220 #ifdef TEAMWARE_MAKE_CMN
230 221 struct itimerval value;
231 222 char def_dmakerc_path[MAXPATHLEN];
232 223 Name dmake_name, dmake_name2;
233 224 Name dmake_value, dmake_value2;
234 225 Property prop, prop2;
235 226 struct stat statbuf;
236 227 int statval;
237 228 #endif
238 229
239 230 struct stat out_stat, err_stat;
240 231 hostid = gethostid();
241 232 #ifdef TEAMWARE_MAKE_CMN
242 233 avo_get_user(NULL, NULL); // Initialize user name
243 234 #endif
244 235 bsd_signals();
245 236
246 237 (void) setlocale(LC_ALL, "");
247 238
248 239
249 240 #ifdef DMAKE_STATISTICS
250 241 if (getenv(NOCATGETS("DMAKE_STATISTICS"))) {
251 242 getname_stat = true;
252 243 }
253 244 #endif
254 245
255 246
256 247 /*
257 248 * avo_init() sets the umask to 0. Save it here and restore
258 249 * it after the avo_init() call.
259 250 */
260 251 #if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL)
261 252 um = umask(0);
262 253 avo_init(argv[0]);
263 254 umask(um);
264 255
265 256 cleanup = new Avo_cleanup(NOCATGETS("dmake"), argc, argv);
266 257 #endif
267 258
268 259 #if defined(TEAMWARE_MAKE_CMN)
269 260 catd = catopen(AVO_DOMAIN_DMAKE, NL_CAT_LOCALE);
270 261 libcli_init();
271 262 #endif
272 263
273 264 // ---> fprintf(stderr, catgets(catd, 15, 666, "--- SUN make ---\n"));
274 265
275 266
276 267 #if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL)
277 268 /*
278 269 * I put libmksdmsi18n_init() under #ifdef because it requires avo_i18n_init()
279 270 * from avo_util library.
280 271 */
281 272 libmksdmsi18n_init();
282 273 #endif
283 274
284 275
285 276 #ifndef TEAMWARE_MAKE_CMN
286 277 textdomain(NOCATGETS("SUNW_SPRO_MAKE"));
287 278 #endif /* TEAMWARE_MAKE_CMN */
288 279
289 280 #ifdef TEAMWARE_MAKE_CMN
290 281 g_argc = argc;
291 282 g_argv = (char **) malloc((g_argc + 1) * sizeof(char *));
292 283 for (i = 0; i < argc; i++) {
293 284 g_argv[i] = argv[i];
294 285 }
295 286 g_argv[i] = NULL;
296 287 #endif /* TEAMWARE_MAKE_CMN */
297 288
298 289 /*
299 290 * Set argv_zero_string to some form of argv[0] for
300 291 * recursive MAKE builds.
301 292 */
302 293
303 294 if (*argv[0] == (int) slash_char) {
304 295 /* argv[0] starts with a slash */
305 296 argv_zero_string = strdup(argv[0]);
306 297 } else if (strchr(argv[0], (int) slash_char) == NULL) {
307 298 /* argv[0] contains no slashes */
308 299 argv_zero_string = strdup(argv[0]);
309 300 } else {
310 301 /*
311 302 * argv[0] contains at least one slash,
312 303 * but doesn't start with a slash
313 304 */
314 305 char *tmp_current_path;
315 306 char *tmp_string;
316 307
317 308 tmp_current_path = get_current_path();
318 309 tmp_string = getmem(strlen(tmp_current_path) + 1 +
319 310 strlen(argv[0]) + 1);
320 311 (void) sprintf(tmp_string,
321 312 "%s/%s",
322 313 tmp_current_path,
323 314 argv[0]);
324 315 argv_zero_string = strdup(tmp_string);
325 316 retmem_mb(tmp_string);
326 317 }
327 318
328 319 /*
329 320 * The following flags are reset if we don't have the
330 321 * (.nse_depinfo or .make.state) files locked and only set
331 322 * AFTER the file has been locked. This ensures that if the user
332 323 * interrupts the program while file_lock() is waiting to lock
333 324 * the file, the interrupt handler doesn't remove a lock
334 325 * that doesn't belong to us.
335 326 */
336 327 make_state_lockfile = NULL;
337 328 make_state_locked = false;
338 329
339 330
340 331 /*
341 332 * look for last slash char in the path to look at the binary
342 333 * name. This is to resolve the hard link and invoke make
343 334 * in svr4 mode.
344 335 */
345 336
346 337 /* Sun OS make standart */
347 338 svr4 = false;
348 339 posix = false;
349 340 if(!strcmp(argv_zero_string, NOCATGETS("/usr/xpg4/bin/make"))) {
350 341 svr4 = false;
351 342 posix = true;
352 343 } else {
353 344 prognameptr = strrchr(argv[0], '/');
354 345 if(prognameptr) {
355 346 prognameptr++;
356 347 } else {
357 348 prognameptr = argv[0];
358 349 }
359 350 if(!strcmp(prognameptr, NOCATGETS("svr4.make"))) {
360 351 svr4 = true;
361 352 posix = false;
362 353 }
363 354 }
364 355 if (getenv(USE_SVR4_MAKE) || getenv(NOCATGETS("USE_SVID"))){
365 356 svr4 = true;
366 357 posix = false;
367 358 }
368 359
369 360 /*
370 361 * Find the dmake_compat_mode: posix, sun, svr4, or gnu_style, .
371 362 */
372 363 char * dmake_compat_mode_var = getenv(NOCATGETS("SUN_MAKE_COMPAT_MODE"));
373 364 if (dmake_compat_mode_var != NULL) {
374 365 if (0 == strcasecmp(dmake_compat_mode_var, NOCATGETS("GNU"))) {
375 366 gnu_style = true;
376 367 }
377 368 //svr4 = false;
378 369 //posix = false;
379 370 }
380 371
381 372 /*
382 373 * Temporary directory set up.
383 374 */
384 375 char * tmpdir_var = getenv(NOCATGETS("TMPDIR"));
385 376 if (tmpdir_var != NULL && *tmpdir_var == '/' && strlen(tmpdir_var) < MAXPATHLEN) {
386 377 strcpy(mbs_buffer, tmpdir_var);
387 378 for (tmpdir_var = mbs_buffer+strlen(mbs_buffer);
388 379 *(--tmpdir_var) == '/' && tmpdir_var > mbs_buffer;
389 380 *tmpdir_var = '\0');
390 381 if (strlen(mbs_buffer) + 32 < MAXPATHLEN) { /* 32 = strlen("/dmake.stdout.%d.%d.XXXXXX") */
391 382 sprintf(mbs_buffer2, NOCATGETS("%s/dmake.tst.%d.XXXXXX"),
392 383 mbs_buffer, getpid());
393 384 int fd = mkstemp(mbs_buffer2);
394 385 if (fd >= 0) {
395 386 close(fd);
396 387 unlink(mbs_buffer2);
397 388 tmpdir = strdup(mbs_buffer);
398 389 }
399 390 }
400 391 }
401 392
402 393 /* find out if stdout and stderr point to the same place */
403 394 if (fstat(1, &out_stat) < 0) {
404 395 fatal(catgets(catd, 1, 165, "fstat of standard out failed: %s"), errmsg(errno));
405 396 }
406 397 if (fstat(2, &err_stat) < 0) {
407 398 fatal(catgets(catd, 1, 166, "fstat of standard error failed: %s"), errmsg(errno));
408 399 }
409 400 if ((out_stat.st_dev == err_stat.st_dev) &&
410 401 (out_stat.st_ino == err_stat.st_ino)) {
411 402 stdout_stderr_same = true;
412 403 } else {
413 404 stdout_stderr_same = false;
414 405 }
415 406 /* Make the vroot package scan the path using shell semantics */
416 407 set_path_style(0);
417 408
418 409 setup_char_semantics();
419 410
420 411 setup_for_projectdir();
421 412
422 413 /*
423 414 * If running with .KEEP_STATE, curdir will be set with
424 415 * the connected directory.
425 416 */
426 417 (void) atexit(cleanup_after_exit);
427 418
428 419 load_cached_names();
429 420
430 421 /*
431 422 * Set command line flags
432 423 */
433 424 setup_makeflags_argv();
434 425 read_command_options(mf_argc, mf_argv);
435 426 read_command_options(argc, argv);
436 427 if (debug_level > 0) {
437 428 cp = getenv(makeflags->string_mb);
438 429 (void) printf(catgets(catd, 1, 167, "MAKEFLAGS value: %s\n"), cp == NULL ? "" : cp);
439 430 }
440 431
441 432 setup_interrupt(handle_interrupt);
442 433
443 434 read_files_and_state(argc, argv);
444 435
445 436 #ifdef TEAMWARE_MAKE_CMN
446 437 /*
447 438 * Find the dmake_output_mode: TXT1, TXT2 or HTML1.
448 439 */
449 440 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
450 441 dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
451 442 prop2 = get_prop(dmake_name2->prop, macro_prop);
452 443 if (prop2 == NULL) {
453 444 /* DMAKE_OUTPUT_MODE not defined, default to TXT1 mode */
454 445 output_mode = txt1_mode;
455 446 } else {
456 447 dmake_value2 = prop2->body.macro.value;
457 448 if ((dmake_value2 == NULL) ||
458 449 (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("TXT1")))) {
459 450 output_mode = txt1_mode;
460 451 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("TXT2"))) {
461 452 output_mode = txt2_mode;
462 453 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("HTML1"))) {
463 454 output_mode = html1_mode;
464 455 } else {
465 456 warning(catgets(catd, 1, 352, "Unsupported value `%s' for DMAKE_OUTPUT_MODE after -x flag (ignored)"),
466 457 dmake_value2->string_mb);
467 458 }
468 459 }
469 460 /*
470 461 * Find the dmake_mode: distributed, parallel, or serial.
471 462 */
472 463 if ((!pmake_cap_r_specified) &&
473 464 (!pmake_machinesfile_specified)) {
474 465 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
475 466 dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
476 467 prop2 = get_prop(dmake_name2->prop, macro_prop);
477 468 if (prop2 == NULL) {
478 469 /* DMAKE_MODE not defined, default to distributed mode */
479 470 dmake_mode_type = distributed_mode;
480 471 no_parallel = false;
481 472 } else {
482 473 dmake_value2 = prop2->body.macro.value;
483 474 if ((dmake_value2 == NULL) ||
484 475 (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("distributed")))) {
485 476 dmake_mode_type = distributed_mode;
486 477 no_parallel = false;
487 478 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("parallel"))) {
488 479 dmake_mode_type = parallel_mode;
489 480 no_parallel = false;
490 481 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("serial"))) {
491 482 dmake_mode_type = serial_mode;
492 483 no_parallel = true;
493 484 } else {
494 485 fatal(catgets(catd, 1, 307, "Unknown dmake mode argument `%s' after -m flag"), dmake_value2->string_mb);
495 486 }
496 487 }
497 488
498 489 if ((!list_all_targets) &&
499 490 (report_dependencies_level == 0)) {
500 491 /*
501 492 * Check to see if either DMAKE_RCFILE or DMAKE_MODE is defined.
502 493 * They could be defined in the env, in the makefile, or on the
503 494 * command line.
504 495 * If neither is defined, and $(HOME)/.dmakerc does not exists,
505 496 * then print a message, and default to parallel mode.
506 497 */
507 498 #ifdef DISTRIBUTED
508 499 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
509 500 dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
510 501 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
511 502 dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
512 503 if ((((prop = get_prop(dmake_name->prop, macro_prop)) == NULL) ||
513 504 ((dmake_value = prop->body.macro.value) == NULL)) &&
514 505 (((prop2 = get_prop(dmake_name2->prop, macro_prop)) == NULL) ||
515 506 ((dmake_value2 = prop2->body.macro.value) == NULL))) {
516 507 Boolean empty_dmakerc = true;
517 508 char *homedir = getenv(NOCATGETS("HOME"));
518 509 if ((homedir != NULL) && (strlen(homedir) < (sizeof(def_dmakerc_path) - 16))) {
519 510 sprintf(def_dmakerc_path, NOCATGETS("%s/.dmakerc"), homedir);
520 511 if ((((statval = stat(def_dmakerc_path, &statbuf)) != 0) && (errno == ENOENT)) ||
521 512 ((statval == 0) && (statbuf.st_size == 0))) {
522 513 } else {
523 514 Avo_dmakerc *rcfile = new Avo_dmakerc();
524 515 Avo_err *err = rcfile->read(def_dmakerc_path, NULL, TRUE);
525 516 if (err) {
526 517 fatal(err->str);
527 518 }
528 519 empty_dmakerc = rcfile->was_empty();
529 520 delete rcfile;
530 521 }
531 522 }
532 523 if (empty_dmakerc) {
533 524 if (getenv(NOCATGETS("DMAKE_DEF_PRINTED")) == NULL) {
534 525 putenv(NOCATGETS("DMAKE_DEF_PRINTED=TRUE"));
535 526 (void) fprintf(stdout, catgets(catd, 1, 302, "dmake: defaulting to parallel mode.\n"));
536 527 (void) fprintf(stdout, catgets(catd, 1, 303, "See the man page dmake(1) for more information on setting up the .dmakerc file.\n"));
537 528 }
538 529 dmake_mode_type = parallel_mode;
539 530 no_parallel = false;
540 531 }
541 532 }
542 533 #else
543 534 if(dmake_mode_type == distributed_mode) {
544 535 (void) fprintf(stdout, NOCATGETS("dmake: Distributed mode not implemented.\n"));
545 536 (void) fprintf(stdout, NOCATGETS(" Defaulting to parallel mode.\n"));
546 537 dmake_mode_type = parallel_mode;
547 538 no_parallel = false;
548 539 }
549 540 #endif /* DISTRIBUTED */
550 541 }
551 542 }
552 543 #endif
553 544
554 545 #ifdef TEAMWARE_MAKE_CMN
555 546 parallel_flag = true;
556 547 /* XXX - This is a major hack for DMake/Licensing. */
557 548 if (getenv(NOCATGETS("DMAKE_CHILD")) == NULL) {
558 549 if (!avo_cli_search_license(argv[0], dmake_exit_callback, TRUE, dmake_message_callback)) {
559 550 /*
560 551 * If the user can not get a TeamWare license,
561 552 * default to serial mode.
562 553 */
563 554 dmake_mode_type = serial_mode;
564 555 no_parallel = true;
565 556 } else {
566 557 putenv(NOCATGETS("DMAKE_CHILD=TRUE"));
567 558 }
568 559 start_time = time(NULL);
569 560 /*
570 561 * XXX - Hack to disable SIGALRM's from licensing library's
571 562 * setitimer().
572 563 */
573 564 value.it_interval.tv_sec = 0;
574 565 value.it_interval.tv_usec = 0;
575 566 value.it_value.tv_sec = 0;
576 567 value.it_value.tv_usec = 0;
577 568 (void) setitimer(ITIMER_REAL, &value, NULL);
578 569 }
579 570
580 571 //
581 572 // If dmake is running with -t option, set dmake_mode_type to serial.
582 573 // This is done because doname() calls touch_command() that runs serially.
583 574 // If we do not do that, maketool will have problems.
584 575 //
585 576 if(touch) {
586 577 dmake_mode_type = serial_mode;
587 578 no_parallel = true;
588 579 }
589 580 #else
590 581 parallel_flag = false;
591 582 #endif
592 583
593 584 #if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR)
594 585 /*
595 586 * Check whether stdout and stderr are physically same.
596 587 * This is in order to decide whether we need to redirect
597 588 * stderr separately from stdout.
598 589 * This check is performed only if __DMAKE_SEPARATE_STDERR
599 590 * is not set. This variable may be used in order to preserve
600 591 * the 'old' behaviour.
601 592 */
602 593 out_err_same = true;
603 594 char * dmake_sep_var = getenv(NOCATGETS("__DMAKE_SEPARATE_STDERR"));
604 595 if (dmake_sep_var == NULL || (0 != strcasecmp(dmake_sep_var, NOCATGETS("NO")))) {
605 596 struct stat stdout_stat;
606 597 struct stat stderr_stat;
607 598 if( (fstat(1, &stdout_stat) == 0)
608 599 && (fstat(2, &stderr_stat) == 0) )
609 600 {
610 601 if( (stdout_stat.st_dev != stderr_stat.st_dev)
611 602 || (stdout_stat.st_ino != stderr_stat.st_ino) )
612 603 {
613 604 out_err_same = false;
614 605 }
615 606 }
616 607 }
617 608 #endif
618 609
619 610 #ifdef DISTRIBUTED
620 611 /*
621 612 * At this point, DMake should startup an rxm with any and all
622 613 * DMake command line options. Rxm will, among other things,
623 614 * read the rc file.
624 615 */
625 616 if ((!list_all_targets) &&
626 617 (report_dependencies_level == 0) &&
627 618 (dmake_mode_type == distributed_mode)) {
628 619 startup_rxm();
629 620 }
630 621 #endif
631 622
632 623 /*
633 624 * Enable interrupt handler for alarms
634 625 */
635 626 (void) bsd_signal(SIGALRM, (SIG_PF)doalarm);
636 627
637 628 /*
638 629 * Check if make should report
639 630 */
640 631 if (getenv(sunpro_dependencies->string_mb) != NULL) {
641 632 FILE *report_file;
642 633
643 634 report_dependency("");
644 635 report_file = get_report_file();
645 636 if ((report_file != NULL) && (report_file != (FILE*)-1)) {
646 637 (void) fprintf(report_file, "\n");
647 638 }
648 639 }
649 640
650 641 /*
651 642 * Make sure SUNPRO_DEPENDENCIES is exported (or not) properly.
652 643 */
653 644 if (keep_state) {
654 645 maybe_append_prop(sunpro_dependencies, macro_prop)->
655 646 body.macro.exported = true;
656 647 } else {
657 648 maybe_append_prop(sunpro_dependencies, macro_prop)->
658 649 body.macro.exported = false;
659 650 }
660 651
661 652 working_on_targets = true;
662 653 if (trace_status) {
663 654 dump_make_state();
664 655 fclose(stdout);
665 656 fclose(stderr);
666 657 exit_status = 0;
667 658 exit(0);
668 659 }
669 660 if (list_all_targets) {
670 661 dump_target_list();
671 662 fclose(stdout);
672 663 fclose(stderr);
673 664 exit_status = 0;
674 665 exit(0);
675 666 }
676 667 trace_reader = false;
677 668
678 669 /*
679 670 * Set temp_file_directory to the directory the .make.state
680 671 * file is written to.
681 672 */
682 673 if ((slash_ptr = strrchr(make_state->string_mb, (int) slash_char)) == NULL) {
683 674 temp_file_directory = strdup(get_current_path());
684 675 } else {
685 676 *slash_ptr = (int) nul_char;
686 677 (void) strcpy(make_state_dir, make_state->string_mb);
687 678 *slash_ptr = (int) slash_char;
688 679 /* when there is only one slash and it's the first
689 680 ** character, make_state_dir should point to '/'.
690 681 */
691 682 if(make_state_dir[0] == '\0') {
692 683 make_state_dir[0] = '/';
693 684 make_state_dir[1] = '\0';
694 685 }
695 686 if (make_state_dir[0] == (int) slash_char) {
696 687 temp_file_directory = strdup(make_state_dir);
697 688 } else {
698 689 char tmp_current_path2[MAXPATHLEN];
699 690
700 691 (void) sprintf(tmp_current_path2,
701 692 "%s/%s",
702 693 get_current_path(),
703 694 make_state_dir);
704 695 temp_file_directory = strdup(tmp_current_path2);
705 696 }
706 697 }
707 698
708 699 #ifdef DISTRIBUTED
709 700 building_serial = false;
710 701 #endif
711 702
712 703 report_dir_enter_leave(true);
713 704
714 705 make_targets(argc, argv, parallel_flag);
715 706
716 707 report_dir_enter_leave(false);
717 708
718 709 if (build_failed_ever_seen) {
719 710 if (posix) {
720 711 exit_status = 1;
721 712 }
722 713 exit(1);
723 714 }
724 715 exit_status = 0;
725 716 exit(0);
726 717 /* NOTREACHED */
727 718 }
728 719
729 720 /*
730 721 * cleanup_after_exit()
731 722 *
732 723 * Called from exit(), performs cleanup actions.
733 724 *
734 725 * Parameters:
735 726 * status The argument exit() was called with
736 727 * arg Address of an argument vector to
737 728 * cleanup_after_exit()
738 729 *
739 730 * Global variables used:
740 731 * command_changed Set if we think .make.state should be rewritten
741 732 * current_line Is set we set commands_changed
742 733 * do_not_exec_rule
743 734 * True if -n flag on
744 735 * done The Name ".DONE", rule we run
745 736 * keep_state Set if .KEEP_STATE seen
746 737 * parallel True if building in parallel
747 738 * quest If -q is on we do not run .DONE
748 739 * report_dependencies
749 740 * True if -P flag on
750 741 * running_list List of parallel running processes
751 742 * temp_file_name The temp file is removed, if any
752 743 * catd the message catalog file
753 744 */
754 745 extern "C" void
755 746 cleanup_after_exit(void)
756 747 {
757 748 Running rp;
758 749
759 750 extern long getname_bytes_count;
760 751 extern long getname_names_count;
761 752 extern long getname_struct_count;
762 753 extern long freename_bytes_count;
763 754 extern long freename_names_count;
764 755 extern long freename_struct_count;
765 756 extern long other_alloc;
766 757
767 758 extern long env_alloc_num;
768 759 extern long env_alloc_bytes;
769 760
770 761
771 762 #ifdef DMAKE_STATISTICS
772 763 if(getname_stat) {
773 764 printf(NOCATGETS(">>> Getname statistics:\n"));
774 765 printf(NOCATGETS(" Allocated:\n"));
775 766 printf(NOCATGETS(" Names: %ld\n"), getname_names_count);
776 767 printf(NOCATGETS(" Strings: %ld Kb (%ld bytes)\n"), getname_bytes_count/1000, getname_bytes_count);
777 768 printf(NOCATGETS(" Structs: %ld Kb (%ld bytes)\n"), getname_struct_count/1000, getname_struct_count);
778 769 printf(NOCATGETS(" Total bytes: %ld Kb (%ld bytes)\n"), getname_struct_count/1000 + getname_bytes_count/1000, getname_struct_count + getname_bytes_count);
779 770
780 771 printf(NOCATGETS("\n Unallocated: %ld\n"), freename_names_count);
781 772 printf(NOCATGETS(" Names: %ld\n"), freename_names_count);
782 773 printf(NOCATGETS(" Strings: %ld Kb (%ld bytes)\n"), freename_bytes_count/1000, freename_bytes_count);
783 774 printf(NOCATGETS(" Structs: %ld Kb (%ld bytes)\n"), freename_struct_count/1000, freename_struct_count);
784 775 printf(NOCATGETS(" Total bytes: %ld Kb (%ld bytes)\n"), freename_struct_count/1000 + freename_bytes_count/1000, freename_struct_count + freename_bytes_count);
785 776
786 777 printf(NOCATGETS("\n Total used: %ld Kb (%ld bytes)\n"), (getname_struct_count/1000 + getname_bytes_count/1000) - (freename_struct_count/1000 + freename_bytes_count/1000), (getname_struct_count + getname_bytes_count) - (freename_struct_count + freename_bytes_count));
787 778
788 779 printf(NOCATGETS("\n>>> Other:\n"));
789 780 printf(
790 781 NOCATGETS(" Env (%ld): %ld Kb (%ld bytes)\n"),
791 782 env_alloc_num,
792 783 env_alloc_bytes/1000,
793 784 env_alloc_bytes
794 785 );
795 786
796 787 }
797 788 #endif
798 789
799 790 /*
800 791 #ifdef DISTRIBUTED
801 792 if (get_parent() == TRUE) {
802 793 #endif
803 794 */
804 795
805 796 parallel = false;
806 797 /* If we used the SVR4_MAKE, don't build .DONE or .FAILED */
807 798 if (!getenv(USE_SVR4_MAKE)){
808 799 /* Build the target .DONE or .FAILED if we caught an error */
809 800 if (!quest && !list_all_targets) {
810 801 Name failed_name;
811 802
812 803 MBSTOWCS(wcs_buffer, NOCATGETS(".FAILED"));
813 804 failed_name = GETNAME(wcs_buffer, FIND_LENGTH);
814 805 if ((exit_status != 0) && (failed_name->prop != NULL)) {
815 806 #ifdef TEAMWARE_MAKE_CMN
816 807 /*
817 808 * [tolik] switch DMake to serial mode
818 809 */
819 810 dmake_mode_type = serial_mode;
820 811 no_parallel = true;
821 812 #endif
822 813 (void) doname(failed_name, false, true);
823 814 } else {
824 815 if (!trace_status) {
825 816 #ifdef TEAMWARE_MAKE_CMN
826 817 /*
827 818 * Switch DMake to serial mode
828 819 */
829 820 dmake_mode_type = serial_mode;
830 821 no_parallel = true;
831 822 #endif
832 823 (void) doname(done, false, true);
833 824 }
834 825 }
835 826 }
836 827 }
837 828 /*
838 829 * Remove the temp file utilities report dependencies thru if it
839 830 * is still around
840 831 */
841 832 if (temp_file_name != NULL) {
842 833 (void) unlink(temp_file_name->string_mb);
843 834 }
844 835 /*
845 836 * Do not save the current command in .make.state if make
846 837 * was interrupted.
847 838 */
848 839 if (current_line != NULL) {
849 840 command_changed = true;
850 841 current_line->body.line.command_used = NULL;
851 842 }
852 843 /*
853 844 * For each parallel build process running, remove the temp files
854 845 * and zap the command line so it won't be put in .make.state
855 846 */
856 847 for (rp = running_list; rp != NULL; rp = rp->next) {
857 848 if (rp->temp_file != NULL) {
858 849 (void) unlink(rp->temp_file->string_mb);
859 850 }
860 851 if (rp->stdout_file != NULL) {
861 852 (void) unlink(rp->stdout_file);
862 853 retmem_mb(rp->stdout_file);
863 854 rp->stdout_file = NULL;
864 855 }
865 856 if (rp->stderr_file != NULL) {
866 857 (void) unlink(rp->stderr_file);
867 858 retmem_mb(rp->stderr_file);
868 859 rp->stderr_file = NULL;
869 860 }
870 861 command_changed = true;
871 862 /*
872 863 line = get_prop(rp->target->prop, line_prop);
873 864 if (line != NULL) {
874 865 line->body.line.command_used = NULL;
875 866 }
876 867 */
877 868 }
878 869 /* Remove the statefile lock file if the file has been locked */
879 870 if ((make_state_lockfile != NULL) && (make_state_locked)) {
880 871 (void) unlink(make_state_lockfile);
881 872 make_state_lockfile = NULL;
882 873 make_state_locked = false;
883 874 }
884 875 /* Write .make.state */
885 876 write_state_file(1, (Boolean) 1);
886 877
887 878 #ifdef TEAMWARE_MAKE_CMN
888 879 // Deleting the usage tracking object sends the usage mail
889 880 cleanup->set_exit_status(exit_status);
890 881 delete cleanup;
891 882 #endif
892 883
893 884 /*
894 885 #ifdef DISTRIBUTED
895 886 }
896 887 #endif
897 888 */
898 889
899 890 #if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
900 891 job_adjust_fini();
901 892 #endif
902 893
903 894 #ifdef TEAMWARE_MAKE_CMN
904 895 catclose(catd);
905 896 #endif
906 897 #ifdef DISTRIBUTED
907 898 if (rxmPid > 0) {
908 899 // Tell rxm to exit by sending it an Avo_AcknowledgeMsg
909 900 Avo_AcknowledgeMsg acknowledgeMsg;
910 901 RWCollectable *msg = (RWCollectable *)&acknowledgeMsg;
911 902
912 903 int xdrResult = xdr(&xdrs_out, msg);
913 904
914 905 if (xdrResult) {
915 906 fflush(dmake_ofp);
916 907 } else {
917 908 /*
918 909 fatal(catgets(catd, 1, 266, "couldn't tell rxm to exit"));
919 910 */
920 911 kill(rxmPid, SIGTERM);
921 912 }
922 913
923 914 waitpid(rxmPid, NULL, 0);
924 915 rxmPid = 0;
925 916 }
926 917 #endif
927 918 }
928 919
929 920 /*
930 921 * handle_interrupt()
931 922 *
932 923 * This is where C-C traps are caught.
933 924 *
934 925 * Parameters:
935 926 *
936 927 * Global variables used (except DMake 1.0):
937 928 * current_target Sometimes the current target is removed
938 929 * do_not_exec_rule But not if -n is on
939 930 * quest or -q
940 931 * running_list List of parallel running processes
941 932 * touch Current target is not removed if -t on
942 933 */
943 934 void
944 935 handle_interrupt(int)
945 936 {
946 937 Property member;
947 938 Running rp;
948 939
949 940 (void) fflush(stdout);
950 941 #ifdef DISTRIBUTED
951 942 if (rxmPid > 0) {
952 943 // Tell rxm to exit by sending it an Avo_AcknowledgeMsg
953 944 Avo_AcknowledgeMsg acknowledgeMsg;
954 945 RWCollectable *msg = (RWCollectable *)&acknowledgeMsg;
955 946
956 947 int xdrResult = xdr(&xdrs_out, msg);
957 948
958 949 if (xdrResult) {
959 950 fflush(dmake_ofp);
960 951 } else {
961 952 kill(rxmPid, SIGTERM);
962 953 rxmPid = 0;
963 954 }
964 955 }
965 956 #endif
966 957 if (childPid > 0) {
967 958 kill(childPid, SIGTERM);
968 959 childPid = -1;
969 960 }
970 961 for (rp = running_list; rp != NULL; rp = rp->next) {
971 962 if (rp->state != build_running) {
972 963 continue;
973 964 }
974 965 if (rp->pid > 0) {
975 966 kill(rp->pid, SIGTERM);
976 967 rp->pid = -1;
977 968 }
978 969 }
979 970 if (getpid() == getpgrp()) {
980 971 bsd_signal(SIGTERM, SIG_IGN);
981 972 kill (-getpid(), SIGTERM);
982 973 }
983 974 #ifdef TEAMWARE_MAKE_CMN
984 975 /* Clean up all parallel/distributed children already finished */
985 976 finish_children(false);
986 977 #endif
987 978
988 979 /* Make sure the processes running under us terminate first */
989 980
990 981 while (wait((int *) NULL) != -1);
991 982 /* Delete the current targets unless they are precious */
992 983 if ((current_target != NULL) &&
993 984 current_target->is_member &&
994 985 ((member = get_prop(current_target->prop, member_prop)) != NULL)) {
995 986 current_target = member->body.member.library;
996 987 }
997 988 if (!do_not_exec_rule &&
998 989 !touch &&
999 990 !quest &&
1000 991 (current_target != NULL) &&
1001 992 !(current_target->stat.is_precious || all_precious)) {
1002 993
1003 994 /* BID_1030811 */
1004 995 /* azv 16 Oct 95 */
1005 996 current_target->stat.time = file_no_time;
1006 997
1007 998 if (exists(current_target) != file_doesnt_exist) {
1008 999 (void) fprintf(stderr,
1009 1000 "\n*** %s ",
1010 1001 current_target->string_mb);
1011 1002 if (current_target->stat.is_dir) {
1012 1003 (void) fprintf(stderr,
1013 1004 catgets(catd, 1, 168, "not removed.\n"),
1014 1005 current_target->string_mb);
1015 1006 } else if (unlink(current_target->string_mb) == 0) {
1016 1007 (void) fprintf(stderr,
1017 1008 catgets(catd, 1, 169, "removed.\n"),
1018 1009 current_target->string_mb);
1019 1010 } else {
1020 1011 (void) fprintf(stderr,
1021 1012 catgets(catd, 1, 170, "could not be removed: %s.\n"),
1022 1013 current_target->string_mb,
1023 1014 errmsg(errno));
1024 1015 }
1025 1016 }
1026 1017 }
1027 1018 for (rp = running_list; rp != NULL; rp = rp->next) {
1028 1019 if (rp->state != build_running) {
1029 1020 continue;
1030 1021 }
1031 1022 if (rp->target->is_member &&
1032 1023 ((member = get_prop(rp->target->prop, member_prop)) !=
1033 1024 NULL)) {
1034 1025 rp->target = member->body.member.library;
1035 1026 }
1036 1027 if (!do_not_exec_rule &&
1037 1028 !touch &&
1038 1029 !quest &&
1039 1030 !(rp->target->stat.is_precious || all_precious)) {
1040 1031
1041 1032 rp->target->stat.time = file_no_time;
1042 1033 if (exists(rp->target) != file_doesnt_exist) {
1043 1034 (void) fprintf(stderr,
1044 1035 "\n*** %s ",
1045 1036 rp->target->string_mb);
1046 1037 if (rp->target->stat.is_dir) {
1047 1038 (void) fprintf(stderr,
1048 1039 catgets(catd, 1, 171, "not removed.\n"),
1049 1040 rp->target->string_mb);
1050 1041 } else if (unlink(rp->target->string_mb) == 0) {
1051 1042 (void) fprintf(stderr,
1052 1043 catgets(catd, 1, 172, "removed.\n"),
1053 1044 rp->target->string_mb);
1054 1045 } else {
1055 1046 (void) fprintf(stderr,
1056 1047 catgets(catd, 1, 173, "could not be removed: %s.\n"),
1057 1048 rp->target->string_mb,
1058 1049 errmsg(errno));
1059 1050 }
1060 1051 }
1061 1052 }
1062 1053 }
1063 1054
1064 1055
1065 1056 /* Have we locked .make.state or .nse_depinfo? */
1066 1057 if ((make_state_lockfile != NULL) && (make_state_locked)) {
1067 1058 unlink(make_state_lockfile);
1068 1059 make_state_lockfile = NULL;
1069 1060 make_state_locked = false;
1070 1061 }
1071 1062 /*
1072 1063 * Re-read .make.state file (it might be changed by recursive make)
1073 1064 */
1074 1065 check_state(NULL);
1075 1066
1076 1067 report_dir_enter_leave(false);
1077 1068
1078 1069 exit_status = 2;
1079 1070 exit(2);
1080 1071 }
1081 1072
1082 1073 /*
1083 1074 * doalarm(sig, ...)
1084 1075 *
1085 1076 * Handle the alarm interrupt but do nothing. Side effect is to
1086 1077 * cause return from wait3.
1087 1078 *
1088 1079 * Parameters:
1089 1080 * sig
1090 1081 *
1091 1082 * Global variables used:
1092 1083 */
1093 1084 /*ARGSUSED*/
1094 1085 static void
1095 1086 doalarm(int)
1096 1087 {
1097 1088 return;
1098 1089 }
1099 1090
1100 1091
1101 1092 /*
1102 1093 * read_command_options(argc, argv)
1103 1094 *
1104 1095 * Scan the cmd line options and process the ones that start with "-"
1105 1096 *
1106 1097 * Return value:
1107 1098 * -M argument, if any
1108 1099 *
1109 1100 * Parameters:
1110 1101 * argc You know what this is
1111 1102 * argv You know what this is
1112 1103 *
1113 1104 * Global variables used:
1114 1105 */
1115 1106 static void
1116 1107 read_command_options(register int argc, register char **argv)
1117 1108 {
1118 1109 register int ch;
1119 1110 int current_optind = 1;
1120 1111 int last_optind_with_double_hyphen = 0;
1121 1112 int last_optind;
1122 1113 int last_current_optind;
1123 1114 register int i;
1124 1115 register int j;
1125 1116 register int k;
1126 1117 register int makefile_next = 0; /*
1127 1118 * flag to note options:
1128 1119 * -c, f, g, j, m, o
1129 1120 */
1130 1121 const char *tptr;
1131 1122 const char *CMD_OPTS;
1132 1123
1133 1124 extern char *optarg;
1134 1125 extern int optind, opterr, optopt;
1135 1126
1136 1127 #define SUNPRO_CMD_OPTS "-~Bbc:Ddef:g:ij:K:kM:m:NnO:o:PpqRrSsTtuVvwx:"
1137 1128
1138 1129 #ifdef TEAMWARE_MAKE_CMN
1139 1130 # define SVR4_CMD_OPTS "-c:ef:g:ij:km:nO:o:pqrsTtVv"
1140 1131 #else
1141 1132 # define SVR4_CMD_OPTS "-ef:iknpqrstV"
1142 1133 #endif
1143 1134
1144 1135 /*
1145 1136 * Added V in SVR4_CMD_OPTS also, which is going to be a hidden
1146 1137 * option, just to make sure that the getopt doesn't fail when some
1147 1138 * users leave their USE_SVR4_MAKE set and try to use the makefiles
1148 1139 * that are designed to issue commands like $(MAKE) -V. Anyway it
1149 1140 * sets the same flag but ensures that getopt doesn't fail.
1150 1141 */
1151 1142
1152 1143 opterr = 0;
1153 1144 optind = 1;
1154 1145 while (1) {
1155 1146 last_optind=optind; /* Save optind and current_optind values */
1156 1147 last_current_optind=current_optind; /* in case we have to repeat this round. */
1157 1148 if (svr4) {
1158 1149 CMD_OPTS=SVR4_CMD_OPTS;
1159 1150 ch = getopt(argc, argv, SVR4_CMD_OPTS);
1160 1151 } else {
1161 1152 CMD_OPTS=SUNPRO_CMD_OPTS;
1162 1153 ch = getopt(argc, argv, SUNPRO_CMD_OPTS);
1163 1154 }
1164 1155 if (ch == EOF) {
1165 1156 if(optind < argc) {
1166 1157 /*
1167 1158 * Fixing bug 4102537:
1168 1159 * Strange behaviour of command make using -- option.
1169 1160 * Not all argv have been processed
1170 1161 * Skip non-flag argv and continue processing.
1171 1162 */
1172 1163 optind++;
1173 1164 current_optind++;
1174 1165 continue;
1175 1166 } else {
1176 1167 break;
1177 1168 }
1178 1169
1179 1170 }
1180 1171 if (ch == '?') {
1181 1172 if (optopt == '-') {
1182 1173 /* Bug 5060758: getopt() changed behavior (s10_60),
1183 1174 * and now we have to deal with cases when options
1184 1175 * with double hyphen appear here, from -$(MAKEFLAGS)
1185 1176 */
1186 1177 i = current_optind;
1187 1178 if (argv[i][0] == '-') {
1188 1179 if (argv[i][1] == '-') {
1189 1180 if (argv[i][2] != '\0') {
1190 1181 /* Check if this option is allowed */
1191 1182 tptr = strchr(CMD_OPTS, argv[i][2]);
1192 1183 if (tptr) {
1193 1184 if (last_optind_with_double_hyphen != current_optind) {
1194 1185 /* This is first time we are trying to fix "--"
1195 1186 * problem with this option. If we come here second
1196 1187 * time, we will go to fatal error.
1197 1188 */
1198 1189 last_optind_with_double_hyphen = current_optind;
1199 1190
1200 1191 /* Eliminate first hyphen character */
1201 1192 for (j=0; argv[i][j] != '\0'; j++) {
1202 1193 argv[i][j] = argv[i][j+1];
1203 1194 }
1204 1195
1205 1196 /* Repeat the processing of this argument */
1206 1197 optind=last_optind;
1207 1198 current_optind=last_current_optind;
1208 1199 continue;
1209 1200 }
1210 1201 }
1211 1202 }
1212 1203 }
1213 1204 }
1214 1205 }
1215 1206 }
1216 1207
1217 1208 if (ch == '?') {
1218 1209 if (svr4) {
1219 1210 #ifdef TEAMWARE_MAKE_CMN
1220 1211 fprintf(stderr,
1221 1212 catgets(catd, 1, 267, "Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ]\n"));
1222 1213 fprintf(stderr,
1223 1214 catgets(catd, 1, 268, " [ -j dmake_max_jobs ][ -m dmake_mode ][ -o dmake_odir ]...\n"));
1224 1215 fprintf(stderr,
1225 1216 catgets(catd, 1, 269, " [ -e ][ -i ][ -k ][ -n ][ -p ][ -q ][ -r ][ -s ][ -t ][ -v ]\n"));
1226 1217 #else
1227 1218 fprintf(stderr,
1228 1219 catgets(catd, 1, 270, "Usage : make [ -f makefile ]... [ -e ][ -i ][ -k ][ -n ][ -p ][ -q ][ -r ]\n"));
1229 1220 fprintf(stderr,
1230 1221 catgets(catd, 1, 271, " [ -s ][ -t ]\n"));
1231 1222 #endif
1232 1223 tptr = strchr(SVR4_CMD_OPTS, optopt);
1233 1224 } else {
1234 1225 #ifdef TEAMWARE_MAKE_CMN
1235 1226 fprintf(stderr,
1236 1227 catgets(catd, 1, 272, "Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ]\n"));
1237 1228 fprintf(stderr,
1238 1229 catgets(catd, 1, 273, " [ -j dmake_max_jobs ][ -K statefile ][ -m dmake_mode ][ -x MODE_NAME=VALUE ][ -o dmake_odir ]...\n"));
1239 1230 fprintf(stderr,
1240 1231 catgets(catd, 1, 274, " [ -d ][ -dd ][ -D ][ -DD ][ -e ][ -i ][ -k ][ -n ][ -p ][ -P ][ -u ][ -w ]\n"));
1241 1232 fprintf(stderr,
1242 1233 catgets(catd, 1, 275, " [ -q ][ -r ][ -s ][ -S ][ -t ][ -v ][ -V ][ target... ][ macro=value... ][ \"macro +=value\"... ]\n"));
1243 1234 #else
1244 1235 fprintf(stderr,
1245 1236 catgets(catd, 1, 276, "Usage : make [ -f makefile ][ -K statefile ]... [ -d ][ -dd ][ -D ][ -DD ]\n"));
1246 1237 fprintf(stderr,
1247 1238 catgets(catd, 1, 277, " [ -e ][ -i ][ -k ][ -n ][ -p ][ -P ][ -q ][ -r ][ -s ][ -S ][ -t ]\n"));
1248 1239 fprintf(stderr,
1249 1240 catgets(catd, 1, 278, " [ -u ][ -w ][ -V ][ target... ][ macro=value... ][ \"macro +=value\"... ]\n"));
1250 1241 #endif
1251 1242 tptr = strchr(SUNPRO_CMD_OPTS, optopt);
1252 1243 }
1253 1244 if (!tptr) {
1254 1245 fatal(catgets(catd, 1, 279, "Unknown option `-%c'"), optopt);
1255 1246 } else {
1256 1247 fatal(catgets(catd, 1, 280, "Missing argument after `-%c'"), optopt);
1257 1248 }
1258 1249 }
1259 1250
1260 1251
1261 1252
1262 1253 makefile_next |= parse_command_option(ch);
1263 1254 /*
1264 1255 * If we're done processing all of the options of
1265 1256 * ONE argument string...
1266 1257 */
1267 1258 if (current_optind < optind) {
1268 1259 i = current_optind;
1269 1260 k = 0;
1270 1261 /* If there's an argument for an option... */
1271 1262 if ((optind - current_optind) > 1) {
1272 1263 k = i + 1;
1273 1264 }
1274 1265 switch (makefile_next) {
1275 1266 case 0:
1276 1267 argv[i] = NULL;
1277 1268 /* This shouldn't happen */
1278 1269 if (k) {
1279 1270 argv[k] = NULL;
1280 1271 }
1281 1272 break;
1282 1273 case 1: /* -f seen */
1283 1274 argv[i] = (char *)NOCATGETS("-f");
1284 1275 break;
1285 1276 case 2: /* -c seen */
1286 1277 argv[i] = (char *)NOCATGETS("-c");
1287 1278 #ifndef TEAMWARE_MAKE_CMN
1288 1279 warning(catgets(catd, 1, 281, "Ignoring DistributedMake -c option"));
1289 1280 #endif
1290 1281 break;
1291 1282 case 4: /* -g seen */
1292 1283 argv[i] = (char *)NOCATGETS("-g");
1293 1284 #ifndef TEAMWARE_MAKE_CMN
1294 1285 warning(catgets(catd, 1, 282, "Ignoring DistributedMake -g option"));
1295 1286 #endif
1296 1287 break;
1297 1288 case 8: /* -j seen */
1298 1289 argv[i] = (char *)NOCATGETS("-j");
1299 1290 #ifndef TEAMWARE_MAKE_CMN
1300 1291 warning(catgets(catd, 1, 283, "Ignoring DistributedMake -j option"));
1301 1292 #endif
1302 1293 break;
1303 1294 case 16: /* -M seen */
1304 1295 argv[i] = (char *)NOCATGETS("-M");
1305 1296 #ifndef TEAMWARE_MAKE_CMN
1306 1297 warning(catgets(catd, 1, 284, "Ignoring ParallelMake -M option"));
1307 1298 #endif
1308 1299 break;
1309 1300 case 32: /* -m seen */
1310 1301 argv[i] = (char *)NOCATGETS("-m");
1311 1302 #ifndef TEAMWARE_MAKE_CMN
1312 1303 warning(catgets(catd, 1, 285, "Ignoring DistributedMake -m option"));
1313 1304 #endif
1314 1305 break;
1315 1306 case 128: /* -O seen */
1316 1307 argv[i] = (char *)NOCATGETS("-O");
1317 1308 break;
1318 1309 case 256: /* -K seen */
1319 1310 argv[i] = (char *)NOCATGETS("-K");
1320 1311 break;
1321 1312 case 512: /* -o seen */
1322 1313 argv[i] = (char *)NOCATGETS("-o");
1323 1314 #ifndef TEAMWARE_MAKE_CMN
1324 1315 warning(catgets(catd, 1, 311, "Ignoring DistributedMake -o option"));
1325 1316 #endif
1326 1317 break;
1327 1318 case 1024: /* -x seen */
1328 1319 argv[i] = (char *)NOCATGETS("-x");
1329 1320 #ifndef TEAMWARE_MAKE_CMN
1330 1321 warning(catgets(catd, 1, 353, "Ignoring DistributedMake -x option"));
1331 1322 #endif
1332 1323 break;
1333 1324 default: /* > 1 of -c, f, g, j, K, M, m, O, o, x seen */
1334 1325 fatal(catgets(catd, 1, 286, "Illegal command line. More than one option requiring\nan argument given in the same argument group"));
1335 1326 }
1336 1327
1337 1328 makefile_next = 0;
1338 1329 current_optind = optind;
1339 1330 }
1340 1331 }
1341 1332 }
1342 1333
1343 1334 static void
1344 1335 quote_str(char *str, char *qstr)
1345 1336 {
1346 1337 char *to;
1347 1338 char *from;
1348 1339
1349 1340 to = qstr;
1350 1341 for (from = str; *from; from++) {
1351 1342 switch (*from) {
1352 1343 case ';': /* End of command */
1353 1344 case '(': /* Start group */
1354 1345 case ')': /* End group */
1355 1346 case '{': /* Start group */
1356 1347 case '}': /* End group */
1357 1348 case '[': /* Reg expr - any of a set of chars */
1358 1349 case ']': /* End of set of chars */
1359 1350 case '|': /* Pipe or logical-or */
1360 1351 case '^': /* Old-fashioned pipe */
1361 1352 case '&': /* Background or logical-and */
1362 1353 case '<': /* Redirect stdin */
1363 1354 case '>': /* Redirect stdout */
1364 1355 case '*': /* Reg expr - any sequence of chars */
1365 1356 case '?': /* Reg expr - any single char */
1366 1357 case '$': /* Variable substitution */
1367 1358 case '\'': /* Singe quote - turn off all magic */
1368 1359 case '"': /* Double quote - span whitespace */
1369 1360 case '`': /* Backquote - run a command */
1370 1361 case '#': /* Comment */
1371 1362 case ' ': /* Space (for MACRO=value1 value2 */
1372 1363 case '\\': /* Escape char - turn off magic of next char */
1373 1364 *to++ = '\\';
1374 1365 break;
1375 1366
1376 1367 default:
1377 1368 break;
1378 1369 }
1379 1370 *to++ = *from;
1380 1371 }
1381 1372 *to = '\0';
1382 1373 }
1383 1374
1384 1375 static void
1385 1376 unquote_str(char *str, char *qstr)
1386 1377 {
1387 1378 char *to;
1388 1379 char *from;
1389 1380
1390 1381 to = qstr;
1391 1382 for (from = str; *from; from++) {
1392 1383 if (*from == '\\') {
1393 1384 from++;
1394 1385 }
1395 1386 *to++ = *from;
1396 1387 }
1397 1388 *to = '\0';
1398 1389 }
1399 1390
1400 1391 /*
1401 1392 * Convert the MAKEFLAGS string value into a vector of char *, similar
1402 1393 * to argv.
1403 1394 */
1404 1395 static void
1405 1396 setup_makeflags_argv()
1406 1397 {
1407 1398 char *cp;
1408 1399 char *cp1;
1409 1400 char *cp2;
1410 1401 char *cp3;
1411 1402 char *cp_orig;
1412 1403 Boolean add_hyphen;
1413 1404 int i;
1414 1405 char tmp_char;
1415 1406
1416 1407 mf_argc = 1;
1417 1408 cp = getenv(makeflags->string_mb);
1418 1409 cp_orig = cp;
1419 1410
1420 1411 if (cp) {
1421 1412 /*
1422 1413 * If new MAKEFLAGS format, no need to add hyphen.
1423 1414 * If old MAKEFLAGS format, add hyphen before flags.
1424 1415 */
1425 1416
1426 1417 if ((strchr(cp, (int) hyphen_char) != NULL) ||
1427 1418 (strchr(cp, (int) equal_char) != NULL)) {
1428 1419
1429 1420 /* New MAKEFLAGS format */
1430 1421
1431 1422 add_hyphen = false;
1432 1423 #ifdef ADDFIX5060758
1433 1424 /* Check if MAKEFLAGS value begins with multiple
1434 1425 * hyphen characters, and remove all duplicates.
1435 1426 * Usually it happens when the next command is
1436 1427 * used: $(MAKE) -$(MAKEFLAGS)
1437 1428 * This is a workaround for BugID 5060758.
1438 1429 */
1439 1430 while (*cp) {
1440 1431 if (*cp != (int) hyphen_char) {
1441 1432 break;
1442 1433 }
1443 1434 cp++;
1444 1435 if (*cp == (int) hyphen_char) {
1445 1436 /* There are two hyphens. Skip one */
1446 1437 cp_orig = cp;
1447 1438 cp++;
1448 1439 }
1449 1440 if (!(*cp)) {
1450 1441 /* There are hyphens only. Skip all */
1451 1442 cp_orig = cp;
1452 1443 break;
1453 1444 }
1454 1445 }
1455 1446 #endif
1456 1447 } else {
1457 1448
1458 1449 /* Old MAKEFLAGS format */
1459 1450
1460 1451 add_hyphen = true;
1461 1452 }
1462 1453 }
1463 1454
1464 1455 /* Find the number of arguments in MAKEFLAGS */
1465 1456 while (cp && *cp) {
1466 1457 /* Skip white spaces */
1467 1458 while (cp && *cp && isspace(*cp)) {
1468 1459 cp++;
1469 1460 }
1470 1461 if (cp && *cp) {
1471 1462 /* Increment arg count */
1472 1463 mf_argc++;
1473 1464 /* Go to next white space */
1474 1465 while (cp && *cp && !isspace(*cp)) {
1475 1466 if(*cp == (int) backslash_char) {
1476 1467 cp++;
1477 1468 }
1478 1469 cp++;
1479 1470 }
1480 1471 }
1481 1472 }
1482 1473 /* Allocate memory for the new MAKEFLAGS argv */
1483 1474 mf_argv = (char **) malloc((mf_argc + 1) * sizeof(char *));
1484 1475 mf_argv[0] = (char *)NOCATGETS("MAKEFLAGS");
1485 1476 /*
1486 1477 * Convert the MAKEFLAGS string value into a vector of char *,
1487 1478 * similar to argv.
1488 1479 */
1489 1480 cp = cp_orig;
1490 1481 for (i = 1; i < mf_argc; i++) {
1491 1482 /* Skip white spaces */
1492 1483 while (cp && *cp && isspace(*cp)) {
1493 1484 cp++;
1494 1485 }
1495 1486 if (cp && *cp) {
1496 1487 cp_orig = cp;
1497 1488 /* Go to next white space */
1498 1489 while (cp && *cp && !isspace(*cp)) {
1499 1490 if(*cp == (int) backslash_char) {
1500 1491 cp++;
1501 1492 }
1502 1493 cp++;
1503 1494 }
1504 1495 tmp_char = *cp;
1505 1496 *cp = (int) nul_char;
1506 1497 if (add_hyphen) {
1507 1498 mf_argv[i] = getmem(2 + strlen(cp_orig));
1508 1499 mf_argv[i][0] = '\0';
1509 1500 (void) strcat(mf_argv[i], "-");
1510 1501 // (void) strcat(mf_argv[i], cp_orig);
1511 1502 unquote_str(cp_orig, mf_argv[i]+1);
1512 1503 } else {
1513 1504 mf_argv[i] = getmem(2 + strlen(cp_orig));
1514 1505 //mf_argv[i] = strdup(cp_orig);
1515 1506 unquote_str(cp_orig, mf_argv[i]);
1516 1507 }
1517 1508 *cp = tmp_char;
1518 1509 }
1519 1510 }
1520 1511 mf_argv[i] = NULL;
1521 1512 }
1522 1513
1523 1514 /*
1524 1515 * parse_command_option(ch)
1525 1516 *
1526 1517 * Parse make command line options.
1527 1518 *
1528 1519 * Return value:
1529 1520 * Indicates if any -f -c or -M were seen
1530 1521 *
1531 1522 * Parameters:
1532 1523 * ch The character to parse
1533 1524 *
1534 1525 * Static variables used:
1535 1526 * dmake_group_specified Set for make -g
1536 1527 * dmake_max_jobs_specified Set for make -j
1537 1528 * dmake_mode_specified Set for make -m
1538 1529 * dmake_add_mode_specified Set for make -x
1539 1530 * dmake_compat_mode_specified Set for make -x SUN_MAKE_COMPAT_MODE=
1540 1531 * dmake_output_mode_specified Set for make -x DMAKE_OUTPUT_MODE=
1541 1532 * dmake_odir_specified Set for make -o
1542 1533 * dmake_rcfile_specified Set for make -c
1543 1534 * env_wins Set for make -e
1544 1535 * ignore_default_mk Set for make -r
1545 1536 * trace_status Set for make -p
1546 1537 *
1547 1538 * Global variables used:
1548 1539 * .make.state path & name set for make -K
1549 1540 * continue_after_error Set for make -k
1550 1541 * debug_level Set for make -d
1551 1542 * do_not_exec_rule Set for make -n
1552 1543 * filter_stderr Set for make -X
1553 1544 * ignore_errors_all Set for make -i
1554 1545 * no_parallel Set for make -R
1555 1546 * quest Set for make -q
1556 1547 * read_trace_level Set for make -D
1557 1548 * report_dependencies Set for make -P
1558 1549 * send_mtool_msgs Set for make -K
1559 1550 * silent_all Set for make -s
1560 1551 * touch Set for make -t
1561 1552 */
1562 1553 static int
1563 1554 parse_command_option(register char ch)
1564 1555 {
1565 1556 static int invert_next = 0;
1566 1557 int invert_this = invert_next;
1567 1558
1568 1559 invert_next = 0;
1569 1560 switch (ch) {
1570 1561 case '-': /* Ignore "--" */
1571 1562 return 0;
1572 1563 case '~': /* Invert next option */
1573 1564 invert_next = 1;
1574 1565 return 0;
1575 1566 case 'B': /* Obsolete */
1576 1567 return 0;
1577 1568 case 'b': /* Obsolete */
1578 1569 return 0;
1579 1570 case 'c': /* Read alternative dmakerc file */
1580 1571 if (invert_this) {
1581 1572 dmake_rcfile_specified = false;
1582 1573 } else {
1583 1574 dmake_rcfile_specified = true;
1584 1575 }
1585 1576 return 2;
1586 1577 case 'D': /* Show lines read */
1587 1578 if (invert_this) {
1588 1579 read_trace_level--;
1589 1580 } else {
1590 1581 read_trace_level++;
1591 1582 }
1592 1583 return 0;
1593 1584 case 'd': /* Debug flag */
1594 1585 if (invert_this) {
1595 1586 debug_level--;
1596 1587 } else {
1597 1588 debug_level++;
1598 1589 }
1599 1590 return 0;
1600 1591 case 'e': /* Environment override flag */
1601 1592 if (invert_this) {
1602 1593 env_wins = false;
1603 1594 } else {
1604 1595 env_wins = true;
1605 1596 }
1606 1597 return 0;
1607 1598 case 'f': /* Read alternative makefile(s) */
1608 1599 return 1;
1609 1600 case 'g': /* Use alternative DMake group */
1610 1601 if (invert_this) {
1611 1602 dmake_group_specified = false;
1612 1603 } else {
1613 1604 dmake_group_specified = true;
1614 1605 }
1615 1606 return 4;
1616 1607 case 'i': /* Ignore errors */
1617 1608 if (invert_this) {
1618 1609 ignore_errors_all = false;
1619 1610 } else {
1620 1611 ignore_errors_all = true;
1621 1612 }
1622 1613 return 0;
1623 1614 case 'j': /* Use alternative DMake max jobs */
1624 1615 if (invert_this) {
1625 1616 dmake_max_jobs_specified = false;
1626 1617 } else {
1627 1618 dmake_max_jobs_specified = true;
1628 1619 }
1629 1620 return 8;
1630 1621 case 'K': /* Read alternative .make.state */
1631 1622 return 256;
1632 1623 case 'k': /* Keep making even after errors */
1633 1624 if (invert_this) {
1634 1625 continue_after_error = false;
1635 1626 } else {
1636 1627 continue_after_error = true;
1637 1628 continue_after_error_ever_seen = true;
1638 1629 }
1639 1630 return 0;
1640 1631 case 'M': /* Read alternative make.machines file */
1641 1632 if (invert_this) {
1642 1633 pmake_machinesfile_specified = false;
1643 1634 } else {
1644 1635 pmake_machinesfile_specified = true;
1645 1636 dmake_mode_type = parallel_mode;
1646 1637 no_parallel = false;
1647 1638 }
1648 1639 return 16;
1649 1640 case 'm': /* Use alternative DMake build mode */
1650 1641 if (invert_this) {
1651 1642 dmake_mode_specified = false;
1652 1643 } else {
1653 1644 dmake_mode_specified = true;
1654 1645 }
1655 1646 return 32;
1656 1647 case 'x': /* Use alternative DMake mode */
1657 1648 if (invert_this) {
1658 1649 dmake_add_mode_specified = false;
1659 1650 } else {
1660 1651 dmake_add_mode_specified = true;
1661 1652 }
1662 1653 return 1024;
1663 1654 case 'N': /* Reverse -n */
1664 1655 if (invert_this) {
1665 1656 do_not_exec_rule = true;
1666 1657 } else {
1667 1658 do_not_exec_rule = false;
1668 1659 }
1669 1660 return 0;
1670 1661 case 'n': /* Print, not exec commands */
1671 1662 if (invert_this) {
1672 1663 do_not_exec_rule = false;
1673 1664 } else {
1674 1665 do_not_exec_rule = true;
1675 1666 }
1676 1667 return 0;
1677 1668 case 'O': /* Send job start & result msgs */
1678 1669 if (invert_this) {
1679 1670 send_mtool_msgs = false;
1680 1671 } else {
1681 1672 #ifdef DISTRIBUTED
1682 1673 send_mtool_msgs = true;
1683 1674 #endif
1684 1675 }
1685 1676 return 128;
1686 1677 case 'o': /* Use alternative dmake output dir */
1687 1678 if (invert_this) {
1688 1679 dmake_odir_specified = false;
1689 1680 } else {
1690 1681 dmake_odir_specified = true;
1691 1682 }
1692 1683 return 512;
1693 1684 case 'P': /* Print for selected targets */
1694 1685 if (invert_this) {
1695 1686 report_dependencies_level--;
1696 1687 } else {
1697 1688 report_dependencies_level++;
1698 1689 }
1699 1690 return 0;
1700 1691 case 'p': /* Print description */
1701 1692 if (invert_this) {
1702 1693 trace_status = false;
1703 1694 do_not_exec_rule = false;
1704 1695 } else {
1705 1696 trace_status = true;
1706 1697 do_not_exec_rule = true;
1707 1698 }
1708 1699 return 0;
1709 1700 case 'q': /* Question flag */
1710 1701 if (invert_this) {
1711 1702 quest = false;
1712 1703 } else {
1713 1704 quest = true;
1714 1705 }
1715 1706 return 0;
1716 1707 case 'R': /* Don't run in parallel */
1717 1708 #ifdef TEAMWARE_MAKE_CMN
1718 1709 if (invert_this) {
1719 1710 pmake_cap_r_specified = false;
1720 1711 no_parallel = false;
1721 1712 } else {
1722 1713 pmake_cap_r_specified = true;
1723 1714 dmake_mode_type = serial_mode;
1724 1715 no_parallel = true;
1725 1716 }
1726 1717 #else
1727 1718 warning(catgets(catd, 1, 182, "Ignoring ParallelMake -R option"));
1728 1719 #endif
1729 1720 return 0;
1730 1721 case 'r': /* Turn off internal rules */
1731 1722 if (invert_this) {
1732 1723 ignore_default_mk = false;
1733 1724 } else {
1734 1725 ignore_default_mk = true;
1735 1726 }
1736 1727 return 0;
1737 1728 case 'S': /* Reverse -k */
1738 1729 if (invert_this) {
1739 1730 continue_after_error = true;
1740 1731 } else {
1741 1732 continue_after_error = false;
1742 1733 stop_after_error_ever_seen = true;
1743 1734 }
1744 1735 return 0;
1745 1736 case 's': /* Silent flag */
1746 1737 if (invert_this) {
1747 1738 silent_all = false;
1748 1739 } else {
1749 1740 silent_all = true;
1750 1741 }
1751 1742 return 0;
1752 1743 case 'T': /* Print target list */
1753 1744 if (invert_this) {
1754 1745 list_all_targets = false;
1755 1746 do_not_exec_rule = false;
1756 1747 } else {
1757 1748 list_all_targets = true;
1758 1749 do_not_exec_rule = true;
1759 1750 }
1760 1751 return 0;
1761 1752 case 't': /* Touch flag */
1762 1753 if (invert_this) {
1763 1754 touch = false;
1764 1755 } else {
1765 1756 touch = true;
1766 1757 }
1767 1758 return 0;
1768 1759 case 'u': /* Unconditional flag */
1769 1760 if (invert_this) {
1770 1761 build_unconditional = false;
1771 1762 } else {
1772 1763 build_unconditional = true;
1773 1764 }
1774 1765 return 0;
1775 1766 case 'V': /* SVR4 mode */
1776 1767 svr4 = true;
1777 1768 return 0;
1778 1769 case 'v': /* Version flag */
1779 1770 if (invert_this) {
1780 1771 } else {
1781 1772 #ifdef TEAMWARE_MAKE_CMN
1782 1773 fprintf(stdout, NOCATGETS("dmake: %s\n"), verstring);
1783 1774 exit_status = 0;
1784 1775 exit(0);
1785 1776 #else
1786 1777 warning(catgets(catd, 1, 324, "Ignoring DistributedMake -v option"));
1787 1778 #endif
1788 1779 }
1789 1780 return 0;
1790 1781 case 'w': /* Unconditional flag */
1791 1782 if (invert_this) {
1792 1783 report_cwd = false;
1793 1784 } else {
1794 1785 report_cwd = true;
1795 1786 }
1796 1787 return 0;
1797 1788 #if 0
1798 1789 case 'X': /* Filter stdout */
1799 1790 if (invert_this) {
1800 1791 filter_stderr = false;
1801 1792 } else {
1802 1793 filter_stderr = true;
1803 1794 }
1804 1795 return 0;
1805 1796 #endif
1806 1797 default:
1807 1798 break;
1808 1799 }
1809 1800 return 0;
1810 1801 }
1811 1802
1812 1803 /*
1813 1804 * setup_for_projectdir()
1814 1805 *
1815 1806 * Read the PROJECTDIR variable, if defined, and set the sccs path
1816 1807 *
1817 1808 * Parameters:
1818 1809 *
1819 1810 * Global variables used:
1820 1811 * sccs_dir_path Set to point to SCCS dir to use
1821 1812 */
1822 1813 static void
1823 1814 setup_for_projectdir(void)
1824 1815 {
1825 1816 static char path[MAXPATHLEN];
1826 1817 char cwdpath[MAXPATHLEN];
1827 1818 uid_t uid;
1828 1819 int done=0;
1829 1820
1830 1821 /* Check if we should use PROJECTDIR when reading the SCCS dir. */
1831 1822 sccs_dir_path = getenv(NOCATGETS("PROJECTDIR"));
1832 1823 if ((sccs_dir_path != NULL) &&
1833 1824 (sccs_dir_path[0] != (int) slash_char)) {
1834 1825 struct passwd *pwent;
1835 1826
1836 1827 {
1837 1828 uid = getuid();
1838 1829 pwent = getpwuid(uid);
1839 1830 if (pwent == NULL) {
1840 1831 fatal(catgets(catd, 1, 188, "Bogus USERID "));
1841 1832 }
1842 1833 if ((pwent = getpwnam(sccs_dir_path)) == NULL) {
1843 1834 /*empty block : it'll go & check cwd */
1844 1835 }
1845 1836 else {
1846 1837 (void) sprintf(path, NOCATGETS("%s/src"), pwent->pw_dir);
1847 1838 if (access(path, F_OK) == 0) {
1848 1839 sccs_dir_path = path;
1849 1840 done = 1;
1850 1841 } else {
1851 1842 (void) sprintf(path, NOCATGETS("%s/source"), pwent->pw_dir);
1852 1843 if (access(path, F_OK) == 0) {
1853 1844 sccs_dir_path = path;
1854 1845 done = 1;
1855 1846 }
1856 1847 }
1857 1848 }
1858 1849 if (!done) {
1859 1850 if (getcwd(cwdpath, MAXPATHLEN - 1 )) {
1860 1851
1861 1852 (void) sprintf(path, NOCATGETS("%s/%s"), cwdpath,sccs_dir_path);
1862 1853 if (access(path, F_OK) == 0) {
1863 1854 sccs_dir_path = path;
1864 1855 done = 1;
1865 1856 } else {
1866 1857 fatal(catgets(catd, 1, 189, "Bogus PROJECTDIR '%s'"), sccs_dir_path);
1867 1858 }
1868 1859 }
1869 1860 }
1870 1861 }
1871 1862 }
1872 1863 }
1873 1864
1874 1865 /*
1875 1866 * set_sgs_support()
1876 1867 *
1877 1868 * Add the libmakestate.so.1 lib to the env var SGS_SUPPORT
1878 1869 * if it's not already in there.
1879 1870 * The SGS_SUPPORT env var and libmakestate.so.1 is used by
1880 1871 * the linker ld to report .make.state info back to make.
1881 1872 */
1882 1873 static void
1883 1874 set_sgs_support()
1884 1875 {
1885 1876 int len;
1886 1877 char *newpath;
1887 1878 char *oldpath;
1888 1879 static char *prev_path;
1889 1880
1890 1881 oldpath = getenv(LD_SUPPORT_ENV_VAR);
1891 1882 if (oldpath == NULL) {
1892 1883 len = strlen(LD_SUPPORT_ENV_VAR) + 1 +
1893 1884 strlen(LD_SUPPORT_MAKE_LIB) + 1;
1894 1885 newpath = (char *) malloc(len);
1895 1886 sprintf(newpath, "%s=", LD_SUPPORT_ENV_VAR);
1896 1887 } else {
1897 1888 len = strlen(LD_SUPPORT_ENV_VAR) + 1 + strlen(oldpath) + 1 +
1898 1889 strlen(LD_SUPPORT_MAKE_LIB) + 1;
1899 1890 newpath = (char *) malloc(len);
1900 1891 sprintf(newpath, "%s=%s", LD_SUPPORT_ENV_VAR, oldpath);
1901 1892 }
1902 1893
1903 1894 #if defined(TEAMWARE_MAKE_CMN)
1904 1895
1905 1896 /* function maybe_append_str_to_env_var() is defined in avo_util library
1906 1897 * Serial make should not use this library !!!
1907 1898 */
1908 1899 maybe_append_str_to_env_var(newpath, LD_SUPPORT_MAKE_LIB);
1909 1900 #else
1910 1901 if (oldpath == NULL) {
1911 1902 sprintf(newpath, "%s%s", newpath, LD_SUPPORT_MAKE_LIB);
1912 1903 } else {
1913 1904 sprintf(newpath, "%s:%s", newpath, LD_SUPPORT_MAKE_LIB);
1914 1905 }
1915 1906 #endif
1916 1907 putenv(newpath);
1917 1908 if (prev_path) {
1918 1909 free(prev_path);
1919 1910 }
1920 1911 prev_path = newpath;
1921 1912 }
1922 1913
1923 1914 /*
1924 1915 * read_files_and_state(argc, argv)
1925 1916 *
1926 1917 * Read the makefiles we care about and the environment
1927 1918 * Also read the = style command line options
1928 1919 *
1929 1920 * Parameters:
1930 1921 * argc You know what this is
1931 1922 * argv You know what this is
1932 1923 *
1933 1924 * Static variables used:
1934 1925 * env_wins make -e, determines if env vars are RO
1935 1926 * ignore_default_mk make -r, determines if make.rules is read
1936 1927 * not_auto_depen dwight
1937 1928 *
1938 1929 * Global variables used:
1939 1930 * default_target_to_build Set to first proper target from file
1940 1931 * do_not_exec_rule Set to false when makfile is made
1941 1932 * dot The Name ".", used to read current dir
1942 1933 * empty_name The Name "", use as macro value
1943 1934 * keep_state Set if KEEP_STATE is in environment
1944 1935 * make_state The Name ".make.state", used to read file
1945 1936 * makefile_type Set to type of file being read
1946 1937 * makeflags The Name "MAKEFLAGS", used to set macro value
1947 1938 * not_auto dwight
1948 1939 * read_trace_level Checked to se if the reader should trace
1949 1940 * report_dependencies If -P is on we do not read .make.state
1950 1941 * trace_reader Set if reader should trace
1951 1942 * virtual_root The Name "VIRTUAL_ROOT", used to check value
1952 1943 */
1953 1944 static void
1954 1945 read_files_and_state(int argc, char **argv)
1955 1946 {
1956 1947 wchar_t buffer[1000];
1957 1948 wchar_t buffer_posix[1000];
1958 1949 register char ch;
1959 1950 register char *cp;
1960 1951 Property def_make_macro = NULL;
1961 1952 Name def_make_name;
1962 1953 Name default_makefile;
1963 1954 String_rec dest;
1964 1955 wchar_t destbuffer[STRING_BUFFER_LENGTH];
1965 1956 register int i;
1966 1957 register int j;
1967 1958 Name keep_state_name;
1968 1959 int length;
1969 1960 Name Makefile;
1970 1961 register Property macro;
1971 1962 struct stat make_state_stat;
1972 1963 Name makefile_name;
1973 1964 register int makefile_next = 0;
1974 1965 register Boolean makefile_read = false;
1975 1966 String_rec makeflags_string;
1976 1967 String_rec makeflags_string_posix;
1977 1968 String_rec * makeflags_string_current;
1978 1969 Name makeflags_value_saved;
1979 1970 register Name name;
1980 1971 Name new_make_value;
1981 1972 Boolean save_do_not_exec_rule;
1982 1973 Name sdotMakefile;
1983 1974 Name sdotmakefile_name;
1984 1975 static wchar_t state_file_str;
1985 1976 static char state_file_str_mb[MAXPATHLEN];
1986 1977 static struct _Name state_filename;
1987 1978 Boolean temp;
1988 1979 char tmp_char;
1989 1980 wchar_t *tmp_wcs_buffer;
1990 1981 register Name value;
1991 1982 ASCII_Dyn_Array makeflags_and_macro;
1992 1983 Boolean is_xpg4;
1993 1984
1994 1985 /*
1995 1986 * Remember current mode. It may be changed after reading makefile
1996 1987 * and we will have to correct MAKEFLAGS variable.
1997 1988 */
1998 1989 is_xpg4 = posix;
1999 1990
2000 1991 MBSTOWCS(wcs_buffer, NOCATGETS("KEEP_STATE"));
2001 1992 keep_state_name = GETNAME(wcs_buffer, FIND_LENGTH);
2002 1993 MBSTOWCS(wcs_buffer, NOCATGETS("Makefile"));
2003 1994 Makefile = GETNAME(wcs_buffer, FIND_LENGTH);
2004 1995 MBSTOWCS(wcs_buffer, NOCATGETS("makefile"));
2005 1996 makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
2006 1997 MBSTOWCS(wcs_buffer, NOCATGETS("s.makefile"));
2007 1998 sdotmakefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
2008 1999 MBSTOWCS(wcs_buffer, NOCATGETS("s.Makefile"));
2009 2000 sdotMakefile = GETNAME(wcs_buffer, FIND_LENGTH);
2010 2001
2011 2002 /*
2012 2003 * Set flag if NSE is active
2013 2004 */
2014 2005
2015 2006 /*
2016 2007 * initialize global dependency entry for .NOT_AUTO
2017 2008 */
2018 2009 not_auto_depen->next = NULL;
2019 2010 not_auto_depen->name = not_auto;
2020 2011 not_auto_depen->automatic = not_auto_depen->stale = false;
2021 2012
2022 2013 /*
2023 2014 * Read internal definitions and rules.
2024 2015 */
2025 2016 if (read_trace_level > 1) {
2026 2017 trace_reader = true;
2027 2018 }
2028 2019 if (!ignore_default_mk) {
2029 2020 if (svr4) {
2030 2021 MBSTOWCS(wcs_buffer, NOCATGETS("svr4.make.rules"));
2031 2022 default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
2032 2023 } else {
2033 2024 MBSTOWCS(wcs_buffer, NOCATGETS("make.rules"));
2034 2025 default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
2035 2026 }
2036 2027 default_makefile->stat.is_file = true;
2037 2028
2038 2029 (void) read_makefile(default_makefile,
2039 2030 true,
2040 2031 false,
2041 2032 true);
2042 2033 }
2043 2034
2044 2035 /*
2045 2036 * If the user did not redefine the MAKE macro in the
2046 2037 * default makefile (make.rules), then we'd like to
2047 2038 * change the macro value of MAKE to be some form
2048 2039 * of argv[0] for recursive MAKE builds.
2049 2040 */
2050 2041 MBSTOWCS(wcs_buffer, NOCATGETS("MAKE"));
2051 2042 def_make_name = GETNAME(wcs_buffer, wslen(wcs_buffer));
2052 2043 def_make_macro = get_prop(def_make_name->prop, macro_prop);
2053 2044 if ((def_make_macro != NULL) &&
2054 2045 (IS_EQUAL(def_make_macro->body.macro.value->string_mb,
2055 2046 NOCATGETS("make")))) {
2056 2047 MBSTOWCS(wcs_buffer, argv_zero_string);
2057 2048 new_make_value = GETNAME(wcs_buffer, wslen(wcs_buffer));
2058 2049 (void) SETVAR(def_make_name,
2059 2050 new_make_value,
2060 2051 false);
2061 2052 }
2062 2053
2063 2054 default_target_to_build = NULL;
2064 2055 trace_reader = false;
2065 2056
2066 2057 /*
2067 2058 * Read environment args. Let file args which follow override unless
2068 2059 * -e option seen. If -e option is not mentioned.
2069 2060 */
2070 2061 read_environment(env_wins);
2071 2062 if (getvar(virtual_root)->hash.length == 0) {
2072 2063 maybe_append_prop(virtual_root, macro_prop)
2073 2064 ->body.macro.exported = true;
2074 2065 MBSTOWCS(wcs_buffer, "/");
2075 2066 (void) SETVAR(virtual_root,
2076 2067 GETNAME(wcs_buffer, FIND_LENGTH),
2077 2068 false);
2078 2069 }
2079 2070
2080 2071 /*
2081 2072 * We now scan mf_argv and argv to see if we need to set
2082 2073 * any of the DMake-added options/variables in MAKEFLAGS.
2083 2074 */
2084 2075
2085 2076 makeflags_and_macro.start = 0;
2086 2077 makeflags_and_macro.size = 0;
2087 2078 enter_argv_values(mf_argc, mf_argv, &makeflags_and_macro);
2088 2079 enter_argv_values(argc, argv, &makeflags_and_macro);
2089 2080
2090 2081 /*
2091 2082 * Set MFLAGS and MAKEFLAGS
2092 2083 *
2093 2084 * Before reading makefile we do not know exactly which mode
2094 2085 * (posix or not) is used. So prepare two MAKEFLAGS strings
2095 2086 * for both posix and solaris modes because they are different.
2096 2087 */
2097 2088 INIT_STRING_FROM_STACK(makeflags_string, buffer);
2098 2089 INIT_STRING_FROM_STACK(makeflags_string_posix, buffer_posix);
2099 2090 append_char((int) hyphen_char, &makeflags_string);
2100 2091 append_char((int) hyphen_char, &makeflags_string_posix);
2101 2092
2102 2093 switch (read_trace_level) {
2103 2094 case 2:
2104 2095 append_char('D', &makeflags_string);
2105 2096 append_char('D', &makeflags_string_posix);
2106 2097 case 1:
2107 2098 append_char('D', &makeflags_string);
2108 2099 append_char('D', &makeflags_string_posix);
2109 2100 }
2110 2101 switch (debug_level) {
2111 2102 case 2:
2112 2103 append_char('d', &makeflags_string);
2113 2104 append_char('d', &makeflags_string_posix);
2114 2105 case 1:
2115 2106 append_char('d', &makeflags_string);
2116 2107 append_char('d', &makeflags_string_posix);
2117 2108 }
2118 2109 if (env_wins) {
2119 2110 append_char('e', &makeflags_string);
2120 2111 append_char('e', &makeflags_string_posix);
2121 2112 }
2122 2113 if (ignore_errors_all) {
2123 2114 append_char('i', &makeflags_string);
2124 2115 append_char('i', &makeflags_string_posix);
2125 2116 }
2126 2117 if (continue_after_error) {
2127 2118 if (stop_after_error_ever_seen) {
2128 2119 append_char('S', &makeflags_string_posix);
2129 2120 append_char((int) space_char, &makeflags_string_posix);
2130 2121 append_char((int) hyphen_char, &makeflags_string_posix);
2131 2122 }
2132 2123 append_char('k', &makeflags_string);
2133 2124 append_char('k', &makeflags_string_posix);
2134 2125 } else {
2135 2126 if (stop_after_error_ever_seen
2136 2127 && continue_after_error_ever_seen) {
2137 2128 append_char('k', &makeflags_string_posix);
2138 2129 append_char((int) space_char, &makeflags_string_posix);
2139 2130 append_char((int) hyphen_char, &makeflags_string_posix);
2140 2131 append_char('S', &makeflags_string_posix);
2141 2132 }
2142 2133 }
2143 2134 if (do_not_exec_rule) {
2144 2135 append_char('n', &makeflags_string);
2145 2136 append_char('n', &makeflags_string_posix);
2146 2137 }
2147 2138 switch (report_dependencies_level) {
2148 2139 case 4:
2149 2140 append_char('P', &makeflags_string);
2150 2141 append_char('P', &makeflags_string_posix);
2151 2142 case 3:
2152 2143 append_char('P', &makeflags_string);
2153 2144 append_char('P', &makeflags_string_posix);
2154 2145 case 2:
2155 2146 append_char('P', &makeflags_string);
2156 2147 append_char('P', &makeflags_string_posix);
2157 2148 case 1:
2158 2149 append_char('P', &makeflags_string);
2159 2150 append_char('P', &makeflags_string_posix);
2160 2151 }
2161 2152 if (trace_status) {
2162 2153 append_char('p', &makeflags_string);
2163 2154 append_char('p', &makeflags_string_posix);
2164 2155 }
2165 2156 if (quest) {
2166 2157 append_char('q', &makeflags_string);
2167 2158 append_char('q', &makeflags_string_posix);
2168 2159 }
2169 2160 if (silent_all) {
2170 2161 append_char('s', &makeflags_string);
2171 2162 append_char('s', &makeflags_string_posix);
2172 2163 }
2173 2164 if (touch) {
2174 2165 append_char('t', &makeflags_string);
2175 2166 append_char('t', &makeflags_string_posix);
2176 2167 }
2177 2168 if (build_unconditional) {
2178 2169 append_char('u', &makeflags_string);
2179 2170 append_char('u', &makeflags_string_posix);
2180 2171 }
2181 2172 if (report_cwd) {
2182 2173 append_char('w', &makeflags_string);
2183 2174 append_char('w', &makeflags_string_posix);
2184 2175 }
2185 2176 /* -c dmake_rcfile */
2186 2177 if (dmake_rcfile_specified) {
2187 2178 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
2188 2179 dmake_rcfile = GETNAME(wcs_buffer, FIND_LENGTH);
2189 2180 append_makeflags_string(dmake_rcfile, &makeflags_string);
2190 2181 append_makeflags_string(dmake_rcfile, &makeflags_string_posix);
2191 2182 }
2192 2183 /* -g dmake_group */
2193 2184 if (dmake_group_specified) {
2194 2185 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_GROUP"));
2195 2186 dmake_group = GETNAME(wcs_buffer, FIND_LENGTH);
2196 2187 append_makeflags_string(dmake_group, &makeflags_string);
2197 2188 append_makeflags_string(dmake_group, &makeflags_string_posix);
2198 2189 }
2199 2190 /* -j dmake_max_jobs */
2200 2191 if (dmake_max_jobs_specified) {
2201 2192 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
2202 2193 dmake_max_jobs = GETNAME(wcs_buffer, FIND_LENGTH);
2203 2194 append_makeflags_string(dmake_max_jobs, &makeflags_string);
2204 2195 append_makeflags_string(dmake_max_jobs, &makeflags_string_posix);
2205 2196 }
2206 2197 /* -m dmake_mode */
2207 2198 if (dmake_mode_specified) {
2208 2199 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
2209 2200 dmake_mode = GETNAME(wcs_buffer, FIND_LENGTH);
2210 2201 append_makeflags_string(dmake_mode, &makeflags_string);
2211 2202 append_makeflags_string(dmake_mode, &makeflags_string_posix);
2212 2203 }
2213 2204 /* -x dmake_compat_mode */
2214 2205 // if (dmake_compat_mode_specified) {
2215 2206 // MBSTOWCS(wcs_buffer, NOCATGETS("SUN_MAKE_COMPAT_MODE"));
2216 2207 // dmake_compat_mode = GETNAME(wcs_buffer, FIND_LENGTH);
2217 2208 // append_makeflags_string(dmake_compat_mode, &makeflags_string);
2218 2209 // append_makeflags_string(dmake_compat_mode, &makeflags_string_posix);
2219 2210 // }
2220 2211 /* -x dmake_output_mode */
2221 2212 if (dmake_output_mode_specified) {
2222 2213 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
2223 2214 dmake_output_mode = GETNAME(wcs_buffer, FIND_LENGTH);
2224 2215 append_makeflags_string(dmake_output_mode, &makeflags_string);
2225 2216 append_makeflags_string(dmake_output_mode, &makeflags_string_posix);
2226 2217 }
2227 2218 /* -o dmake_odir */
2228 2219 if (dmake_odir_specified) {
2229 2220 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
2230 2221 dmake_odir = GETNAME(wcs_buffer, FIND_LENGTH);
2231 2222 append_makeflags_string(dmake_odir, &makeflags_string);
2232 2223 append_makeflags_string(dmake_odir, &makeflags_string_posix);
2233 2224 }
2234 2225 /* -M pmake_machinesfile */
2235 2226 if (pmake_machinesfile_specified) {
2236 2227 MBSTOWCS(wcs_buffer, NOCATGETS("PMAKE_MACHINESFILE"));
2237 2228 pmake_machinesfile = GETNAME(wcs_buffer, FIND_LENGTH);
2238 2229 append_makeflags_string(pmake_machinesfile, &makeflags_string);
2239 2230 append_makeflags_string(pmake_machinesfile, &makeflags_string_posix);
2240 2231 }
2241 2232 /* -R */
2242 2233 if (pmake_cap_r_specified) {
2243 2234 append_char((int) space_char, &makeflags_string);
2244 2235 append_char((int) hyphen_char, &makeflags_string);
2245 2236 append_char('R', &makeflags_string);
2246 2237 append_char((int) space_char, &makeflags_string_posix);
2247 2238 append_char((int) hyphen_char, &makeflags_string_posix);
2248 2239 append_char('R', &makeflags_string_posix);
2249 2240 }
2250 2241
2251 2242 /*
2252 2243 * Make sure MAKEFLAGS is exported
2253 2244 */
2254 2245 maybe_append_prop(makeflags, macro_prop)->
2255 2246 body.macro.exported = true;
2256 2247
2257 2248 if (makeflags_string.buffer.start[1] != (int) nul_char) {
2258 2249 if (makeflags_string.buffer.start[1] != (int) space_char) {
2259 2250 MBSTOWCS(wcs_buffer, NOCATGETS("MFLAGS"));
2260 2251 (void) SETVAR(GETNAME(wcs_buffer, FIND_LENGTH),
2261 2252 GETNAME(makeflags_string.buffer.start,
2262 2253 FIND_LENGTH),
2263 2254 false);
2264 2255 } else {
2265 2256 MBSTOWCS(wcs_buffer, NOCATGETS("MFLAGS"));
2266 2257 (void) SETVAR(GETNAME(wcs_buffer, FIND_LENGTH),
2267 2258 GETNAME(makeflags_string.buffer.start + 2,
2268 2259 FIND_LENGTH),
2269 2260 false);
2270 2261 }
2271 2262 }
2272 2263
2273 2264 /*
2274 2265 * Add command line macro to POSIX makeflags_string
2275 2266 */
2276 2267 if (makeflags_and_macro.start) {
2277 2268 tmp_char = (char) space_char;
2278 2269 cp = makeflags_and_macro.start;
2279 2270 do {
2280 2271 append_char(tmp_char, &makeflags_string_posix);
2281 2272 } while ( tmp_char = *cp++ );
2282 2273 retmem_mb(makeflags_and_macro.start);
2283 2274 }
2284 2275
2285 2276 /*
2286 2277 * Now set the value of MAKEFLAGS macro in accordance
2287 2278 * with current mode.
2288 2279 */
2289 2280 macro = maybe_append_prop(makeflags, macro_prop);
2290 2281 temp = (Boolean) macro->body.macro.read_only;
2291 2282 macro->body.macro.read_only = false;
2292 2283 if(posix || gnu_style) {
2293 2284 makeflags_string_current = &makeflags_string_posix;
2294 2285 } else {
2295 2286 makeflags_string_current = &makeflags_string;
2296 2287 }
2297 2288 if (makeflags_string_current->buffer.start[1] == (int) nul_char) {
2298 2289 makeflags_value_saved =
2299 2290 GETNAME( makeflags_string_current->buffer.start + 1
2300 2291 , FIND_LENGTH
2301 2292 );
2302 2293 } else {
2303 2294 if (makeflags_string_current->buffer.start[1] != (int) space_char) {
2304 2295 makeflags_value_saved =
2305 2296 GETNAME( makeflags_string_current->buffer.start
2306 2297 , FIND_LENGTH
2307 2298 );
2308 2299 } else {
2309 2300 makeflags_value_saved =
2310 2301 GETNAME( makeflags_string_current->buffer.start + 2
2311 2302 , FIND_LENGTH
2312 2303 );
2313 2304 }
2314 2305 }
2315 2306 (void) SETVAR( makeflags
2316 2307 , makeflags_value_saved
2317 2308 , false
2318 2309 );
2319 2310 macro->body.macro.read_only = temp;
2320 2311
2321 2312 /*
2322 2313 * Read command line "-f" arguments and ignore -c, g, j, K, M, m, O and o args.
2323 2314 */
2324 2315 save_do_not_exec_rule = do_not_exec_rule;
2325 2316 do_not_exec_rule = false;
2326 2317 if (read_trace_level > 0) {
2327 2318 trace_reader = true;
2328 2319 }
2329 2320
2330 2321 for (i = 1; i < argc; i++) {
2331 2322 if (argv[i] &&
2332 2323 (argv[i][0] == (int) hyphen_char) &&
2333 2324 (argv[i][1] == 'f') &&
2334 2325 (argv[i][2] == (int) nul_char)) {
2335 2326 argv[i] = NULL; /* Remove -f */
2336 2327 if (i >= argc - 1) {
2337 2328 fatal(catgets(catd, 1, 190, "No filename argument after -f flag"));
2338 2329 }
2339 2330 MBSTOWCS(wcs_buffer, argv[++i]);
2340 2331 primary_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
2341 2332 (void) read_makefile(primary_makefile, true, true, true);
2342 2333 argv[i] = NULL; /* Remove filename */
2343 2334 makefile_read = true;
2344 2335 } else if (argv[i] &&
2345 2336 (argv[i][0] == (int) hyphen_char) &&
2346 2337 (argv[i][1] == 'c' ||
2347 2338 argv[i][1] == 'g' ||
2348 2339 argv[i][1] == 'j' ||
2349 2340 argv[i][1] == 'K' ||
2350 2341 argv[i][1] == 'M' ||
2351 2342 argv[i][1] == 'm' ||
2352 2343 argv[i][1] == 'O' ||
2353 2344 argv[i][1] == 'o') &&
2354 2345 (argv[i][2] == (int) nul_char)) {
2355 2346 argv[i] = NULL;
2356 2347 argv[++i] = NULL;
2357 2348 }
2358 2349 }
2359 2350
2360 2351 /*
2361 2352 * If no command line "-f" args then look for "makefile", and then for
2362 2353 * "Makefile" if "makefile" isn't found.
2363 2354 */
2364 2355 if (!makefile_read) {
2365 2356 (void) read_dir(dot,
2366 2357 (wchar_t *) NULL,
2367 2358 (Property) NULL,
2368 2359 (wchar_t *) NULL);
2369 2360 if (!posix) {
2370 2361 if (makefile_name->stat.is_file) {
2371 2362 if (Makefile->stat.is_file) {
2372 2363 warning(catgets(catd, 1, 310, "Both `makefile' and `Makefile' exist"));
2373 2364 }
2374 2365 primary_makefile = makefile_name;
2375 2366 makefile_read = read_makefile(makefile_name,
2376 2367 false,
2377 2368 false,
2378 2369 true);
2379 2370 }
2380 2371 if (!makefile_read &&
2381 2372 Makefile->stat.is_file) {
2382 2373 primary_makefile = Makefile;
2383 2374 makefile_read = read_makefile(Makefile,
2384 2375 false,
2385 2376 false,
2386 2377 true);
2387 2378 }
2388 2379 } else {
2389 2380
2390 2381 enum sccs_stat save_m_has_sccs = NO_SCCS;
2391 2382 enum sccs_stat save_M_has_sccs = NO_SCCS;
2392 2383
2393 2384 if (makefile_name->stat.is_file) {
2394 2385 if (Makefile->stat.is_file) {
2395 2386 warning(catgets(catd, 1, 191, "Both `makefile' and `Makefile' exist"));
2396 2387 }
2397 2388 }
2398 2389 if (makefile_name->stat.is_file) {
2399 2390 if (makefile_name->stat.has_sccs == NO_SCCS) {
2400 2391 primary_makefile = makefile_name;
2401 2392 makefile_read = read_makefile(makefile_name,
2402 2393 false,
2403 2394 false,
2404 2395 true);
2405 2396 } else {
2406 2397 save_m_has_sccs = makefile_name->stat.has_sccs;
2407 2398 makefile_name->stat.has_sccs = NO_SCCS;
2408 2399 primary_makefile = makefile_name;
2409 2400 makefile_read = read_makefile(makefile_name,
2410 2401 false,
2411 2402 false,
2412 2403 true);
2413 2404 }
2414 2405 }
2415 2406 if (!makefile_read &&
2416 2407 Makefile->stat.is_file) {
2417 2408 if (Makefile->stat.has_sccs == NO_SCCS) {
2418 2409 primary_makefile = Makefile;
2419 2410 makefile_read = read_makefile(Makefile,
2420 2411 false,
2421 2412 false,
2422 2413 true);
2423 2414 } else {
2424 2415 save_M_has_sccs = Makefile->stat.has_sccs;
2425 2416 Makefile->stat.has_sccs = NO_SCCS;
2426 2417 primary_makefile = Makefile;
2427 2418 makefile_read = read_makefile(Makefile,
2428 2419 false,
2429 2420 false,
2430 2421 true);
2431 2422 }
2432 2423 }
2433 2424 if (!makefile_read &&
2434 2425 makefile_name->stat.is_file) {
2435 2426 makefile_name->stat.has_sccs = save_m_has_sccs;
2436 2427 primary_makefile = makefile_name;
2437 2428 makefile_read = read_makefile(makefile_name,
2438 2429 false,
2439 2430 false,
2440 2431 true);
2441 2432 }
2442 2433 if (!makefile_read &&
2443 2434 Makefile->stat.is_file) {
2444 2435 Makefile->stat.has_sccs = save_M_has_sccs;
2445 2436 primary_makefile = Makefile;
2446 2437 makefile_read = read_makefile(Makefile,
2447 2438 false,
2448 2439 false,
2449 2440 true);
2450 2441 }
2451 2442 }
2452 2443 }
2453 2444 do_not_exec_rule = save_do_not_exec_rule;
2454 2445 allrules_read = makefile_read;
2455 2446 trace_reader = false;
2456 2447
2457 2448 /*
2458 2449 * Now get current value of MAKEFLAGS and compare it with
2459 2450 * the saved value we set before reading makefile.
2460 2451 * If they are different then MAKEFLAGS is subsequently set by
2461 2452 * makefile, just leave it there. Otherwise, if make mode
2462 2453 * is changed by using .POSIX target in makefile we need
2463 2454 * to correct MAKEFLAGS value.
2464 2455 */
2465 2456 Name mf_val = getvar(makeflags);
2466 2457 if( (posix != is_xpg4)
2467 2458 && (!strcmp(mf_val->string_mb, makeflags_value_saved->string_mb)))
2468 2459 {
2469 2460 if (makeflags_string_posix.buffer.start[1] == (int) nul_char) {
2470 2461 (void) SETVAR(makeflags,
2471 2462 GETNAME(makeflags_string_posix.buffer.start + 1,
2472 2463 FIND_LENGTH),
2473 2464 false);
2474 2465 } else {
2475 2466 if (makeflags_string_posix.buffer.start[1] != (int) space_char) {
2476 2467 (void) SETVAR(makeflags,
2477 2468 GETNAME(makeflags_string_posix.buffer.start,
2478 2469 FIND_LENGTH),
2479 2470 false);
2480 2471 } else {
2481 2472 (void) SETVAR(makeflags,
2482 2473 GETNAME(makeflags_string_posix.buffer.start + 2,
2483 2474 FIND_LENGTH),
2484 2475 false);
2485 2476 }
2486 2477 }
2487 2478 }
2488 2479
2489 2480 if (makeflags_string.free_after_use) {
2490 2481 retmem(makeflags_string.buffer.start);
2491 2482 }
2492 2483 if (makeflags_string_posix.free_after_use) {
2493 2484 retmem(makeflags_string_posix.buffer.start);
2494 2485 }
2495 2486 makeflags_string.buffer.start = NULL;
2496 2487 makeflags_string_posix.buffer.start = NULL;
2497 2488
2498 2489 if (posix) {
2499 2490 /*
2500 2491 * If the user did not redefine the ARFLAGS macro in the
2501 2492 * default makefile (make.rules), then we'd like to
2502 2493 * change the macro value of ARFLAGS to be in accordance
2503 2494 * with "POSIX" requirements.
2504 2495 */
2505 2496 MBSTOWCS(wcs_buffer, NOCATGETS("ARFLAGS"));
2506 2497 name = GETNAME(wcs_buffer, wslen(wcs_buffer));
2507 2498 macro = get_prop(name->prop, macro_prop);
2508 2499 if ((macro != NULL) && /* Maybe (macro == NULL) || ? */
2509 2500 (IS_EQUAL(macro->body.macro.value->string_mb,
2510 2501 NOCATGETS("rv")))) {
2511 2502 MBSTOWCS(wcs_buffer, NOCATGETS("-rv"));
2512 2503 value = GETNAME(wcs_buffer, wslen(wcs_buffer));
2513 2504 (void) SETVAR(name,
2514 2505 value,
2515 2506 false);
2516 2507 }
2517 2508 }
2518 2509
2519 2510 if (!posix && !svr4) {
2520 2511 set_sgs_support();
2521 2512 }
2522 2513
2523 2514
2524 2515 /*
2525 2516 * Make sure KEEP_STATE is in the environment if KEEP_STATE is on.
2526 2517 */
2527 2518 macro = get_prop(keep_state_name->prop, macro_prop);
2528 2519 if ((macro != NULL) &&
2529 2520 macro->body.macro.exported) {
2530 2521 keep_state = true;
2531 2522 }
2532 2523 if (keep_state) {
2533 2524 if (macro == NULL) {
2534 2525 macro = maybe_append_prop(keep_state_name,
2535 2526 macro_prop);
2536 2527 }
2537 2528 macro->body.macro.exported = true;
2538 2529 (void) SETVAR(keep_state_name,
2539 2530 empty_name,
2540 2531 false);
2541 2532
2542 2533 /*
2543 2534 * Read state file
2544 2535 */
2545 2536
2546 2537 /* Before we read state, let's make sure we have
2547 2538 ** right state file.
2548 2539 */
2549 2540 /* just in case macro references are used in make_state file
2550 2541 ** name, we better expand them at this stage using expand_value.
2551 2542 */
2552 2543 INIT_STRING_FROM_STACK(dest, destbuffer);
2553 2544 expand_value(make_state, &dest, false);
2554 2545
2555 2546 make_state = GETNAME(dest.buffer.start, FIND_LENGTH);
2556 2547
2557 2548 if(!stat(make_state->string_mb, &make_state_stat)) {
2558 2549 if(!(make_state_stat.st_mode & S_IFREG) ) {
2559 2550 /* copy the make_state structure to the other
2560 2551 ** and then let make_state point to the new
2561 2552 ** one.
2562 2553 */
2563 2554 memcpy(&state_filename, make_state,sizeof(state_filename));
2564 2555 state_filename.string_mb = state_file_str_mb;
2565 2556 /* Just a kludge to avoid two slashes back to back */
2566 2557 if((make_state->hash.length == 1)&&
2567 2558 (make_state->string_mb[0] == '/')) {
2568 2559 make_state->hash.length = 0;
2569 2560 make_state->string_mb[0] = '\0';
2570 2561 }
2571 2562 sprintf(state_file_str_mb,NOCATGETS("%s%s"),
2572 2563 make_state->string_mb,NOCATGETS("/.make.state"));
2573 2564 make_state = &state_filename;
2574 2565 /* adjust the length to reflect the appended string */
2575 2566 make_state->hash.length += 12;
2576 2567 }
2577 2568 } else { /* the file doesn't exist or no permission */
2578 2569 char tmp_path[MAXPATHLEN];
2579 2570 char *slashp;
2580 2571
2581 2572 if (slashp = strrchr(make_state->string_mb, '/')) {
2582 2573 strncpy(tmp_path, make_state->string_mb,
2583 2574 (slashp - make_state->string_mb));
2584 2575 tmp_path[slashp - make_state->string_mb]=0;
2585 2576 if(strlen(tmp_path)) {
2586 2577 if(stat(tmp_path, &make_state_stat)) {
2587 2578 warning(catgets(catd, 1, 192, "directory %s for .KEEP_STATE_FILE does not exist"),tmp_path);
2588 2579 }
2589 2580 if (access(tmp_path, F_OK) != 0) {
2590 2581 warning(catgets(catd, 1, 193, "can't access dir %s"),tmp_path);
2591 2582 }
2592 2583 }
2593 2584 }
2594 2585 }
2595 2586 if (report_dependencies_level != 1) {
2596 2587 Makefile_type makefile_type_temp = makefile_type;
2597 2588 makefile_type = reading_statefile;
2598 2589 if (read_trace_level > 1) {
2599 2590 trace_reader = true;
2600 2591 }
2601 2592 (void) read_simple_file(make_state,
2602 2593 false,
2603 2594 false,
2604 2595 false,
2605 2596 false,
2606 2597 false,
2607 2598 true);
2608 2599 trace_reader = false;
2609 2600 makefile_type = makefile_type_temp;
2610 2601 }
2611 2602 }
2612 2603 }
2613 2604
2614 2605 /*
2615 2606 * Scan the argv for options and "=" type args and make them readonly.
2616 2607 */
2617 2608 static void
2618 2609 enter_argv_values(int argc, char *argv[], ASCII_Dyn_Array *makeflags_and_macro)
2619 2610 {
2620 2611 register char *cp;
2621 2612 register int i;
2622 2613 int length;
2623 2614 register Name name;
2624 2615 int opt_separator = argc;
2625 2616 char tmp_char;
2626 2617 wchar_t *tmp_wcs_buffer;
2627 2618 register Name value;
2628 2619 Boolean append = false;
2629 2620 Property macro;
2630 2621 struct stat statbuf;
2631 2622
2632 2623
2633 2624 /* Read argv options and "=" type args and make them readonly. */
2634 2625 makefile_type = reading_nothing;
2635 2626 for (i = 1; i < argc; ++i) {
2636 2627 append = false;
2637 2628 if (argv[i] == NULL) {
2638 2629 continue;
2639 2630 } else if (((argv[i][0] == '-') && (argv[i][1] == '-')) ||
2640 2631 ((argv[i][0] == (int) ' ') &&
2641 2632 (argv[i][1] == (int) '-') &&
2642 2633 (argv[i][2] == (int) ' ') &&
2643 2634 (argv[i][3] == (int) '-'))) {
2644 2635 argv[i] = NULL;
2645 2636 opt_separator = i;
2646 2637 continue;
2647 2638 } else if ((i < opt_separator) && (argv[i][0] == (int) hyphen_char)) {
2648 2639 switch (parse_command_option(argv[i][1])) {
2649 2640 case 1: /* -f seen */
2650 2641 ++i;
2651 2642 continue;
2652 2643 case 2: /* -c seen */
2653 2644 if (argv[i+1] == NULL) {
2654 2645 fatal(catgets(catd, 1, 194, "No dmake rcfile argument after -c flag"));
2655 2646 }
2656 2647 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
2657 2648 name = GETNAME(wcs_buffer, FIND_LENGTH);
2658 2649 break;
2659 2650 case 4: /* -g seen */
2660 2651 if (argv[i+1] == NULL) {
2661 2652 fatal(catgets(catd, 1, 195, "No dmake group argument after -g flag"));
2662 2653 }
2663 2654 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_GROUP"));
2664 2655 name = GETNAME(wcs_buffer, FIND_LENGTH);
2665 2656 break;
2666 2657 case 8: /* -j seen */
2667 2658 if (argv[i+1] == NULL) {
2668 2659 fatal(catgets(catd, 1, 196, "No dmake max jobs argument after -j flag"));
2669 2660 }
2670 2661 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
2671 2662 name = GETNAME(wcs_buffer, FIND_LENGTH);
2672 2663 break;
2673 2664 case 16: /* -M seen */
2674 2665 if (argv[i+1] == NULL) {
2675 2666 fatal(catgets(catd, 1, 323, "No pmake machinesfile argument after -M flag"));
2676 2667 }
2677 2668 MBSTOWCS(wcs_buffer, NOCATGETS("PMAKE_MACHINESFILE"));
2678 2669 name = GETNAME(wcs_buffer, FIND_LENGTH);
2679 2670 break;
2680 2671 case 32: /* -m seen */
2681 2672 if (argv[i+1] == NULL) {
2682 2673 fatal(catgets(catd, 1, 197, "No dmake mode argument after -m flag"));
2683 2674 }
2684 2675 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
2685 2676 name = GETNAME(wcs_buffer, FIND_LENGTH);
2686 2677 break;
2687 2678 case 128: /* -O seen */
2688 2679 if (argv[i+1] == NULL) {
2689 2680 fatal(catgets(catd, 1, 287, "No file descriptor argument after -O flag"));
2690 2681 }
2691 2682 mtool_msgs_fd = atoi(argv[i+1]);
2692 2683 /* find out if mtool_msgs_fd is a valid file descriptor */
2693 2684 if (fstat(mtool_msgs_fd, &statbuf) < 0) {
2694 2685 fatal(catgets(catd, 1, 355, "Invalid file descriptor %d after -O flag"), mtool_msgs_fd);
2695 2686 }
2696 2687 argv[i] = NULL;
2697 2688 argv[i+1] = NULL;
2698 2689 continue;
2699 2690 case 256: /* -K seen */
2700 2691 if (argv[i+1] == NULL) {
2701 2692 fatal(catgets(catd, 1, 288, "No makestate filename argument after -K flag"));
2702 2693 }
2703 2694 MBSTOWCS(wcs_buffer, argv[i+1]);
2704 2695 make_state = GETNAME(wcs_buffer, FIND_LENGTH);
2705 2696 keep_state = true;
2706 2697 argv[i] = NULL;
2707 2698 argv[i+1] = NULL;
2708 2699 continue;
2709 2700 case 512: /* -o seen */
2710 2701 if (argv[i+1] == NULL) {
2711 2702 fatal(catgets(catd, 1, 312, "No dmake output dir argument after -o flag"));
2712 2703 }
2713 2704 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
2714 2705 name = GETNAME(wcs_buffer, FIND_LENGTH);
2715 2706 break;
2716 2707 case 1024: /* -x seen */
2717 2708 if (argv[i+1] == NULL) {
2718 2709 fatal(catgets(catd, 1, 351, "No argument after -x flag"));
2719 2710 }
2720 2711 length = strlen( NOCATGETS("SUN_MAKE_COMPAT_MODE="));
2721 2712 if (strncmp(argv[i+1], NOCATGETS("SUN_MAKE_COMPAT_MODE="), length) == 0) {
2722 2713 argv[i+1] = &argv[i+1][length];
2723 2714 MBSTOWCS(wcs_buffer, NOCATGETS("SUN_MAKE_COMPAT_MODE"));
2724 2715 name = GETNAME(wcs_buffer, FIND_LENGTH);
2725 2716 dmake_compat_mode_specified = dmake_add_mode_specified;
2726 2717 break;
2727 2718 }
2728 2719 length = strlen( NOCATGETS("DMAKE_OUTPUT_MODE="));
2729 2720 if (strncmp(argv[i+1], NOCATGETS("DMAKE_OUTPUT_MODE="), length) == 0) {
2730 2721 argv[i+1] = &argv[i+1][length];
2731 2722 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
2732 2723 name = GETNAME(wcs_buffer, FIND_LENGTH);
2733 2724 dmake_output_mode_specified = dmake_add_mode_specified;
2734 2725 } else {
2735 2726 warning(catgets(catd, 1, 354, "Unknown argument `%s' after -x flag (ignored)"),
2736 2727 argv[i+1]);
2737 2728 argv[i] = argv[i + 1] = NULL;
2738 2729 continue;
2739 2730 }
2740 2731 break;
2741 2732 default: /* Shouldn't reach here */
2742 2733 argv[i] = NULL;
2743 2734 continue;
2744 2735 }
2745 2736 argv[i] = NULL;
2746 2737 if (i == (argc - 1)) {
2747 2738 break;
2748 2739 }
2749 2740 if ((length = strlen(argv[i+1])) >= MAXPATHLEN) {
2750 2741 tmp_wcs_buffer = ALLOC_WC(length + 1);
2751 2742 (void) mbstowcs(tmp_wcs_buffer, argv[i+1], length + 1);
2752 2743 value = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
2753 2744 retmem(tmp_wcs_buffer);
2754 2745 } else {
2755 2746 MBSTOWCS(wcs_buffer, argv[i+1]);
2756 2747 value = GETNAME(wcs_buffer, FIND_LENGTH);
2757 2748 }
2758 2749 argv[i+1] = NULL;
2759 2750 } else if ((cp = strchr(argv[i], (int) equal_char)) != NULL) {
2760 2751 /*
2761 2752 * Combine all macro in dynamic array
2762 2753 */
2763 2754 if(*(cp-1) == (int) plus_char)
2764 2755 {
2765 2756 if(isspace(*(cp-2))) {
2766 2757 append = true;
2767 2758 cp--;
2768 2759 }
2769 2760 }
2770 2761 if(!append)
2771 2762 append_or_replace_macro_in_dyn_array(makeflags_and_macro, argv[i]);
2772 2763
2773 2764 while (isspace(*(cp-1))) {
2774 2765 cp--;
2775 2766 }
2776 2767 tmp_char = *cp;
2777 2768 *cp = (int) nul_char;
2778 2769 MBSTOWCS(wcs_buffer, argv[i]);
2779 2770 *cp = tmp_char;
2780 2771 name = GETNAME(wcs_buffer, wslen(wcs_buffer));
2781 2772 while (*cp != (int) equal_char) {
2782 2773 cp++;
2783 2774 }
2784 2775 cp++;
2785 2776 while (isspace(*cp) && (*cp != (int) nul_char)) {
2786 2777 cp++;
2787 2778 }
2788 2779 if ((length = strlen(cp)) >= MAXPATHLEN) {
2789 2780 tmp_wcs_buffer = ALLOC_WC(length + 1);
2790 2781 (void) mbstowcs(tmp_wcs_buffer, cp, length + 1);
2791 2782 value = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
2792 2783 retmem(tmp_wcs_buffer);
2793 2784 } else {
2794 2785 MBSTOWCS(wcs_buffer, cp);
2795 2786 value = GETNAME(wcs_buffer, FIND_LENGTH);
2796 2787 }
2797 2788 argv[i] = NULL;
2798 2789 } else {
2799 2790 /* Illegal MAKEFLAGS argument */
2800 2791 continue;
2801 2792 }
2802 2793 if(append) {
2803 2794 setvar_append(name, value);
2804 2795 append = false;
2805 2796 } else {
2806 2797 macro = maybe_append_prop(name, macro_prop);
2807 2798 macro->body.macro.exported = true;
2808 2799 SETVAR(name, value, false)->body.macro.read_only = true;
2809 2800 }
2810 2801 }
2811 2802 }
2812 2803
2813 2804 /*
2814 2805 * Append the DMake option and value to the MAKEFLAGS string.
2815 2806 */
2816 2807 static void
2817 2808 append_makeflags_string(Name name, register String makeflags_string)
2818 2809 {
2819 2810 const char *option;
2820 2811
2821 2812 if (strcmp(name->string_mb, NOCATGETS("DMAKE_GROUP")) == 0) {
2822 2813 option = NOCATGETS(" -g ");
2823 2814 } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_MAX_JOBS")) == 0) {
2824 2815 option = NOCATGETS(" -j ");
2825 2816 } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_MODE")) == 0) {
2826 2817 option = NOCATGETS(" -m ");
2827 2818 } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_ODIR")) == 0) {
2828 2819 option = NOCATGETS(" -o ");
2829 2820 } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_RCFILE")) == 0) {
2830 2821 option = NOCATGETS(" -c ");
2831 2822 } else if (strcmp(name->string_mb, NOCATGETS("PMAKE_MACHINESFILE")) == 0) {
2832 2823 option = NOCATGETS(" -M ");
2833 2824 } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_OUTPUT_MODE")) == 0) {
2834 2825 option = NOCATGETS(" -x DMAKE_OUTPUT_MODE=");
2835 2826 } else if (strcmp(name->string_mb, NOCATGETS("SUN_MAKE_COMPAT_MODE")) == 0) {
2836 2827 option = NOCATGETS(" -x SUN_MAKE_COMPAT_MODE=");
2837 2828 } else {
2838 2829 fatal(catgets(catd, 1, 289, "Internal error: name not recognized in append_makeflags_string()"));
2839 2830 }
2840 2831 Property prop = maybe_append_prop(name, macro_prop);
2841 2832 if( prop == 0 || prop->body.macro.value == 0 ||
2842 2833 prop->body.macro.value->string_mb == 0 ) {
2843 2834 return;
2844 2835 }
2845 2836 char mbs_value[MAXPATHLEN + 100];
2846 2837 strcpy(mbs_value, option);
2847 2838 strcat(mbs_value, prop->body.macro.value->string_mb);
2848 2839 MBSTOWCS(wcs_buffer, mbs_value);
2849 2840 append_string(wcs_buffer, makeflags_string, FIND_LENGTH);
2850 2841 }
2851 2842
2852 2843 /*
2853 2844 * read_environment(read_only)
2854 2845 *
2855 2846 * This routine reads the process environment when make starts and enters
2856 2847 * it as make macros. The environment variable SHELL is ignored.
2857 2848 *
2858 2849 * Parameters:
2859 2850 * read_only Should we make env vars read only?
2860 2851 *
2861 2852 * Global variables used:
2862 2853 * report_pwd Set if this make was started by other make
2863 2854 */
2864 2855 static void
2865 2856 read_environment(Boolean read_only)
2866 2857 {
2867 2858 register char **environment;
2868 2859 int length;
2869 2860 wchar_t *tmp_wcs_buffer;
2870 2861 Boolean alloced_tmp_wcs_buffer = false;
2871 2862 register wchar_t *name;
2872 2863 register wchar_t *value;
2873 2864 register Name macro;
2874 2865 Property val;
2875 2866 Boolean read_only_saved;
2876 2867
2877 2868 reading_environment = true;
2878 2869 environment = environ;
2879 2870 for (; *environment; environment++) {
2880 2871 read_only_saved = read_only;
2881 2872 if ((length = strlen(*environment)) >= MAXPATHLEN) {
2882 2873 tmp_wcs_buffer = ALLOC_WC(length + 1);
2883 2874 alloced_tmp_wcs_buffer = true;
2884 2875 (void) mbstowcs(tmp_wcs_buffer, *environment, length + 1);
2885 2876 name = tmp_wcs_buffer;
2886 2877 } else {
2887 2878 MBSTOWCS(wcs_buffer, *environment);
2888 2879 name = wcs_buffer;
2889 2880 }
2890 2881 value = (wchar_t *) wschr(name, (int) equal_char);
2891 2882
2892 2883 /*
2893 2884 * Looks like there's a bug in the system, but sometimes
2894 2885 * you can get blank lines in *environment.
2895 2886 */
2896 2887 if (!value) {
2897 2888 continue;
2898 2889 }
2899 2890 MBSTOWCS(wcs_buffer2, NOCATGETS("SHELL="));
2900 2891 if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
2901 2892 continue;
2902 2893 }
2903 2894 MBSTOWCS(wcs_buffer2, NOCATGETS("MAKEFLAGS="));
2904 2895 if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
2905 2896 report_pwd = true;
2906 2897 /*
2907 2898 * In POSIX mode we do not want MAKEFLAGS to be readonly.
2908 2899 * If the MAKEFLAGS macro is subsequently set by the makefile,
2909 2900 * it replaces the MAKEFLAGS variable currently found in the
2910 2901 * environment.
2911 2902 * See Assertion 50 in section 6.2.5.3 of standard P1003.3.2/D8.
2912 2903 */
2913 2904 if(posix) {
2914 2905 read_only_saved = false;
2915 2906 }
2916 2907 }
2917 2908
2918 2909 /*
2919 2910 * We ignore SUNPRO_DEPENDENCIES. This environment variable is
2920 2911 * set by make and read by cpp which then writes info to
2921 2912 * .make.dependency.xxx. When make is invoked by another make
2922 2913 * (recursive make), we don't want to read this because then
2923 2914 * the child make will end up writing to the parent
2924 2915 * directory's .make.state and clobbering them.
2925 2916 */
2926 2917 MBSTOWCS(wcs_buffer2, NOCATGETS("SUNPRO_DEPENDENCIES"));
2927 2918 if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
2928 2919 continue;
2929 2920 }
2930 2921
2931 2922 macro = GETNAME(name, value - name);
2932 2923 maybe_append_prop(macro, macro_prop)->body.macro.exported =
2933 2924 true;
2934 2925 if ((value == NULL) || ((value + 1)[0] == (int) nul_char)) {
2935 2926 val = setvar_daemon(macro,
2936 2927 (Name) NULL,
2937 2928 false, no_daemon, false, debug_level);
2938 2929 } else {
2939 2930 val = setvar_daemon(macro,
2940 2931 GETNAME(value + 1, FIND_LENGTH),
2941 2932 false, no_daemon, false, debug_level);
2942 2933 }
2943 2934 val->body.macro.read_only = read_only_saved;
2944 2935 if (alloced_tmp_wcs_buffer) {
2945 2936 retmem(tmp_wcs_buffer);
2946 2937 alloced_tmp_wcs_buffer = false;
2947 2938 }
2948 2939 }
2949 2940 reading_environment = false;
2950 2941 }
2951 2942
2952 2943 /*
2953 2944 * read_makefile(makefile, complain, must_exist, report_file)
2954 2945 *
2955 2946 * Read one makefile and check the result
2956 2947 *
2957 2948 * Return value:
2958 2949 * false is the read failed
2959 2950 *
2960 2951 * Parameters:
2961 2952 * makefile The file to read
2962 2953 * complain Passed thru to read_simple_file()
2963 2954 * must_exist Passed thru to read_simple_file()
2964 2955 * report_file Passed thru to read_simple_file()
2965 2956 *
2966 2957 * Global variables used:
2967 2958 * makefile_type Set to indicate we are reading main file
2968 2959 * recursion_level Initialized
2969 2960 */
2970 2961 static Boolean
2971 2962 read_makefile(register Name makefile, Boolean complain, Boolean must_exist, Boolean report_file)
2972 2963 {
2973 2964 Boolean b;
2974 2965
2975 2966 makefile_type = reading_makefile;
2976 2967 recursion_level = 0;
2977 2968 reading_dependencies = true;
2978 2969 b = read_simple_file(makefile, true, true, complain,
2979 2970 must_exist, report_file, false);
2980 2971 reading_dependencies = false;
2981 2972 return b;
2982 2973 }
2983 2974
2984 2975 /*
2985 2976 * make_targets(argc, argv, parallel_flag)
2986 2977 *
2987 2978 * Call doname on the specified targets
2988 2979 *
2989 2980 * Parameters:
2990 2981 * argc You know what this is
2991 2982 * argv You know what this is
2992 2983 * parallel_flag True if building in parallel
2993 2984 *
2994 2985 * Global variables used:
2995 2986 * build_failed_seen Used to generated message after failed -k
2996 2987 * commands_done Used to generate message "Up to date"
2997 2988 * default_target_to_build First proper target in makefile
2998 2989 * init The Name ".INIT", use to run command
2999 2990 * parallel Global parallel building flag
3000 2991 * quest make -q, suppresses messages
3001 2992 * recursion_level Initialized, used for tracing
3002 2993 * report_dependencies make -P, regroves whole process
3003 2994 */
3004 2995 static void
3005 2996 make_targets(int argc, char **argv, Boolean parallel_flag)
3006 2997 {
3007 2998 int i;
3008 2999 char *cp;
3009 3000 Doname result;
3010 3001 register Boolean target_to_make_found = false;
3011 3002
3012 3003 (void) doname(init, true, true);
3013 3004 recursion_level = 1;
3014 3005 parallel = parallel_flag;
3015 3006 /*
3016 3007 * make remaining args
3017 3008 */
3018 3009 #ifdef TEAMWARE_MAKE_CMN
3019 3010 /*
3020 3011 if ((report_dependencies_level == 0) && parallel) {
3021 3012 */
3022 3013 if (parallel) {
3023 3014 /*
3024 3015 * If building targets in parallel, start all of the
3025 3016 * remaining args to build in parallel.
3026 3017 */
3027 3018 for (i = 1; i < argc; i++) {
3028 3019 if ((cp = argv[i]) != NULL) {
3029 3020 commands_done = false;
3030 3021 if ((cp[0] == (int) period_char) &&
3031 3022 (cp[1] == (int) slash_char)) {
3032 3023 cp += 2;
3033 3024 }
3034 3025 if((cp[0] == (int) ' ') &&
3035 3026 (cp[1] == (int) '-') &&
3036 3027 (cp[2] == (int) ' ') &&
3037 3028 (cp[3] == (int) '-')) {
3038 3029 argv[i] = NULL;
3039 3030 continue;
3040 3031 }
3041 3032 MBSTOWCS(wcs_buffer, cp);
3042 3033 //default_target_to_build = GETNAME(wcs_buffer,
3043 3034 // FIND_LENGTH);
3044 3035 default_target_to_build = normalize_name(wcs_buffer,
3045 3036 wslen(wcs_buffer));
3046 3037 if (default_target_to_build == wait_name) {
3047 3038 if (parallel_process_cnt > 0) {
3048 3039 finish_running();
3049 3040 }
3050 3041 continue;
3051 3042 }
3052 3043 top_level_target = get_wstring(default_target_to_build->string_mb);
3053 3044 /*
3054 3045 * If we can't execute the current target in
3055 3046 * parallel, hold off the target processing
3056 3047 * to preserve the order of the targets as they appeared
3057 3048 * in command line.
3058 3049 */
3059 3050 if (!parallel_ok(default_target_to_build, false)
3060 3051 && parallel_process_cnt > 0) {
3061 3052 finish_running();
3062 3053 }
3063 3054 result = doname_check(default_target_to_build,
3064 3055 true,
3065 3056 false,
3066 3057 false);
3067 3058 gather_recursive_deps();
3068 3059 if (/* !commands_done && */
3069 3060 (result == build_ok) &&
3070 3061 !quest &&
3071 3062 (report_dependencies_level == 0) /* &&
3072 3063 (exists(default_target_to_build) > file_doesnt_exist) */) {
3073 3064 if (posix) {
3074 3065 if (!commands_done) {
3075 3066 (void) printf(catgets(catd, 1, 293, "`%s' is updated.\n"),
3076 3067 default_target_to_build->string_mb);
3077 3068 } else {
3078 3069 if (no_action_was_taken) {
3079 3070 (void) printf(catgets(catd, 1, 294, "`%s': no action was taken.\n"),
3080 3071 default_target_to_build->string_mb);
3081 3072 }
3082 3073 }
3083 3074 } else {
3084 3075 default_target_to_build->stat.time = file_no_time;
3085 3076 if (!commands_done &&
3086 3077 (exists(default_target_to_build) > file_doesnt_exist)) {
3087 3078 (void) printf(catgets(catd, 1, 295, "`%s' is up to date.\n"),
3088 3079 default_target_to_build->string_mb);
3089 3080 }
3090 3081 }
3091 3082 }
3092 3083 }
3093 3084 }
3094 3085 /* Now wait for all of the targets to finish running */
3095 3086 finish_running();
3096 3087 // setjmp(jmpbuffer);
3097 3088
3098 3089 }
3099 3090 #endif
3100 3091 for (i = 1; i < argc; i++) {
3101 3092 if ((cp = argv[i]) != NULL) {
3102 3093 target_to_make_found = true;
3103 3094 if ((cp[0] == (int) period_char) &&
3104 3095 (cp[1] == (int) slash_char)) {
3105 3096 cp += 2;
3106 3097 }
3107 3098 if((cp[0] == (int) ' ') &&
3108 3099 (cp[1] == (int) '-') &&
3109 3100 (cp[2] == (int) ' ') &&
3110 3101 (cp[3] == (int) '-')) {
3111 3102 argv[i] = NULL;
3112 3103 continue;
3113 3104 }
3114 3105 MBSTOWCS(wcs_buffer, cp);
3115 3106 default_target_to_build = normalize_name(wcs_buffer, wslen(wcs_buffer));
3116 3107 top_level_target = get_wstring(default_target_to_build->string_mb);
3117 3108 report_recursion(default_target_to_build);
3118 3109 commands_done = false;
3119 3110 if (parallel) {
3120 3111 result = (Doname) default_target_to_build->state;
3121 3112 } else {
3122 3113 result = doname_check(default_target_to_build,
3123 3114 true,
3124 3115 false,
3125 3116 false);
3126 3117 }
3127 3118 gather_recursive_deps();
3128 3119 if (build_failed_seen) {
3129 3120 build_failed_ever_seen = true;
3130 3121 warning(catgets(catd, 1, 200, "Target `%s' not remade because of errors"),
3131 3122 default_target_to_build->string_mb);
3132 3123 }
3133 3124 build_failed_seen = false;
3134 3125 if (report_dependencies_level > 0) {
3135 3126 print_dependencies(default_target_to_build,
3136 3127 get_prop(default_target_to_build->prop,
3137 3128 line_prop));
3138 3129 }
3139 3130 default_target_to_build->stat.time =
3140 3131 file_no_time;
3141 3132 if (default_target_to_build->colon_splits > 0) {
3142 3133 default_target_to_build->state =
3143 3134 build_dont_know;
3144 3135 }
3145 3136 if (!parallel &&
3146 3137 /* !commands_done && */
3147 3138 (result == build_ok) &&
3148 3139 !quest &&
3149 3140 (report_dependencies_level == 0) /* &&
3150 3141 (exists(default_target_to_build) > file_doesnt_exist) */) {
3151 3142 if (posix) {
3152 3143 if (!commands_done) {
3153 3144 (void) printf(catgets(catd, 1, 296, "`%s' is updated.\n"),
3154 3145 default_target_to_build->string_mb);
3155 3146 } else {
3156 3147 if (no_action_was_taken) {
3157 3148 (void) printf(catgets(catd, 1, 297, "`%s': no action was taken.\n"),
3158 3149 default_target_to_build->string_mb);
3159 3150 }
3160 3151 }
3161 3152 } else {
3162 3153 if (!commands_done &&
3163 3154 (exists(default_target_to_build) > file_doesnt_exist)) {
3164 3155 (void) printf(catgets(catd, 1, 298, "`%s' is up to date.\n"),
3165 3156 default_target_to_build->string_mb);
3166 3157 }
3167 3158 }
3168 3159 }
3169 3160 }
3170 3161 }
3171 3162
3172 3163 /*
3173 3164 * If no file arguments have been encountered,
3174 3165 * make the first name encountered that doesnt start with a dot
3175 3166 */
3176 3167 if (!target_to_make_found) {
3177 3168 if (default_target_to_build == NULL) {
3178 3169 fatal(catgets(catd, 1, 202, "No arguments to build"));
3179 3170 }
3180 3171 commands_done = false;
3181 3172 top_level_target = get_wstring(default_target_to_build->string_mb);
3182 3173 report_recursion(default_target_to_build);
3183 3174
3184 3175
3185 3176 if (getenv(NOCATGETS("SPRO_EXPAND_ERRORS"))){
3186 3177 (void) printf(NOCATGETS("::(%s)\n"),
3187 3178 default_target_to_build->string_mb);
3188 3179 }
3189 3180
3190 3181
3191 3182 #ifdef TEAMWARE_MAKE_CMN
3192 3183 result = doname_parallel(default_target_to_build, true, false);
3193 3184 #else
3194 3185 result = doname_check(default_target_to_build, true,
3195 3186 false, false);
3196 3187 #endif
3197 3188 gather_recursive_deps();
3198 3189 if (build_failed_seen) {
3199 3190 build_failed_ever_seen = true;
3200 3191 warning(catgets(catd, 1, 203, "Target `%s' not remade because of errors"),
3201 3192 default_target_to_build->string_mb);
3202 3193 }
3203 3194 build_failed_seen = false;
3204 3195 if (report_dependencies_level > 0) {
3205 3196 print_dependencies(default_target_to_build,
3206 3197 get_prop(default_target_to_build->
3207 3198 prop,
3208 3199 line_prop));
3209 3200 }
3210 3201 default_target_to_build->stat.time = file_no_time;
3211 3202 if (default_target_to_build->colon_splits > 0) {
3212 3203 default_target_to_build->state = build_dont_know;
3213 3204 }
3214 3205 if (/* !commands_done && */
3215 3206 (result == build_ok) &&
3216 3207 !quest &&
3217 3208 (report_dependencies_level == 0) /* &&
3218 3209 (exists(default_target_to_build) > file_doesnt_exist) */) {
3219 3210 if (posix) {
3220 3211 if (!commands_done) {
3221 3212 (void) printf(catgets(catd, 1, 299, "`%s' is updated.\n"),
3222 3213 default_target_to_build->string_mb);
3223 3214 } else {
3224 3215 if (no_action_was_taken) {
3225 3216 (void) printf(catgets(catd, 1, 300, "`%s': no action was taken.\n"),
3226 3217 default_target_to_build->string_mb);
3227 3218 }
3228 3219 }
3229 3220 } else {
3230 3221 if (!commands_done &&
3231 3222 (exists(default_target_to_build) > file_doesnt_exist)) {
3232 3223 (void) printf(catgets(catd, 1, 301, "`%s' is up to date.\n"),
3233 3224 default_target_to_build->string_mb);
3234 3225 }
3235 3226 }
3236 3227 }
3237 3228 }
3238 3229 }
3239 3230
3240 3231 /*
3241 3232 * report_recursion(target)
3242 3233 *
3243 3234 * If this is a recursive make and the parent make has KEEP_STATE on
3244 3235 * this routine reports the dependency to the parent make
3245 3236 *
3246 3237 * Parameters:
3247 3238 * target Target to report
3248 3239 *
3249 3240 * Global variables used:
3250 3241 * makefiles_used List of makefiles read
3251 3242 * recursive_name The Name ".RECURSIVE", printed
3252 3243 * report_dependency dwight
3253 3244 */
3254 3245 static void
3255 3246 report_recursion(register Name target)
3256 3247 {
3257 3248 register FILE *report_file = get_report_file();
3258 3249
3259 3250 if ((report_file == NULL) || (report_file == (FILE*)-1)) {
3260 3251 return;
3261 3252 }
3262 3253 if (primary_makefile == NULL) {
3263 3254 /*
3264 3255 * This can happen when there is no makefile and
3265 3256 * only implicit rules are being used.
3266 3257 */
3267 3258 return;
3268 3259 }
3269 3260 (void) fprintf(report_file,
3270 3261 "%s: %s ",
3271 3262 get_target_being_reported_for(),
3272 3263 recursive_name->string_mb);
3273 3264 report_dependency(get_current_path());
3274 3265 report_dependency(target->string_mb);
3275 3266 report_dependency(primary_makefile->string_mb);
3276 3267 (void) fprintf(report_file, "\n");
3277 3268 }
3278 3269
3279 3270 /* Next function "append_or_replace_macro_in_dyn_array" must be in "misc.cc". */
3280 3271 /* NIKMOL */
3281 3272 extern void
3282 3273 append_or_replace_macro_in_dyn_array(ASCII_Dyn_Array *Ar, char *macro)
3283 3274 {
3284 3275 register char *cp0; /* work pointer in macro */
3285 3276 register char *cp1; /* work pointer in array */
3286 3277 register char *cp2; /* work pointer in array */
3287 3278 register char *cp3; /* work pointer in array */
3288 3279 register char *name; /* macro name */
3289 3280 register char *value; /* macro value */
3290 3281 register int len_array;
3291 3282 register int len_macro;
3292 3283
3293 3284 char * esc_value = NULL;
3294 3285 int esc_len;
3295 3286
3296 3287 if (!(len_macro = strlen(macro))) return;
3297 3288 name = macro;
3298 3289 while (isspace(*(name))) {
3299 3290 name++;
3300 3291 }
3301 3292 if (!(value = strchr(name, (int) equal_char))) {
3302 3293 /* no '=' in macro */
3303 3294 goto ERROR_MACRO;
3304 3295 }
3305 3296 cp0 = value;
3306 3297 value++;
3307 3298 while (isspace(*(value))) {
3308 3299 value++;
3309 3300 }
3310 3301 while (isspace(*(cp0-1))) {
3311 3302 cp0--;
3312 3303 }
3313 3304 if (cp0 <= name) goto ERROR_MACRO; /* no name */
3314 3305 if (!(Ar->size)) goto ALLOC_ARRAY;
3315 3306 cp1 = Ar->start;
3316 3307
3317 3308 LOOK_FOR_NAME:
3318 3309 if (!(cp1 = strchr(cp1, name[0]))) goto APPEND_MACRO;
3319 3310 if (!(cp2 = strchr(cp1, (int) equal_char))) goto APPEND_MACRO;
3320 3311 if (strncmp(cp1, name, (size_t)(cp0-name))) {
3321 3312 /* another name */
3322 3313 cp1++;
3323 3314 goto LOOK_FOR_NAME;
3324 3315 }
3325 3316 if (cp1 != Ar->start) {
3326 3317 if (!isspace(*(cp1-1))) {
3327 3318 /* another name */
3328 3319 cp1++;
3329 3320 goto LOOK_FOR_NAME;
3330 3321 }
3331 3322 }
3332 3323 for (cp3 = cp1 + (cp0-name); cp3 < cp2; cp3++) {
3333 3324 if (isspace(*cp3)) continue;
3334 3325 /* else: another name */
3335 3326 cp1++;
3336 3327 goto LOOK_FOR_NAME;
3337 3328 }
3338 3329 /* Look for the next macro name in array */
3339 3330 cp3 = cp2+1;
3340 3331 if (*cp3 != (int) doublequote_char) {
3341 3332 /* internal error */
3342 3333 goto ERROR_MACRO;
3343 3334 }
3344 3335 if (!(cp3 = strchr(cp3+1, (int) doublequote_char))) {
3345 3336 /* internal error */
3346 3337 goto ERROR_MACRO;
3347 3338 }
3348 3339 cp3++;
3349 3340 while (isspace(*cp3)) {
3350 3341 cp3++;
3351 3342 }
3352 3343
3353 3344 cp2 = cp1; /* remove old macro */
3354 3345 if ((*cp3) && (cp3 < Ar->start + Ar->size)) {
3355 3346 for (; cp3 < Ar->start + Ar->size; cp3++) {
3356 3347 *cp2++ = *cp3;
3357 3348 }
3358 3349 }
3359 3350 for (; cp2 < Ar->start + Ar->size; cp2++) {
3360 3351 *cp2 = 0;
3361 3352 }
3362 3353 if (*cp1) {
3363 3354 /* check next name */
3364 3355 goto LOOK_FOR_NAME;
3365 3356 }
3366 3357 goto APPEND_MACRO;
3367 3358
3368 3359 ALLOC_ARRAY:
3369 3360 if (Ar->size) {
3370 3361 cp1 = Ar->start;
3371 3362 } else {
3372 3363 cp1 = 0;
3373 3364 }
3374 3365 Ar->size += 128;
3375 3366 Ar->start = getmem(Ar->size);
3376 3367 for (len_array=0; len_array < Ar->size; len_array++) {
3377 3368 Ar->start[len_array] = 0;
3378 3369 }
3379 3370 if (cp1) {
3380 3371 strcpy(Ar->start, cp1);
3381 3372 retmem((wchar_t *) cp1);
3382 3373 }
3383 3374
3384 3375 APPEND_MACRO:
3385 3376 len_array = strlen(Ar->start);
3386 3377 esc_value = (char*)malloc(strlen(value)*2 + 1);
3387 3378 quote_str(value, esc_value);
3388 3379 esc_len = strlen(esc_value) - strlen(value);
3389 3380 if (len_array + len_macro + esc_len + 5 >= Ar->size) goto ALLOC_ARRAY;
3390 3381 strcat(Ar->start, " ");
3391 3382 strncat(Ar->start, name, cp0-name);
3392 3383 strcat(Ar->start, "=");
3393 3384 strncat(Ar->start, esc_value, strlen(esc_value));
3394 3385 free(esc_value);
3395 3386 return;
3396 3387 ERROR_MACRO:
3397 3388 /* Macro without '=' or with invalid left/right part */
3398 3389 return;
3399 3390 }
3400 3391
3401 3392 #ifdef TEAMWARE_MAKE_CMN
3402 3393 /*
3403 3394 * This function, if registered w/ avo_cli_get_license(), will be called
3404 3395 * if the application is about to exit because:
3405 3396 * 1) there has been certain unrecoverable error(s) that cause the
3406 3397 * application to exit immediately.
3407 3398 * 2) the user has lost a license while the application is running.
3408 3399 */
3409 3400 extern "C" void
3410 3401 dmake_exit_callback(void)
3411 3402 {
3412 3403 fatal(catgets(catd, 1, 306, "can not get a license, exiting..."));
3413 3404 exit(1);
3414 3405 }
3415 3406
3416 3407 /*
3417 3408 * This function, if registered w/ avo_cli_get_license(), will be called
3418 3409 * if the application can not get a license.
3419 3410 */
3420 3411 extern "C" void
3421 3412 dmake_message_callback(char *err_msg)
3422 3413 {
3423 3414 static Boolean first = true;
3424 3415
3425 3416 if (!first) {
3426 3417 return;
3427 3418 }
3428 3419 first = false;
3429 3420 if ((!list_all_targets) &&
3430 3421 (report_dependencies_level == 0) &&
3431 3422 (dmake_mode_type != serial_mode)) {
3432 3423 warning(catgets(catd, 1, 313, "can not get a TeamWare license, defaulting to serial mode..."));
3433 3424 }
3434 3425 }
3435 3426 #endif
3436 3427
3437 3428 #ifdef DISTRIBUTED
3438 3429 /*
3439 3430 * Returns whether -c is set or not.
3440 3431 */
3441 3432 Boolean
3442 3433 get_dmake_rcfile_specified(void)
3443 3434 {
3444 3435 return(dmake_rcfile_specified);
3445 3436 }
3446 3437
3447 3438 /*
3448 3439 * Returns whether -g is set or not.
3449 3440 */
3450 3441 Boolean
3451 3442 get_dmake_group_specified(void)
3452 3443 {
3453 3444 return(dmake_group_specified);
3454 3445 }
3455 3446
3456 3447 /*
3457 3448 * Returns whether -j is set or not.
3458 3449 */
3459 3450 Boolean
3460 3451 get_dmake_max_jobs_specified(void)
3461 3452 {
3462 3453 return(dmake_max_jobs_specified);
3463 3454 }
3464 3455
3465 3456 /*
3466 3457 * Returns whether -m is set or not.
3467 3458 */
3468 3459 Boolean
3469 3460 get_dmake_mode_specified(void)
3470 3461 {
3471 3462 return(dmake_mode_specified);
3472 3463 }
3473 3464
3474 3465 /*
3475 3466 * Returns whether -o is set or not.
3476 3467 */
3477 3468 Boolean
3478 3469 get_dmake_odir_specified(void)
3479 3470 {
3480 3471 return(dmake_odir_specified);
3481 3472 }
3482 3473
3483 3474 #endif
3484 3475
3485 3476 static void
3486 3477 report_dir_enter_leave(Boolean entering)
3487 3478 {
3488 3479 char rcwd[MAXPATHLEN];
3489 3480 static char * mlev = NULL;
3490 3481 char * make_level_str = NULL;
3491 3482 int make_level_val = 0;
3492 3483
3493 3484 make_level_str = getenv(NOCATGETS("MAKELEVEL"));
3494 3485 if(make_level_str) {
3495 3486 make_level_val = atoi(make_level_str);
3496 3487 }
3497 3488 if(mlev == NULL) {
3498 3489 mlev = (char*) malloc(MAXPATHLEN);
3499 3490 }
3500 3491 if(entering) {
3501 3492 sprintf(mlev, NOCATGETS("MAKELEVEL=%d"), make_level_val + 1);
3502 3493 } else {
3503 3494 make_level_val--;
3504 3495 sprintf(mlev, NOCATGETS("MAKELEVEL=%d"), make_level_val);
3505 3496 }
3506 3497 putenv(mlev);
3507 3498
3508 3499 if(report_cwd) {
3509 3500 if(make_level_val <= 0) {
3510 3501 if(entering) {
3511 3502 #ifdef TEAMWARE_MAKE_CMN
3512 3503 sprintf( rcwd
3513 3504 , catgets(catd, 1, 329, "dmake: Entering directory `%s'\n")
3514 3505 , get_current_path());
3515 3506 #else
3516 3507 sprintf( rcwd
3517 3508 , catgets(catd, 1, 330, "make: Entering directory `%s'\n")
3518 3509 , get_current_path());
3519 3510 #endif
3520 3511 } else {
3521 3512 #ifdef TEAMWARE_MAKE_CMN
3522 3513 sprintf( rcwd
3523 3514 , catgets(catd, 1, 331, "dmake: Leaving directory `%s'\n")
3524 3515 , get_current_path());
3525 3516 #else
3526 3517 sprintf( rcwd
3527 3518 , catgets(catd, 1, 332, "make: Leaving directory `%s'\n")
3528 3519 , get_current_path());
3529 3520 #endif
3530 3521 }
3531 3522 } else {
3532 3523 if(entering) {
3533 3524 #ifdef TEAMWARE_MAKE_CMN
3534 3525 sprintf( rcwd
3535 3526 , catgets(catd, 1, 333, "dmake[%d]: Entering directory `%s'\n")
3536 3527 , make_level_val, get_current_path());
3537 3528 #else
3538 3529 sprintf( rcwd
3539 3530 , catgets(catd, 1, 334, "make[%d]: Entering directory `%s'\n")
3540 3531 , make_level_val, get_current_path());
3541 3532 #endif
3542 3533 } else {
3543 3534 #ifdef TEAMWARE_MAKE_CMN
3544 3535 sprintf( rcwd
3545 3536 , catgets(catd, 1, 335, "dmake[%d]: Leaving directory `%s'\n")
3546 3537 , make_level_val, get_current_path());
3547 3538 #else
3548 3539 sprintf( rcwd
3549 3540 , catgets(catd, 1, 336, "make[%d]: Leaving directory `%s'\n")
3550 3541 , make_level_val, get_current_path());
3551 3542 #endif
3552 3543 }
3553 3544 }
3554 3545 printf(NOCATGETS("%s"), rcwd);
3555 3546 }
3556 3547 }
↓ open down ↓ |
3493 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX