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