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