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