|
|
|
@ -3,265 +3,306 @@
|
|
|
|
|
* Released under the terms of the GNU GPL v2.0.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <locale.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <getopt.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
|
|
#include "lkc.h"
|
|
|
|
|
|
|
|
|
|
static void conf(struct menu *menu);
|
|
|
|
|
static void check_conf(struct menu *menu);
|
|
|
|
|
static void xfgets(char *str, int size, FILE *in);
|
|
|
|
|
|
|
|
|
|
#include <locale.h> // 引入本地化相关功能的头文件
|
|
|
|
|
#include <ctype.h> // 引入字符处理函数的头文件,例如 isspace、isdigit 等
|
|
|
|
|
#include <stdio.h> // 引入标准输入输出库
|
|
|
|
|
#include <stdlib.h> // 引入标准库,提供内存管理、程序退出等功能
|
|
|
|
|
#include <string.h> // 引入字符串处理函数库
|
|
|
|
|
#include <time.h> // 引入时间日期相关函数
|
|
|
|
|
#include <unistd.h> // 引入 Unix 系统 API,提供与系统交互的功能
|
|
|
|
|
#include <getopt.h> // 引入命令行参数解析函数
|
|
|
|
|
#include <sys/stat.h> // 引入文件状态函数
|
|
|
|
|
#include <sys/time.h> // 引入时间管理函数
|
|
|
|
|
#include <errno.h> // 引入错误码定义
|
|
|
|
|
#include "lkc.h" // 引入项目自定义的头文件
|
|
|
|
|
|
|
|
|
|
// 函数声明
|
|
|
|
|
static void conf(struct menu *menu); // 配置函数
|
|
|
|
|
static void check_conf(struct menu *menu); // 检查配置函数
|
|
|
|
|
static void xfgets(char *str, int size, FILE *in); // 自定义的 fgets 函数
|
|
|
|
|
|
|
|
|
|
// 定义输入模式枚举类型
|
|
|
|
|
enum input_mode {
|
|
|
|
|
oldaskconfig,
|
|
|
|
|
silentoldconfig,
|
|
|
|
|
oldconfig,
|
|
|
|
|
allnoconfig,
|
|
|
|
|
allyesconfig,
|
|
|
|
|
allmodconfig,
|
|
|
|
|
alldefconfig,
|
|
|
|
|
randconfig,
|
|
|
|
|
defconfig,
|
|
|
|
|
savedefconfig,
|
|
|
|
|
listnewconfig,
|
|
|
|
|
olddefconfig,
|
|
|
|
|
} input_mode = oldaskconfig;
|
|
|
|
|
|
|
|
|
|
static int indent = 1;
|
|
|
|
|
static int tty_stdio;
|
|
|
|
|
static int valid_stdin = 1;
|
|
|
|
|
static int sync_kconfig;
|
|
|
|
|
static int conf_cnt;
|
|
|
|
|
static char line[128];
|
|
|
|
|
static struct menu *rootEntry;
|
|
|
|
|
|
|
|
|
|
oldaskconfig, // 用户交互模式
|
|
|
|
|
silentoldconfig, // 无用户交互模式,使用默认值
|
|
|
|
|
oldconfig, // 使用旧的配置
|
|
|
|
|
allnoconfig, // 所有选项都为 no
|
|
|
|
|
allyesconfig, // 所有选项都为 yes
|
|
|
|
|
allmodconfig, // 所有选项都为模块
|
|
|
|
|
alldefconfig, // 所有选项都为默认值
|
|
|
|
|
randconfig, // 随机配置
|
|
|
|
|
defconfig, // 使用默认配置
|
|
|
|
|
savedefconfig, // 保存默认配置
|
|
|
|
|
listnewconfig, // 列出新的配置项
|
|
|
|
|
olddefconfig, // 使用旧的默认配置
|
|
|
|
|
} input_mode = oldaskconfig; // 设置默认输入模式为 oldaskconfig
|
|
|
|
|
|
|
|
|
|
// 静态变量声明
|
|
|
|
|
static int indent = 1; // 配置输出时的缩进级别
|
|
|
|
|
static int tty_stdio; // 标识标准输入输出是否是终端设备
|
|
|
|
|
static int valid_stdin = 1; // 标识标准输入是否有效
|
|
|
|
|
static int sync_kconfig; // 同步配置标志
|
|
|
|
|
static int conf_cnt; // 配置项计数器
|
|
|
|
|
static char line[128]; // 用于存储输入行的缓冲区
|
|
|
|
|
static struct menu *rootEntry; // 配置菜单的根节点指针
|
|
|
|
|
|
|
|
|
|
// 打印帮助信息
|
|
|
|
|
static void print_help(struct menu *menu)
|
|
|
|
|
{
|
|
|
|
|
struct gstr help = str_new();
|
|
|
|
|
struct gstr help = str_new(); // 创建一个新的字符串对象
|
|
|
|
|
|
|
|
|
|
menu_get_ext_help(menu, &help);
|
|
|
|
|
menu_get_ext_help(menu, &help); // 获取菜单项的扩展帮助信息
|
|
|
|
|
|
|
|
|
|
printf("\n%s\n", str_get(&help));
|
|
|
|
|
str_free(&help);
|
|
|
|
|
printf("\n%s\n", str_get(&help)); // 打印帮助信息
|
|
|
|
|
str_free(&help); // 释放帮助字符串资源
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 去除字符串两端的空白字符
|
|
|
|
|
static void strip(char *str)
|
|
|
|
|
{
|
|
|
|
|
char *p = str;
|
|
|
|
|
int l;
|
|
|
|
|
|
|
|
|
|
while ((isspace(*p)))
|
|
|
|
|
p++;
|
|
|
|
|
l = strlen(p);
|
|
|
|
|
if (p != str)
|
|
|
|
|
memmove(str, p, l + 1);
|
|
|
|
|
if (!l)
|
|
|
|
|
return;
|
|
|
|
|
p = str + l - 1;
|
|
|
|
|
while ((isspace(*p)))
|
|
|
|
|
*p-- = 0;
|
|
|
|
|
char *p = str;
|
|
|
|
|
int l;
|
|
|
|
|
|
|
|
|
|
// 跳过前导空格
|
|
|
|
|
while ((isspace(*p)))
|
|
|
|
|
p++;
|
|
|
|
|
|
|
|
|
|
l = strlen(p); // 获取字符串的长度
|
|
|
|
|
if (p != str) // 如果有前导空格,移动字符串内容
|
|
|
|
|
memmove(str, p, l + 1);
|
|
|
|
|
|
|
|
|
|
if (!l) // 如果字符串为空,返回
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// 去除尾部空格
|
|
|
|
|
p = str + l - 1;
|
|
|
|
|
while ((isspace(*p))) // 从字符串末尾向前查找空格并去除
|
|
|
|
|
*p-- = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查标准输入是否有效
|
|
|
|
|
static void check_stdin(void)
|
|
|
|
|
{
|
|
|
|
|
if (!valid_stdin) {
|
|
|
|
|
printf(_("aborted!\n\n"));
|
|
|
|
|
printf(_("Console input/output is redirected. "));
|
|
|
|
|
printf(_("Run 'make oldconfig' to update configuration.\n\n"));
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
if (!valid_stdin) { // 如果标准输入无效
|
|
|
|
|
printf(_("aborted!\n\n"));
|
|
|
|
|
printf(_("Console input/output is redirected. "));
|
|
|
|
|
printf(_("Run 'make oldconfig' to update configuration.\n\n"));
|
|
|
|
|
exit(1); // 退出程序
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 配置选项的处理函数
|
|
|
|
|
static int conf_askvalue(struct symbol *sym, const char *def)
|
|
|
|
|
{
|
|
|
|
|
enum symbol_type type = sym_get_type(sym);
|
|
|
|
|
|
|
|
|
|
if (!sym_has_value(sym))
|
|
|
|
|
printf(_("(NEW) "));
|
|
|
|
|
|
|
|
|
|
line[0] = '\n';
|
|
|
|
|
line[1] = 0;
|
|
|
|
|
|
|
|
|
|
if (!sym_is_changable(sym)) {
|
|
|
|
|
printf("%s\n", def);
|
|
|
|
|
line[0] = '\n';
|
|
|
|
|
line[1] = 0;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (input_mode) {
|
|
|
|
|
case oldconfig:
|
|
|
|
|
case silentoldconfig:
|
|
|
|
|
if (sym_has_value(sym)) {
|
|
|
|
|
printf("%s\n", def);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
check_stdin();
|
|
|
|
|
/* fall through */
|
|
|
|
|
case oldaskconfig:
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
xfgets(line, 128, stdin);
|
|
|
|
|
if (!tty_stdio)
|
|
|
|
|
printf("\n");
|
|
|
|
|
return 1;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case S_INT:
|
|
|
|
|
case S_HEX:
|
|
|
|
|
case S_STRING:
|
|
|
|
|
printf("%s\n", def);
|
|
|
|
|
return 1;
|
|
|
|
|
default:
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
printf("%s", line);
|
|
|
|
|
return 1;
|
|
|
|
|
enum symbol_type type = sym_get_type(sym); // 获取符号的类型
|
|
|
|
|
|
|
|
|
|
if (!sym_has_value(sym)) // 如果没有值,标记为新选项
|
|
|
|
|
printf(_("(NEW) "));
|
|
|
|
|
|
|
|
|
|
line[0] = '\n';
|
|
|
|
|
line[1] = 0;
|
|
|
|
|
|
|
|
|
|
if (!sym_is_changable(sym)) { // 如果符号不可修改,直接输出默认值
|
|
|
|
|
printf("%s\n", def);
|
|
|
|
|
line[0] = '\n';
|
|
|
|
|
line[1] = 0;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据输入模式不同执行不同的操作
|
|
|
|
|
switch (input_mode) {
|
|
|
|
|
case oldconfig:
|
|
|
|
|
case silentoldconfig:
|
|
|
|
|
if (sym_has_value(sym)) { // 如果已有值,直接输出默认值
|
|
|
|
|
printf("%s\n", def);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
check_stdin(); // 检查标准输入有效性
|
|
|
|
|
/* fall through */
|
|
|
|
|
case oldaskconfig:
|
|
|
|
|
fflush(stdout); // 刷新标准输出缓冲区
|
|
|
|
|
xfgets(line, 128, stdin); // 获取用户输入
|
|
|
|
|
if (!tty_stdio) // 如果标准输入不是终端,换行
|
|
|
|
|
printf("\n");
|
|
|
|
|
return 1;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据符号类型进行处理
|
|
|
|
|
switch (type) {
|
|
|
|
|
case S_INT:
|
|
|
|
|
case S_HEX:
|
|
|
|
|
case S_STRING:
|
|
|
|
|
printf("%s\n", def);
|
|
|
|
|
return 1;
|
|
|
|
|
default:
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
printf("%s", line); // 输出用户输入的内容
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 配置字符串类型的处理函数
|
|
|
|
|
static int conf_string(struct menu *menu)
|
|
|
|
|
{
|
|
|
|
|
struct symbol *sym = menu->sym;
|
|
|
|
|
const char *def;
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
|
|
|
|
|
printf("(%s) ", sym->name);
|
|
|
|
|
def = sym_get_string_value(sym);
|
|
|
|
|
if (sym_get_string_value(sym))
|
|
|
|
|
printf("[%s] ", def);
|
|
|
|
|
if (!conf_askvalue(sym, def))
|
|
|
|
|
return 0;
|
|
|
|
|
switch (line[0]) {
|
|
|
|
|
case '\n':
|
|
|
|
|
break;
|
|
|
|
|
case '?':
|
|
|
|
|
/* print help */
|
|
|
|
|
if (line[1] == '\n') {
|
|
|
|
|
print_help(menu);
|
|
|
|
|
def = NULL;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
/* fall through */
|
|
|
|
|
default:
|
|
|
|
|
line[strlen(line)-1] = 0;
|
|
|
|
|
def = line;
|
|
|
|
|
}
|
|
|
|
|
if (def && sym_set_string_value(sym, def))
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
struct symbol *sym = menu->sym;
|
|
|
|
|
const char *def;
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); // 打印菜单提示
|
|
|
|
|
printf("(%s) ", sym->name); // 打印符号名称
|
|
|
|
|
def = sym_get_string_value(sym); // 获取符号的默认字符串值
|
|
|
|
|
if (def) // 如果有默认值,打印出来
|
|
|
|
|
printf("[%s] ", def);
|
|
|
|
|
if (!conf_askvalue(sym, def)) // 获取用户输入并处理
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
// 根据用户输入的内容进行处理
|
|
|
|
|
switch (line[0]) {
|
|
|
|
|
case '\n':
|
|
|
|
|
break; // 如果用户没有输入内容,继续
|
|
|
|
|
case '?':
|
|
|
|
|
// 打印帮助信息
|
|
|
|
|
if (line[1] == '\n') {
|
|
|
|
|
print_help(menu); // 打印帮助
|
|
|
|
|
def = NULL;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
/* fall through */
|
|
|
|
|
default:
|
|
|
|
|
line[strlen(line) - 1] = 0; // 去掉换行符
|
|
|
|
|
def = line; // 将用户输入的内容赋给 def
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置符号的字符串值
|
|
|
|
|
if (def && sym_set_string_value(sym, def))
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 配置符号的值(如:yes、no、mod)的函数
|
|
|
|
|
static int conf_sym(struct menu *menu)
|
|
|
|
|
{
|
|
|
|
|
struct symbol *sym = menu->sym;
|
|
|
|
|
tristate oldval, newval;
|
|
|
|
|
struct symbol *sym = menu->sym; // 获取菜单项的符号
|
|
|
|
|
tristate oldval, newval; // 旧值和新值变量,tristate表示三种状态(yes、no、mod)
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
// 打印菜单提示信息,包括符号名称(如果存在)
|
|
|
|
|
printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); // 打印缩进和提示文本
|
|
|
|
|
if (sym->name) // 如果符号有名称,打印符号名称
|
|
|
|
|
printf("(%s) ", sym->name);
|
|
|
|
|
|
|
|
|
|
putchar('['); // 打印开头的方括号
|
|
|
|
|
oldval = sym_get_tristate_value(sym); // 获取符号的当前值
|
|
|
|
|
|
|
|
|
|
// 根据当前的状态值(oldval),打印相应的字符
|
|
|
|
|
switch (oldval) {
|
|
|
|
|
case no:
|
|
|
|
|
putchar('N'); // 输出 'N' 表示当前为 no
|
|
|
|
|
break;
|
|
|
|
|
case mod:
|
|
|
|
|
putchar('M'); // 输出 'M' 表示当前为 mod
|
|
|
|
|
break;
|
|
|
|
|
case yes:
|
|
|
|
|
putchar('Y'); // 输出 'Y' 表示当前为 yes
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据当前的状态值,显示可选的值(no、mod、yes),如果符号的值在范围内
|
|
|
|
|
if (oldval != no && sym_tristate_within_range(sym, no))
|
|
|
|
|
printf("/n");
|
|
|
|
|
if (oldval != mod && sym_tristate_within_range(sym, mod))
|
|
|
|
|
printf("/m");
|
|
|
|
|
if (oldval != yes && sym_tristate_within_range(sym, yes))
|
|
|
|
|
printf("/y");
|
|
|
|
|
|
|
|
|
|
// 如果菜单项有帮助信息,显示帮助提示
|
|
|
|
|
if (menu_has_help(menu))
|
|
|
|
|
printf("/?");
|
|
|
|
|
|
|
|
|
|
printf("] "); // 打印结束的方括号
|
|
|
|
|
// 询问用户输入新值,如果没有输入有效值,返回 0
|
|
|
|
|
if (!conf_askvalue(sym, sym_get_string_value(sym)))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
strip(line); // 去除用户输入的字符串两端空格
|
|
|
|
|
|
|
|
|
|
// 根据用户输入的值进行处理
|
|
|
|
|
switch (line[0]) {
|
|
|
|
|
case 'n':
|
|
|
|
|
case 'N': // 如果输入是 'n' 或 'N',设置新值为 no
|
|
|
|
|
newval = no;
|
|
|
|
|
if (!line[1] || !strcmp(&line[1], "o"))
|
|
|
|
|
break;
|
|
|
|
|
continue; // 如果有其他字符,继续下一次循环
|
|
|
|
|
case 'm':
|
|
|
|
|
case 'M': // 如果输入是 'm' 或 'M',设置新值为 mod
|
|
|
|
|
newval = mod;
|
|
|
|
|
if (!line[1])
|
|
|
|
|
break;
|
|
|
|
|
continue; // 如果有其他字符,继续下一次循环
|
|
|
|
|
case 'y':
|
|
|
|
|
case 'Y': // 如果输入是 'y' 或 'Y',设置新值为 yes
|
|
|
|
|
newval = yes;
|
|
|
|
|
if (!line[1] || !strcmp(&line[1], "es"))
|
|
|
|
|
break;
|
|
|
|
|
continue; // 如果有其他字符,继续下一次循环
|
|
|
|
|
case 0: // 如果没有输入内容,保留旧值
|
|
|
|
|
newval = oldval;
|
|
|
|
|
break;
|
|
|
|
|
case '?': // 如果输入是 '?',显示帮助
|
|
|
|
|
goto help;
|
|
|
|
|
default:
|
|
|
|
|
continue; // 继续循环,直到输入合法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置符号的新值
|
|
|
|
|
if (sym_set_tristate_value(sym, newval))
|
|
|
|
|
return 0; // 如果设置失败,返回 0
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
|
|
|
|
|
if (sym->name)
|
|
|
|
|
printf("(%s) ", sym->name);
|
|
|
|
|
putchar('[');
|
|
|
|
|
oldval = sym_get_tristate_value(sym);
|
|
|
|
|
switch (oldval) {
|
|
|
|
|
case no:
|
|
|
|
|
putchar('N');
|
|
|
|
|
break;
|
|
|
|
|
case mod:
|
|
|
|
|
putchar('M');
|
|
|
|
|
break;
|
|
|
|
|
case yes:
|
|
|
|
|
putchar('Y');
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (oldval != no && sym_tristate_within_range(sym, no))
|
|
|
|
|
printf("/n");
|
|
|
|
|
if (oldval != mod && sym_tristate_within_range(sym, mod))
|
|
|
|
|
printf("/m");
|
|
|
|
|
if (oldval != yes && sym_tristate_within_range(sym, yes))
|
|
|
|
|
printf("/y");
|
|
|
|
|
if (menu_has_help(menu))
|
|
|
|
|
printf("/?");
|
|
|
|
|
printf("] ");
|
|
|
|
|
if (!conf_askvalue(sym, sym_get_string_value(sym)))
|
|
|
|
|
return 0;
|
|
|
|
|
strip(line);
|
|
|
|
|
|
|
|
|
|
switch (line[0]) {
|
|
|
|
|
case 'n':
|
|
|
|
|
case 'N':
|
|
|
|
|
newval = no;
|
|
|
|
|
if (!line[1] || !strcmp(&line[1], "o"))
|
|
|
|
|
break;
|
|
|
|
|
continue;
|
|
|
|
|
case 'm':
|
|
|
|
|
case 'M':
|
|
|
|
|
newval = mod;
|
|
|
|
|
if (!line[1])
|
|
|
|
|
break;
|
|
|
|
|
continue;
|
|
|
|
|
case 'y':
|
|
|
|
|
case 'Y':
|
|
|
|
|
newval = yes;
|
|
|
|
|
if (!line[1] || !strcmp(&line[1], "es"))
|
|
|
|
|
break;
|
|
|
|
|
continue;
|
|
|
|
|
case 0:
|
|
|
|
|
newval = oldval;
|
|
|
|
|
break;
|
|
|
|
|
case '?':
|
|
|
|
|
goto help;
|
|
|
|
|
default:
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (sym_set_tristate_value(sym, newval))
|
|
|
|
|
return 0;
|
|
|
|
|
help:
|
|
|
|
|
print_help(menu);
|
|
|
|
|
}
|
|
|
|
|
print_help(menu); // 打印帮助信息
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 配置选择菜单项的函数
|
|
|
|
|
static int conf_choice(struct menu *menu)
|
|
|
|
|
{
|
|
|
|
|
struct symbol *sym, *def_sym;
|
|
|
|
|
struct menu *child;
|
|
|
|
|
bool is_new;
|
|
|
|
|
|
|
|
|
|
sym = menu->sym;
|
|
|
|
|
is_new = !sym_has_value(sym);
|
|
|
|
|
if (sym_is_changable(sym)) {
|
|
|
|
|
conf_sym(menu);
|
|
|
|
|
sym_calc_value(sym);
|
|
|
|
|
switch (sym_get_tristate_value(sym)) {
|
|
|
|
|
case no:
|
|
|
|
|
return 1;
|
|
|
|
|
case mod:
|
|
|
|
|
return 0;
|
|
|
|
|
case yes:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
switch (sym_get_tristate_value(sym)) {
|
|
|
|
|
case no:
|
|
|
|
|
return 1;
|
|
|
|
|
case mod:
|
|
|
|
|
printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
|
|
|
|
|
return 0;
|
|
|
|
|
case yes:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
struct symbol *sym, *def_sym;
|
|
|
|
|
struct menu *child;
|
|
|
|
|
bool is_new;
|
|
|
|
|
|
|
|
|
|
sym = menu->sym; // 获取当前菜单项的符号
|
|
|
|
|
is_new = !sym_has_value(sym); // 检查符号是否有值(是否为新符号)
|
|
|
|
|
|
|
|
|
|
// 如果符号可修改,进行符号的配置
|
|
|
|
|
if (sym_is_changable(sym)) {
|
|
|
|
|
conf_sym(menu); // 调用 conf_sym 函数配置符号
|
|
|
|
|
sym_calc_value(sym); // 计算符号的值
|
|
|
|
|
|
|
|
|
|
// 根据符号的值执行不同的操作
|
|
|
|
|
switch (sym_get_tristate_value(sym)) {
|
|
|
|
|
case no: // 如果值是 no,返回 1
|
|
|
|
|
return 1;
|
|
|
|
|
case mod: // 如果值是 mod,返回 0
|
|
|
|
|
return 0;
|
|
|
|
|
case yes: // 如果值是 yes,继续执行
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else { // 如果符号不可修改
|
|
|
|
|
switch (sym_get_tristate_value(sym)) {
|
|
|
|
|
case no: // 如果值是 no,返回 1
|
|
|
|
|
return 1;
|
|
|
|
|
case mod: // 如果值是 mod,打印菜单提示并返回 0
|
|
|
|
|
printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
|
|
|
|
|
return 0;
|
|
|
|
|
case yes: // 如果值是 yes,继续执行
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
int cnt, def;
|
|
|
|
|