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