#ifndef _MKSH_DEFS_H
#define _MKSH_DEFS_H
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/types.h>
#include <vroot/vroot.h>
#include <sys/time.h>
#include <errno.h>
#include <wctype.h>
#define false BOOLEAN_false
#define true BOOLEAN_true
typedef enum {
false = 0,
true = 1,
failed = 0,
succeeded = 1
} Boolean;
#define BOOLEAN(expr) ((expr) ? true : false)
enum {
update_delay = 30,
ar_member_name_len = 1024,
hashsize = 2048
};
enum {
ampersand_char = '&',
asterisk_char = '*',
at_char = '@',
backquote_char = '`',
backslash_char = '\\',
bar_char = '|',
braceleft_char = '{',
braceright_char = '}',
bracketleft_char = '[',
bracketright_char = ']',
colon_char = ':',
comma_char = ',',
dollar_char = '$',
doublequote_char = '"',
equal_char = '=',
exclam_char = '!',
greater_char = '>',
hat_char = '^',
hyphen_char = '-',
less_char = '<',
newline_char = '\n',
nul_char = '\0',
numbersign_char = '#',
parenleft_char = '(',
parenright_char = ')',
percent_char = '%',
period_char = '.',
plus_char = '+',
question_char = '?',
quote_char = '\'',
semicolon_char = ';',
slash_char = '/',
space_char = ' ',
tab_char = '\t',
tilde_char = '~'
};
enum {
ampersand_char_entry = 0,
asterisk_char_entry,
at_char_entry,
backquote_char_entry,
backslash_char_entry,
bar_char_entry,
bracketleft_char_entry,
bracketright_char_entry,
colon_char_entry,
dollar_char_entry,
doublequote_char_entry,
equal_char_entry,
exclam_char_entry,
greater_char_entry,
hat_char_entry,
hyphen_char_entry,
less_char_entry,
newline_char_entry,
numbersign_char_entry,
parenleft_char_entry,
parenright_char_entry,
percent_char_entry,
plus_char_entry,
question_char_entry,
quote_char_entry,
semicolon_char_entry,
no_semantics_entry
};
#define CHAR_SEMANTICS_ENTRIES 27
#define ALLOC(x) ((struct _##x *)getmem(sizeof (struct _##x)))
#define ALLOC_WC(x) ((wchar_t *)getmem((x) * SIZEOFWCHAR_T))
#define FIND_LENGTH -1
#define GETNAME(a,b) getname_fn((a), (b), false)
#define IS_EQUAL(a,b) (!strcmp((a), (b)))
#define IS_EQUALN(a,b,n) (!strncmp((a), (b), (n)))
#define IS_WEQUAL(a,b) (!wcscmp((a), (b)))
#define IS_WEQUALN(a,b,n) (!wcsncmp((a), (b), (n)))
#define MBLEN(a) mblen((a), MB_LEN_MAX)
#define MBSTOWCS(a,b) (void) mbstowcs_with_check((a), (b), MAXPATHLEN)
#define MBTOWC(a,b) mbtowc((a), (b), MB_LEN_MAX)
#define SIZEOFWCHAR_T (sizeof (wchar_t))
#define VSIZEOF(v) (sizeof (v) / sizeof ((v)[0]))
#define WCSTOMBS(a,b) (void) wcstombs((a), (b), (MAXPATHLEN * MB_LEN_MAX))
#define WCTOMB(a,b) (void) wctomb((a), (b))
#define HASH(v, c) (v = (v)*31 + (unsigned int)(c))
extern void mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n);
enum {
dollar_sem = 0001,
meta_sem = 0002,
percent_sem = 0004,
wildcard_sem = 0010,
command_prefix_sem = 0020,
special_macro_sem = 0040,
colon_sem = 0100,
parenleft_sem = 0200
};
typedef enum {
build_dont_know = 0,
build_failed,
build_ok,
build_in_progress,
build_running,
build_pending,
build_serial,
build_subtree
} Doname;
struct _String {
struct Text {
wchar_t *p;
wchar_t *end;
} text;
struct Physical_buffer {
wchar_t *start;
wchar_t *end;
} buffer;
Boolean free_after_use:1;
};
#define STRING_BUFFER_LENGTH 1024
#define INIT_STRING_FROM_STACK(str, buf) { \
str.buffer.start = (buf); \
str.text.p = (buf); \
str.text.end = NULL; \
str.buffer.end = (buf) \
+ (sizeof (buf)/SIZEOFWCHAR_T); \
str.free_after_use = false; \
}
#define APPEND_NAME(np, dest, len) append_string((np)->string_mb, (dest), (len));
class Wstring {
public:
struct _String string;
wchar_t string_buf[STRING_BUFFER_LENGTH];
public:
Wstring();
Wstring(struct _Name * name);
~Wstring();
void init(struct _Name * name);
void init(wchar_t * name, unsigned length);
unsigned length() {
return wcslen(string.buffer.start);
};
void append_to_str(struct _String * str, unsigned off, unsigned length);
wchar_t * get_string() {
return string.buffer.start;
};
wchar_t * get_string(unsigned off) {
return string.buffer.start + off;
};
Boolean equaln(wchar_t * str, unsigned length);
Boolean equal(wchar_t * str);
Boolean equal(wchar_t * str, unsigned off);
Boolean equal(wchar_t * str, unsigned off, unsigned length);
Boolean equaln(Wstring * str, unsigned length);
Boolean equal(Wstring * str);
Boolean equal(Wstring * str, unsigned off);
Boolean equal(Wstring * str, unsigned off, unsigned length);
};
struct _Chain {
struct _Chain *next;
struct _Name *name;
struct _Percent *percent_member;
};
struct _Cmd_line {
struct _Cmd_line *next;
struct _Name *command_line;
Boolean make_refd:1;
Boolean ignore_command_dependency:1;
Boolean assign:1;
Boolean ignore_error:1;
Boolean silent:1;
Boolean always_exec:1;
};
struct _Dependency {
struct _Dependency *next;
struct _Name *name;
Boolean automatic:1;
Boolean stale:1;
Boolean built:1;
};
typedef enum {
no_special,
built_last_make_run_special,
default_special,
get_posix_special,
get_special,
ignore_special,
keep_state_file_special,
keep_state_special,
make_version_special,
no_parallel_special,
parallel_special,
posix_special,
precious_special,
sccs_get_posix_special,
sccs_get_special,
silent_special,
suffixes_special,
svr4_special,
localhost_special
} Special;
typedef enum {
no_colon,
one_colon,
two_colon,
equal_seen,
conditional_seen,
none_seen
} Separator;
extern const timestruc_t file_no_time;
extern const timestruc_t file_doesnt_exist;
extern const timestruc_t file_is_dir;
extern const timestruc_t file_min_time;
extern const timestruc_t file_max_time;
typedef enum {
no_prop,
conditional_prop,
line_prop,
macro_prop,
makefile_prop,
member_prop,
recursive_prop,
sccs_prop,
suffix_prop,
target_prop,
time_prop,
vpath_alias_prop,
long_member_name_prop,
macro_append_prop,
env_mem_prop
} Property_id;
typedef enum {
no_daemon = 0,
chain_daemon
} Daemon;
struct _Env_mem {
char *value;
};
struct _Macro_appendix {
struct _Name *value;
struct _Name *value_to_append;
};
struct _Macro {
struct _Name *value;
Boolean exported:1;
Boolean read_only:1;
Boolean is_conditional:1;
Daemon daemon:2;
};
struct _Macro_list {
struct _Macro_list *next;
char *macro_name;
char *value;
};
enum sccs_stat {
DONT_KNOW_SCCS = 0,
NO_SCCS,
HAS_SCCS
};
struct _Name {
struct _Property *prop;
char *string_mb;
struct {
unsigned int length;
} hash;
struct {
timestruc_t time;
int stat_errno;
off_t size;
mode_t mode;
Boolean is_file:1;
Boolean is_dir:1;
Boolean is_sym_link:1;
Boolean is_precious:1;
enum sccs_stat has_sccs:2;
} stat;
short colon_splits;
short temp_file_number;
short conditional_cnt;
Boolean depends_on_conditional:1;
struct _Macro_list *conditional_macro_list;
Boolean has_member_depe:1;
Boolean is_member:1;
Boolean has_read_dir:1;
Boolean being_expanded:1;
Special special_reader:5;
Doname state:3;
Separator colons:3;
Boolean has_depe_list_expanded:1;
Boolean suffix_scan_done:1;
Boolean has_complained:1;
Boolean ran_command:1;
Boolean with_squiggle:1;
Boolean without_squiggle:1;
Boolean has_read_suffixes:1;
Boolean has_suffixes:1;
Boolean has_target_prop:1;
Boolean has_vpath_alias_prop:1;
Boolean dependency_printed:1;
Boolean dollar:1;
Boolean meta:1;
Boolean percent:1;
Boolean wildcard:1;
Boolean has_parent:1;
Boolean is_target:1;
Boolean has_built:1;
Boolean colon:1;
Boolean parenleft:1;
Boolean has_recursive_dependency:1;
Boolean has_regular_dependency:1;
Boolean is_double_colon:1;
Boolean is_double_colon_parent:1;
Boolean has_long_member_name:1;
Boolean parallel:1;
Boolean no_parallel:1;
Boolean checking_subtree:1;
Boolean added_pattern_conditionals:1;
Boolean rechecking_target:1;
Boolean silent_mode:1;
Boolean ignore_error_mode:1;
Boolean dont_activate_cond_values:1;
Boolean localhost:1;
};
struct _Percent {
struct _Percent *next;
struct _Name **patterns;
struct _Name *name;
struct _Percent *dependencies;
struct _Cmd_line *command_template;
struct _Chain *target_group;
int patterns_total;
Boolean being_expanded;
};
struct Conditional {
struct _Name *target;
struct _Name *name;
struct _Name *value;
int sequence;
Boolean append:1;
};
struct Line {
struct _Cmd_line *command_template;
struct _Cmd_line *command_used;
struct _Dependency *dependencies;
timestruc_t dependency_time;
struct _Chain *target_group;
Boolean is_out_of_date:1;
Boolean sccs_command:1;
Boolean command_template_redefined:1;
Boolean dont_rebuild_command_used:1;
struct _Name *target;
struct _Name *star;
struct _Name *less;
struct _Name *percent;
struct _Chain *query;
};
struct Makefile {
wchar_t *contents;
off_t size;
};
struct Member {
struct _Name *library;
struct _Name *entry;
struct _Name *member;
};
struct Recursive {
struct _Name *directory;
struct _Name *target;
struct _Dependency *makefiles;
Boolean has_built;
Boolean in_depinfo;
};
struct Sccs {
struct _Name *file;
};
struct Suffix {
struct _Name *suffix;
struct _Cmd_line *command_template;
};
struct Target {
struct _Name *target;
};
struct STime {
timestruc_t time;
};
struct Vpath_alias {
struct _Name *alias;
};
struct Long_member_name {
struct _Name *member_name;
};
union Body {
struct _Macro macro;
struct Conditional conditional;
struct Line line;
struct Makefile makefile;
struct Member member;
struct Recursive recursive;
struct Sccs sccs;
struct Suffix suffix;
struct Target target;
struct STime time;
struct Vpath_alias vpath_alias;
struct Long_member_name long_member_name;
struct _Macro_appendix macro_appendix;
struct _Env_mem env_mem;
};
#define PROPERTY_HEAD_SIZE (sizeof (struct _Property)-sizeof (union Body))
struct _Property {
struct _Property *next;
Property_id type:4;
union Body body;
};
struct ASCII_Dyn_Array {
char *start;
size_t size;
};
struct _Envvar {
struct _Name *name;
struct _Name *value;
struct _Envvar *next;
char *env_string;
Boolean already_put:1;
};
#define GOTO_STATE(new_state) { \
SET_STATE(new_state); \
goto enter_state; \
}
#define SET_STATE(new_state) state = (new_state)
#define UNCACHE_SOURCE() if (source != NULL) { \
source->string.text.p = source_p; \
}
#define CACHE_SOURCE(comp) if (source != NULL) { \
source_p = source->string.text.p - \
(comp); \
source_end = source->string.text.end; \
}
#define GET_NEXT_BLOCK_NOCHK(source) { UNCACHE_SOURCE(); \
source = get_next_block_fn(source); \
CACHE_SOURCE(0) \
}
#define GET_NEXT_BLOCK(source) { GET_NEXT_BLOCK_NOCHK(source); \
if (source != NULL && source->error_converting) { \
GOTO_STATE(illegal_bytes_state); \
} \
}
#define GET_CHAR() ((source == NULL) || \
(source_p >= source_end) ? 0 : *source_p)
struct _Source {
struct _String string;
struct _Source *previous;
off_t bytes_left_in_file;
short fd;
Boolean already_expanded:1;
Boolean error_converting:1;
char *inp_buf;
char *inp_buf_end;
char *inp_buf_ptr;
};
typedef enum {
reading_nothing,
reading_makefile,
reading_statefile,
rereading_statefile,
reading_cpp_file
} Makefile_type;
typedef struct _Chain *Chain, Chain_rec;
typedef struct _Envvar *Envvar, Envvar_rec;
typedef struct _Macro_list *Macro_list, Macro_list_rec;
typedef struct _Name *Name, Name_rec;
typedef struct _Property *Property, Property_rec;
typedef struct _Source *Source, Source_rec;
typedef struct _String *String, String_rec;
struct Name_set {
private:
struct entry {
entry(Name name_, entry *parent_) :
name(name_),
parent(parent_),
left(0),
right(0),
depth(1)
{}
Name name;
entry *parent;
entry *left;
entry *right;
unsigned depth;
void setup_depth() {
unsigned rdepth = (right != 0) ? right->depth : 0;
unsigned ldepth = (left != 0) ? left->depth : 0;
depth = 1 + ((ldepth > rdepth) ? ldepth : rdepth);
}
};
public:
struct iterator;
friend struct Name_set::iterator;
struct iterator {
public:
iterator() : node(0) {}
iterator(entry *node_) : node(node_) {}
iterator(const iterator&) = default;
Name operator->() const { return node->name; }
operator Name() { return node->name; }
iterator& operator=(const iterator &o) { node = o.node; return *this; }
int operator==(const iterator &o) const { return (node == o.node); }
int operator!=(const iterator &o) const { return (node != o.node); }
iterator& operator++();
iterator operator++(int) { iterator it = *this; ++*this; return it; }
private:
entry *node;
};
public:
Name_set() : root(0) {}
Name lookup(const char *key);
Name insert(const char *key, Boolean &found);
void insert(Name name);
iterator begin() const;
iterator end() const { return iterator(); }
private:
void rebalance(entry *node);
private:
entry *root;
};
extern char char_semantics[];
extern wchar_t char_semantics_char[];
extern Macro_list cond_macro_list;
extern Boolean conditional_macro_used;
extern Boolean do_not_exec_rule;
extern Boolean dollarget_seen;
extern Boolean dollarless_flag;
extern Name dollarless_value;
extern char **environ;
extern Envvar envvar;
extern int exit_status;
extern wchar_t *file_being_read;
extern Boolean gnu_style;
extern Name_set hashtab;
extern Name host_arch;
extern Name host_mach;
extern int line_number;
extern char *make_state_lockfile;
extern Boolean make_word_mentioned;
extern Makefile_type makefile_type;
extern char mbs_buffer[];
extern Name path_name;
extern Boolean posix;
extern Name query;
extern Boolean query_mentioned;
extern Name hat;
extern Boolean reading_environment;
extern Name shell_name;
extern Boolean svr4;
extern Name target_arch;
extern Name target_mach;
extern Boolean tilde_rule;
extern wchar_t wcs_buffer[];
extern Boolean working_on_targets;
extern Name virtual_root;
extern Boolean vpath_defined;
extern Name vpath_name;
extern Boolean make_state_locked;
extern Boolean out_err_same;
extern pid_t childPid;
inline int
operator==(const timestruc_t &t1, const timestruc_t &t2) {
return ((t1.tv_sec == t2.tv_sec) && (t1.tv_nsec == t2.tv_nsec));
}
inline int
operator!=(const timestruc_t &t1, const timestruc_t &t2) {
return ((t1.tv_sec != t2.tv_sec) || (t1.tv_nsec != t2.tv_nsec));
}
inline int
operator>(const timestruc_t &t1, const timestruc_t &t2) {
if (t1.tv_sec == t2.tv_sec) {
return (t1.tv_nsec > t2.tv_nsec);
}
return (t1.tv_sec > t2.tv_sec);
}
inline int
operator>=(const timestruc_t &t1, const timestruc_t &t2) {
if (t1.tv_sec == t2.tv_sec) {
return (t1.tv_nsec >= t2.tv_nsec);
}
return (t1.tv_sec > t2.tv_sec);
}
inline int
operator<(const timestruc_t &t1, const timestruc_t &t2) {
if (t1.tv_sec == t2.tv_sec) {
return (t1.tv_nsec < t2.tv_nsec);
}
return (t1.tv_sec < t2.tv_sec);
}
inline int
operator<=(const timestruc_t &t1, const timestruc_t &t2) {
if (t1.tv_sec == t2.tv_sec) {
return (t1.tv_nsec <= t2.tv_nsec);
}
return (t1.tv_sec < t2.tv_sec);
}
#endif