]> rtime.felk.cvut.cz Git - linux-conf-perf.git/blobdiff - kconfig2sat/kconfig2sat.cc
kconfig2sat: Implement reading (and checking) of variable symbols
[linux-conf-perf.git] / kconfig2sat / kconfig2sat.cc
index 62edfedc53029ea5bfa04526cf9497d652e10e48..ed214eff819a0428ab13f6ba294cb17b55e0e8c8 100644 (file)
@@ -16,6 +16,7 @@ enum options {
        OPT__START = 256,
        OPT_BASECONFIG,
        OPT_CNF,
+       OPT_DUMP,
        OPT_ENV,
        OPT_HELP,
        OPT_KCONFIG,
@@ -26,15 +27,114 @@ enum options {
 
 void print_help()
 {
-        printf("kconfig2sat [ options ]\n"
+        printf("Usage: kconfig2sat [options/actions]\n"
                "\n"
                "Options:\n"
-               "-b, --baseconf <.config>  Linux .config file with base configuration\n"
-              "--env <.conf.mk>          .conf.mk file for setting variables such as ARCH\n"
-               "-k, --kconfig <Kconfig>   Kconfig file (with path)\n"
-               "--varfile <file>          File listing variable options (one option per line)\n"
-              "--cnf <file>              Generate CNF representation to <file>\n"
-               );
+               "  -b, --baseconf <.config>  Linux .config file with base configuration\n"
+               "  --env <.conf.mk>          Set env. variables such as ARCH from .conf.mk\n"
+               "  -k, --kconfig <Kconfig>   Kconfig file (with path)\n"
+               "  --varfile <file>          File listing variable options (one option per line)\n"
+               "\n"
+               "Actions:\n"
+               "  --dump                    Dump internal data (for debugging)\n"
+               "  --cnf <file>              Generate CNF representation to <file>\n"
+                );
+}
+
+void dump_symbol(struct symbol *sym)
+{
+       struct property *prop;
+       const char *name = sym->name;
+       const char *type = sym_type_name(sym->type);
+       const char *prompt = NULL;
+       char flags[256] = "fl(";
+       char val = '.';
+
+       if (sym->type == S_BOOLEAN || sym->type == S_TRISTATE) {
+               switch (sym->curr.tri) {
+               case no:  val = 'n'; break;
+               case mod: val = 'm'; break;
+               case yes: val = 'y'; break;
+               }
+       }
+
+#define FLAG(f) do { if (sym->flags & (SYMBOL_##f)) strcat(flags, #f " "); } while (0)
+       FLAG(CONST);
+       FLAG(CHECK);
+       FLAG(CHOICE);
+       FLAG(CHOICEVAL);
+       FLAG(VALID);
+       FLAG(OPTIONAL);
+       FLAG(WRITE);
+       FLAG(CHANGED);
+       FLAG(AUTO);
+       FLAG(CHECKED);
+       FLAG(WARNED);
+       FLAG(DEF_USER);
+       FLAG(DEF_AUTO);
+       FLAG(DEF3);
+       FLAG(DEF4);
+       if (flags[3])
+               flags[strlen(flags)-1] = ')'; /* Replace trailing space */
+#undef FLAG
+
+       for_all_properties(sym, prop, P_PROMPT) {
+               prompt = prop->text;
+       }
+
+       printf("%-40s %c %-8s %-50s %s\n", name, val, type, flags, prompt);
+}
+
+void do_dump()
+{
+    int i;
+    struct symbol *sym;
+    for_all_symbols(i, sym) {
+           dump_symbol(sym);
+    }
+}
+
+void read_varfile(const char *varfile)
+{
+       FILE *f = fopen(varfile, "r");
+       char line[1000];
+
+       if (!f) {
+               perror(varfile);
+               exit(EXIT_FAILURE);
+       }
+
+       int lineno = 0;
+       while (fgets(line, sizeof(line), f)) {
+               char *p = line;
+               lineno++;
+
+               if (strncmp(line, CONFIG_, strlen(CONFIG_)) == 0)
+                       p += strlen(CONFIG_);
+
+               const char *sym_name = strtok(p, " =\n");
+               struct symbol *sym = sym_find(sym_name);
+               if (!sym) {
+                       fprintf(stderr, "%s:%d: Invalid symbol: %s\n", varfile, lineno, sym_name);
+                       exit(EXIT_FAILURE);
+               }
+               if (!(sym->flags & SYMBOL_WRITE)) {
+                       fprintf(stderr, "%s:%d: Symbol %s not visible\n", varfile, lineno, sym_name);
+                       exit(EXIT_FAILURE);
+               }
+               if (sym->flags & (SYMBOL_CHOICEVAL | SYMBOL_CHOICE)) {
+                       fprintf(stderr, "%s:%d: Choice values not yet supported: %s", varfile, lineno, sym_name);
+                       exit(EXIT_FAILURE);
+               }
+               struct property *prop;
+               const char *prompt = NULL;
+               for_all_properties(sym, prop, P_PROMPT) {
+                       prompt = prop->text;
+               }
+               if (!prompt) {
+                       fprintf(stderr, "%s:%d: Warning: Symbol %s is internal (has no prompt)\n", varfile, lineno, sym_name);
+               }
+       }
 }
 
 int main(int argc, char **argv)
@@ -45,19 +145,21 @@ int main(int argc, char **argv)
        char *cnf = NULL;
        char *kconfig = NULL;
        char *varfile = NULL;
+       int  dump = false;
 
        while (1) {
                int option_index = 0;
                static struct option long_options[] = {
-                       {"baseconf",    required_argument, 0,  OPT_BASECONFIG },
-                       {"cnf",         required_argument, 0,  OPT_CNF },
-                       {"env",         required_argument, 0,  OPT_ENV },
-                       {"help",        no_argument,       0,  OPT_HELP },
-                       {"kconfig",     required_argument, 0,  OPT_KCONFIG },
-                       {"varfile",     required_argument, 0,  OPT_VARFILE },
-//                     {"varopt",      required_argument, 0,  OPT_VAROPTION },
-                       {"verbose",     no_argument,       0,  OPT_VERBOSE },
-                       {0,             0,                 0,  0 }
+                       {"baseconf",    required_argument, 0,     OPT_BASECONFIG },
+                       {"cnf",         required_argument, 0,     OPT_CNF },
+                       {"env",         required_argument, 0,     OPT_ENV },
+                       {"dump",        no_argument,       &dump, true },
+                       {"help",        no_argument,       0,     OPT_HELP },
+                       {"kconfig",     required_argument, 0,     OPT_KCONFIG },
+                       {"varfile",     required_argument, 0,     OPT_VARFILE },
+//                     {"varopt",      required_argument, 0,     OPT_VAROPTION },
+                       {"verbose",     no_argument,       0,     OPT_VERBOSE },
+                       {0,             0,                 0,     0 }
                };
 
                c = getopt_long(argc, argv, "b:hk:v",
@@ -66,6 +168,8 @@ int main(int argc, char **argv)
                        break;
 
                switch (c) {
+               case 0: /* long option with flag != NULL */
+                       break;
                case 'b':
                case OPT_BASECONFIG:
                        baseconf = optarg;
@@ -117,6 +221,15 @@ int main(int argc, char **argv)
 
        conf_parse_path(kconfig);
 
+       if (baseconf)
+               conf_read(baseconf);
+
+       if (varfile)
+               read_varfile(varfile);
+
+       if (dump)
+               do_dump();
+
 //     char *rules_file, *symbol_map_file, *variable_count_file;
 //     asprintf(&rules_file, "%s/%s", folder, DEFAULT_RULES_FILE);
 //     asprintf(&symbol_map_file, "%s/%s", folder, DEFAULT_SYMBOL_MAP_FILE);