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