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 #ifdef NSE
338 derived_src_special,
339 #endif
340 get_posix_special,
341 get_special,
342 ignore_special,
343 keep_state_file_special,
344 keep_state_special,
345 make_version_special,
346 no_parallel_special,
347 parallel_special,
348 posix_special,
349 precious_special,
350 sccs_get_posix_special,
351 sccs_get_special,
352 silent_special,
353 suffixes_special,
354 svr4_special,
355 localhost_special
356 } Special;
357
358 typedef enum {
359 no_colon,
360 one_colon,
361 two_colon,
362 equal_seen,
363 conditional_seen,
364 none_seen
365 } Separator;
366
367 /*
368 * Magic values for the timestamp stored with each name object
369 */
370
371
372 extern const timestruc_t file_no_time;
373 extern const timestruc_t file_doesnt_exist;
374 extern const timestruc_t file_is_dir;
375 extern const timestruc_t file_min_time;
376 extern const timestruc_t file_max_time;
377
378 /*
379 * Each Name has a list of properties
380 * The properties are used to store information that only
381 * a subset of the Names need
382 */
383 typedef enum {
384 no_prop,
385 conditional_prop,
386 line_prop,
387 macro_prop,
388 makefile_prop,
389 member_prop,
390 recursive_prop,
391 sccs_prop,
392 suffix_prop,
393 target_prop,
394 time_prop,
395 vpath_alias_prop,
396 long_member_name_prop,
397 macro_append_prop,
398 env_mem_prop
399 } Property_id;
400
401 typedef enum {
402 no_daemon = 0,
403 chain_daemon
404 } Daemon;
405
406 struct _Env_mem {
407 char *value;
408 };
409
410 struct _Macro_appendix {
411 struct _Name *value;
412 struct _Name *value_to_append;
413 };
414
415 struct _Macro {
416 /*
417 * For "ABC = xyz" constructs
418 * Name "ABC" get one macro prop
419 */
420 struct _Name *value;
421 #ifdef NSE
422 Boolean imported:1;
423 #endif
424 Boolean exported:1;
425 Boolean read_only:1;
426 /*
427 * This macro is defined conditionally
428 */
429 Boolean is_conditional:1;
430 /*
431 * The list for $? is stored as a structured list that
432 * is translated into a string iff it is referenced.
433 * This is why some macro values need a daemon.
434 */
435 Daemon daemon:2;
436 };
437
438 struct _Macro_list {
439 struct _Macro_list *next;
440 char *macro_name;
441 char *value;
442 };
443
444 enum sccs_stat {
445 DONT_KNOW_SCCS = 0,
446 NO_SCCS,
447 HAS_SCCS
448 };
449
450 struct _Name {
451 struct _Property *prop; /* List of properties */
452 char *string_mb; /* Multi-byte name string */
453 struct {
454 unsigned int length;
455 } hash;
456 struct {
457 timestruc_t time; /* Modification */
458 int stat_errno; /* error from "stat" */
459 off_t size; /* Of file */
460 mode_t mode; /* Of file */
461 Boolean is_file:1;
462 Boolean is_dir:1;
463 Boolean is_sym_link:1;
464 Boolean is_precious:1;
465 #ifdef NSE
466 Boolean is_derived_src:1;
467 #endif
468 enum sccs_stat has_sccs:2;
469 } stat;
470 /*
471 * Count instances of :: definitions for this target
472 */
473 short colon_splits;
474 /*
475 * We only clear the automatic depes once per target per report
476 */
477 short temp_file_number;
478 /*
479 * Count how many conditional macros this target has defined
480 */
481 short conditional_cnt;
482 /*
483 * A conditional macro was used when building this target
484 */
485 Boolean depends_on_conditional:1;
486 /*
487 * Pointer to list of conditional macros which were used to build
488 * this target
489 */
490 struct _Macro_list *conditional_macro_list;
491 Boolean has_member_depe:1;
492 Boolean is_member:1;
493 /*
494 * This target is a directory that has been read
495 */
496 Boolean has_read_dir:1;
497 /*
498 * This name is a macro that is now being expanded
499 */
500 Boolean being_expanded:1;
501 /*
502 * This name is a magic name that the reader must know about
503 */
504 Special special_reader:5;
505 Doname state:3;
506 Separator colons:3;
507 Boolean has_depe_list_expanded:1;
508 Boolean suffix_scan_done:1;
509 Boolean has_complained:1; /* For sccs */
510 /*
511 * This target has been built during this make run
512 */
513 Boolean ran_command:1;
514 Boolean with_squiggle:1; /* for .SUFFIXES */
515 Boolean without_squiggle:1; /* for .SUFFIXES */
516 Boolean has_read_suffixes:1; /* Suffix list cached*/
517 Boolean has_suffixes:1;
518 Boolean has_target_prop:1;
519 Boolean has_vpath_alias_prop:1;
520 Boolean dependency_printed:1; /* For dump_make_state() */
521 Boolean dollar:1; /* In namestring */
522 Boolean meta:1; /* In namestring */
523 Boolean percent:1; /* In namestring */
524 Boolean wildcard:1; /* In namestring */
525 Boolean has_parent:1;
526 Boolean is_target:1;
527 Boolean has_built:1;
528 Boolean colon:1; /* In namestring */
529 Boolean parenleft:1; /* In namestring */
530 Boolean has_recursive_dependency:1;
531 Boolean has_regular_dependency:1;
532 Boolean is_double_colon:1;
533 Boolean is_double_colon_parent:1;
534 Boolean has_long_member_name:1;
535 /*
536 * allowed to run in parallel
537 */
538 Boolean parallel:1;
539 /*
540 * not allowed to run in parallel
541 */
542 Boolean no_parallel:1;
543 /*
544 * used in dependency_conflict
545 */
546 Boolean checking_subtree:1;
547 Boolean added_pattern_conditionals:1;
548 /*
549 * rechecking target for possible rebuild
550 */
551 Boolean rechecking_target:1;
552 /*
553 * build this target in silent mode
554 */
555 Boolean silent_mode:1;
556 /*
557 * build this target in ignore error mode
558 */
559 Boolean ignore_error_mode:1;
560 Boolean dont_activate_cond_values:1;
561 /*
562 * allowed to run serially on local host
563 */
564 Boolean localhost:1;
565 };
566
567 /*
568 * Stores the % matched default rules
569 */
570 struct _Percent {
571 struct _Percent *next;
572 struct _Name **patterns;
573 struct _Name *name;
574 struct _Percent *dependencies;
575 struct _Cmd_line *command_template;
576 struct _Chain *target_group;
577 int patterns_total;
578 Boolean being_expanded;
579 };
580
581 struct Conditional {
582 /*
583 * For "foo := ABC [+]= xyz" constructs
584 * Name "foo" gets one conditional prop
585 */
586 struct _Name *target;
587 struct _Name *name;
588 struct _Name *value;
589 int sequence;
590 Boolean append:1;
591 };
592
593 struct Line {
594 /*
595 * For "target : dependencies" constructs
596 * Name "target" gets one line prop
597 */
598 struct _Cmd_line *command_template;
599 struct _Cmd_line *command_used;
600 struct _Dependency *dependencies;
601 timestruc_t dependency_time;
602 struct _Chain *target_group;
603 Boolean is_out_of_date:1;
604 Boolean sccs_command:1;
605 Boolean command_template_redefined:1;
606 Boolean dont_rebuild_command_used:1;
607 /*
608 * Values for the dynamic macros
609 */
610 struct _Name *target;
611 struct _Name *star;
612 struct _Name *less;
613 struct _Name *percent;
614 struct _Chain *query;
615 };
616
617 struct Makefile {
618 /*
619 * Names that reference makefiles gets one prop
620 */
621 wchar_t *contents;
622 off_t size;
623 };
624
625 struct Member {
626 /*
627 * For "lib(member)" and "lib((entry))" constructs
628 * Name "lib(member)" gets one member prop
629 * Name "lib((entry))" gets one member prop
630 * The member field is filled in when the prop is refd
631 */
632 struct _Name *library;
633 struct _Name *entry;
634 struct _Name *member;
635 };
636
637 struct Recursive {
638 /*
639 * For "target: .RECURSIVE dir makefiles" constructs
640 * Used to keep track of recursive calls to make
641 * Name "target" gets one recursive prop
642 */
643 struct _Name *directory;
644 struct _Name *target;
645 struct _Dependency *makefiles;
646 Boolean has_built;
647 Boolean in_depinfo;
648 };
649
650 struct Sccs {
651 /*
652 * Each file that has a SCCS s. file gets one prop
653 */
654 struct _Name *file;
655 };
656
657 struct Suffix {
658 /*
659 * Cached list of suffixes that can build this target
660 * suffix is built from .SUFFIXES
661 */
662 struct _Name *suffix;
663 struct _Cmd_line *command_template;
664 };
665
666 struct Target {
667 /*
668 * For "target:: dependencies" constructs
669 * The "::" construct is handled by converting it to
670 * "foo: 1@foo" + "1@foo: dependecies"
671 * "1@foo" gets one target prop
672 * This target prop cause $@ to be bound to "foo"
673 * not "1@foo" when the rule is evaluated
674 */
675 struct _Name *target;
676 };
677
678 struct STime {
679 /*
680 * Save the original time for :: targets
681 */
682 timestruc_t time;
683 };
684
685 struct Vpath_alias {
686 /*
687 * If a file was found using the VPATH it gets
688 * a vpath_alias prop
689 */
690 struct _Name *alias;
691 };
692
693 struct Long_member_name {
694 /*
695 * Targets with a truncated member name carries
696 * the full lib(member) name for the state file
697 */
698 struct _Name *member_name;
699 };
700
701 union Body {
702 struct _Macro macro;
703 struct Conditional conditional;
704 struct Line line;
705 struct Makefile makefile;
706 struct Member member;
707 struct Recursive recursive;
708 struct Sccs sccs;
709 struct Suffix suffix;
710 struct Target target;
711 struct STime time;
712 struct Vpath_alias vpath_alias;
713 struct Long_member_name long_member_name;
714 struct _Macro_appendix macro_appendix;
715 struct _Env_mem env_mem;
716 };
717
718 #define PROPERTY_HEAD_SIZE (sizeof (struct _Property)-sizeof (union Body))
719 struct _Property {
720 struct _Property *next;
721 Property_id type:4;
722 union Body body;
723 };
724
725 /* Structure for dynamic "ascii" arrays */
726 struct ASCII_Dyn_Array {
727 char *start;
728 size_t size;
729 };
730
731 struct _Envvar {
732 struct _Name *name;
733 struct _Name *value;
734 struct _Envvar *next;
735 char *env_string;
736 Boolean already_put:1;
737 };
738
739 /*
740 * Macros for the reader
741 */
742 #define GOTO_STATE(new_state) { \
743 SET_STATE(new_state); \
744 goto enter_state; \
745 }
746 #define SET_STATE(new_state) state = (new_state)
747
748 #define UNCACHE_SOURCE() if (source != NULL) { \
749 source->string.text.p = source_p; \
750 }
751 #define CACHE_SOURCE(comp) if (source != NULL) { \
752 source_p = source->string.text.p - \
753 (comp); \
754 source_end = source->string.text.end; \
755 }
756 #define GET_NEXT_BLOCK_NOCHK(source) { UNCACHE_SOURCE(); \
757 source = get_next_block_fn(source); \
758 CACHE_SOURCE(0) \
759 }
760 #define GET_NEXT_BLOCK(source) { GET_NEXT_BLOCK_NOCHK(source); \
761 if (source != NULL && source->error_converting) { \
762 GOTO_STATE(illegal_bytes_state); \
763 } \
764 }
765 #define GET_CHAR() ((source == NULL) || \
766 (source_p >= source_end) ? 0 : *source_p)
767
768 struct _Source {
769 struct _String string;
770 struct _Source *previous;
771 off_t bytes_left_in_file;
772 short fd;
773 Boolean already_expanded:1;
774 Boolean error_converting:1;
775 char *inp_buf;
776 char *inp_buf_end;
777 char *inp_buf_ptr;
778 };
779
780 typedef enum {
781 reading_nothing,
782 reading_makefile,
783 reading_statefile,
784 rereading_statefile,
785 reading_cpp_file
786 } Makefile_type;
787
788 /*
789 * Typedefs for all structs
790 */
791 typedef struct _Chain *Chain, Chain_rec;
792 typedef struct _Envvar *Envvar, Envvar_rec;
793 typedef struct _Macro_list *Macro_list, Macro_list_rec;
794 typedef struct _Name *Name, Name_rec;
795 typedef struct _Property *Property, Property_rec;
796 typedef struct _Source *Source, Source_rec;
797 typedef struct _String *String, String_rec;
798
799 /*
800 * name records hash table.
801 */
802 struct Name_set {
803 private:
804 // single node in a tree
805 struct entry {
806 entry(Name name_, entry *parent_) :
807 name(name_),
808 parent(parent_),
809 left(0),
810 right(0),
811 depth(1)
812 {}
813
814 Name name;
815
816 entry *parent;
817 entry *left;
818 entry *right;
819 unsigned depth;
820
821 void setup_depth() {
822 unsigned rdepth = (right != 0) ? right->depth : 0;
823 unsigned ldepth = (left != 0) ? left->depth : 0;
824 depth = 1 + ((ldepth > rdepth) ? ldepth : rdepth);
825 }
826 };
827
828 public:
829 // make iterator a friend of Name_set to have access to struct entry
830 struct iterator;
831 friend struct Name_set::iterator;
832
833 // iterator over tree nodes
834 struct iterator {
835 public:
836 // constructors
837 iterator() : node(0) {}
838 iterator(entry *node_) : node(node_) {}
839
840 // dereference operator
841 Name operator->() const { return node->name; }
842
843 // conversion operator
844 operator Name() { return node->name; }
845
846 // assignment operator
847 iterator& operator=(const iterator &o) { node = o.node; return *this; }
848
849 // equality/inequality operators
850 int operator==(const iterator &o) const { return (node == o.node); }
851 int operator!=(const iterator &o) const { return (node != o.node); }
852
853 // pre/post increment operators
854 iterator& operator++();
855 iterator operator++(int) { iterator it = *this; ++*this; return it; }
856
857 private:
858 // the node iterator points to
859 entry *node;
860 };
861
862 public:
863 // constructor
864 Name_set() : root(0) {}
865
866 // lookup, insert and remove operations
867 Name lookup(const char *key);
868 Name insert(const char *key, Boolean &found);
869 void insert(Name name);
870
871 // begin/end iterators
872 iterator begin() const;
873 iterator end() const { return iterator(); }
874
875 private:
876 // rebalance given node
877 void rebalance(entry *node);
878
879 private:
880 // tree root
881 entry *root;
882 };
883
884 /*
885 * extern declarations for all global variables.
886 * The actual declarations are in globals.cc
887 */
888 extern char char_semantics[];
889 extern wchar_t char_semantics_char[];
890 extern Macro_list cond_macro_list;
891 extern Boolean conditional_macro_used;
892 extern Boolean do_not_exec_rule; /* `-n' */
893 extern Boolean dollarget_seen;
894 extern Boolean dollarless_flag;
895 extern Name dollarless_value;
896 extern char **environ;
897 extern Envvar envvar;
898 extern int exit_status;
899 extern wchar_t *file_being_read;
900 /* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */
901 extern Boolean gnu_style;
902 extern Name_set hashtab;
903 extern Name host_arch;
904 extern Name host_mach;
905 extern int line_number;
906 extern char *make_state_lockfile;
907 extern Boolean make_word_mentioned;
908 extern Makefile_type makefile_type;
909 extern char mbs_buffer[];
910 extern Name path_name;
911 extern Boolean posix;
912 extern Name query;
913 extern Boolean query_mentioned;
914 extern Name hat;
915 extern Boolean reading_environment;
916 extern Name shell_name;
917 extern Boolean svr4;
918 extern Name target_arch;
919 extern Name target_mach;
920 extern Boolean tilde_rule;
921 extern wchar_t wcs_buffer[];
922 extern Boolean working_on_targets;
923 extern Name virtual_root;
924 extern Boolean vpath_defined;
925 extern Name vpath_name;
926 extern Boolean make_state_locked;
927 #if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR)
928 extern Boolean out_err_same;
929 #endif
930 extern pid_t childPid;
931 extern nl_catd libmksh_catd;
932
933 /*
934 * RFE 1257407: make does not use fine granularity time info available from stat.
935 * High resolution time comparison.
936 */
937
938 inline int
939 operator==(const timestruc_t &t1, const timestruc_t &t2) {
940 return ((t1.tv_sec == t2.tv_sec) && (t1.tv_nsec == t2.tv_nsec));
941 }
942
943 inline int
944 operator!=(const timestruc_t &t1, const timestruc_t &t2) {
945 return ((t1.tv_sec != t2.tv_sec) || (t1.tv_nsec != t2.tv_nsec));
946 }
947
948 inline int
949 operator>(const timestruc_t &t1, const timestruc_t &t2) {
950 if (t1.tv_sec == t2.tv_sec) {
951 return (t1.tv_nsec > t2.tv_nsec);
952 }
953 return (t1.tv_sec > t2.tv_sec);
954 }
955
956 inline int
957 operator>=(const timestruc_t &t1, const timestruc_t &t2) {
958 if (t1.tv_sec == t2.tv_sec) {
959 return (t1.tv_nsec >= t2.tv_nsec);
960 }
961 return (t1.tv_sec > t2.tv_sec);
962 }
963
964 inline int
965 operator<(const timestruc_t &t1, const timestruc_t &t2) {
966 if (t1.tv_sec == t2.tv_sec) {
967 return (t1.tv_nsec < t2.tv_nsec);
968 }
969 return (t1.tv_sec < t2.tv_sec);
970 }
971
972 inline int
973 operator<=(const timestruc_t &t1, const timestruc_t &t2) {
974 if (t1.tv_sec == t2.tv_sec) {
975 return (t1.tv_nsec <= t2.tv_nsec);
976 }
977 return (t1.tv_sec < t2.tv_sec);
978 }
979
980 #endif