--- /dev/null
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#include <kconfig/lkc.h>
+#include <build_files.h>
+#include <macros.h>
+
+#define STRINGIFY(val) #val
+#define TOSTRING(val) STRINGIFY(val)
+#define CHECK(cmd) ({ int ret = (cmd); if (ret == -1) { perror(#cmd " line " TOSTRING(__LINE__)); exit(1); }; ret; })
+#define CHECKPTR(cmd) ({ void *ptr = (cmd); if (ptr == (void*)-1) { perror(#cmd " line " TOSTRING(__LINE__)); exit(1); }; ptr; })
+#define CHECKNULL(cmd) ({ void *ptr = (cmd); if (ptr == NULL) { perror(#cmd " line " TOSTRING(__LINE__)); exit(1); }; ptr; })
+
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*(x)))
+
+int verbose_level;
+
+char *kconfig_file;
+char *dot_file;
+/* char *input_config_file; */
+
+const char *interesting_opts[] = {
+ "BLK_DEV_IO_TRACE",
+ "BRANCH_PROFILE_NONE",
+ "BRANCH_TRACER",
+ "CONSTRUCTORS",
+ "DYNAMIC_FTRACE",
+ "ENABLE_DEFAULT_TRACERS",
+ "EVENT_TRACE_TEST_SYSCALLS",
+ "FREEZER",
+ "FTRACE_MCOUNT_RECORD",
+ "FTRACE_SELFTEST",
+ "FTRACE_STARTUP_TEST",
+ "FTRACE_SYSCALLS",
+ "FUNCTION_GRAPH_TRACER",
+ "FUNCTION_PROFILER",
+ "FUNCTION_TRACER",
+ "GCOV_KERNEL",
+ "GENERIC_TRACER",
+ "HIBERNATE_CALLBACKS",
+ "HIBERNATION",
+ "HZ_PERIODIC",
+ "INTERRUPT_OFF_HIST",
+ "IRQSOFF_TRACER",
+ "IRQ_DOMAIN_DEBUG",
+ "LZO_COMPRESS",
+ "LZO_DECOMPRESS",
+ "MISSED_TIMER_OFFSETS_HIST",
+ "NO_HZ",
+ "NO_HZ_COMMON",
+ "NO_HZ_IDLE",
+ "PM",
+ "PM_ADVANCED_DEBUG",
+ "PM_AUTOSLEEP",
+ "PM_CLK",
+ "PM_DEBUG",
+ "PM_RUNTIME",
+ "PM_SLEEP",
+ "PM_SLEEP_DEBUG",
+ "PM_WAKELOCKS",
+ "PM_WAKELOCKS_GC",
+ "PREEMPT_OFF_HIST",
+ "PREEMPT_TRACER",
+ "PROFILE_ANNOTATED_BRANCHES",
+ "RING_BUFFER_ALLOW_SWAP",
+ "RING_BUFFER_BENCHMARK",
+ "RING_BUFFER_STARTUP_TEST",
+ "SCHED_TRACER",
+ "STACK_TRACER",
+ "TRACER_MAX_TRACE",
+ "TRACER_SNAPSHOT",
+ "TRACER_SNAPSHOT_PER_CPU_SWAP",
+ "TRACE_BRANCH_PROFILING",
+ "TRACE_IRQFLAGS",
+ "TRACING_BRANCHES",
+ "WAKEUP_LATENCY_HIST",
+ "WQ_POWER_EFFICIENT_DEFAULT",
+};
+
+bool is_interesting(struct symbol *sym)
+{
+ int i;
+
+ if (!sym->name)
+ return false;
+
+ for (i = 0; i < ARRAY_SIZE(interesting_opts); i++) {
+ if (strcmp(sym->name, interesting_opts[i]) == 0)
+ return true;
+ }
+ return false;
+}
+
+void print_help();
+
+void print_expr(FILE *f, struct expr *e, const char *parent, const char *suffix, const char *edge_opts);
+void print_symbol(FILE *f, struct symbol *sym);
+
+
+void print_oper(FILE *f, struct expr *e, const char *parent, const char *label)
+{
+ fprintf(f, "\"%s\" [shape=diamond,label=\"%s\"];\n", e->id, label);
+ fprintf(f, "\"%s\" -> \"%s\";\n", parent, e->id);
+ print_expr(f, e->left.expr, e->id, "l", "");
+ print_expr(f, e->right.expr, e->id, "r", "");
+}
+
+void print_expr(FILE *f, struct expr *e, const char *parent, const char *suffix, const char *edge_opts)
+{
+ if (e) {
+ switch (e->type) {
+ case E_NONE:
+ printf("NONE\n");
+ break;
+ case E_OR:
+ print_oper(f, e, parent, "|");
+ break;
+ case E_AND:
+ print_oper(f, e, parent, "&");
+ break;
+ case E_NOT:
+ print_expr(f, e->left.expr, parent, suffix, "label=\"!\",color=red");
+ break;
+ case E_EQUAL:
+ print_oper(f, e, parent, "=");
+ break;
+ case E_UNEQUAL:
+ print_oper(f, e, parent, "!=");
+ break;
+ case E_LIST:
+ printf("LIST\n");
+ break;
+ case E_SYMBOL: {
+ if (e->left.sym->name) {
+ fprintf(f, "\"%s\" -> \"%s\" [%s]\n", parent, e->left.sym->name, edge_opts);
+ print_symbol(f, e->left.sym);
+ }
+ break;
+ }
+ case E_RANGE:
+ printf("RANGE\n");
+ break;
+ }
+ }
+}
+
+void print_symbol(FILE *f, struct symbol *sym)
+{
+#define SYMBOL_PRINTED 0x80000000
+ if (sym->flags & SYMBOL_PRINTED)
+ return;
+ sym->flags |= SYMBOL_PRINTED;
+
+ char *opts = "";
+ if (is_interesting(sym))
+ opts = " [color=blue,fontcolor=blue]";
+ fprintf(f, "\"%s\"%s;\n", sym->name, opts);
+ print_expr(f, sym->dir_dep.expr, sym->name, "", "");
+}
+
+
+void generate_expr_id(struct expr *e);
+
+void generate_expr_id_oper(struct expr *e, const char *op_str)
+{
+ generate_expr_id(e->left.expr);
+ generate_expr_id(e->right.expr);
+ asprintf(&e->id, "(%s %s %s)", e->left.expr->id, op_str, e->right.expr->id);
+}
+
+void generate_expr_id(struct expr *e)
+{
+ if (e) {
+ switch (e->type) {
+ case E_NONE:
+ printf("NONE not implemented\n");
+ break;
+ case E_OR:
+ generate_expr_id_oper(e, "||");
+ break;
+ case E_AND:
+ generate_expr_id_oper(e, "&&");
+ break;
+ case E_NOT:
+ generate_expr_id(e->left.expr);
+ asprintf(&e->id, "not_%s", e->left.expr->id);
+ break;
+ case E_EQUAL:
+ generate_expr_id_oper(e, "==");
+ break;
+ case E_UNEQUAL:
+ generate_expr_id_oper(e, "!=");
+ break;
+ case E_LIST:
+ printf("LIST not implemented\n");
+ break;
+ case E_SYMBOL: {
+ if (e->left.sym->name) {
+ asprintf(&e->id, e->left.sym->name);
+ generate_expr_id(e->left.sym->dir_dep.expr);
+ }
+ break;
+ }
+ case E_RANGE:
+ printf("RANGE not implemented\n");
+ break;
+ }
+ }
+}
+
+void generate_expr_ids()
+{
+ int i;
+ struct symbol *sym;
+
+ for_all_symbols(i, sym) {
+ if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE)
+ && sym->name != NULL) {
+ if (is_interesting(sym)) {
+ generate_expr_id(sym->dir_dep.expr);
+ }
+ }
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ verbose_level = 1;
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
+ print_help();
+ exit(0);
+ } else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) {
+ verbose_level++;
+/* } else if (!strcmp(argv[i], "--all")) { */
+/* full_config = true; */
+/* } else if (!strcmp(argv[i], "--inv")) { */
+/* inv_config = true; */
+ } else if (kconfig_file == NULL) {
+ kconfig_file = argv[i];
+ } else if (dot_file == NULL) {
+ dot_file = argv[i];
+/* } else if (output_config_file == NULL) { */
+/* output_config_file = argv[i]; */
+ } else {
+ Eprintf("Unknown parameter: %s\n", argv[i]);
+ exit(1);
+ }
+ }
+
+ if (dot_file == NULL || kconfig_file == NULL
+ /* || input_config_file == NULL */) {
+ Eprintf("Missing mandatroy arguments.\n");
+ print_help();
+ exit(2);
+ }
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ setenv("ARCH", "powerpc", /*overwrite*/0);
+ setenv("KERNELVERSION", "1.2.3", /*overwrite*/0);
+ setenv("SRCARCH", "powerpc", /*overwrite*/0);
+
+ FILE *f;
+ if (strcmp(dot_file, "-") == 0) {
+ f = stdout;
+ } else {
+ f = fopen(dot_file, "w");
+ if (f == NULL) {
+ perror(dot_file);
+ exit(3);
+ }
+ }
+
+ char *slash = strrchr(kconfig_file, '/');
+ if (slash) {
+ *slash = 0;
+ if (chdir(kconfig_file)) {
+ perror(kconfig_file);
+ exit(1);
+ }
+ kconfig_file = slash + 1;
+ }
+
+ conf_parse(kconfig_file);
+ /* conf_read(input_config_file); */
+
+ generate_expr_ids();
+
+ fprintf(f, "digraph conf {\n");
+
+ struct symbol *sym;
+ for_all_symbols(i, sym) {
+ if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE)
+ && sym->name != NULL) {
+ if (is_interesting(sym)) {
+ print_symbol(f, sym);
+ }
+ }
+ }
+ fprintf(f, "}\n");
+
+ fclose(f);
+
+ return 0;
+}
+
+void print_help() {
+ printf
+ ("Usage: allconfig [-v] [-h] [--all] [--inv] Kconfig Input Output\n");
+ printf(" This is generating full configuration.\n");
+ printf(" Output configuration has all configuration options.\n");
+ printf("\n");
+ printf(" Options:\n");
+ printf(" -v, --verbose Increase level of verbose output.\n");
+ printf(" -h, --help Print this help text.\n");
+ printf
+ (" --all Genetate full configuration. Including non dependency\n");
+ printf(" configuration options");
+ printf
+ (" --inv Generate configuration of missing configratuon options.\n");
+}