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 #ifdef NSE 338 derived_src_special, 339 #endif 340 get_posix_special, 341 get_special, 342 ignore_special, 343 keep_state_file_special, 344 keep_state_special, 345 make_version_special, 346 no_parallel_special, 347 parallel_special, 348 posix_special, 349 precious_special, 350 sccs_get_posix_special, 351 sccs_get_special, 352 silent_special, 353 suffixes_special, 354 svr4_special, 355 localhost_special 356 } Special; 357 358 typedef enum { 359 no_colon, 360 one_colon, 361 two_colon, 362 equal_seen, 363 conditional_seen, 364 none_seen 365 } Separator; 366 367 /* 368 * Magic values for the timestamp stored with each name object 369 */ 370 371 372 extern const timestruc_t file_no_time; 373 extern const timestruc_t file_doesnt_exist; 374 extern const timestruc_t file_is_dir; 375 extern const timestruc_t file_min_time; 376 extern const timestruc_t file_max_time; 377 378 /* 379 * Each Name has a list of properties 380 * The properties are used to store information that only 381 * a subset of the Names need 382 */ 383 typedef enum { 384 no_prop, 385 conditional_prop, 386 line_prop, 387 macro_prop, 388 makefile_prop, 389 member_prop, 390 recursive_prop, 391 sccs_prop, 392 suffix_prop, 393 target_prop, 394 time_prop, 395 vpath_alias_prop, 396 long_member_name_prop, 397 macro_append_prop, 398 env_mem_prop 399 } Property_id; 400 401 typedef enum { 402 no_daemon = 0, 403 chain_daemon 404 } Daemon; 405 406 struct _Env_mem { 407 char *value; 408 }; 409 410 struct _Macro_appendix { 411 struct _Name *value; 412 struct _Name *value_to_append; 413 }; 414 415 struct _Macro { 416 /* 417 * For "ABC = xyz" constructs 418 * Name "ABC" get one macro prop 419 */ 420 struct _Name *value; 421 #ifdef NSE 422 Boolean imported:1; 423 #endif 424 Boolean exported:1; 425 Boolean read_only:1; 426 /* 427 * This macro is defined conditionally 428 */ 429 Boolean is_conditional:1; 430 /* 431 * The list for $? is stored as a structured list that 432 * is translated into a string iff it is referenced. 433 * This is why some macro values need a daemon. 434 */ 435 Daemon daemon:2; 436 }; 437 438 struct _Macro_list { 439 struct _Macro_list *next; 440 char *macro_name; 441 char *value; 442 }; 443 444 enum sccs_stat { 445 DONT_KNOW_SCCS = 0, 446 NO_SCCS, 447 HAS_SCCS 448 }; 449 450 struct _Name { 451 struct _Property *prop; /* List of properties */ 452 char *string_mb; /* Multi-byte name string */ 453 struct { 454 unsigned int length; 455 } hash; 456 struct { 457 timestruc_t time; /* Modification */ 458 int stat_errno; /* error from "stat" */ 459 off_t size; /* Of file */ 460 mode_t mode; /* Of file */ 461 Boolean is_file:1; 462 Boolean is_dir:1; 463 Boolean is_sym_link:1; 464 Boolean is_precious:1; 465 #ifdef NSE 466 Boolean is_derived_src:1; 467 #endif 468 enum sccs_stat has_sccs:2; 469 } stat; 470 /* 471 * Count instances of :: definitions for this target 472 */ 473 short colon_splits; 474 /* 475 * We only clear the automatic depes once per target per report 476 */ 477 short temp_file_number; 478 /* 479 * Count how many conditional macros this target has defined 480 */ 481 short conditional_cnt; 482 /* 483 * A conditional macro was used when building this target 484 */ 485 Boolean depends_on_conditional:1; 486 /* 487 * Pointer to list of conditional macros which were used to build 488 * this target 489 */ 490 struct _Macro_list *conditional_macro_list; 491 Boolean has_member_depe:1; 492 Boolean is_member:1; 493 /* 494 * This target is a directory that has been read 495 */ 496 Boolean has_read_dir:1; 497 /* 498 * This name is a macro that is now being expanded 499 */ 500 Boolean being_expanded:1; 501 /* 502 * This name is a magic name that the reader must know about 503 */ 504 Special special_reader:5; 505 Doname state:3; 506 Separator colons:3; 507 Boolean has_depe_list_expanded:1; 508 Boolean suffix_scan_done:1; 509 Boolean has_complained:1; /* For sccs */ 510 /* 511 * This target has been built during this make run 512 */ 513 Boolean ran_command:1; 514 Boolean with_squiggle:1; /* for .SUFFIXES */ 515 Boolean without_squiggle:1; /* for .SUFFIXES */ 516 Boolean has_read_suffixes:1; /* Suffix list cached*/ 517 Boolean has_suffixes:1; 518 Boolean has_target_prop:1; 519 Boolean has_vpath_alias_prop:1; 520 Boolean dependency_printed:1; /* For dump_make_state() */ 521 Boolean dollar:1; /* In namestring */ 522 Boolean meta:1; /* In namestring */ 523 Boolean percent:1; /* In namestring */ 524 Boolean wildcard:1; /* In namestring */ 525 Boolean has_parent:1; 526 Boolean is_target:1; 527 Boolean has_built:1; 528 Boolean colon:1; /* In namestring */ 529 Boolean parenleft:1; /* In namestring */ 530 Boolean has_recursive_dependency:1; 531 Boolean has_regular_dependency:1; 532 Boolean is_double_colon:1; 533 Boolean is_double_colon_parent:1; 534 Boolean has_long_member_name:1; 535 /* 536 * allowed to run in parallel 537 */ 538 Boolean parallel:1; 539 /* 540 * not allowed to run in parallel 541 */ 542 Boolean no_parallel:1; 543 /* 544 * used in dependency_conflict 545 */ 546 Boolean checking_subtree:1; 547 Boolean added_pattern_conditionals:1; 548 /* 549 * rechecking target for possible rebuild 550 */ 551 Boolean rechecking_target:1; 552 /* 553 * build this target in silent mode 554 */ 555 Boolean silent_mode:1; 556 /* 557 * build this target in ignore error mode 558 */ 559 Boolean ignore_error_mode:1; 560 Boolean dont_activate_cond_values:1; 561 /* 562 * allowed to run serially on local host 563 */ 564 Boolean localhost:1; 565 }; 566 567 /* 568 * Stores the % matched default rules 569 */ 570 struct _Percent { 571 struct _Percent *next; 572 struct _Name **patterns; 573 struct _Name *name; 574 struct _Percent *dependencies; 575 struct _Cmd_line *command_template; 576 struct _Chain *target_group; 577 int patterns_total; 578 Boolean being_expanded; 579 }; 580 581 struct Conditional { 582 /* 583 * For "foo := ABC [+]= xyz" constructs 584 * Name "foo" gets one conditional prop 585 */ 586 struct _Name *target; 587 struct _Name *name; 588 struct _Name *value; 589 int sequence; 590 Boolean append:1; 591 }; 592 593 struct Line { 594 /* 595 * For "target : dependencies" constructs 596 * Name "target" gets one line prop 597 */ 598 struct _Cmd_line *command_template; 599 struct _Cmd_line *command_used; 600 struct _Dependency *dependencies; 601 timestruc_t dependency_time; 602 struct _Chain *target_group; 603 Boolean is_out_of_date:1; 604 Boolean sccs_command:1; 605 Boolean command_template_redefined:1; 606 Boolean dont_rebuild_command_used:1; 607 /* 608 * Values for the dynamic macros 609 */ 610 struct _Name *target; 611 struct _Name *star; 612 struct _Name *less; 613 struct _Name *percent; 614 struct _Chain *query; 615 }; 616 617 struct Makefile { 618 /* 619 * Names that reference makefiles gets one prop 620 */ 621 wchar_t *contents; 622 off_t size; 623 }; 624 625 struct Member { 626 /* 627 * For "lib(member)" and "lib((entry))" constructs 628 * Name "lib(member)" gets one member prop 629 * Name "lib((entry))" gets one member prop 630 * The member field is filled in when the prop is refd 631 */ 632 struct _Name *library; 633 struct _Name *entry; 634 struct _Name *member; 635 }; 636 637 struct Recursive { 638 /* 639 * For "target: .RECURSIVE dir makefiles" constructs 640 * Used to keep track of recursive calls to make 641 * Name "target" gets one recursive prop 642 */ 643 struct _Name *directory; 644 struct _Name *target; 645 struct _Dependency *makefiles; 646 Boolean has_built; 647 Boolean in_depinfo; 648 }; 649 650 struct Sccs { 651 /* 652 * Each file that has a SCCS s. file gets one prop 653 */ 654 struct _Name *file; 655 }; 656 657 struct Suffix { 658 /* 659 * Cached list of suffixes that can build this target 660 * suffix is built from .SUFFIXES 661 */ 662 struct _Name *suffix; 663 struct _Cmd_line *command_template; 664 }; 665 666 struct Target { 667 /* 668 * For "target:: dependencies" constructs 669 * The "::" construct is handled by converting it to 670 * "foo: 1@foo" + "1@foo: dependecies" 671 * "1@foo" gets one target prop 672 * This target prop cause $@ to be bound to "foo" 673 * not "1@foo" when the rule is evaluated 674 */ 675 struct _Name *target; 676 }; 677 678 struct STime { 679 /* 680 * Save the original time for :: targets 681 */ 682 timestruc_t time; 683 }; 684 685 struct Vpath_alias { 686 /* 687 * If a file was found using the VPATH it gets 688 * a vpath_alias prop 689 */ 690 struct _Name *alias; 691 }; 692 693 struct Long_member_name { 694 /* 695 * Targets with a truncated member name carries 696 * the full lib(member) name for the state file 697 */ 698 struct _Name *member_name; 699 }; 700 701 union Body { 702 struct _Macro macro; 703 struct Conditional conditional; 704 struct Line line; 705 struct Makefile makefile; 706 struct Member member; 707 struct Recursive recursive; 708 struct Sccs sccs; 709 struct Suffix suffix; 710 struct Target target; 711 struct STime time; 712 struct Vpath_alias vpath_alias; 713 struct Long_member_name long_member_name; 714 struct _Macro_appendix macro_appendix; 715 struct _Env_mem env_mem; 716 }; 717 718 #define PROPERTY_HEAD_SIZE (sizeof (struct _Property)-sizeof (union Body)) 719 struct _Property { 720 struct _Property *next; 721 Property_id type:4; 722 union Body body; 723 }; 724 725 /* Structure for dynamic "ascii" arrays */ 726 struct ASCII_Dyn_Array { 727 char *start; 728 size_t size; 729 }; 730 731 struct _Envvar { 732 struct _Name *name; 733 struct _Name *value; 734 struct _Envvar *next; 735 char *env_string; 736 Boolean already_put:1; 737 }; 738 739 /* 740 * Macros for the reader 741 */ 742 #define GOTO_STATE(new_state) { \ 743 SET_STATE(new_state); \ 744 goto enter_state; \ 745 } 746 #define SET_STATE(new_state) state = (new_state) 747 748 #define UNCACHE_SOURCE() if (source != NULL) { \ 749 source->string.text.p = source_p; \ 750 } 751 #define CACHE_SOURCE(comp) if (source != NULL) { \ 752 source_p = source->string.text.p - \ 753 (comp); \ 754 source_end = source->string.text.end; \ 755 } 756 #define GET_NEXT_BLOCK_NOCHK(source) { UNCACHE_SOURCE(); \ 757 source = get_next_block_fn(source); \ 758 CACHE_SOURCE(0) \ 759 } 760 #define GET_NEXT_BLOCK(source) { GET_NEXT_BLOCK_NOCHK(source); \ 761 if (source != NULL && source->error_converting) { \ 762 GOTO_STATE(illegal_bytes_state); \ 763 } \ 764 } 765 #define GET_CHAR() ((source == NULL) || \ 766 (source_p >= source_end) ? 0 : *source_p) 767 768 struct _Source { 769 struct _String string; 770 struct _Source *previous; 771 off_t bytes_left_in_file; 772 short fd; 773 Boolean already_expanded:1; 774 Boolean error_converting:1; 775 char *inp_buf; 776 char *inp_buf_end; 777 char *inp_buf_ptr; 778 }; 779 780 typedef enum { 781 reading_nothing, 782 reading_makefile, 783 reading_statefile, 784 rereading_statefile, 785 reading_cpp_file 786 } Makefile_type; 787 788 /* 789 * Typedefs for all structs 790 */ 791 typedef struct _Chain *Chain, Chain_rec; 792 typedef struct _Envvar *Envvar, Envvar_rec; 793 typedef struct _Macro_list *Macro_list, Macro_list_rec; 794 typedef struct _Name *Name, Name_rec; 795 typedef struct _Property *Property, Property_rec; 796 typedef struct _Source *Source, Source_rec; 797 typedef struct _String *String, String_rec; 798 799 /* 800 * name records hash table. 801 */ 802 struct Name_set { 803 private: 804 // single node in a tree 805 struct entry { 806 entry(Name name_, entry *parent_) : 807 name(name_), 808 parent(parent_), 809 left(0), 810 right(0), 811 depth(1) 812 {} 813 814 Name name; 815 816 entry *parent; 817 entry *left; 818 entry *right; 819 unsigned depth; 820 821 void setup_depth() { 822 unsigned rdepth = (right != 0) ? right->depth : 0; 823 unsigned ldepth = (left != 0) ? left->depth : 0; 824 depth = 1 + ((ldepth > rdepth) ? ldepth : rdepth); 825 } 826 }; 827 828 public: 829 // make iterator a friend of Name_set to have access to struct entry 830 struct iterator; 831 friend struct Name_set::iterator; 832 833 // iterator over tree nodes 834 struct iterator { 835 public: 836 // constructors 837 iterator() : node(0) {} 838 iterator(entry *node_) : node(node_) {} 839 840 // dereference operator 841 Name operator->() const { return node->name; } 842 843 // conversion operator 844 operator Name() { return node->name; } 845 846 // assignment operator 847 iterator& operator=(const iterator &o) { node = o.node; return *this; } 848 849 // equality/inequality operators 850 int operator==(const iterator &o) const { return (node == o.node); } 851 int operator!=(const iterator &o) const { return (node != o.node); } 852 853 // pre/post increment operators 854 iterator& operator++(); 855 iterator operator++(int) { iterator it = *this; ++*this; return it; } 856 857 private: 858 // the node iterator points to 859 entry *node; 860 }; 861 862 public: 863 // constructor 864 Name_set() : root(0) {} 865 866 // lookup, insert and remove operations 867 Name lookup(const char *key); 868 Name insert(const char *key, Boolean &found); 869 void insert(Name name); 870 871 // begin/end iterators 872 iterator begin() const; 873 iterator end() const { return iterator(); } 874 875 private: 876 // rebalance given node 877 void rebalance(entry *node); 878 879 private: 880 // tree root 881 entry *root; 882 }; 883 884 /* 885 * extern declarations for all global variables. 886 * The actual declarations are in globals.cc 887 */ 888 extern char char_semantics[]; 889 extern wchar_t char_semantics_char[]; 890 extern Macro_list cond_macro_list; 891 extern Boolean conditional_macro_used; 892 extern Boolean do_not_exec_rule; /* `-n' */ 893 extern Boolean dollarget_seen; 894 extern Boolean dollarless_flag; 895 extern Name dollarless_value; 896 extern char **environ; 897 extern Envvar envvar; 898 extern int exit_status; 899 extern wchar_t *file_being_read; 900 /* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */ 901 extern Boolean gnu_style; 902 extern Name_set hashtab; 903 extern Name host_arch; 904 extern Name host_mach; 905 extern int line_number; 906 extern char *make_state_lockfile; 907 extern Boolean make_word_mentioned; 908 extern Makefile_type makefile_type; 909 extern char mbs_buffer[]; 910 extern Name path_name; 911 extern Boolean posix; 912 extern Name query; 913 extern Boolean query_mentioned; 914 extern Name hat; 915 extern Boolean reading_environment; 916 extern Name shell_name; 917 extern Boolean svr4; 918 extern Name target_arch; 919 extern Name target_mach; 920 extern Boolean tilde_rule; 921 extern wchar_t wcs_buffer[]; 922 extern Boolean working_on_targets; 923 extern Name virtual_root; 924 extern Boolean vpath_defined; 925 extern Name vpath_name; 926 extern Boolean make_state_locked; 927 #if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR) 928 extern Boolean out_err_same; 929 #endif 930 extern pid_t childPid; 931 extern nl_catd libmksh_catd; 932 933 /* 934 * RFE 1257407: make does not use fine granularity time info available from stat. 935 * High resolution time comparison. 936 */ 937 938 inline int 939 operator==(const timestruc_t &t1, const timestruc_t &t2) { 940 return ((t1.tv_sec == t2.tv_sec) && (t1.tv_nsec == t2.tv_nsec)); 941 } 942 943 inline int 944 operator!=(const timestruc_t &t1, const timestruc_t &t2) { 945 return ((t1.tv_sec != t2.tv_sec) || (t1.tv_nsec != t2.tv_nsec)); 946 } 947 948 inline int 949 operator>(const timestruc_t &t1, const timestruc_t &t2) { 950 if (t1.tv_sec == t2.tv_sec) { 951 return (t1.tv_nsec > t2.tv_nsec); 952 } 953 return (t1.tv_sec > t2.tv_sec); 954 } 955 956 inline int 957 operator>=(const timestruc_t &t1, const timestruc_t &t2) { 958 if (t1.tv_sec == t2.tv_sec) { 959 return (t1.tv_nsec >= t2.tv_nsec); 960 } 961 return (t1.tv_sec > t2.tv_sec); 962 } 963 964 inline int 965 operator<(const timestruc_t &t1, const timestruc_t &t2) { 966 if (t1.tv_sec == t2.tv_sec) { 967 return (t1.tv_nsec < t2.tv_nsec); 968 } 969 return (t1.tv_sec < t2.tv_sec); 970 } 971 972 inline int 973 operator<=(const timestruc_t &t1, const timestruc_t &t2) { 974 if (t1.tv_sec == t2.tv_sec) { 975 return (t1.tv_nsec <= t2.tv_nsec); 976 } 977 return (t1.tv_sec < t2.tv_sec); 978 } 979 980 #endif