"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.

    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