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