kconfig: remove S_OTHER symbol type and correct dependency tracking
[carl9170fw.git] / config / expr.h
index a72597f48a5d6cf35deba9703bde3f3e48bb54a0..2b7e222b07840826d68a836a1384f106b575dd47 100644 (file)
@@ -10,7 +10,9 @@
 extern "C" {
 #endif
 
+#include <assert.h>
 #include <stdio.h>
+#include "list.h"
 #ifndef __cplusplus
 #include <stdbool.h>
 #endif
@@ -18,20 +20,18 @@ extern "C" {
 struct file {
        struct file *next;
        struct file *parent;
-       char *name;
+       const char *name;
        int lineno;
-       int flags;
 };
 
-#define FILE_BUSY              0x0001
-#define FILE_SCANNED           0x0002
-
 typedef enum tristate {
        no, mod, yes
 } tristate;
 
 enum expr_type {
-       E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE
+       E_NONE, E_OR, E_AND, E_NOT,
+       E_EQUAL, E_UNEQUAL, E_LTH, E_LEQ, E_GTH, E_GEQ,
+       E_LIST, E_SYMBOL, E_RANGE
 };
 
 union expr_data {
@@ -44,8 +44,8 @@ struct expr {
        union expr_data left, right;
 };
 
-#define EXPR_OR(dep1, dep2)    (((dep1) > (dep2)) ? (dep1) : (dep2))
-#define EXPR_AND(dep1, dep2)   (((dep1) < (dep2)) ? (dep1) : (dep2))
+#define EXPR_OR(dep1, dep2)    (((dep1)>(dep2))?(dep1):(dep2))
+#define EXPR_AND(dep1, dep2)   (((dep1)<(dep2))?(dep1):(dep2))
 #define EXPR_NOT(dep)          (2-(dep))
 
 #define expr_list_for_each_sym(l, e, s) \
@@ -62,7 +62,7 @@ struct symbol_value {
 };
 
 enum symbol_type {
-       S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
+       S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING
 };
 
 /* enum values are used as index to symbol.def[] */
@@ -74,19 +74,64 @@ enum {
        S_DEF_COUNT
 };
 
+/*
+ * Represents a configuration symbol.
+ *
+ * Choices are represented as a special kind of symbol and have the
+ * SYMBOL_CHOICE bit set in 'flags'.
+ */
 struct symbol {
+       /* The next symbol in the same bucket in the symbol hash table */
        struct symbol *next;
+
+       /* The name of the symbol, e.g. "FOO" for 'config FOO' */
        char *name;
+
+       /* S_BOOLEAN, S_TRISTATE, ... */
        enum symbol_type type;
+
+       /*
+        * The calculated value of the symbol. The SYMBOL_VALID bit is set in
+        * 'flags' when this is up to date. Note that this value might differ
+        * from the user value set in e.g. a .config file, due to visibility.
+        */
        struct symbol_value curr;
+
+       /*
+        * Values for the symbol provided from outside. def[S_DEF_USER] holds
+        * the .config value.
+        */
        struct symbol_value def[S_DEF_COUNT];
+
+       /*
+        * An upper bound on the tristate value the user can set for the symbol
+        * if it is a boolean or tristate. Calculated from prompt dependencies,
+        * which also inherit dependencies from enclosing menus, choices, and
+        * ifs. If 'n', the user value will be ignored.
+        *
+        * Symbols lacking prompts always have visibility 'n'.
+        */
        tristate visible;
+
+       /* SYMBOL_* flags */
        int flags;
+
+       /* List of properties. See prop_type. */
        struct property *prop;
+
+       /* Dependencies from enclosing menus, choices, and ifs */
+       struct expr_value dir_dep;
+
+       /* Reverse dependencies through being selected by other symbols */
        struct expr_value rev_dep;
+
+       /*
+        * "Weak" reverse dependencies through being implied by other symbols
+        */
+       struct expr_value implied;
 };
 
-#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)
+#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next)
 
 #define SYMBOL_CONST      0x0001  /* symbol is const */
 #define SYMBOL_CHECK      0x0008  /* used during dependency checking */
@@ -94,9 +139,9 @@ struct symbol {
 #define SYMBOL_CHOICEVAL  0x0020  /* used as a value in a choice block */
 #define SYMBOL_VALID      0x0080  /* set when symbol.curr is calculated */
 #define SYMBOL_OPTIONAL   0x0100  /* choice is optional - values can be 'n' */
-#define SYMBOL_WRITE      0x0200  /* ? */
+#define SYMBOL_WRITE      0x0200  /* write symbol to file (KCONFIG_CONFIG) */
 #define SYMBOL_CHANGED    0x0400  /* ? */
-#define SYMBOL_AUTO       0x1000  /* value from environment variable */
+#define SYMBOL_NO_WRITE   0x1000  /* Symbol for internal use only; it will not be written */
 #define SYMBOL_CHECKED    0x2000  /* used during dependency checking */
 #define SYMBOL_WARNED     0x8000  /* warning has been issued */
 
@@ -107,9 +152,14 @@ struct symbol {
 #define SYMBOL_DEF3       0x40000  /* symbol.def[S_DEF_3] is valid */
 #define SYMBOL_DEF4       0x80000  /* symbol.def[S_DEF_4] is valid */
 
+/* choice values need to be set before calculating this symbol value */
+#define SYMBOL_NEED_SET_CHOICE_VALUES  0x100000
+
+/* Set symbol to y if allnoconfig; used for symbols that hide others */
+#define SYMBOL_ALLNOCONFIG_Y 0x200000
+
 #define SYMBOL_MAXLENGTH       256
-#define SYMBOL_HASHSIZE                257
-#define SYMBOL_HASHMASK                0xff
+#define SYMBOL_HASHSIZE                9973
 
 /* A property represent the config options that can be associated
  * with a config "symbol".
@@ -121,17 +171,21 @@ struct symbol {
  * config BAZ
  *         int "BAZ Value"
  *         range 1..255
+ *
+ * Please, also check zconf.y:print_symbol() when modifying the
+ * list of property types!
  */
 enum prop_type {
        P_UNKNOWN,
        P_PROMPT,   /* prompt "foo prompt" or "BAZ Value" */
        P_COMMENT,  /* text associated with a comment */
-       P_MENU,     /* prompt associated with a menuconfig option */
+       P_MENU,     /* prompt associated with a menu or menuconfig symbol */
        P_DEFAULT,  /* default y */
        P_CHOICE,   /* choice value */
        P_SELECT,   /* select BAR */
+       P_IMPLY,    /* imply BAR */
        P_RANGE,    /* range 7..100 (for a symbol) */
-       P_ENV,      /* value from environment variable */
+       P_SYMBOL,   /* where a symbol is defined */
 };
 
 struct property {
@@ -142,8 +196,8 @@ struct property {
        struct expr_value visible;
        struct expr *expr;         /* the optional conditional part of the property */
        struct menu *menu;         /* the menu the property are associated with
-                                   * valid for: P_SELECT, P_RANGE, P_CHOICE,
-                                   * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */
+                                   * valid for: P_SELECT, P_RANGE, P_CHOICE,
+                                   * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */
        struct file *file;         /* what file was this property defined */
        int lineno;                /* what lineno was this property defined */
 };
@@ -157,24 +211,77 @@ struct property {
        for (st = sym->prop; st; st = st->next) \
                if (st->text)
 
+/*
+ * Represents a node in the menu tree, as seen in e.g. menuconfig (though used
+ * for all front ends). Each symbol, menu, etc. defined in the Kconfig files
+ * gets a node. A symbol defined in multiple locations gets one node at each
+ * location.
+ */
 struct menu {
+       /* The next menu node at the same level */
        struct menu *next;
+
+       /* The parent menu node, corresponding to e.g. a menu or choice */
        struct menu *parent;
+
+       /* The first child menu node, for e.g. menus and choices */
        struct menu *list;
+
+       /*
+        * The symbol associated with the menu node. Choices are implemented as
+        * a special kind of symbol. NULL for menus, comments, and ifs.
+        */
        struct symbol *sym;
+
+       /*
+        * The prompt associated with the node. This holds the prompt for a
+        * symbol as well as the text for a menu or comment, along with the
+        * type (P_PROMPT, P_MENU, etc.)
+        */
        struct property *prompt;
+
+       /*
+        * 'visible if' dependencies. If more than one is given, they will be
+        * ANDed together.
+        */
+       struct expr *visibility;
+
+       /*
+        * Ordinary dependencies from e.g. 'depends on' and 'if', ANDed
+        * together
+        */
        struct expr *dep;
+
+       /* MENU_* flags */
        unsigned int flags;
+
+       /* Any help text associated with the node */
        char *help;
+
+       /* The location where the menu node appears in the Kconfig files */
        struct file *file;
        int lineno;
+
+       /* For use by front ends that need to store auxiliary data */
        void *data;
 };
 
+/*
+ * Set on a menu node when the corresponding symbol changes state in some way.
+ * Can be checked by front ends.
+ */
 #define MENU_CHANGED           0x0001
+
 #define MENU_ROOT              0x0002
 
-#ifndef SWIG
+struct jump_key {
+       struct list_head entries;
+       size_t offset;
+       struct menu *target;
+       int index;
+};
+
+#define JUMP_NB                        9
 
 extern struct file *file_list;
 extern struct file *current_file;
@@ -190,25 +297,22 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e
 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
-struct expr *expr_copy(struct expr *org);
+struct expr *expr_copy(const struct expr *org);
 void expr_free(struct expr *e);
-int expr_eq(struct expr *e1, struct expr *e2);
 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
 tristate expr_calc_value(struct expr *e);
-struct expr *expr_eliminate_yn(struct expr *e);
 struct expr *expr_trans_bool(struct expr *e);
 struct expr *expr_eliminate_dups(struct expr *e);
 struct expr *expr_transform(struct expr *e);
 int expr_contains_symbol(struct expr *dep, struct symbol *sym);
 bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
-struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
-struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
-void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
 
 void expr_fprint(struct expr *e, FILE *out);
 struct gstr; /* forward */
 void expr_gstr_print(struct expr *e, struct gstr *gs);
+void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
+                           tristate pr_type, const char *title);
 
 static inline int expr_is_yes(struct expr *e)
 {
@@ -219,7 +323,6 @@ static inline int expr_is_no(struct expr *e)
 {
        return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
 }
-#endif
 
 #ifdef __cplusplus
 }