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