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