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