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