improve the command-line interface.
This commit is contained in:
parent
4ea54f2d0a
commit
dfe653fc49
5 changed files with 285 additions and 136 deletions
36
ChangeLog
36
ChangeLog
|
@ -1,3 +1,39 @@
|
|||
1999-09-17 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||
|
||||
Killing, yanking and manipulating the history are supported.
|
||||
|
||||
* stage2/shared.h (cur_cmdline): Removed.
|
||||
(MAX_CMDLINE): Moved near the beginning of the file.
|
||||
(NEW_HEAPSIZE): Likewise.
|
||||
(CMDLINE_BUFLEN): Set to MAX_CMDLINE.
|
||||
(KILL_BUF): New macro.
|
||||
(KILL_BUFLEN): Likewise.
|
||||
(HISTORY_BUF): Likewise.
|
||||
(HISTORY_SIZE): Likewise.
|
||||
(HISTORY_BUFLEN): Likewise.
|
||||
(MENU_BUF): Set to HISTORY_BUF + HISTORY_BUFLEN.
|
||||
(MENU_BUFLEN): Set to 0x8000 + PASSWORD_BUF - HISTORY_BUF.
|
||||
(strcpy): New macro.
|
||||
(grub_strcpy): Delared.
|
||||
* stage2/boot.c (cur_cmdline): Removed.
|
||||
* stage2/char_io.c [!STAGE1_5] (grub_strcpy): New function.
|
||||
[!STAGE1_5] (get_history): Likewise.
|
||||
[!STAGE1_5] (add_history): Likewise.
|
||||
[!STAGE1_5] (get_cmdline): Use BUF instead of CMDLINE for the
|
||||
working buffer for the command-line.
|
||||
A new function cl_insert is used to insert a string to the
|
||||
command-line.
|
||||
In the case where C-u or C-k is pressed, copy the string being
|
||||
deleted to KILL.
|
||||
If C-y is pressed, insert KILL to the command-line.
|
||||
If C-p is pressed, fetch the previous command from the history
|
||||
list HISTORY, and if C-n is pressed, fetch the next command from
|
||||
it.
|
||||
If LPOS is less than LLEN, add CMDLINE into the history list.
|
||||
If C is equal to KEY_UP, set C to 16, and if C is equal to
|
||||
KEY_DOWN, set C to 14.
|
||||
[!STAGE1_5] (num_history): New variable.
|
||||
|
||||
1999-09-15 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||
|
||||
* stage2/size_test: Do not check for the size of Stage 2.
|
||||
|
|
2
NEWS
2
NEWS
|
@ -24,6 +24,8 @@ New in 0.5.93:
|
|||
the second floppy drive.
|
||||
* Integrated the netboot support in the Dresden version of GRUB.
|
||||
* FreeBSD support in the grub shell is improved.
|
||||
* Killing (C-u and C-k), yanking (C-y) and manipulating the history
|
||||
(C-p and C-n) are supported.
|
||||
|
||||
New in 0.5.92 - 1999-07-26:
|
||||
* Bug fixes (i.e. Stage 1.5 can work fine again).
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "imgact_aout.h"
|
||||
#include "i386-elf.h"
|
||||
|
||||
char *cur_cmdline;
|
||||
static int cur_addr;
|
||||
entry_func entry_addr;
|
||||
static struct mod_list mll[99];
|
||||
|
|
354
stage2/char_io.c
354
stage2/char_io.c
|
@ -184,6 +184,31 @@ init_page (void)
|
|||
version_string, mbi.mem_lower, mbi.mem_upper);
|
||||
}
|
||||
|
||||
/* The number of the history entries. */
|
||||
static int num_history = 0;
|
||||
|
||||
/* Get the NOth history. If NO is less than zero or greater than or
|
||||
equal to NUM_HISTORY, return NULL. Otherwise return a valid string. */
|
||||
static char *
|
||||
get_history (int no)
|
||||
{
|
||||
if (no < 0 || no >= num_history)
|
||||
return 0;
|
||||
|
||||
return (char *) HISTORY_BUF + MAX_CMDLINE * no;
|
||||
}
|
||||
|
||||
/* Add CMDLINE to the history buffer. */
|
||||
static void
|
||||
add_history (const char *cmdline, int no)
|
||||
{
|
||||
grub_memmove ((char *) HISTORY_BUF + MAX_CMDLINE * (no + 1),
|
||||
(char *) HISTORY_BUF + MAX_CMDLINE * no,
|
||||
MAX_CMDLINE * (num_history - no));
|
||||
grub_strcpy ((char *) HISTORY_BUF + MAX_CMDLINE * no, cmdline);
|
||||
if (num_history < HISTORY_SIZE)
|
||||
num_history++;
|
||||
}
|
||||
|
||||
/* Don't use this with a MAXLEN greater than 1600 or so! The problem
|
||||
is that GET_CMDLINE depends on the everything fitting on the screen
|
||||
|
@ -198,69 +223,103 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
int echo_char, int completion)
|
||||
{
|
||||
int ystart, yend, xend, lpos, c;
|
||||
/* The length of PROMPT. */
|
||||
int plen = 0;
|
||||
/* The length of the command-line. */
|
||||
int llen = 0;
|
||||
|
||||
/* The index for the history. */
|
||||
int history = -1;
|
||||
/* The working buffer for the command-line. */
|
||||
char *buf = (char *) CMDLINE_BUF;
|
||||
/* The kill buffer. */
|
||||
char *kill = (char *) KILL_BUF;
|
||||
|
||||
/* nested function definition for code simplicity */
|
||||
static void cl_print (char *str, int echo_char)
|
||||
{
|
||||
while (*str != 0)
|
||||
{
|
||||
putchar (echo_char ? echo_char : *str);
|
||||
str++;
|
||||
if (++xend > 78)
|
||||
{
|
||||
xend = 0;
|
||||
putchar (' ');
|
||||
if (yend == (getxy () & 0xff))
|
||||
ystart--;
|
||||
else
|
||||
yend++;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
while (*str != 0)
|
||||
{
|
||||
putchar (echo_char ? echo_char : *str);
|
||||
str++;
|
||||
if (++xend > 78)
|
||||
{
|
||||
xend = 0;
|
||||
putchar (' ');
|
||||
if (yend == (getxy () & 0xff))
|
||||
ystart--;
|
||||
else
|
||||
yend++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* nested function definition for code simplicity */
|
||||
static void cl_setcpos (void)
|
||||
{
|
||||
yend = ((lpos + plen) / 79) + ystart;
|
||||
xend = ((lpos + plen) % 79);
|
||||
gotoxy (xend, yend);
|
||||
}
|
||||
|
||||
{
|
||||
yend = ((lpos + plen) / 79) + ystart;
|
||||
xend = ((lpos + plen) % 79);
|
||||
gotoxy (xend, yend);
|
||||
}
|
||||
|
||||
/* nested function definition for initial command-line printing */
|
||||
static void cl_init ()
|
||||
{
|
||||
/* distinguish us from other lines and error messages! */
|
||||
putchar ('\n');
|
||||
|
||||
/* print full line and set position here */
|
||||
ystart = (getxy () & 0xff);
|
||||
yend = ystart;
|
||||
xend = 0;
|
||||
cl_print (prompt, 0);
|
||||
cl_print (cmdline, echo_char);
|
||||
cl_setcpos ();
|
||||
}
|
||||
|
||||
{
|
||||
/* distinguish us from other lines and error messages! */
|
||||
putchar ('\n');
|
||||
|
||||
/* print full line and set position here */
|
||||
ystart = (getxy () & 0xff);
|
||||
yend = ystart;
|
||||
xend = 0;
|
||||
cl_print (prompt, 0);
|
||||
cl_print (buf, echo_char);
|
||||
cl_setcpos ();
|
||||
}
|
||||
|
||||
/* nested function definition for erasing to the end of the line */
|
||||
static void cl_kill_to_end ()
|
||||
{
|
||||
int i;
|
||||
cmdline[lpos] = 0;
|
||||
for (i = lpos; i <= llen; i++)
|
||||
{
|
||||
if (i && ((i + plen) % 79) == 0)
|
||||
{
|
||||
int i;
|
||||
buf[lpos] = 0;
|
||||
for (i = lpos; i <= llen; i++)
|
||||
{
|
||||
if (i && ((i + plen) % 79) == 0)
|
||||
putchar (' ');
|
||||
putchar (' ');
|
||||
putchar (' ');
|
||||
}
|
||||
llen = lpos;
|
||||
cl_setcpos ();
|
||||
}
|
||||
}
|
||||
llen = lpos;
|
||||
cl_setcpos ();
|
||||
}
|
||||
|
||||
static void cl_insert (const char *str)
|
||||
{
|
||||
int l = grub_strlen (str);
|
||||
|
||||
if (llen + l < maxlen)
|
||||
{
|
||||
if (lpos == llen)
|
||||
{
|
||||
grub_memmove (buf + lpos, str, l + 1);
|
||||
cl_print (buf + lpos, echo_char);
|
||||
lpos += l;
|
||||
cl_setcpos ();
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_memmove (buf + lpos + l, buf + lpos, llen - lpos + 1);
|
||||
grub_memmove (buf + lpos, str, l);
|
||||
cl_setcpos ();
|
||||
cl_print (buf + lpos, echo_char);
|
||||
lpos += l;
|
||||
cl_setcpos ();
|
||||
}
|
||||
llen += l;
|
||||
}
|
||||
}
|
||||
|
||||
plen = grub_strlen (prompt);
|
||||
llen = grub_strlen (cmdline);
|
||||
|
||||
while (prompt[plen])
|
||||
plen++;
|
||||
while (cmdline[llen])
|
||||
llen++;
|
||||
if (maxlen > MAX_CMDLINE)
|
||||
{
|
||||
maxlen = MAX_CMDLINE;
|
||||
|
@ -271,9 +330,11 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
}
|
||||
}
|
||||
lpos = llen;
|
||||
|
||||
grub_strcpy (buf, cmdline);
|
||||
*kill = 0;
|
||||
|
||||
cl_init ();
|
||||
|
||||
|
||||
while (ASCII_CHAR (c = getkey ()) != '\n' && ASCII_CHAR (c) != '\r')
|
||||
{
|
||||
switch (c)
|
||||
|
@ -284,6 +345,12 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
case KEY_RIGHT:
|
||||
c = 6;
|
||||
break;
|
||||
case KEY_UP:
|
||||
c = 16;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
c = 14;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
c = 1;
|
||||
break;
|
||||
|
@ -296,11 +363,10 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
case KEY_BACKSPACE:
|
||||
c = 8;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
c = ASCII_CHAR (c);
|
||||
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 27: /* ESC immediately return 1 */
|
||||
|
@ -311,14 +377,14 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
int i, j = 0, llen_old = llen;
|
||||
|
||||
/* Find the first word. */
|
||||
while (cmdline[j] == ' ')
|
||||
while (buf[j] == ' ')
|
||||
j++;
|
||||
while (cmdline[j] && cmdline[j] != '=' && cmdline[j] != ' ')
|
||||
while (buf[j] && buf[j] != '=' && buf[j] != ' ')
|
||||
j++;
|
||||
|
||||
/* Since the command line cannot have a '\n', we're OK to
|
||||
use C. */
|
||||
c = cmdline[lpos];
|
||||
c = buf[lpos];
|
||||
|
||||
cl_kill_to_end ();
|
||||
|
||||
|
@ -330,21 +396,21 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
|
||||
if (lpos > j)
|
||||
{
|
||||
for (i = lpos; i > 0 && cmdline[i - 1] != ' '; i--);
|
||||
for (i = lpos; i > 0 && buf[i - 1] != ' '; i--);
|
||||
if (i <= j)
|
||||
i = j + 1;
|
||||
/* print possible completions */
|
||||
print_completions (cmdline + i);
|
||||
print_completions (buf + i);
|
||||
/* if somebody in print_completions has added something,
|
||||
account for that */
|
||||
while (cmdline[lpos])
|
||||
while (buf[lpos])
|
||||
lpos++, llen_old++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Print the command list. */
|
||||
struct builtin **builtin;
|
||||
|
||||
|
||||
for (builtin = builtin_table; *builtin != 0; builtin++)
|
||||
{
|
||||
/* Do not print the name if it cannot be run in
|
||||
|
@ -357,7 +423,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
}
|
||||
|
||||
/* restore command-line */
|
||||
cmdline[lpos] = c;
|
||||
buf[lpos] = c;
|
||||
llen = llen_old;
|
||||
cl_init ();
|
||||
}
|
||||
|
@ -373,7 +439,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
case 6: /* C-f forward one character */
|
||||
if (lpos < llen)
|
||||
{
|
||||
lpos ++;
|
||||
lpos++;
|
||||
cl_setcpos ();
|
||||
}
|
||||
break;
|
||||
|
@ -387,7 +453,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
case 4: /* C-d delete character under cursor */
|
||||
if (lpos == llen)
|
||||
break;
|
||||
lpos ++;
|
||||
lpos++;
|
||||
/* fallthrough is on purpose! */
|
||||
case 8: /* C-h backspace */
|
||||
#ifdef GRUB_UTIL
|
||||
|
@ -396,8 +462,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
if (lpos > 0)
|
||||
{
|
||||
int i;
|
||||
for (i = lpos - 1; i < llen; i++)
|
||||
cmdline[i] = cmdline[i + 1];
|
||||
grub_memmove (buf + lpos - 1, buf + lpos, llen - lpos + 1);
|
||||
i = lpos;
|
||||
lpos = llen - 1;
|
||||
cl_setcpos ();
|
||||
|
@ -407,7 +472,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
cl_setcpos ();
|
||||
if (lpos != llen)
|
||||
{
|
||||
cl_print (cmdline + lpos, echo_char);
|
||||
cl_print (buf + lpos, echo_char);
|
||||
cl_setcpos ();
|
||||
}
|
||||
}
|
||||
|
@ -415,78 +480,108 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
case 21: /* C-u kill to beginning of line */
|
||||
if (lpos == 0)
|
||||
break;
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (llen - lpos); i++)
|
||||
cmdline[i] = cmdline[lpos + i];
|
||||
}
|
||||
/* Copy the string being deleted to KILL. */
|
||||
grub_memmove (kill, buf, lpos);
|
||||
kill[lpos] = 0;
|
||||
grub_memmove (buf, buf + lpos, llen - lpos + 1);
|
||||
lpos = llen - lpos;
|
||||
cl_setcpos ();
|
||||
/* fallthrough on purpose! */
|
||||
cl_kill_to_end ();
|
||||
lpos = 0;
|
||||
cl_setcpos ();
|
||||
cl_print (buf, echo_char);
|
||||
cl_setcpos ();
|
||||
break;
|
||||
case 11: /* C-k kill to end of line */
|
||||
if (lpos < llen)
|
||||
{
|
||||
cl_kill_to_end ();
|
||||
if (c == 21)
|
||||
{
|
||||
lpos = 0;
|
||||
cl_setcpos ();
|
||||
cl_print (cmdline, echo_char);
|
||||
cl_setcpos ();
|
||||
}
|
||||
}
|
||||
if (lpos == llen)
|
||||
break;
|
||||
/* Copy the string being deleted to KILL. */
|
||||
grub_memmove (kill, buf + lpos, llen - lpos + 1);
|
||||
cl_kill_to_end ();
|
||||
break;
|
||||
case 25: /* C-y yank the kill buffer */
|
||||
cl_insert (kill);
|
||||
break;
|
||||
case 16: /* C-p fetch the previous command */
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (history < 0)
|
||||
/* Save the working buffer. */
|
||||
grub_strcpy (cmdline, buf);
|
||||
else if (grub_strcmp (get_history (history), buf) != 0)
|
||||
/* If BUF is modified, add it into the history list. */
|
||||
add_history (buf, history);
|
||||
|
||||
history++;
|
||||
p = get_history (history);
|
||||
if (! p)
|
||||
{
|
||||
history--;
|
||||
break;
|
||||
}
|
||||
|
||||
lpos = 0;
|
||||
cl_setcpos ();
|
||||
cl_kill_to_end ();
|
||||
grub_strcpy (buf, p);
|
||||
llen = grub_strlen (buf);
|
||||
lpos = llen;
|
||||
cl_print (buf, 0);
|
||||
cl_setcpos ();
|
||||
}
|
||||
break;
|
||||
case 14: /* C-n fetch the next command */
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (history < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (grub_strcmp (get_history (history), buf) != 0)
|
||||
/* If BUF is modified, add it into the history list. */
|
||||
add_history (buf, history);
|
||||
|
||||
history--;
|
||||
p = get_history (history);
|
||||
if (! p)
|
||||
p = cmdline;
|
||||
|
||||
lpos = 0;
|
||||
cl_setcpos ();
|
||||
cl_kill_to_end ();
|
||||
grub_strcpy (buf, p);
|
||||
llen = grub_strlen (buf);
|
||||
lpos = llen;
|
||||
cl_print (buf, 0);
|
||||
cl_setcpos ();
|
||||
}
|
||||
break;
|
||||
default: /* insert printable character into line */
|
||||
if (llen < (maxlen - 1) && c >= ' ' && c <= '~')
|
||||
if (c >= ' ' && c <= '~')
|
||||
{
|
||||
if (lpos == llen)
|
||||
{
|
||||
cmdline[lpos] = c;
|
||||
cmdline[lpos + 1] = 0;
|
||||
cl_print (cmdline + lpos, echo_char);
|
||||
lpos ++;
|
||||
cl_setcpos ();
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i = llen; i >= lpos; i--)
|
||||
cmdline[i + 1] = cmdline[i];
|
||||
cmdline[lpos] = c;
|
||||
cl_setcpos ();
|
||||
cl_print (cmdline + lpos, echo_char);
|
||||
lpos++;
|
||||
cl_setcpos ();
|
||||
}
|
||||
llen++;
|
||||
char str[2];
|
||||
|
||||
str[0] = c;
|
||||
str[1] = 0;
|
||||
cl_insert (str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* goto part after line here */
|
||||
yend = ((llen + plen) / 79) + ystart;
|
||||
putchar ('\n');
|
||||
gotoxy (0, getxy () & 0xff);
|
||||
|
||||
|
||||
/* remove leading spaces */
|
||||
/* use c and lpos as indexes now */
|
||||
for (lpos = 0; cmdline[lpos] == ' '; lpos++);
|
||||
|
||||
if (lpos != 0)
|
||||
{
|
||||
c = 0;
|
||||
do
|
||||
{
|
||||
cmdline[c] = cmdline[lpos];
|
||||
c++;
|
||||
lpos++;
|
||||
}
|
||||
while (cmdline[lpos]);
|
||||
|
||||
/* Zero-terminate the string. */
|
||||
cmdline[c] = 0;
|
||||
}
|
||||
|
||||
for (lpos = 0; buf[lpos] == ' '; lpos++);
|
||||
|
||||
grub_memmove (cmdline, buf + lpos, llen - lpos + 1);
|
||||
if (lpos < llen)
|
||||
add_history (cmdline, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -753,4 +848,11 @@ grub_memset (void *start, int c, int len)
|
|||
|
||||
return errnum ? NULL : start;
|
||||
}
|
||||
|
||||
char *
|
||||
grub_strcpy (char *dest, const char *src)
|
||||
{
|
||||
grub_memmove (dest, src, grub_strlen (src) + 1);
|
||||
return dest;
|
||||
}
|
||||
#endif /* ! STAGE1_5 */
|
||||
|
|
|
@ -48,6 +48,11 @@ extern char *grub_scratch_mem;
|
|||
|
||||
#define MAXINT 0x7FFFFFFF
|
||||
|
||||
/* Maximum command line size. Before you blindly increase this value,
|
||||
see the comment in char_io.c (get_cmdline). */
|
||||
#define MAX_CMDLINE 1600
|
||||
#define NEW_HEAPSIZE 1500
|
||||
|
||||
/* 512-byte scratch area */
|
||||
#define SCRATCHADDR RAW_ADDR (0x77e00)
|
||||
#define SCRATCHSEG RAW_SEG (0x77e0)
|
||||
|
@ -89,12 +94,20 @@ extern char *grub_scratch_mem;
|
|||
|
||||
/* The buffer for the command-line. */
|
||||
#define CMDLINE_BUF (PASSWORD_BUF + PASSWORD_BUFLEN)
|
||||
/* Make sure that this is larger than NEW_HEAPSIZE defined below. */
|
||||
#define CMDLINE_BUFLEN 0x600
|
||||
#define CMDLINE_BUFLEN MAX_CMDLINE
|
||||
|
||||
/* The kill buffer for the command-line. */
|
||||
#define KILL_BUF (CMDLINE_BUF + CMDLINE_BUFLEN)
|
||||
#define KILL_BUFLEN MAX_CMDLINE
|
||||
|
||||
/* The history buffer for the command-line. */
|
||||
#define HISTORY_BUF (KILL_BUF + KILL_BUFLEN)
|
||||
#define HISTORY_SIZE 5
|
||||
#define HISTORY_BUFLEN (MAX_CMDLINE * HISTORY_SIZE)
|
||||
|
||||
/* The buffer for the menu entries. */
|
||||
#define MENU_BUF (CMDLINE_BUF + CMDLINE_BUFLEN)
|
||||
#define MENU_BUFLEN (0x8000 + PASSWORD_BUF - MENU_BUF)
|
||||
#define MENU_BUF (HISTORY_BUF + HISTORY_BUFLEN)
|
||||
#define MENU_BUFLEN (0x8000 + PASSWORD_BUF - HISTORY_BUF)
|
||||
|
||||
/*
|
||||
* Linux setup parameters
|
||||
|
@ -272,6 +285,7 @@ extern char *grub_scratch_mem;
|
|||
#define strcmp grub_strcmp
|
||||
#define tolower grub_tolower
|
||||
#define strlen grub_strlen
|
||||
#define strcpy grub_strcpy
|
||||
#endif /* WITHOUT_LIBC_STUBS */
|
||||
|
||||
|
||||
|
@ -448,11 +462,6 @@ extern char *err_list[];
|
|||
typedef void (*entry_func) (int, int, int, int, int, int)
|
||||
__attribute__ ((noreturn));
|
||||
|
||||
/* Maximum command line size. Before you blindly increase this value,
|
||||
see the comment in char_io.c (get_cmdline). */
|
||||
#define MAX_CMDLINE 1600
|
||||
#define NEW_HEAPSIZE 1500
|
||||
extern char *cur_cmdline;
|
||||
extern entry_func entry_addr;
|
||||
|
||||
/* Enter the stage1.5/stage2 C code after the stack is set up. */
|
||||
|
@ -598,6 +607,7 @@ char *grub_strstr (const char *s1, const char *s2);
|
|||
int grub_memcmp (const char *s1, const char *s2, int n);
|
||||
int grub_strcmp (const char *s1, const char *s2);
|
||||
int grub_strlen (const char *str);
|
||||
char *grub_strcpy (char *dest, const char *src);
|
||||
|
||||
/* misc */
|
||||
void init_page (void);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue