kconfig/expr.h
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sun Jan 17 23:06:02 2010 +0100 (2010-01-17)
changeset 1740 c57458bb354d
parent 1235 1cb6cf834483
child 2448 a103abae1560
permissions -rw-r--r--
configure: do not require hg when configuring in an hg clone

When configuring in an hg clone, we need hg to compute the version string.
It can happen that users do not have Mercurial (eg. if they got a snapshot
rather that they did a full clone). In this case, we can still run, of
course, so simply fill the version string with a sufficiently explicit
value, that does not require hg. The date is a good candidate.
yann@1
     1
/*
yann@1
     2
 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
yann@1
     3
 * Released under the terms of the GNU GPL v2.0.
yann@1
     4
 */
yann@1
     5
yann@1
     6
#ifndef EXPR_H
yann@1
     7
#define EXPR_H
yann@1
     8
yann@1
     9
#ifdef __cplusplus
yann@1
    10
extern "C" {
yann@1
    11
#endif
yann@1
    12
yann@1
    13
#include <stdio.h>
yann@1
    14
#ifndef __cplusplus
yann@1
    15
#include <stdbool.h>
yann@1
    16
#endif
yann@1
    17
yann@1
    18
struct file {
yann@1
    19
	struct file *next;
yann@1
    20
	struct file *parent;
yann@1
    21
	char *name;
yann@1
    22
	int lineno;
yann@1
    23
	int flags;
yann@1
    24
};
yann@1
    25
yann@1
    26
#define FILE_BUSY		0x0001
yann@1
    27
#define FILE_SCANNED		0x0002
yann@1
    28
yann@1
    29
typedef enum tristate {
yann@1
    30
	no, mod, yes
yann@1
    31
} tristate;
yann@1
    32
yann@1
    33
enum expr_type {
yann@943
    34
	E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE
yann@1
    35
};
yann@1
    36
yann@1
    37
union expr_data {
yann@1
    38
	struct expr *expr;
yann@1
    39
	struct symbol *sym;
yann@1
    40
};
yann@1
    41
yann@1
    42
struct expr {
yann@1
    43
	enum expr_type type;
yann@1
    44
	union expr_data left, right;
yann@1
    45
};
yann@1
    46
yann@943
    47
#define EXPR_OR(dep1, dep2)	(((dep1)>(dep2))?(dep1):(dep2))
yann@943
    48
#define EXPR_AND(dep1, dep2)	(((dep1)<(dep2))?(dep1):(dep2))
yann@943
    49
#define EXPR_NOT(dep)		(2-(dep))
yann@943
    50
yann@943
    51
#define expr_list_for_each_sym(l, e, s) \
yann@943
    52
	for (e = (l); e && (s = e->right.sym); e = e->left.expr)
yann@1
    53
yann@1
    54
struct expr_value {
yann@1
    55
	struct expr *expr;
yann@1
    56
	tristate tri;
yann@1
    57
};
yann@1
    58
yann@1
    59
struct symbol_value {
yann@1
    60
	void *val;
yann@1
    61
	tristate tri;
yann@1
    62
};
yann@1
    63
yann@1
    64
enum symbol_type {
yann@1
    65
	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
yann@1
    66
};
yann@1
    67
yann@1234
    68
/* enum values are used as index to symbol.def[] */
yann@1
    69
enum {
yann@1
    70
	S_DEF_USER,		/* main user value */
yann@1234
    71
	S_DEF_AUTO,		/* values read from auto.conf */
yann@1234
    72
	S_DEF_DEF3,		/* Reserved for UI usage */
yann@1234
    73
	S_DEF_DEF4,		/* Reserved for UI usage */
yann@1234
    74
	S_DEF_COUNT
yann@1
    75
};
yann@1
    76
yann@1
    77
struct symbol {
yann@1
    78
	struct symbol *next;
yann@1
    79
	char *name;
yann@1
    80
	enum symbol_type type;
yann@1
    81
	struct symbol_value curr;
yann@1234
    82
	struct symbol_value def[S_DEF_COUNT];
yann@1
    83
	tristate visible;
yann@1
    84
	int flags;
yann@1
    85
	struct property *prop;
yann@1
    86
	struct expr_value rev_dep;
yann@1
    87
};
yann@1
    88
yann@1
    89
#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
yann@1
    90
yann@1235
    91
#define SYMBOL_CONST      0x0001  /* symbol is const */
yann@1235
    92
#define SYMBOL_CHECK      0x0008  /* used during dependency checking */
yann@1235
    93
#define SYMBOL_CHOICE     0x0010  /* start of a choice block (null name) */
yann@1235
    94
#define SYMBOL_CHOICEVAL  0x0020  /* used as a value in a choice block */
yann@1235
    95
#define SYMBOL_VALID      0x0080  /* set when symbol.curr is calculated */
yann@1235
    96
#define SYMBOL_OPTIONAL   0x0100  /* choice is optional - values can be 'n' */
yann@1235
    97
#define SYMBOL_WRITE      0x0200  /* ? */
yann@1235
    98
#define SYMBOL_CHANGED    0x0400  /* ? */
yann@1235
    99
#define SYMBOL_AUTO       0x1000  /* value from environment variable */
yann@1235
   100
#define SYMBOL_CHECKED    0x2000  /* used during dependency checking */
yann@1235
   101
#define SYMBOL_WARNED     0x8000  /* warning has been issued */
yann@1235
   102
yann@1235
   103
/* Set when symbol.def[] is used */
yann@1235
   104
#define SYMBOL_DEF        0x10000  /* First bit of SYMBOL_DEF */
yann@1235
   105
#define SYMBOL_DEF_USER   0x10000  /* symbol.def[S_DEF_USER] is valid */
yann@1235
   106
#define SYMBOL_DEF_AUTO   0x20000  /* symbol.def[S_DEF_AUTO] is valid */
yann@1235
   107
#define SYMBOL_DEF3       0x40000  /* symbol.def[S_DEF_3] is valid */
yann@1235
   108
#define SYMBOL_DEF4       0x80000  /* symbol.def[S_DEF_4] is valid */
yann@1
   109
yann@1
   110
#define SYMBOL_MAXLENGTH	256
yann@1
   111
#define SYMBOL_HASHSIZE		257
yann@1
   112
#define SYMBOL_HASHMASK		0xff
yann@1
   113
yann@1236
   114
/* A property represent the config options that can be associated
yann@1236
   115
 * with a config "symbol".
yann@1236
   116
 * Sample:
yann@1236
   117
 * config FOO
yann@1236
   118
 *         default y
yann@1236
   119
 *         prompt "foo prompt"
yann@1236
   120
 *         select BAR
yann@1236
   121
 * config BAZ
yann@1236
   122
 *         int "BAZ Value"
yann@1236
   123
 *         range 1..255
yann@1236
   124
 */
yann@1
   125
enum prop_type {
yann@1236
   126
	P_UNKNOWN,
yann@1236
   127
	P_PROMPT,   /* prompt "foo prompt" or "BAZ Value" */
yann@1236
   128
	P_COMMENT,  /* text associated with a comment */
yann@1236
   129
	P_MENU,     /* prompt associated with a menuconfig option */
yann@1236
   130
	P_DEFAULT,  /* default y */
yann@1236
   131
	P_CHOICE,   /* choice value */
yann@1236
   132
	P_SELECT,   /* select BAR */
yann@1236
   133
	P_RANGE,    /* range 7..100 (for a symbol) */
yann@1236
   134
	P_ENV,      /* value from environment variable */
yann@1
   135
};
yann@1
   136
yann@1
   137
struct property {
yann@1236
   138
	struct property *next;     /* next property - null if last */
yann@1236
   139
	struct symbol *sym;        /* the symbol for which the property is associated */
yann@1236
   140
	enum prop_type type;       /* type of property */
yann@1236
   141
	const char *text;          /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */
yann@1
   142
	struct expr_value visible;
yann@1236
   143
	struct expr *expr;         /* the optional conditional part of the property */
yann@1236
   144
	struct menu *menu;         /* the menu the property are associated with
yann@1236
   145
	                            * valid for: P_SELECT, P_RANGE, P_CHOICE,
yann@1236
   146
	                            * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */
yann@1236
   147
	struct file *file;         /* what file was this property defined */
yann@1236
   148
	int lineno;                /* what lineno was this property defined */
yann@1
   149
};
yann@1
   150
yann@1
   151
#define for_all_properties(sym, st, tok) \
yann@1
   152
	for (st = sym->prop; st; st = st->next) \
yann@1
   153
		if (st->type == (tok))
yann@1
   154
#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT)
yann@1
   155
#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE)
yann@1
   156
#define for_all_prompts(sym, st) \
yann@1
   157
	for (st = sym->prop; st; st = st->next) \
yann@1
   158
		if (st->text)
yann@1
   159
yann@1
   160
struct menu {
yann@1
   161
	struct menu *next;
yann@1
   162
	struct menu *parent;
yann@1
   163
	struct menu *list;
yann@1
   164
	struct symbol *sym;
yann@1
   165
	struct property *prompt;
yann@1
   166
	struct expr *dep;
yann@1
   167
	unsigned int flags;
yann@943
   168
	char *help;
yann@1
   169
	struct file *file;
yann@1
   170
	int lineno;
yann@1
   171
	void *data;
yann@1
   172
};
yann@1
   173
yann@1
   174
#define MENU_CHANGED		0x0001
yann@1
   175
#define MENU_ROOT		0x0002
yann@1
   176
yann@1
   177
#ifndef SWIG
yann@1
   178
yann@1
   179
extern struct file *file_list;
yann@1
   180
extern struct file *current_file;
yann@1
   181
struct file *lookup_file(const char *name);
yann@1
   182
yann@1
   183
extern struct symbol symbol_yes, symbol_no, symbol_mod;
yann@1
   184
extern struct symbol *modules_sym;
yann@1
   185
extern struct symbol *sym_defconfig_list;
yann@1
   186
extern int cdebug;
yann@1
   187
struct expr *expr_alloc_symbol(struct symbol *sym);
yann@1
   188
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
yann@1
   189
struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
yann@1
   190
struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
yann@1
   191
struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
yann@1
   192
struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
yann@1
   193
struct expr *expr_copy(struct expr *org);
yann@1
   194
void expr_free(struct expr *e);
yann@1
   195
int expr_eq(struct expr *e1, struct expr *e2);
yann@1
   196
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
yann@1
   197
tristate expr_calc_value(struct expr *e);
yann@1
   198
struct expr *expr_eliminate_yn(struct expr *e);
yann@1
   199
struct expr *expr_trans_bool(struct expr *e);
yann@1
   200
struct expr *expr_eliminate_dups(struct expr *e);
yann@1
   201
struct expr *expr_transform(struct expr *e);
yann@1
   202
int expr_contains_symbol(struct expr *dep, struct symbol *sym);
yann@1
   203
bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
yann@1
   204
struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
yann@1
   205
struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
yann@1
   206
void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
yann@1
   207
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
yann@1
   208
yann@1
   209
void expr_fprint(struct expr *e, FILE *out);
yann@1
   210
struct gstr; /* forward */
yann@1
   211
void expr_gstr_print(struct expr *e, struct gstr *gs);
yann@1
   212
yann@1
   213
static inline int expr_is_yes(struct expr *e)
yann@1
   214
{
yann@1
   215
	return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes);
yann@1
   216
}
yann@1
   217
yann@1
   218
static inline int expr_is_no(struct expr *e)
yann@1
   219
{
yann@1
   220
	return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
yann@1
   221
}
yann@1
   222
#endif
yann@1
   223
yann@1
   224
#ifdef __cplusplus
yann@1
   225
}
yann@1
   226
#endif
yann@1
   227
yann@1
   228
#endif /* EXPR_H */