Add command line interface

This commit is contained in:
Laurent Vivier 2008-09-02 19:40:35 +00:00
parent bcd309d505
commit 5de80e9c48
4 changed files with 257 additions and 4 deletions

View File

@ -33,13 +33,13 @@ LIBS = $(OPT_LIBS) \
LS = ls
AWK = awk
HEADERS = arch.h bank.h bootenv.h bootinfo.h bootx.h console.h driver.h enter_kernel030.h enter_kernel040.h enter_kernel.h enter_kernelnoMMU.h switch_to_PPC.h head.h keyboard.h load.h misc.h MMU030.h MMU040.h serial.h vga.h config.h copymem.i
HEADERS = arch.h bank.h bootenv.h bootinfo.h bootx.h console.h driver.h enter_kernel030.h enter_kernel040.h enter_kernel.h enter_kernelnoMMU.h switch_to_PPC.h head.h keyboard.h load.h misc.h MMU030.h MMU040.h serial.h vga.h config.h copymem.i cli.h
SOURCES = head.S main.c console.c \
font_8x16.c \
misc.c bank.c arch.c \
load.c serial.c vga.c driver.c \
enter_kernel.c config.c
enter_kernel.c config.c cli.c
SOURCES_CLI = keyboard.c

232
second/cli.c Normal file
View File

@ -0,0 +1,232 @@
/*
*
* (c) 2008 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libui.h>
#include "vga.h"
#include "console.h"
#include "arch.h"
#include "cli.h"
#define COMMAND_LINE_LENGTH 256
typedef int (*command_handler)(int argc, char **argv);
struct command_interface {
char *name;
command_handler handler;
char *help;
};
static struct command_interface command[];
static int get_command(char *name);
static int do_loop;
static int exit_handler(int argc, char **argv)
{
do_loop = 0;
return 0;
}
static int help_handler(int argc, char **argv)
{
int index;
if (argc != 2)
{
printf("help needs one parameter\n");
printf("Available commands are:\n");
for (index = 0; command[index].name; index++)
{
printf("%s", command[index].name);
if (command[index].help)
printf(" %s", command[index].help);
printf("\n");
}
return 1;
}
index = get_command(argv[1]);
if (index == -1)
{
printf("Unknown command: %s\n", argv[1]);
return 1;
}
if (command[index].help == NULL)
{
printf("No help available for %s\n", argv[1]);
return 2;
}
printf("%s\n", command[index].help);
return 0;
}
static int vga_handler(int argc, char **argv)
{
if (argc != 2)
{
printf("vga needs one parameter to set the display mode\n");
return 1;
}
vga_init(argv[1]);
return 0;
}
static int modem_handler(int argc, char **argv)
{
return 0;
}
static int printer_handler(int argc, char **argv)
{
return 0;
}
static int gestaltid_handler(int argc, char **argv)
{
if (argc != 2)
{
printf("gestaltID needs a parameter\n");
return 1;
}
machine_id = strtol(argv[1], NULL, 0);
printf("New gestalt ID is %ld\n", machine_id);
return 0;
}
#define COMMAND_NB 7
static struct command_interface command[COMMAND_NB];
#define NEW_COMMAND(a,b,c) \
do { \
if (i < COMMAND_NB) { \
command[i].name = a; \
command[i].handler = b; \
command[i].help = c; \
i++; \
} \
} while(0)
static void cli_init(void)
{
int i = 0;
/* because of GOT */
NEW_COMMAND("exit", exit_handler, "exit from interpreter");
NEW_COMMAND("help", help_handler, "give help of commands");
NEW_COMMAND("vga", vga_handler, "set display mode");
NEW_COMMAND("modem", modem_handler,
"set modem serial port configuation");
NEW_COMMAND("printer", printer_handler,
"set printer serial port configuration");
NEW_COMMAND("gestaltID", gestaltid_handler, "set machine gestalt ID");
NEW_COMMAND(NULL, NULL, NULL);
}
static int get_command(char *name)
{
int i;
for (i = 0; command[i].name; i++)
{
if (strcmp(name, command[i].name) == 0)
return i;
}
return -1;
}
static int skip_blank(char *line, int i)
{
while (line[i] == ' ' || line[i] == '\t')
i++;
return i;
}
static int skip_word(char *line, int i)
{
while (line[i] != ' ' && line[i] != '\t' && line[i])
i++;
return i;
}
static int split_line(char *line, char ***argv)
{
int i, j;
int argc;
char **words;
/* how many words ? */
argc = 0;
for (i = skip_blank(line, 0); line[i]; i = skip_blank(line, i))
{
i = skip_word(line, i);
argc++;
}
words = (char**)malloc(argc * sizeof(char*));
/* where are the words ? */
i = skip_blank(line, 0);
j = 0;
while(1)
{
words[j++] = line + i;
i = skip_word(line, i);
if (line[i] == 0)
break;
line[i++] = 0;
i = skip_blank(line, i);
}
*argv = words;
return argc;
}
void cli(void)
{
char line[COMMAND_LINE_LENGTH];
int argc;
char **argv;
int index;
do_loop = 1;
cli_init();
console_clear();
while(do_loop)
{
printf("emile> ");
memset(line, 0, COMMAND_LINE_LENGTH);
emile_edit(line, COMMAND_LINE_LENGTH);
printf("\n");
argc = split_line(line, &argv);
if (argc > 0)
{
index = get_command(argv[0]);
if (index == -1)
printf("Unknown command: %s\n", argv[0]);
else
{
command[index].handler(argc, argv);
free(argv);
}
}
}
console_clear();
}

7
second/cli.h Normal file
View File

@ -0,0 +1,7 @@
/*
*
* (c) 2008 Laurent Vivier <Laurent@lvivier.info>
*
*/
extern void cli(void);

View File

@ -16,6 +16,7 @@
#include "config.h"
#if defined(USE_CLI) && defined(__LINUX__)
#include "console.h"
#include "cli.h"
#endif
#include "arch.h"
#include "misc.h"
@ -28,12 +29,13 @@ extern int boot_unit;
#endif
#define MSG_STATE_0 console_set_cursor_position(win.l + win.h + 1, 1); \
printf(" Press 'b' or [RETURN] to boot or 'e' to edit\n");
printf(" Press 'b' or [RETURN] to boot or 'e' to edit\n"); \
printf(" Press 'c' to enter command line interpreter \n");
#define MSG_STATE_1 console_set_cursor_position(win.l + win.h + 1, 1); \
printf(" Press 'b' to boot, 'e' or [RETURN] to edit \n" \
" Press 'd' to delete, 'n' to create \n" \
" Press [ESC] to go back \n");
" Press 'c' to enter CLI or [ESC] to go back \n");
#define MSG_CLEAN console_set_cursor_position(win.l + win.h + 1, 1); \
printf(" \n" \
@ -341,6 +343,12 @@ int read_config(emile_l2_header_t* info, emile_config_t *econfig)
state = 1;
MSG_STATE_1
break;
case 'c':
cli();
console_set_cursor_position(1, len);
printf("%s\n", line);
MSG_STATE_0
break;
}
break;
case 1: /* select parameter */
@ -383,6 +391,12 @@ int read_config(emile_l2_header_t* info, emile_config_t *econfig)
MSG_CLEAN
state = 2;
break;
case 'c':
cli();
console_set_cursor_position(1, len);
printf("%s\n", line);
MSG_STATE_1
break;
}
break;
case 2: /* edit parameter */