-4.9.0 69973b830859bc6529a7a0468ba0d80ee5117826 Roaring Lionus
+4.10.0 c470abd4fde40ea6a0846a2beab642a578c0b8cd Fearless Coyote
0
That will limit the usefulness but on the other hand avoid
the illegal configurations all over.
+- weak reverse dependencies: "imply" <symbol> ["if" <expr>]
+ This is similar to "select" as it enforces a lower limit on another
+ symbol except that the "implied" symbol's value may still be set to n
+ from a direct dependency or with a visible prompt.
+
+ Given the following example:
+
+ config FOO
+ tristate
+ imply BAZ
+
+ config BAZ
+ tristate
+ depends on BAR
+
+ The following values are possible:
+
+ FOO BAR BAZ's default choice for BAZ
+ --- --- ------------- --------------
+ n y n N/m/y
+ m y m M/y/n
+ y y y Y/n
+ y n * N
+
+ This is useful e.g. with multiple drivers that want to indicate their
+ ability to hook into a secondary subsystem while allowing the user to
+ configure that subsystem out without also having to unset these drivers.
+
- limiting menu display: "visible if" <expr>
This attribute is only applicable to menu blocks, if the condition is
false, the menu block is not displayed to the user (the symbols
b) Match dependency semantics:
b1) Swap all "select FOO" to "depends on FOO" or,
b2) Swap all "depends on FOO" to "select FOO"
+ c) Consider the use of "imply" instead of "select"
The resolution to a) can be tested with the sample Kconfig file
Documentation/kbuild/Kconfig.recursion-issue-01 through the removal
* Derived from menuconfig.
*
*/
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#endif
#include <string.h>
#include <stdlib.h>
WINDOW *prompt_win;
WINDOW *form_win;
PANEL *panel;
- int i, x, y;
+ int i, x, y, lines, columns, win_lines, win_cols;
int res = -1;
int cursor_position = strlen(init);
int cursor_form_win;
char *result = *resultp;
+ getmaxyx(stdscr, lines, columns);
+
if (strlen(init)+1 > *result_len) {
*result_len = strlen(init)+1;
*resultp = result = realloc(result, *result_len);
if (title)
prompt_width = max(prompt_width, strlen(title));
+ win_lines = min(prompt_lines+6, lines-2);
+ win_cols = min(prompt_width+7, columns-2);
+ prompt_lines = max(win_lines-6, 0);
+ prompt_width = max(win_cols-7, 0);
+
/* place dialog in middle of screen */
- y = (getmaxy(stdscr)-(prompt_lines+4))/2;
- x = (getmaxx(stdscr)-(prompt_width+4))/2;
+ y = (lines-win_lines)/2;
+ x = (columns-win_cols)/2;
strncpy(result, init, *result_len);
/* create the windows */
- win = newwin(prompt_lines+6, prompt_width+7, y, x);
+ win = newwin(win_lines, win_cols, y, x);
prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
keypad(form_win, TRUE);
QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
{
QList<int> result;
- QStringList entryList = value(key).toStringList();
- QStringList::Iterator it;
- for (it = entryList.begin(); it != entryList.end(); ++it)
- result.push_back((*it).toInt());
+ if (contains(key))
+ {
+ QStringList entryList = value(key).toStringList();
+ QStringList::Iterator it;
+
+ for (it = entryList.begin(); it != entryList.end(); ++it)
+ result.push_back((*it).toInt());
+
+ *ok = true;
+ }
+ else
+ *ok = false;
return result;
}
if (!objectName().isEmpty()) {
configSettings->beginGroup(objectName());
- _showDebug = configSettings->value("/showDebug", false).toBool();
+ setShowDebug(configSettings->value("/showDebug", false).toBool());
configSettings->endGroup();
connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
}
optionMenu->addSeparator();
optionMenu->addActions(optGroup->actions());
optionMenu->addSeparator();
+ optionMenu->addAction(showDebugAction);
// create help menu
menu->addSeparator();
struct property *prop;
struct expr_value dir_dep;
struct expr_value rev_dep;
+ struct expr_value implied;
};
#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
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 */
hex, T_TYPE, TF_COMMAND, S_HEX
string, T_TYPE, TF_COMMAND, S_STRING
select, T_SELECT, TF_COMMAND
+imply, T_IMPLY, TF_COMMAND
range, T_RANGE, TF_COMMAND
visible, T_VISIBLE, TF_COMMAND
option, T_OPTION, TF_COMMAND
{
struct property *prop;
struct symbol *sym2;
+ char *use;
+
for (prop = sym->prop; prop; prop = prop->next) {
switch (prop->type) {
case P_DEFAULT:
}
break;
case P_SELECT:
+ case P_IMPLY:
+ use = prop->type == P_SELECT ? "select" : "imply";
sym2 = prop_get_symbol(prop);
if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
prop_warn(prop,
- "config symbol '%s' uses select, but is "
- "not boolean or tristate", sym->name);
+ "config symbol '%s' uses %s, but is "
+ "not boolean or tristate", sym->name, use);
else if (sym2->type != S_UNKNOWN &&
sym2->type != S_BOOLEAN &&
sym2->type != S_TRISTATE)
prop_warn(prop,
- "'%s' has wrong type. 'select' only "
+ "'%s' has wrong type. '%s' only "
"accept arguments of boolean and "
- "tristate type", sym2->name);
+ "tristate type", sym2->name, use);
break;
case P_RANGE:
if (sym->type != S_INT && sym->type != S_HEX)
struct symbol *es = prop_get_symbol(prop);
es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
+ } else if (prop->type == P_IMPLY) {
+ struct symbol *es = prop_get_symbol(prop);
+ es->implied.expr = expr_alloc_or(es->implied.expr,
+ expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
}
}
}
return prop;
}
+static void get_symbol_props_str(struct gstr *r, struct symbol *sym,
+ enum prop_type tok, const char *prefix)
+{
+ bool hit = false;
+ struct property *prop;
+
+ for_all_properties(sym, prop, tok) {
+ if (!hit) {
+ str_append(r, prefix);
+ hit = true;
+ } else
+ str_printf(r, " && ");
+ expr_gstr_print(prop->expr, r);
+ }
+ if (hit)
+ str_append(r, "\n");
+}
+
/*
* head is optional and may be NULL
*/
static void get_symbol_str(struct gstr *r, struct symbol *sym,
struct list_head *head)
{
- bool hit;
struct property *prop;
if (sym && sym->name) {
}
}
- hit = false;
- for_all_properties(sym, prop, P_SELECT) {
- if (!hit) {
- str_append(r, " Selects: ");
- hit = true;
- } else
- str_printf(r, " && ");
- expr_gstr_print(prop->expr, r);
- }
- if (hit)
- str_append(r, "\n");
+ get_symbol_props_str(r, sym, P_SELECT, _(" Selects: "));
if (sym->rev_dep.expr) {
str_append(r, _(" Selected by: "));
expr_gstr_print(sym->rev_dep.expr, r);
str_append(r, "\n");
}
+
+ get_symbol_props_str(r, sym, P_IMPLY, _(" Implies: "));
+ if (sym->implied.expr) {
+ str_append(r, _(" Implied by: "));
+ expr_gstr_print(sym->implied.expr, r);
+ str_append(r, "\n");
+ }
+
str_append(r, "\n\n");
}
sym->rev_dep.tri = tri;
sym_set_changed(sym);
}
+ tri = no;
+ if (sym->implied.expr && sym->dir_dep.tri != no)
+ tri = expr_calc_value(sym->implied.expr);
+ if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
+ tri = yes;
+ if (sym->implied.tri != tri) {
+ sym->implied.tri = tri;
+ sym_set_changed(sym);
+ }
}
/*
newval.tri = EXPR_AND(expr_calc_value(prop->expr),
prop->visible.tri);
}
+ if (sym->implied.tri != no) {
+ sym->flags |= SYMBOL_WRITE;
+ newval.tri = EXPR_OR(newval.tri, sym->implied.tri);
+ }
}
calc_newval:
if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
}
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
}
- if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
+ if (newval.tri == mod &&
+ (sym_get_type(sym) == S_BOOLEAN || sym->implied.tri == yes))
newval.tri = yes;
break;
case S_STRING:
return false;
if (sym->visible <= sym->rev_dep.tri)
return false;
+ if (sym->implied.tri == yes && val == mod)
+ return false;
if (sym_is_choice_value(sym) && sym->visible == yes)
return val == yes;
return val >= sym->rev_dep.tri && val <= sym->visible;
if (sym->type == S_BOOLEAN && val == mod)
val = yes;
+ /* adjust the default value if this symbol is implied by another */
+ if (val < sym->implied.tri)
+ val = sym->implied.tri;
+
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
return "choice";
case P_SELECT:
return "select";
+ case P_IMPLY:
+ return "imply";
case P_RANGE:
return "range";
case P_SYMBOL:
static struct menu *current_menu, *current_entry;
%}
-%expect 30
+%expect 32
%union
{
%token <id>T_TYPE
%token <id>T_DEFAULT
%token <id>T_SELECT
+%token <id>T_IMPLY
%token <id>T_RANGE
%token <id>T_VISIBLE
%token <id>T_OPTION
;
option_name:
- T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
+ T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_IMPLY | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
;
common_stmt:
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
};
+config_option: T_IMPLY T_WORD if_expr T_EOL
+{
+ menu_add_symbol(P_IMPLY, sym_lookup($2, 0), $3);
+ printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
+};
+
config_option: T_RANGE symbol symbol if_expr T_EOL
{
menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
expr_fprint(prop->expr, out);
fputc('\n', out);
break;
+ case P_IMPLY:
+ fputs( " imply ", out);
+ expr_fprint(prop->expr, out);
+ fputc('\n', out);
+ break;
case P_RANGE:
fputs( " range ", out);
expr_fprint(prop->expr, out);
032a318 kconfig-language: elaborate on the type of a choice
fa64e5f kconfig/symbol.c: handle choice_values that depend on 'm' symbols
cfd7c612 kconfig-language: improve menuconfig usage description
+237e3ad Kconfig: Introduce the "imply" keyword
+0eb4734 Scripts: kconfig: nconf: fix _GNU_SOURCE redefined warning
+79e51b5 kconfig/nconf: Fix hang when editing symbol with a long prompt
+e039303 xconfig: fix 'Show Debug' functionality
+83c3a1b xconfig: fix missing suboption and help panels on first run