"Fossies" - the Fresh Open Source Software Archive

Member "schily-2021-09-18/sunpro/Make/include/mksh/defs.h" (6 Sep 2021, 27923 Bytes) of package /linux/privat/schily-2021-09-18.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "defs.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes reports: 2021-09-01_vs_2021-09-18 or 2021-08-14_vs_2021-09-18 or 2021-07-29_vs_2021-09-18.

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