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