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