1 #ifndef _MKSH_DEFS_H 2 #define _MKSH_DEFS_H 3 /* 4 * CDDL HEADER START 5 * 6 * The contents of this file are subject to the terms of the 7 * Common Development and Distribution License (the "License"). 8 * You may not use this file except in compliance with the License. 9 * 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11 * or http://www.opensolaris.org/os/licensing. 12 * See the License for the specific language governing permissions 13 * and limitations under the License. 14 * 15 * When distributing Covered Code, include this CDDL HEADER in each 16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17 * If applicable, add the following below this CDDL HEADER, with the 18 * fields enclosed by brackets "[]" replaced with your own identifying 19 * information: Portions Copyright [yyyy] [name of copyright owner] 20 * 21 * CDDL HEADER END 22 */ 23 /* 24 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* 29 * This is not "#ifdef TEAMWARE_MAKE_CMN" because we're currently 30 * using the TW fake i18n headers and libraries to build both 31 * SMake and PMake on SPARC/S1 and x86/S2. 32 */ 33 34 #include <avo/intl.h> 35 #include <limits.h> /* MB_LEN_MAX */ 36 #include <stdio.h> 37 #include <stdlib.h> /* wchar_t */ 38 #include <string.h> /* strcmp() */ 39 #include <nl_types.h> /* catgets() */ 40 #include <sys/param.h> /* MAXPATHLEN */ 41 #include <sys/types.h> /* time_t, caddr_t */ 42 #include <vroot/vroot.h> /* pathpt */ 43 #include <sys/time.h> /* timestruc_t */ 44 #include <errno.h> /* errno */ 45 46 #include <wctype.h> 47 #include <widec.h> 48 49 50 /* 51 * A type and some utilities for boolean values 52 */ 53 54 #define false BOOLEAN_false 55 #define true BOOLEAN_true 56 57 typedef enum { 58 false = 0, 59 true = 1, 60 failed = 0, 61 succeeded = 1 62 } Boolean; 63 #define BOOLEAN(expr) ((expr) ? true : false) 64 65 /* 66 * Some random constants (in an enum so dbx knows their values) 67 */ 68 enum { 69 update_delay = 30, /* time between rstat checks */ 70 ar_member_name_len = 1024, 71 hashsize = 2048 /* size of hash table */ 72 }; 73 74 75 /* 76 * Symbols that defines all the different char constants make uses 77 */ 78 enum { 79 ampersand_char = '&', 80 asterisk_char = '*', 81 at_char = '@', 82 backquote_char = '`', 83 backslash_char = '\\', 84 bar_char = '|', 85 braceleft_char = '{', 86 braceright_char = '}', 87 bracketleft_char = '[', 88 bracketright_char = ']', 89 colon_char = ':', 90 comma_char = ',', 91 dollar_char = '$', 92 doublequote_char = '"', 93 equal_char = '=', 94 exclam_char = '!', 95 greater_char = '>', 96 hat_char = '^', 97 hyphen_char = '-', 98 less_char = '<', 99 newline_char = '\n', 100 nul_char = '\0', 101 numbersign_char = '#', 102 parenleft_char = '(', 103 parenright_char = ')', 104 percent_char = '%', 105 period_char = '.', 106 plus_char = '+', 107 question_char = '?', 108 quote_char = '\'', 109 semicolon_char = ';', 110 slash_char = '/', 111 space_char = ' ', 112 tab_char = '\t', 113 tilde_char = '~' 114 }; 115 116 /* 117 * For make i18n. Codeset independent. 118 * Setup character semantics by identifying all the special characters 119 * of make, and assigning each an entry in the char_semantics[] vector. 120 */ 121 enum { 122 ampersand_char_entry = 0, /* 0 */ 123 asterisk_char_entry, /* 1 */ 124 at_char_entry, /* 2 */ 125 backquote_char_entry, /* 3 */ 126 backslash_char_entry, /* 4 */ 127 bar_char_entry, /* 5 */ 128 bracketleft_char_entry, /* 6 */ 129 bracketright_char_entry, /* 7 */ 130 colon_char_entry, /* 8 */ 131 dollar_char_entry, /* 9 */ 132 doublequote_char_entry, /* 10 */ 133 equal_char_entry, /* 11 */ 134 exclam_char_entry, /* 12 */ 135 greater_char_entry, /* 13 */ 136 hat_char_entry, /* 14 */ 137 hyphen_char_entry, /* 15 */ 138 less_char_entry, /* 16 */ 139 newline_char_entry, /* 17 */ 140 numbersign_char_entry, /* 18 */ 141 parenleft_char_entry, /* 19 */ 142 parenright_char_entry, /* 20 */ 143 percent_char_entry, /* 21 */ 144 plus_char_entry, /* 22 */ 145 question_char_entry, /* 23 */ 146 quote_char_entry, /* 24 */ 147 semicolon_char_entry, /* 25 */ 148 #ifdef SGE_SUPPORT 149 space_char_entry, /* 26 */ 150 tab_char_entry, /* 27 */ 151 no_semantics_entry /* 28 */ 152 #else 153 no_semantics_entry /* 26 */ 154 #endif /* SGE_SUPPORT */ 155 }; 156 157 /* 158 * CHAR_SEMANTICS_ENTRIES should be the number of entries above. 159 * The last entry in char_semantics[] should be blank. 160 */ 161 #ifdef SGE_SUPPORT 162 #define CHAR_SEMANTICS_ENTRIES 29 163 /* 164 #define CHAR_SEMANTICS_STRING "&*@`\\|[]:$=!>-\n#()%+?;^<'\" \t" 165 */ 166 #else 167 #define CHAR_SEMANTICS_ENTRIES 27 168 /* 169 #define CHAR_SEMANTICS_STRING "&*@`\\|[]:$=!>-\n#()%+?;^<'\"" 170 */ 171 #endif /* SGE_SUPPORT */ 172 173 /* 174 * Some utility macros 175 */ 176 #define ALLOC(x) ((struct _##x *)getmem(sizeof (struct _##x))) 177 #define ALLOC_WC(x) ((wchar_t *)getmem((x) * SIZEOFWCHAR_T)) 178 #define FIND_LENGTH -1 179 #define GETNAME(a,b) getname_fn((a), (b), false) 180 #define IS_EQUAL(a,b) (!strcmp((a), (b))) 181 #define IS_EQUALN(a,b,n) (!strncmp((a), (b), (n))) 182 #define IS_WEQUAL(a,b) (!wscmp((a), (b))) 183 #define IS_WEQUALN(a,b,n) (!wsncmp((a), (b), (n))) 184 #define MBLEN(a) mblen((a), MB_LEN_MAX) 185 #define MBSTOWCS(a,b) (void) mbstowcs_with_check((a), (b), MAXPATHLEN) 186 #define MBTOWC(a,b) mbtowc((a), (b), MB_LEN_MAX) 187 #define SIZEOFWCHAR_T (sizeof (wchar_t)) 188 #define VSIZEOF(v) (sizeof (v) / sizeof ((v)[0])) 189 #define WCSTOMBS(a,b) (void) wcstombs((a), (b), (MAXPATHLEN * MB_LEN_MAX)) 190 #define WCTOMB(a,b) (void) wctomb((a), (b)) 191 #define HASH(v, c) (v = (v)*31 + (unsigned int)(c)) 192 193 extern void mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n); 194 195 /* 196 * Bits stored in funny vector to classify chars 197 */ 198 enum { 199 dollar_sem = 0001, 200 meta_sem = 0002, 201 percent_sem = 0004, 202 wildcard_sem = 0010, 203 command_prefix_sem = 0020, 204 special_macro_sem = 0040, 205 colon_sem = 0100, 206 parenleft_sem = 0200 207 }; 208 209 /* 210 * Type returned from doname class functions 211 */ 212 typedef enum { 213 build_dont_know = 0, 214 build_failed, 215 build_ok, 216 build_in_progress, 217 build_running, /* PARALLEL & DISTRIBUTED */ 218 build_pending, /* PARALLEL & DISTRIBUTED */ 219 build_serial, /* PARALLEL & DISTRIBUTED */ 220 build_subtree /* PARALLEL & DISTRIBUTED */ 221 } Doname; 222 223 /* 224 * The String struct defines a string with the following layout 225 * "xxxxxxxxxxxxxxxCxxxxxxxxxxxxxxx________" 226 * ^ ^ ^ ^ 227 * | | | | 228 * buffer.start text.p text.end buffer.end 229 * text.p points to the next char to read/write. 230 */ 231 struct _String { 232 struct Text { 233 wchar_t *p; /* Read/Write pointer */ 234 wchar_t *end; /* Read limit pointer */ 235 } text; 236 struct Physical_buffer { 237 wchar_t *start; /* Points to start of buffer */ 238 wchar_t *end; /* End of physical buffer */ 239 } buffer; 240 Boolean free_after_use:1; 241 }; 242 243 #define STRING_BUFFER_LENGTH 1024 244 #define INIT_STRING_FROM_STACK(str, buf) { \ 245 str.buffer.start = (buf); \ 246 str.text.p = (buf); \ 247 str.text.end = NULL; \ 248 str.buffer.end = (buf) \ 249 + (sizeof (buf)/SIZEOFWCHAR_T); \ 250 str.free_after_use = false; \ 251 } 252 253 #define APPEND_NAME(np, dest, len) append_string((np)->string_mb, (dest), (len)); 254 255 class Wstring { 256 public: 257 struct _String string; 258 wchar_t string_buf[STRING_BUFFER_LENGTH]; 259 260 public: 261 Wstring(); 262 Wstring(struct _Name * name); 263 ~Wstring(); 264 265 void init(struct _Name * name); 266 void init(wchar_t * name, unsigned length); 267 unsigned length() { 268 return wslen(string.buffer.start); 269 }; 270 void append_to_str(struct _String * str, unsigned off, unsigned length); 271 272 wchar_t * get_string() { 273 return string.buffer.start; 274 }; 275 276 wchar_t * get_string(unsigned off) { 277 return string.buffer.start + off; 278 }; 279 280 Boolean equaln(wchar_t * str, unsigned length); 281 Boolean equal(wchar_t * str); 282 Boolean equal(wchar_t * str, unsigned off); 283 Boolean equal(wchar_t * str, unsigned off, unsigned length); 284 285 Boolean equaln(Wstring * str, unsigned length); 286 Boolean equal(Wstring * str); 287 Boolean equal(Wstring * str, unsigned off); 288 Boolean equal(Wstring * str, unsigned off, unsigned length); 289 }; 290 291 292 /* 293 * Used for storing the $? list and also for the "target + target:" 294 * construct. 295 */ 296 struct _Chain { 297 struct _Chain *next; 298 struct _Name *name; 299 struct _Percent *percent_member; 300 }; 301 302 /* 303 * Stores one command line for a rule 304 */ 305 struct _Cmd_line { 306 struct _Cmd_line *next; 307 struct _Name *command_line; 308 Boolean make_refd:1; /* $(MAKE) referenced? */ 309 /* 310 * Remember any command line prefixes given 311 */ 312 Boolean ignore_command_dependency:1; /* `?' */ 313 Boolean assign:1; /* `=' */ 314 Boolean ignore_error:1; /* `-' */ 315 Boolean silent:1; /* `@' */ 316 Boolean always_exec:1; /* `+' */ 317 }; 318 319 /* 320 * Linked list of targets/files 321 */ 322 struct _Dependency { 323 struct _Dependency *next; 324 struct _Name *name; 325 Boolean automatic:1; 326 Boolean stale:1; 327 Boolean built:1; 328 }; 329 330 /* 331 * The specials are markers for targets that the reader should special case 332 */ 333 typedef enum { 334 no_special, 335 built_last_make_run_special, 336 default_special, 337 get_posix_special, 338 get_special, 339 ignore_special, 340 keep_state_file_special, 341 keep_state_special, 342 make_version_special, 343 no_parallel_special, 344 parallel_special, 345 posix_special, 346 precious_special, 347 sccs_get_posix_special, 348 sccs_get_special, 349 silent_special, 350 suffixes_special, 351 svr4_special, 352 localhost_special 353 } Special; 354 355 typedef enum { 356 no_colon, 357 one_colon, 358 two_colon, 359 equal_seen, 360 conditional_seen, 361 none_seen 362 } Separator; 363 364 /* 365 * Magic values for the timestamp stored with each name object 366 */ 367 368 369 extern const timestruc_t file_no_time; 370 extern const timestruc_t file_doesnt_exist; 371 extern const timestruc_t file_is_dir; 372 extern const timestruc_t file_min_time; 373 extern const timestruc_t file_max_time; 374 375 /* 376 * Each Name has a list of properties 377 * The properties are used to store information that only 378 * a subset of the Names need 379 */ 380 typedef enum { 381 no_prop, 382 conditional_prop, 383 line_prop, 384 macro_prop, 385 makefile_prop, 386 member_prop, 387 recursive_prop, 388 sccs_prop, 389 suffix_prop, 390 target_prop, 391 time_prop, 392 vpath_alias_prop, 393 long_member_name_prop, 394 macro_append_prop, 395 env_mem_prop 396 } Property_id; 397 398 typedef enum { 399 no_daemon = 0, 400 chain_daemon 401 } Daemon; 402 403 struct _Env_mem { 404 char *value; 405 }; 406 407 struct _Macro_appendix { 408 struct _Name *value; 409 struct _Name *value_to_append; 410 }; 411 412 struct _Macro { 413 /* 414 * For "ABC = xyz" constructs 415 * Name "ABC" get one macro prop 416 */ 417 struct _Name *value; 418 Boolean exported:1; 419 Boolean read_only:1; 420 /* 421 * This macro is defined conditionally 422 */ 423 Boolean is_conditional:1; 424 /* 425 * The list for $? is stored as a structured list that 426 * is translated into a string iff it is referenced. 427 * This is why some macro values need a daemon. 428 */ 429 Daemon daemon:2; 430 }; 431 432 struct _Macro_list { 433 struct _Macro_list *next; 434 char *macro_name; 435 char *value; 436 }; 437 438 enum sccs_stat { 439 DONT_KNOW_SCCS = 0, 440 NO_SCCS, 441 HAS_SCCS 442 }; 443 444 struct _Name { 445 struct _Property *prop; /* List of properties */ 446 char *string_mb; /* Multi-byte name string */ 447 struct { 448 unsigned int length; 449 } hash; 450 struct { 451 timestruc_t time; /* Modification */ 452 int stat_errno; /* error from "stat" */ 453 off_t size; /* Of file */ 454 mode_t mode; /* Of file */ 455 Boolean is_file:1; 456 Boolean is_dir:1; 457 Boolean is_sym_link:1; 458 Boolean is_precious:1; 459 enum sccs_stat has_sccs:2; 460 } stat; 461 /* 462 * Count instances of :: definitions for this target 463 */ 464 short colon_splits; 465 /* 466 * We only clear the automatic depes once per target per report 467 */ 468 short temp_file_number; 469 /* 470 * Count how many conditional macros this target has defined 471 */ 472 short conditional_cnt; 473 /* 474 * A conditional macro was used when building this target 475 */ 476 Boolean depends_on_conditional:1; 477 /* 478 * Pointer to list of conditional macros which were used to build 479 * this target 480 */ 481 struct _Macro_list *conditional_macro_list; 482 Boolean has_member_depe:1; 483 Boolean is_member:1; 484 /* 485 * This target is a directory that has been read 486 */ 487 Boolean has_read_dir:1; 488 /* 489 * This name is a macro that is now being expanded 490 */ 491 Boolean being_expanded:1; 492 /* 493 * This name is a magic name that the reader must know about 494 */ 495 Special special_reader:5; 496 Doname state:3; 497 Separator colons:3; 498 Boolean has_depe_list_expanded:1; 499 Boolean suffix_scan_done:1; 500 Boolean has_complained:1; /* For sccs */ 501 /* 502 * This target has been built during this make run 503 */ 504 Boolean ran_command:1; 505 Boolean with_squiggle:1; /* for .SUFFIXES */ 506 Boolean without_squiggle:1; /* for .SUFFIXES */ 507 Boolean has_read_suffixes:1; /* Suffix list cached*/ 508 Boolean has_suffixes:1; 509 Boolean has_target_prop:1; 510 Boolean has_vpath_alias_prop:1; 511 Boolean dependency_printed:1; /* For dump_make_state() */ 512 Boolean dollar:1; /* In namestring */ 513 Boolean meta:1; /* In namestring */ 514 Boolean percent:1; /* In namestring */ 515 Boolean wildcard:1; /* In namestring */ 516 Boolean has_parent:1; 517 Boolean is_target:1; 518 Boolean has_built:1; 519 Boolean colon:1; /* In namestring */ 520 Boolean parenleft:1; /* In namestring */ 521 Boolean has_recursive_dependency:1; 522 Boolean has_regular_dependency:1; 523 Boolean is_double_colon:1; 524 Boolean is_double_colon_parent:1; 525 Boolean has_long_member_name:1; 526 /* 527 * allowed to run in parallel 528 */ 529 Boolean parallel:1; 530 /* 531 * not allowed to run in parallel 532 */ 533 Boolean no_parallel:1; 534 /* 535 * used in dependency_conflict 536 */ 537 Boolean checking_subtree:1; 538 Boolean added_pattern_conditionals:1; 539 /* 540 * rechecking target for possible rebuild 541 */ 542 Boolean rechecking_target:1; 543 /* 544 * build this target in silent mode 545 */ 546 Boolean silent_mode:1; 547 /* 548 * build this target in ignore error mode 549 */ 550 Boolean ignore_error_mode:1; 551 Boolean dont_activate_cond_values:1; 552 /* 553 * allowed to run serially on local host 554 */ 555 Boolean localhost:1; 556 }; 557 558 /* 559 * Stores the % matched default rules 560 */ 561 struct _Percent { 562 struct _Percent *next; 563 struct _Name **patterns; 564 struct _Name *name; 565 struct _Percent *dependencies; 566 struct _Cmd_line *command_template; 567 struct _Chain *target_group; 568 int patterns_total; 569 Boolean being_expanded; 570 }; 571 572 struct Conditional { 573 /* 574 * For "foo := ABC [+]= xyz" constructs 575 * Name "foo" gets one conditional prop 576 */ 577 struct _Name *target; 578 struct _Name *name; 579 struct _Name *value; 580 int sequence; 581 Boolean append:1; 582 }; 583 584 struct Line { 585 /* 586 * For "target : dependencies" constructs 587 * Name "target" gets one line prop 588 */ 589 struct _Cmd_line *command_template; 590 struct _Cmd_line *command_used; 591 struct _Dependency *dependencies; 592 timestruc_t dependency_time; 593 struct _Chain *target_group; 594 Boolean is_out_of_date:1; 595 Boolean sccs_command:1; 596 Boolean command_template_redefined:1; 597 Boolean dont_rebuild_command_used:1; 598 /* 599 * Values for the dynamic macros 600 */ 601 struct _Name *target; 602 struct _Name *star; 603 struct _Name *less; 604 struct _Name *percent; 605 struct _Chain *query; 606 }; 607 608 struct Makefile { 609 /* 610 * Names that reference makefiles gets one prop 611 */ 612 wchar_t *contents; 613 off_t size; 614 }; 615 616 struct Member { 617 /* 618 * For "lib(member)" and "lib((entry))" constructs 619 * Name "lib(member)" gets one member prop 620 * Name "lib((entry))" gets one member prop 621 * The member field is filled in when the prop is refd 622 */ 623 struct _Name *library; 624 struct _Name *entry; 625 struct _Name *member; 626 }; 627 628 struct Recursive { 629 /* 630 * For "target: .RECURSIVE dir makefiles" constructs 631 * Used to keep track of recursive calls to make 632 * Name "target" gets one recursive prop 633 */ 634 struct _Name *directory; 635 struct _Name *target; 636 struct _Dependency *makefiles; 637 Boolean has_built; 638 Boolean in_depinfo; 639 }; 640 641 struct Sccs { 642 /* 643 * Each file that has a SCCS s. file gets one prop 644 */ 645 struct _Name *file; 646 }; 647 648 struct Suffix { 649 /* 650 * Cached list of suffixes that can build this target 651 * suffix is built from .SUFFIXES 652 */ 653 struct _Name *suffix; 654 struct _Cmd_line *command_template; 655 }; 656 657 struct Target { 658 /* 659 * For "target:: dependencies" constructs 660 * The "::" construct is handled by converting it to 661 * "foo: 1@foo" + "1@foo: dependecies" 662 * "1@foo" gets one target prop 663 * This target prop cause $@ to be bound to "foo" 664 * not "1@foo" when the rule is evaluated 665 */ 666 struct _Name *target; 667 }; 668 669 struct STime { 670 /* 671 * Save the original time for :: targets 672 */ 673 timestruc_t time; 674 }; 675 676 struct Vpath_alias { 677 /* 678 * If a file was found using the VPATH it gets 679 * a vpath_alias prop 680 */ 681 struct _Name *alias; 682 }; 683 684 struct Long_member_name { 685 /* 686 * Targets with a truncated member name carries 687 * the full lib(member) name for the state file 688 */ 689 struct _Name *member_name; 690 }; 691 692 union Body { 693 struct _Macro macro; 694 struct Conditional conditional; 695 struct Line line; 696 struct Makefile makefile; 697 struct Member member; 698 struct Recursive recursive; 699 struct Sccs sccs; 700 struct Suffix suffix; 701 struct Target target; 702 struct STime time; 703 struct Vpath_alias vpath_alias; 704 struct Long_member_name long_member_name; 705 struct _Macro_appendix macro_appendix; 706 struct _Env_mem env_mem; 707 }; 708 709 #define PROPERTY_HEAD_SIZE (sizeof (struct _Property)-sizeof (union Body)) 710 struct _Property { 711 struct _Property *next; 712 Property_id type:4; 713 union Body body; 714 }; 715 716 /* Structure for dynamic "ascii" arrays */ 717 struct ASCII_Dyn_Array { 718 char *start; 719 size_t size; 720 }; 721 722 struct _Envvar { 723 struct _Name *name; 724 struct _Name *value; 725 struct _Envvar *next; 726 char *env_string; 727 Boolean already_put:1; 728 }; 729 730 /* 731 * Macros for the reader 732 */ 733 #define GOTO_STATE(new_state) { \ 734 SET_STATE(new_state); \ 735 goto enter_state; \ 736 } 737 #define SET_STATE(new_state) state = (new_state) 738 739 #define UNCACHE_SOURCE() if (source != NULL) { \ 740 source->string.text.p = source_p; \ 741 } 742 #define CACHE_SOURCE(comp) if (source != NULL) { \ 743 source_p = source->string.text.p - \ 744 (comp); \ 745 source_end = source->string.text.end; \ 746 } 747 #define GET_NEXT_BLOCK_NOCHK(source) { UNCACHE_SOURCE(); \ 748 source = get_next_block_fn(source); \ 749 CACHE_SOURCE(0) \ 750 } 751 #define GET_NEXT_BLOCK(source) { GET_NEXT_BLOCK_NOCHK(source); \ 752 if (source != NULL && source->error_converting) { \ 753 GOTO_STATE(illegal_bytes_state); \ 754 } \ 755 } 756 #define GET_CHAR() ((source == NULL) || \ 757 (source_p >= source_end) ? 0 : *source_p) 758 759 struct _Source { 760 struct _String string; 761 struct _Source *previous; 762 off_t bytes_left_in_file; 763 short fd; 764 Boolean already_expanded:1; 765 Boolean error_converting:1; 766 char *inp_buf; 767 char *inp_buf_end; 768 char *inp_buf_ptr; 769 }; 770 771 typedef enum { 772 reading_nothing, 773 reading_makefile, 774 reading_statefile, 775 rereading_statefile, 776 reading_cpp_file 777 } Makefile_type; 778 779 /* 780 * Typedefs for all structs 781 */ 782 typedef struct _Chain *Chain, Chain_rec; 783 typedef struct _Envvar *Envvar, Envvar_rec; 784 typedef struct _Macro_list *Macro_list, Macro_list_rec; 785 typedef struct _Name *Name, Name_rec; 786 typedef struct _Property *Property, Property_rec; 787 typedef struct _Source *Source, Source_rec; 788 typedef struct _String *String, String_rec; 789 790 /* 791 * name records hash table. 792 */ 793 struct Name_set { 794 private: 795 // single node in a tree 796 struct entry { 797 entry(Name name_, entry *parent_) : 798 name(name_), 799 parent(parent_), 800 left(0), 801 right(0), 802 depth(1) 803 {} 804 805 Name name; 806 807 entry *parent; 808 entry *left; 809 entry *right; 810 unsigned depth; 811 812 void setup_depth() { 813 unsigned rdepth = (right != 0) ? right->depth : 0; 814 unsigned ldepth = (left != 0) ? left->depth : 0; 815 depth = 1 + ((ldepth > rdepth) ? ldepth : rdepth); 816 } 817 }; 818 819 public: 820 // make iterator a friend of Name_set to have access to struct entry 821 struct iterator; 822 friend struct Name_set::iterator; 823 824 // iterator over tree nodes 825 struct iterator { 826 public: 827 // constructors 828 iterator() : node(0) {} 829 iterator(entry *node_) : node(node_) {} 830 831 // dereference operator 832 Name operator->() const { return node->name; } 833 834 // conversion operator 835 operator Name() { return node->name; } 836 837 // assignment operator 838 iterator& operator=(const iterator &o) { node = o.node; return *this; } 839 840 // equality/inequality operators 841 int operator==(const iterator &o) const { return (node == o.node); } 842 int operator!=(const iterator &o) const { return (node != o.node); } 843 844 // pre/post increment operators 845 iterator& operator++(); 846 iterator operator++(int) { iterator it = *this; ++*this; return it; } 847 848 private: 849 // the node iterator points to 850 entry *node; 851 }; 852 853 public: 854 // constructor 855 Name_set() : root(0) {} 856 857 // lookup, insert and remove operations 858 Name lookup(const char *key); 859 Name insert(const char *key, Boolean &found); 860 void insert(Name name); 861 862 // begin/end iterators 863 iterator begin() const; 864 iterator end() const { return iterator(); } 865 866 private: 867 // rebalance given node 868 void rebalance(entry *node); 869 870 private: 871 // tree root 872 entry *root; 873 }; 874 875 /* 876 * extern declarations for all global variables. 877 * The actual declarations are in globals.cc 878 */ 879 extern char char_semantics[]; 880 extern wchar_t char_semantics_char[]; 881 extern Macro_list cond_macro_list; 882 extern Boolean conditional_macro_used; 883 extern Boolean do_not_exec_rule; /* `-n' */ 884 extern Boolean dollarget_seen; 885 extern Boolean dollarless_flag; 886 extern Name dollarless_value; 887 extern char **environ; 888 extern Envvar envvar; 889 extern int exit_status; 890 extern wchar_t *file_being_read; 891 /* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */ 892 extern Boolean gnu_style; 893 extern Name_set hashtab; 894 extern Name host_arch; 895 extern Name host_mach; 896 extern int line_number; 897 extern char *make_state_lockfile; 898 extern Boolean make_word_mentioned; 899 extern Makefile_type makefile_type; 900 extern char mbs_buffer[]; 901 extern Name path_name; 902 extern Boolean posix; 903 extern Name query; 904 extern Boolean query_mentioned; 905 extern Name hat; 906 extern Boolean reading_environment; 907 extern Name shell_name; 908 extern Boolean svr4; 909 extern Name target_arch; 910 extern Name target_mach; 911 extern Boolean tilde_rule; 912 extern wchar_t wcs_buffer[]; 913 extern Boolean working_on_targets; 914 extern Name virtual_root; 915 extern Boolean vpath_defined; 916 extern Name vpath_name; 917 extern Boolean make_state_locked; 918 #if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR) 919 extern Boolean out_err_same; 920 #endif 921 extern pid_t childPid; 922 extern nl_catd libmksh_catd; 923 924 /* 925 * RFE 1257407: make does not use fine granularity time info available from stat. 926 * High resolution time comparison. 927 */ 928 929 inline int 930 operator==(const timestruc_t &t1, const timestruc_t &t2) { 931 return ((t1.tv_sec == t2.tv_sec) && (t1.tv_nsec == t2.tv_nsec)); 932 } 933 934 inline int 935 operator!=(const timestruc_t &t1, const timestruc_t &t2) { 936 return ((t1.tv_sec != t2.tv_sec) || (t1.tv_nsec != t2.tv_nsec)); 937 } 938 939 inline int 940 operator>(const timestruc_t &t1, const timestruc_t &t2) { 941 if (t1.tv_sec == t2.tv_sec) { 942 return (t1.tv_nsec > t2.tv_nsec); 943 } 944 return (t1.tv_sec > t2.tv_sec); 945 } 946 947 inline int 948 operator>=(const timestruc_t &t1, const timestruc_t &t2) { 949 if (t1.tv_sec == t2.tv_sec) { 950 return (t1.tv_nsec >= t2.tv_nsec); 951 } 952 return (t1.tv_sec > t2.tv_sec); 953 } 954 955 inline int 956 operator<(const timestruc_t &t1, const timestruc_t &t2) { 957 if (t1.tv_sec == t2.tv_sec) { 958 return (t1.tv_nsec < t2.tv_nsec); 959 } 960 return (t1.tv_sec < t2.tv_sec); 961 } 962 963 inline int 964 operator<=(const timestruc_t &t1, const timestruc_t &t2) { 965 if (t1.tv_sec == t2.tv_sec) { 966 return (t1.tv_nsec <= t2.tv_nsec); 967 } 968 return (t1.tv_sec < t2.tv_sec); 969 } 970 971 #endif