mirror of https://github.com/l4ka/pistachio.git
285 lines
6.7 KiB
C++
285 lines
6.7 KiB
C++
/*********************************************************************
|
|
*
|
|
* Copyright (C) 2002-2004, Karlsruhe University
|
|
*
|
|
* File path: kdb/generic/input.cc
|
|
* Description: Various input functions
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* $Id: input.cc,v 1.14 2004/03/17 19:16:19 skoglund Exp $
|
|
*
|
|
********************************************************************/
|
|
#include <debug.h>
|
|
#include <kdb/input.h>
|
|
#include <kdb/kdb.h>
|
|
#include <kdb/console.h>
|
|
|
|
|
|
/**
|
|
* Read hex value from console
|
|
*
|
|
* @param prompt prompt
|
|
* @param defnum default value
|
|
* @param defstr default string
|
|
*
|
|
* Prompt for a hex value using PROMPT and return the typed in value.
|
|
* If PROMPT is NULL, do not display it. If user just presses return,
|
|
* DEFNUM will be displayed and returned. If DEFSTR is non-nil, it
|
|
* will be displayed as a default value instead of DEFNUM.
|
|
*
|
|
* @returns value read from console
|
|
*/
|
|
word_t SECTION(SEC_KDEBUG) get_hex (const char * prompt, const word_t defnum, const char * defstr)
|
|
{
|
|
word_t num = 0;
|
|
word_t len = 0;
|
|
char c, r;
|
|
|
|
if (prompt)
|
|
{
|
|
if (defstr)
|
|
printf ("%s [%s]: ", prompt, defstr);
|
|
else
|
|
printf ("%s [0x%lx]: ", prompt, defnum);
|
|
}
|
|
|
|
while (len < (sizeof (word_t) * 2))
|
|
{
|
|
switch (r = c = getc ())
|
|
{
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
case '5': case '6': case '7': case '8': case '9':
|
|
num *= 16;
|
|
num += c - '0';
|
|
putc (r);
|
|
len++;
|
|
break;
|
|
|
|
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
|
c += 'a' - 'A';
|
|
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
|
num *= 16;
|
|
num += c - 'a' + 10;
|
|
putc (r);
|
|
len++;
|
|
break;
|
|
|
|
case 'x': case 'X':
|
|
// Allow "0x" prefix
|
|
if (len == 1 && num == 0)
|
|
{
|
|
putc (r);
|
|
len--;
|
|
}
|
|
break;
|
|
|
|
case '\b':
|
|
// Backspace
|
|
if (len > 0)
|
|
{
|
|
printf ("\b \b");
|
|
num /= 16;
|
|
len--;
|
|
}
|
|
break;
|
|
|
|
case KEY_RETURN:
|
|
if (len == 0)
|
|
{
|
|
// Use default value
|
|
if (defstr)
|
|
printf ("%s\n", defstr);
|
|
else
|
|
printf ("%lx\n", defnum);
|
|
return defnum;
|
|
}
|
|
len = sizeof (word_t) * 2;
|
|
break;
|
|
|
|
case '\e':
|
|
putc ('\n');
|
|
return ABORT_MAGIC;
|
|
}
|
|
}
|
|
|
|
putc ('\n');
|
|
return num;
|
|
}
|
|
|
|
|
|
/**
|
|
* Read decimal value from console
|
|
*
|
|
* @param prompt prompt
|
|
* @param defnum default value
|
|
* @param defstr default string
|
|
*
|
|
* Prompt for a decimal value using PROMPT and return the typed in value.
|
|
* If PROMPT is NULL, do not display it. If user just presses return,
|
|
* DEFNUM will be displayed and returned. If DEFSTR is non-nil, it
|
|
* will be displayed as a default value instead of DEFNUM.
|
|
*
|
|
* @returns value read from console
|
|
*/
|
|
word_t SECTION(SEC_KDEBUG) get_dec (const char * prompt, const word_t defnum, const char * defstr)
|
|
{
|
|
word_t num = 0;
|
|
int len = 0;
|
|
char c;
|
|
|
|
if (prompt)
|
|
{
|
|
if (defstr)
|
|
printf ("%s [%s]: ", prompt, defstr);
|
|
else
|
|
printf ("%s [%d]: ", prompt, defnum);
|
|
}
|
|
|
|
for (;;)
|
|
{
|
|
switch (c = getc ())
|
|
{
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
case '5': case '6': case '7': case '8': case '9':
|
|
num *= 10;
|
|
num += c - '0';
|
|
putc (c);
|
|
len++;
|
|
break;
|
|
|
|
case '\b':
|
|
// Backspace
|
|
if (len > 0)
|
|
{
|
|
printf ("\b \b");
|
|
num /= 10;
|
|
len--;
|
|
}
|
|
break;
|
|
|
|
case KEY_RETURN:
|
|
if (len == 0)
|
|
{
|
|
// Use default value
|
|
if (defstr)
|
|
printf ("%s\n", defstr);
|
|
else
|
|
printf ("%d\n", defnum);
|
|
return defnum;
|
|
}
|
|
putc ('\n');
|
|
return num;
|
|
|
|
case '\e':
|
|
putc ('\n');
|
|
return ABORT_MAGIC;
|
|
}
|
|
}
|
|
|
|
/* NOTREACHED */
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
static char * get_key_string (char key, const char * choices);
|
|
|
|
/**
|
|
* Prompt for a choice
|
|
*
|
|
* @param prompt prompt
|
|
* @param choices string of choices separated by '/'
|
|
* @param def default choice
|
|
*
|
|
* Prompt for a choice using PROMPT and return the character
|
|
* associated by the choice. The choices string consist of choices
|
|
* separated by the '/' character. An uppercase letter in the choice
|
|
* string indicates the key to be pressed for selecting the choice. A
|
|
* choice string with a single character also indicates the
|
|
* appropriate key for selecting the choice. The function does not
|
|
* return until user has selected a valid choice. Be absolutely quiet
|
|
* if PROMPT is NULL.
|
|
*
|
|
* @returns the character associated with the choice made
|
|
*/
|
|
char SECTION(SEC_KDEBUG) get_choice (const char * prompt, const char * choices, char def)
|
|
{
|
|
char *p, c;
|
|
|
|
if (prompt)
|
|
{
|
|
printf ("%s (%s)", prompt, choices);
|
|
|
|
if ((p = get_key_string (def, choices)))
|
|
{
|
|
printf (" [");
|
|
for (; *p != '/' && *p != 0; p++)
|
|
putc (*p >= 'A' && *p <= 'Z' ? (*p + ('a'-'A')) : *p);
|
|
putc (']');
|
|
}
|
|
|
|
printf (": ");
|
|
}
|
|
|
|
for (;;)
|
|
{
|
|
c = getc ();
|
|
p = get_key_string (c == KEY_RETURN ? def : c, choices);
|
|
for (; p && *p != '/' && *p != 0; p++)
|
|
if (prompt)
|
|
putc (*p >= 'A' && *p <= 'Z' ? (*p + ('a'-'A')) : *p);
|
|
if (p || c == KEY_RETURN)
|
|
break;
|
|
}
|
|
|
|
if (prompt)
|
|
putc ('\n');
|
|
|
|
return (c == KEY_RETURN) ? def : c;
|
|
}
|
|
|
|
static char SECTION(SEC_KDEBUG) * get_key_string (char key, const char * choices)
|
|
{
|
|
const char * p;
|
|
|
|
if (key == 0)
|
|
return NULL;
|
|
|
|
for (p = choices; *p; p++)
|
|
{
|
|
if ((*p >= 'A' && *p <= 'Z') && (*p + ('a'-'A')) == key)
|
|
break;
|
|
if ((p == choices || p[-1] == '/') && (p[1] == 0 || p[1] == '/') &&
|
|
(*p == key))
|
|
break;
|
|
}
|
|
|
|
if (*p == 0)
|
|
return NULL;
|
|
|
|
while (p > choices && p[-1] != '/')
|
|
p--;
|
|
|
|
return (char *) p;
|
|
}
|