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