-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
126 lines (103 loc) · 3.84 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2023 JiauZhang <https://github.com/JiauZhang/menuconfig>
extern "C" {
#include <signal.h>
#include <string.h>
#include "lkc.h"
#include "lxdialog/dialog.h"
extern void sig_handler_api(int signo);
extern void set_config_filename_api(const char *config_filename);
extern void conf_message_callback_api(const char *s);
extern void conf_api(struct menu *menu, struct menu *active_menu);
extern int handle_exit_api(void);
extern int *silent_api;
extern int *single_menu_mode_api;
}
#include <cstdlib>
#include <filesystem>
#include "argparse.hpp"
namespace fs = std::filesystem;
int main(int argc, char **argv)
{
argparse::ArgumentParser parser("menuconfig options");
parser.add_argument("--verbose")
.help("change output verbosity")
.default_value(false)
.implicit_value(true);
parser.add_argument("--syncconfig")
.help("generates configuration in include/{generated/,config/}")
.default_value(false)
.implicit_value(true);
parser.add_argument("--kconfig")
.help("specify the Kconfig file");
try {
parser.parse_args(argc, argv);
} catch (const std::runtime_error& err) {
std::cout << "runtime error:\n";
std::cerr << err.what() << std::endl;
std::cerr << parser;
std::exit(1);
}
const char *KCONFIG_CONFIG = "KCONFIG_CONFIG";
const char *KCONFIG_AUTOCONFIG = "KCONFIG_AUTOCONFIG";
const char *KCONFIG_AUTOHEADER = "KCONFIG_AUTOHEADER";
setenv(KCONFIG_CONFIG, ".config", 1);
setenv(KCONFIG_AUTOCONFIG, "include/config/auto.conf", 1);
setenv(KCONFIG_AUTOHEADER, "include/generated/autoconf.h", 1);
signal(SIGINT, sig_handler_api);
if (parser["--verbose"] == false) {
*silent_api = 1;
/* Silence conf_read() until the real callback is set up */
conf_set_message_callback(NULL);
}
std::string kconfig("Kconfig");
if (parser.is_used("--kconfig"))
kconfig = parser.get<std::string>("--kconfig");
fs::file_status file_status(fs::status(kconfig));
if (file_status.type() != fs::file_type::regular) {
std::cerr << "Runtime Error:\n";
std::cerr << "\tKconfig file: " << kconfig
<< " is not a regular file!\n" << std::endl;
if (!parser.is_used("--kconfig"))
std::cout << parser << std::endl;
std::exit(1);
}
fs::path kconfig_file = fs::absolute(fs::path(kconfig));
fs::path dirname = kconfig_file.parent_path();
fs::path dot_config_file = dirname / fs::path(".config");
fs::current_path(dirname);
conf_parse(kconfig_file.c_str());
conf_read(dot_config_file.c_str());
int res;
char *mode = getenv("MENUCONFIG_MODE");
if (mode) {
if (!strcasecmp(mode, "single_menu"))
*single_menu_mode_api = 1;
}
if (init_dialog(NULL)) {
fprintf(stderr, "Your display is too small to run Menuconfig!\n");
fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
return 1;
}
set_config_filename_api(conf_get_configname());
conf_set_message_callback(conf_message_callback_api);
do {
conf_api(&rootmenu, NULL);
res = handle_exit_api();
} while (res == KEY_ESC);
if (parser["--syncconfig"] == true) {
if (!fs::exists(getenv(KCONFIG_CONFIG))) {
fprintf(stderr, "***\n");
fprintf(stderr, "Configuration file .config not found! Please run `make menuconfig`.\n");
fprintf(stderr, "***\n");
return -1;
}
bool need_sync = fs::exists(getenv(KCONFIG_AUTOCONFIG));
if (need_sync)
need_sync = need_sync &&
fs::last_write_time(getenv(KCONFIG_CONFIG)) > fs::last_write_time(getenv(KCONFIG_AUTOCONFIG));
if (need_sync)
res = conf_write_autoconf(1);
}
return res;
}