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