Espresso 0.0.1b

This commit is contained in:
2025-06-27 14:48:06 -05:00
parent fca025a9bf
commit c336584114
39 changed files with 2676 additions and 936 deletions

296
scripts/kconfig.c Normal file
View File

@ -0,0 +1,296 @@
#include <ncurses.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
typedef struct {
const char* name;
int enabled;
} option_t;
typedef struct {
const char* title;
option_t* options;
size_t num_options;
} menu_t;
void show_menu(menu_t* menu);
void load_config(menu_t* menus, size_t menu_count);
void save_config(menu_t* menus, size_t menu_count);
#define SIZE(x) (sizeof(x) / sizeof(option_t))
#define NUM_MENUS (sizeof(all_menus) / sizeof(menu_t))
#define KEY_ESCAPE 27
option_t general_opts[] = {
{ "Enable Debugging Messages", 1 },
{ "Enable Filesystems", 0 },
};
option_t drivers_opts[] = {
{ "Enable IDE", 1 },
{ "Enable USB", 0 },
{ "Enable Network", 0 },
};
menu_t all_menus[] = {
{ "General Settings", general_opts, SIZE(general_opts) },
{ "Device Drivers", drivers_opts, SIZE(drivers_opts) },
};
bool current_config_saved = false;
void strfix(char *str)
{
for (size_t i = 0; str[i] != '\0'; ++i)
{
if (isspace((unsigned char)str[i]))
{
str[i] = '_';
}
else
{
str[i] = toupper((unsigned char)str[i]);
}
}
}
void load_config(menu_t* menus, size_t menu_count)
{
FILE* f = fopen(".config", "r");
if (!f)
{
return;
}
char line[128];
while (fgets(line, sizeof(line), f))
{
char* newline = strchr(line, '\n');
if (newline)
{
*newline = 0;
}
for (size_t m = 0; m < menu_count; m++)
{
for (size_t i = 0; i < menus[m].num_options; i++)
{
if (strncmp(line, menus[m].options[i].name, strlen(menus[m].options[i].name)) == 0)
{
if (strstr(line, "=y"))
{
menus[m].options[i].enabled = 1;
}
else
{
menus[m].options[i].enabled = 0;
}
}
}
}
}
fclose(f);
}
const char* cc = "\n\nstatic inline kconf_t get_kconfig(void)\n"
"{\n"
"\tkconf_t kc = { false, false, false, false, false };\n\n"
"#ifdef ENABLE_DEBUGGING_MESSAGES\n"
"\tkc.enable_debug = true;\n"
"#endif\n"
"#ifdef ENABLE_FILESYSTEMS\n"
"\tkc.enable_fs = true;\n"
"#endif\n"
"#ifdef ENABLE_IDE\n"
"\tkc.enable_ide = true;\n"
"#endif\n"
"#ifdef ENABLE_USB\n"
"\tkc.enable_usb = true;\n"
"#endif\n"
"#ifdef ENABLE_NETWORK\n"
"\tkc.enable_networking = true;\n"
"#endif\n\n"
"\treturn kc;\n"
"}\n\n"
"#ifdef __cplusplus\n"
"}\n"
"#endif\n";
/* Save current configuration options to Makefile and/or kconfig.h */
void save_config(menu_t* menus, size_t menu_count)
{
FILE* kconff = fopen("../include/kernel/kconfig.h", "w");
if (!kconff)
{
return;
}
const char* hg = "#ifndef _KCONFIG_H\n#define _KCONFIG_H\n\n#include <types.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n";
fprintf(kconff, hg);
for (size_t m = 0; m < menu_count; m++)
{
for (size_t i = 0; i < menus[m].num_options; i++)
{
char buffer[128];
strncpy(buffer, menus[m].options[i].name, sizeof(buffer));
buffer[sizeof(buffer)-1] = '\0';
strfix(buffer);
if (menus[m].options[i].enabled == 0)
{
fprintf(kconff, "//");
}
fprintf(kconff, "#define %s\n", buffer, menus[m].options[i].enabled);
}
}
fprintf(kconff, cc);
fprintf(kconff, "\n#endif\n");
fclose(kconff);
current_config_saved = true;
}
menu_t* create_menu(const char* title)
{
menu_t* menu = malloc(sizeof(menu_t));
menu->title = strdup(title);
menu->options = NULL;
menu->num_options = 0;
return menu;
}
void add_option(menu_t* menu, const char* name, int default_value)
{
menu->options = realloc(menu->options, sizeof(option_t) * (menu->num_options + 1));
menu->options[menu->num_options].name = strdup(name);
menu->options[menu->num_options].enabled = default_value;
menu->num_options++;
}
/* Display a single submenu */
void show_menu(menu_t* menu)
{
int selected = 0;
while (1)
{
clear();
mvprintw(0, 0, "%s (SPACE=toggle, (left arrow key or esc)=back, S=save)", menu->title);
for (size_t i = 0; i < menu->num_options; i++)
{
if ((int)i == selected)
{
attron(A_REVERSE);
}
mvprintw(i + 2, 2, "[%c] %s", menu->options[i].enabled ? 'X' : ' ', menu->options[i].name);
if ((int)i == selected)
{
attroff(A_REVERSE);
}
}
int ch = getch();
if (ch == KEY_UP && selected > 0)
{
selected--;
}
else if (ch == KEY_DOWN && selected < (int)menu->num_options - 1)
{
selected++;
}
else if (ch == ' ')
{
menu->options[selected].enabled = !menu->options[selected].enabled;
current_config_saved = false;
}
else if (ch == 's' || ch == 'S')
{
save_config(all_menus, NUM_MENUS);
mvprintw(menu->num_options + 3, 2, "Saved.");
refresh();
getch();
}
else if (ch == KEY_LEFT || ch == KEY_ESCAPE || ch == 'q' || ch == 'Q')
{
break;
}
}
}
/* Main menu with submenu navigation */
int main(void)
{
initscr();
noecho();
cbreak();
keypad(stdscr, TRUE);
set_escdelay(25); /* wait only 25ms for escape sequences */
/*load_config(all_menus, NUM_MENUS);*/
int selected = 0;
while (1)
{
clear();
mvprintw(0, 0, "Kernel Configuration (ENTER=submenu, S=save, Q=quit)");
for (size_t i = 0; i < NUM_MENUS; i++)
{
if ((int)i == selected)
{
attron(A_REVERSE);
}
mvprintw(i + 2, 2, "> %s", all_menus[i].title);
if ((int)i == selected)
{
attroff(A_REVERSE);
}
}
int ch = getch();
if (ch == KEY_UP && selected > 0)
{
selected--;
}
else if (ch == KEY_DOWN && selected < (int)NUM_MENUS - 1)
{
selected++;
}
else if (ch == '\n')
{
show_menu(&all_menus[selected]);
}
else if (ch == 's' || ch == 'S')
{
save_config(all_menus, NUM_MENUS);
mvprintw(NUM_MENUS + 3, 2, "Saved.");
refresh();
getch();
}
else if (ch == 'q' || ch == 'Q')
{
break;
}
}
endwin();
return 0;
}