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