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.
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.
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]
24 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 #include <limits.h> /* MB_LEN_MAX */
30 #include <stdlib.h> /* wchar_t */
31 #include <string.h> /* strcmp() */
32 #include <sys/param.h> /* MAXPATHLEN */
33 #include <sys/types.h> /* time_t, caddr_t */
34 #include <vroot/vroot.h> /* pathpt */
35 #include <sys/time.h> /* timestruc_t */
36 #include <errno.h> /* errno */
41 * A type and some utilities for boolean values
44 #define false BOOLEAN_false
45 #define true BOOLEAN_true
53 #define BOOLEAN(expr) ((expr) ? true : false)
56 * Some random constants (in an enum so dbx knows their values)
59 update_delay
= 30, /* time between rstat checks */
60 ar_member_name_len
= 1024,
61 hashsize
= 2048 /* size of hash table */
66 * Symbols that defines all the different char constants make uses
73 backslash_char
= '\\',
76 braceright_char
= '}',
77 bracketleft_char
= '[',
78 bracketright_char
= ']',
82 doublequote_char
= '"',
91 numbersign_char
= '#',
93 parenright_char
= ')',
107 * For make i18n. Codeset independent.
108 * Setup character semantics by identifying all the special characters
109 * of make, and assigning each an entry in the char_semantics[] vector.
112 ampersand_char_entry
= 0, /* 0 */
113 asterisk_char_entry
, /* 1 */
114 at_char_entry
, /* 2 */
115 backquote_char_entry
, /* 3 */
116 backslash_char_entry
, /* 4 */
117 bar_char_entry
, /* 5 */
118 bracketleft_char_entry
, /* 6 */
119 bracketright_char_entry
, /* 7 */
120 colon_char_entry
, /* 8 */
121 dollar_char_entry
, /* 9 */
122 doublequote_char_entry
, /* 10 */
123 equal_char_entry
, /* 11 */
124 exclam_char_entry
, /* 12 */
125 greater_char_entry
, /* 13 */
126 hat_char_entry
, /* 14 */
127 hyphen_char_entry
, /* 15 */
128 less_char_entry
, /* 16 */
129 newline_char_entry
, /* 17 */
130 numbersign_char_entry
, /* 18 */
131 parenleft_char_entry
, /* 19 */
132 parenright_char_entry
, /* 20 */
133 percent_char_entry
, /* 21 */
134 plus_char_entry
, /* 22 */
135 question_char_entry
, /* 23 */
136 quote_char_entry
, /* 24 */
137 semicolon_char_entry
, /* 25 */
138 no_semantics_entry
/* 26 */
142 * CHAR_SEMANTICS_ENTRIES should be the number of entries above.
143 * The last entry in char_semantics[] should be blank.
145 #define CHAR_SEMANTICS_ENTRIES 27
147 #define CHAR_SEMANTICS_STRING "&*@`\\|[]:$=!>-\n#()%+?;^<'\""
151 * Some utility macros
153 #define ALLOC(x) ((struct _##x *)getmem(sizeof (struct _##x)))
154 #define ALLOC_WC(x) ((wchar_t *)getmem((x) * SIZEOFWCHAR_T))
155 #define FIND_LENGTH -1
156 #define GETNAME(a,b) getname_fn((a), (b), false)
157 #define IS_EQUAL(a,b) (!strcmp((a), (b)))
158 #define IS_EQUALN(a,b,n) (!strncmp((a), (b), (n)))
159 #define IS_WEQUAL(a,b) (!wcscmp((a), (b)))
160 #define IS_WEQUALN(a,b,n) (!wcsncmp((a), (b), (n)))
161 #define MBLEN(a) mblen((a), MB_LEN_MAX)
162 #define MBSTOWCS(a,b) (void) mbstowcs_with_check((a), (b), MAXPATHLEN)
163 #define MBTOWC(a,b) mbtowc((a), (b), MB_LEN_MAX)
164 #define SIZEOFWCHAR_T (sizeof (wchar_t))
165 #define VSIZEOF(v) (sizeof (v) / sizeof ((v)[0]))
166 #define WCSTOMBS(a,b) (void) wcstombs((a), (b), (MAXPATHLEN * MB_LEN_MAX))
167 #define WCTOMB(a,b) (void) wctomb((a), (b))
168 #define HASH(v, c) (v = (v)*31 + (unsigned int)(c))
170 extern void mbstowcs_with_check(wchar_t *pwcs
, const char *s
, size_t n
);
173 * Bits stored in funny vector to classify chars
180 command_prefix_sem
= 0020,
181 special_macro_sem
= 0040,
187 * Type returned from doname class functions
194 build_running
, /* PARALLEL & DISTRIBUTED */
195 build_pending
, /* PARALLEL & DISTRIBUTED */
196 build_serial
, /* PARALLEL & DISTRIBUTED */
197 build_subtree
/* PARALLEL & DISTRIBUTED */
201 * The String struct defines a string with the following layout
202 * "xxxxxxxxxxxxxxxCxxxxxxxxxxxxxxx________"
205 * buffer.start text.p text.end buffer.end
206 * text.p points to the next char to read/write.
210 wchar_t *p
; /* Read/Write pointer */
211 wchar_t *end
; /* Read limit pointer */
213 struct Physical_buffer
{
214 wchar_t *start
; /* Points to start of buffer */
215 wchar_t *end
; /* End of physical buffer */
217 Boolean free_after_use
:1;
220 #define STRING_BUFFER_LENGTH 1024
221 #define INIT_STRING_FROM_STACK(str, buf) { \
222 str.buffer.start = (buf); \
223 str.text.p = (buf); \
224 str.text.end = NULL; \
225 str.buffer.end = (buf) \
226 + (sizeof (buf)/SIZEOFWCHAR_T); \
227 str.free_after_use = false; \
230 #define APPEND_NAME(np, dest, len) append_string((np)->string_mb, (dest), (len));
234 struct _String string
;
235 wchar_t string_buf
[STRING_BUFFER_LENGTH
];
239 Wstring(struct _Name
* name
);
242 void init(struct _Name
* name
);
243 void init(wchar_t * name
, unsigned length
);
245 return wcslen(string
.buffer
.start
);
247 void append_to_str(struct _String
* str
, unsigned off
, unsigned length
);
249 wchar_t * get_string() {
250 return string
.buffer
.start
;
253 wchar_t * get_string(unsigned off
) {
254 return string
.buffer
.start
+ off
;
257 Boolean
equaln(wchar_t * str
, unsigned length
);
258 Boolean
equal(wchar_t * str
);
259 Boolean
equal(wchar_t * str
, unsigned off
);
260 Boolean
equal(wchar_t * str
, unsigned off
, unsigned length
);
262 Boolean
equaln(Wstring
* str
, unsigned length
);
263 Boolean
equal(Wstring
* str
);
264 Boolean
equal(Wstring
* str
, unsigned off
);
265 Boolean
equal(Wstring
* str
, unsigned off
, unsigned length
);
270 * Used for storing the $? list and also for the "target + target:"
276 struct _Percent
*percent_member
;
280 * Stores one command line for a rule
283 struct _Cmd_line
*next
;
284 struct _Name
*command_line
;
285 Boolean make_refd
:1; /* $(MAKE) referenced? */
287 * Remember any command line prefixes given
289 Boolean ignore_command_dependency
:1; /* `?' */
290 Boolean assign
:1; /* `=' */
291 Boolean ignore_error
:1; /* `-' */
292 Boolean silent
:1; /* `@' */
293 Boolean always_exec
:1; /* `+' */
297 * Linked list of targets/files
300 struct _Dependency
*next
;
308 * The specials are markers for targets that the reader should special case
312 built_last_make_run_special
,
317 keep_state_file_special
,
319 make_version_special
,
324 sccs_get_posix_special
,
342 * Magic values for the timestamp stored with each name object
346 extern const timestruc_t file_no_time
;
347 extern const timestruc_t file_doesnt_exist
;
348 extern const timestruc_t file_is_dir
;
349 extern const timestruc_t file_min_time
;
350 extern const timestruc_t file_max_time
;
353 * Each Name has a list of properties
354 * The properties are used to store information that only
355 * a subset of the Names need
370 long_member_name_prop
,
384 struct _Macro_appendix
{
386 struct _Name
*value_to_append
;
391 * For "ABC = xyz" constructs
392 * Name "ABC" get one macro prop
398 * This macro is defined conditionally
400 Boolean is_conditional
:1;
402 * The list for $? is stored as a structured list that
403 * is translated into a string iff it is referenced.
404 * This is why some macro values need a daemon.
410 struct _Macro_list
*next
;
422 struct _Property
*prop
; /* List of properties */
423 char *string_mb
; /* Multi-byte name string */
428 timestruc_t time
; /* Modification */
429 int stat_errno
; /* error from "stat" */
430 off_t size
; /* Of file */
431 mode_t mode
; /* Of file */
434 Boolean is_sym_link
:1;
435 Boolean is_precious
:1;
436 enum sccs_stat has_sccs
:2;
439 * Count instances of :: definitions for this target
443 * We only clear the automatic depes once per target per report
445 short temp_file_number
;
447 * Count how many conditional macros this target has defined
449 short conditional_cnt
;
451 * A conditional macro was used when building this target
453 Boolean depends_on_conditional
:1;
455 * Pointer to list of conditional macros which were used to build
458 struct _Macro_list
*conditional_macro_list
;
459 Boolean has_member_depe
:1;
462 * This target is a directory that has been read
464 Boolean has_read_dir
:1;
466 * This name is a macro that is now being expanded
468 Boolean being_expanded
:1;
470 * This name is a magic name that the reader must know about
472 Special special_reader
:5;
475 Boolean has_depe_list_expanded
:1;
476 Boolean suffix_scan_done
:1;
477 Boolean has_complained
:1; /* For sccs */
479 * This target has been built during this make run
481 Boolean ran_command
:1;
482 Boolean with_squiggle
:1; /* for .SUFFIXES */
483 Boolean without_squiggle
:1; /* for .SUFFIXES */
484 Boolean has_read_suffixes
:1; /* Suffix list cached*/
485 Boolean has_suffixes
:1;
486 Boolean has_target_prop
:1;
487 Boolean has_vpath_alias_prop
:1;
488 Boolean dependency_printed
:1; /* For dump_make_state() */
489 Boolean dollar
:1; /* In namestring */
490 Boolean meta
:1; /* In namestring */
491 Boolean percent
:1; /* In namestring */
492 Boolean wildcard
:1; /* In namestring */
493 Boolean has_parent
:1;
496 Boolean colon
:1; /* In namestring */
497 Boolean parenleft
:1; /* In namestring */
498 Boolean has_recursive_dependency
:1;
499 Boolean has_regular_dependency
:1;
500 Boolean is_double_colon
:1;
501 Boolean is_double_colon_parent
:1;
502 Boolean has_long_member_name
:1;
504 * allowed to run in parallel
508 * not allowed to run in parallel
510 Boolean no_parallel
:1;
512 * used in dependency_conflict
514 Boolean checking_subtree
:1;
515 Boolean added_pattern_conditionals
:1;
517 * rechecking target for possible rebuild
519 Boolean rechecking_target
:1;
521 * build this target in silent mode
523 Boolean silent_mode
:1;
525 * build this target in ignore error mode
527 Boolean ignore_error_mode
:1;
528 Boolean dont_activate_cond_values
:1;
530 * allowed to run serially on local host
536 * Stores the % matched default rules
539 struct _Percent
*next
;
540 struct _Name
**patterns
;
542 struct _Percent
*dependencies
;
543 struct _Cmd_line
*command_template
;
544 struct _Chain
*target_group
;
546 Boolean being_expanded
;
551 * For "foo := ABC [+]= xyz" constructs
552 * Name "foo" gets one conditional prop
554 struct _Name
*target
;
563 * For "target : dependencies" constructs
564 * Name "target" gets one line prop
566 struct _Cmd_line
*command_template
;
567 struct _Cmd_line
*command_used
;
568 struct _Dependency
*dependencies
;
569 timestruc_t dependency_time
;
570 struct _Chain
*target_group
;
571 Boolean is_out_of_date
:1;
572 Boolean sccs_command
:1;
573 Boolean command_template_redefined
:1;
574 Boolean dont_rebuild_command_used
:1;
576 * Values for the dynamic macros
578 struct _Name
*target
;
581 struct _Name
*percent
;
582 struct _Chain
*query
;
587 * Names that reference makefiles gets one prop
595 * For "lib(member)" and "lib((entry))" constructs
596 * Name "lib(member)" gets one member prop
597 * Name "lib((entry))" gets one member prop
598 * The member field is filled in when the prop is refd
600 struct _Name
*library
;
602 struct _Name
*member
;
607 * For "target: .RECURSIVE dir makefiles" constructs
608 * Used to keep track of recursive calls to make
609 * Name "target" gets one recursive prop
611 struct _Name
*directory
;
612 struct _Name
*target
;
613 struct _Dependency
*makefiles
;
620 * Each file that has a SCCS s. file gets one prop
627 * Cached list of suffixes that can build this target
628 * suffix is built from .SUFFIXES
630 struct _Name
*suffix
;
631 struct _Cmd_line
*command_template
;
636 * For "target:: dependencies" constructs
637 * The "::" construct is handled by converting it to
638 * "foo: 1@foo" + "1@foo: dependecies"
639 * "1@foo" gets one target prop
640 * This target prop cause $@ to be bound to "foo"
641 * not "1@foo" when the rule is evaluated
643 struct _Name
*target
;
648 * Save the original time for :: targets
655 * If a file was found using the VPATH it gets
661 struct Long_member_name
{
663 * Targets with a truncated member name carries
664 * the full lib(member) name for the state file
666 struct _Name
*member_name
;
671 struct Conditional conditional
;
673 struct Makefile makefile
;
674 struct Member member
;
675 struct Recursive recursive
;
677 struct Suffix suffix
;
678 struct Target target
;
680 struct Vpath_alias vpath_alias
;
681 struct Long_member_name long_member_name
;
682 struct _Macro_appendix macro_appendix
;
683 struct _Env_mem env_mem
;
686 #define PROPERTY_HEAD_SIZE (sizeof (struct _Property)-sizeof (union Body))
688 struct _Property
*next
;
693 /* Structure for dynamic "ascii" arrays */
694 struct ASCII_Dyn_Array
{
702 struct _Envvar
*next
;
704 Boolean already_put
:1;
708 * Macros for the reader
710 #define GOTO_STATE(new_state) { \
711 SET_STATE(new_state); \
714 #define SET_STATE(new_state) state = (new_state)
716 #define UNCACHE_SOURCE() if (source != NULL) { \
717 source->string.text.p = source_p; \
719 #define CACHE_SOURCE(comp) if (source != NULL) { \
720 source_p = source->string.text.p - \
722 source_end = source->string.text.end; \
724 #define GET_NEXT_BLOCK_NOCHK(source) { UNCACHE_SOURCE(); \
725 source = get_next_block_fn(source); \
728 #define GET_NEXT_BLOCK(source) { GET_NEXT_BLOCK_NOCHK(source); \
729 if (source != NULL && source->error_converting) { \
730 GOTO_STATE(illegal_bytes_state); \
733 #define GET_CHAR() ((source == NULL) || \
734 (source_p >= source_end) ? 0 : *source_p)
737 struct _String string
;
738 struct _Source
*previous
;
739 off_t bytes_left_in_file
;
741 Boolean already_expanded
:1;
742 Boolean error_converting
:1;
757 * Typedefs for all structs
759 typedef struct _Chain
*Chain
, Chain_rec
;
760 typedef struct _Envvar
*Envvar
, Envvar_rec
;
761 typedef struct _Macro_list
*Macro_list
, Macro_list_rec
;
762 typedef struct _Name
*Name
, Name_rec
;
763 typedef struct _Property
*Property
, Property_rec
;
764 typedef struct _Source
*Source
, Source_rec
;
765 typedef struct _String
*String
, String_rec
;
768 * name records hash table.
772 // single node in a tree
774 entry(Name name_
, entry
*parent_
) :
790 unsigned rdepth
= (right
!= 0) ? right
->depth
: 0;
791 unsigned ldepth
= (left
!= 0) ? left
->depth
: 0;
792 depth
= 1 + ((ldepth
> rdepth
) ? ldepth
: rdepth
);
797 // make iterator a friend of Name_set to have access to struct entry
799 friend struct Name_set::iterator
;
801 // iterator over tree nodes
805 iterator() : node(0) {}
806 iterator(entry
*node_
) : node(node_
) {}
808 // dereference operator
809 Name
operator->() const { return node
->name
; }
811 // conversion operator
812 operator Name() { return node
->name
; }
814 // assignment operator
815 iterator
& operator=(const iterator
&o
) { node
= o
.node
; return *this; }
817 // equality/inequality operators
818 int operator==(const iterator
&o
) const { return (node
== o
.node
); }
819 int operator!=(const iterator
&o
) const { return (node
!= o
.node
); }
821 // pre/post increment operators
822 iterator
& operator++();
823 iterator
operator++(int) { iterator it
= *this; ++*this; return it
; }
826 // the node iterator points to
832 Name_set() : root(0) {}
834 // lookup, insert and remove operations
835 Name
lookup(const char *key
);
836 Name
insert(const char *key
, Boolean
&found
);
837 void insert(Name name
);
839 // begin/end iterators
840 iterator
begin() const;
841 iterator
end() const { return iterator(); }
844 // rebalance given node
845 void rebalance(entry
*node
);
853 * extern declarations for all global variables.
854 * The actual declarations are in globals.cc
856 extern char char_semantics
[];
857 extern wchar_t char_semantics_char
[];
858 extern Macro_list cond_macro_list
;
859 extern Boolean conditional_macro_used
;
860 extern Boolean do_not_exec_rule
; /* `-n' */
861 extern Boolean dollarget_seen
;
862 extern Boolean dollarless_flag
;
863 extern Name dollarless_value
;
864 extern char **environ
;
865 extern Envvar envvar
;
866 extern int exit_status
;
867 extern wchar_t *file_being_read
;
868 /* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */
869 extern Boolean gnu_style
;
870 extern Name_set hashtab
;
871 extern Name host_arch
;
872 extern Name host_mach
;
873 extern int line_number
;
874 extern char *make_state_lockfile
;
875 extern Boolean make_word_mentioned
;
876 extern Makefile_type makefile_type
;
877 extern char mbs_buffer
[];
878 extern Name path_name
;
879 extern Boolean posix
;
881 extern Boolean query_mentioned
;
883 extern Boolean reading_environment
;
884 extern Name shell_name
;
886 extern Name target_arch
;
887 extern Name target_mach
;
888 extern Boolean tilde_rule
;
889 extern wchar_t wcs_buffer
[];
890 extern Boolean working_on_targets
;
891 extern Name virtual_root
;
892 extern Boolean vpath_defined
;
893 extern Name vpath_name
;
894 extern Boolean make_state_locked
;
895 extern Boolean out_err_same
;
896 extern pid_t childPid
;
899 * RFE 1257407: make does not use fine granularity time info available from stat.
900 * High resolution time comparison.
904 operator==(const timestruc_t
&t1
, const timestruc_t
&t2
) {
905 return ((t1
.tv_sec
== t2
.tv_sec
) && (t1
.tv_nsec
== t2
.tv_nsec
));
909 operator!=(const timestruc_t
&t1
, const timestruc_t
&t2
) {
910 return ((t1
.tv_sec
!= t2
.tv_sec
) || (t1
.tv_nsec
!= t2
.tv_nsec
));
914 operator>(const timestruc_t
&t1
, const timestruc_t
&t2
) {
915 if (t1
.tv_sec
== t2
.tv_sec
) {
916 return (t1
.tv_nsec
> t2
.tv_nsec
);
918 return (t1
.tv_sec
> t2
.tv_sec
);
922 operator>=(const timestruc_t
&t1
, const timestruc_t
&t2
) {
923 if (t1
.tv_sec
== t2
.tv_sec
) {
924 return (t1
.tv_nsec
>= t2
.tv_nsec
);
926 return (t1
.tv_sec
> t2
.tv_sec
);
930 operator<(const timestruc_t
&t1
, const timestruc_t
&t2
) {
931 if (t1
.tv_sec
== t2
.tv_sec
) {
932 return (t1
.tv_nsec
< t2
.tv_nsec
);
934 return (t1
.tv_sec
< t2
.tv_sec
);
938 operator<=(const timestruc_t
&t1
, const timestruc_t
&t2
) {
939 if (t1
.tv_sec
== t2
.tv_sec
) {
940 return (t1
.tv_nsec
<= t2
.tv_nsec
);
942 return (t1
.tv_sec
< t2
.tv_sec
);