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