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