/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>
#include <sys/utsname.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
struct symbol symbol_yes = {
.name = "y",
.curr = { "y", yes },
.flags = SYMBOL_YES|SYMBOL_VALID,
}, symbol_mod = {
.name = "m",
.curr = { "m", mod },
.flags = SYMBOL_MOD|SYMBOL_VALID,
}, symbol_no = {
.name = "n",
.curr = { "n", no },
.flags = SYMBOL_NO|SYMBOL_VALID,
}, symbol_empty = {
.name = "",
.curr = { "", no },
.flags = SYMBOL_VALID,
};
int sym_change_count;
struct symbol *modules_sym;
tristate modules_val;
void sym_add_default(struct symbol *sym, const char *def)
{
struct property *prop = prop_alloc(P_DEFAULT, sym);
prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
}
void sym_init(void)
{
struct symbol *sym;
struct utsname uts;
char *p;
static bool inited = false;
if (inited)
return;
inited = true;
uname(&uts);
sym = sym_lookup("ARCH", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
p = getenv("ARCH");
if (p)
sym_add_default(sym, p);
sym = sym_lookup("KERNELRELEASE", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
p = getenv("KERNELRELEASE");
if (p)
sym_add_default(sym, p);
sym = sym_lookup("UNAME_RELEASE", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
sym_add_default(sym, uts.release);
}
enum symbol_type sym_get_type(struct symbol *sym)
{
enum symbol_type type = sym->type;
if (type == S_TRISTATE) {
if (sym_is_choice_value(sym) && sym->visible == yes)
type = S_BOOLEAN;
else if (modules_val == no)
type = S_BOOLEAN;
}
return type;
}
const char *sym_type_name(enum symbol_type type)
{
switch (type) {
case S_BOOLEAN:
return "boolean";
case S_TRISTATE:
return "tristate";
case S_INT:
return "integer";
case S_HEX:
return "hex";
case S_STRING:
return "string";
case S_UNKNOWN:
return "unknown";
case S_OTHER:
break;
}
return "???";
}
struct property *sym_get_choice_prop(struct symbol *sym)
{
struct property *prop;
for_all_choices(sym, prop)
return prop;
return NULL;
}
struct property *sym_get_default_prop(struct symbol *sym)
{
struct property *prop;
for_all_defaults(sym, prop) {
prop->visible.tri = expr_calc_value(prop->visible.expr);
if (prop->visible.tri != no)
return prop;
}
return NULL;
}
struct property *sym_get_range_prop(struct symbol *sym)
{
struct property *prop;
for_all_properties(sym, prop, P_RANGE) {
prop->visible.tri = expr_calc_value(prop->visible.expr);
if (prop->visible.tri != no)
return prop;
}
return NULL;
}
static void sym_calc_visibility(struct symbol *sym)
{
struct property *prop;
tristate tri;
/* any prompt visible? */
tri = no;
for_all_prompts(sym, prop) {
prop->visible.tri = expr_calc_value(prop->visible.expr);
tri = E_OR(tri, prop->visible.tri);
}
if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
tri = yes;
if (sym->visible != tri) {
sym->visible = tri;
sym_set_changed(sym);
}
if (sym_is_choice_value(sym))
return;
tri = no;
if (sym->rev_dep.expr)
tri = expr_calc_value(sym->rev_dep.expr);
if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
tri = yes;
if (sym->rev_dep.tri != tri) {
sym->rev_dep.tri = tri;
sym_set_changed(sym);
}
}
static struct symbol *sym_calc_choice(struct symbol *sym)
{