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