Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 600 → Rev 601

/kernel/trunk/generic/include/symtab.h
41,6 → 41,7
extern char * get_symtab_entry(__native addr);
extern __address get_symbol_addr(const char *name);
extern void symtab_print_search(const char *name);
extern int symtab_compl(char *name);
 
/* Symtable linked together by build process */
extern struct symtab_entry symbol_table[];
/kernel/trunk/generic/include/console/kconsole.h
34,6 → 34,7
#include <synch/spinlock.h>
 
#define MAX_CMDLINE 256
#define KCONSOLE_HISTORY 10
 
enum cmd_arg_type {
ARG_TYPE_INVALID = 0,
/kernel/trunk/generic/include/console/console.h
36,6 → 36,7
extern chardev_t *stdout;
 
extern __u8 getc(chardev_t *chardev);
__u8 _getc(chardev_t *chardev);
extern count_t gets(chardev_t *chardev, char *buf, size_t buflen);
extern void putchar(char c);
 
/kernel/trunk/generic/src/console/console.c
39,13 → 39,13
chardev_t *stdin = NULL;
chardev_t *stdout = NULL;
 
/** Get character from character device.
/** Get character from character device. Do not echo character.
*
* @param chardev Character device.
*
* @return Character read.
*/
static __u8 _getc(chardev_t *chardev)
__u8 _getc(chardev_t *chardev)
{
__u8 ch;
ipl_t ipl;
/kernel/trunk/generic/src/console/kconsole.c
69,14 → 69,19
 
static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
static bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end);
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
 
/** Initialize kconsole data structures. */
void kconsole_init(void)
{
int i;
 
spinlock_initialize(&cmd_lock, "kconsole_cmd");
list_initialize(&cmd_head);
 
cmd_init();
for (i=0; i<KCONSOLE_HISTORY; i++)
history[i][0] = '\0';
}
 
 
137,6 → 142,226
return 1;
}
 
static void rdln_print_c(char ch, int count)
{
int i;
for (i=0;i<count;i++)
putchar(ch);
}
 
static void insert_char(char *str, char ch, int pos)
{
int i;
for (i=strlen(str);i > pos; i--)
str[i] = str[i-1];
str[pos] = ch;
}
 
static const char * cmdtab_search_one(const char *name,link_t **startpos)
{
int namelen = strlen(name);
const char *curname;
char *foundsym = NULL;
int foundpos = 0;
 
spinlock_lock(&cmd_lock);
 
if (!*startpos)
*startpos = cmd_head.next;
 
for (;*startpos != &cmd_head;*startpos = (*startpos)->next) {
cmd_info_t *hlp;
hlp = list_get_instance(*startpos, cmd_info_t, link);
 
curname = hlp->name;
if (strlen(curname) < namelen)
continue;
if (strncmp(curname, name, namelen) == 0) {
spinlock_unlock(&cmd_lock);
return curname+namelen;
}
}
spinlock_unlock(&cmd_lock);
return NULL;
}
 
 
/** Command completion of the commands
*
* @param name - string to match, changed to hint on exit
* @return number of found matches
*/
static int cmdtab_compl(char *name)
{
char output[MAX_SYMBOL_NAME+1];
link_t *startpos = NULL;
const char *foundtxt;
int found = 0;
int i;
 
output[0] = '\0';
while ((foundtxt = cmdtab_search_one(name, &startpos))) {
startpos = startpos->next;
if (!found)
strncpy(output, foundtxt, strlen(foundtxt)+1);
else {
for (i=0; output[i] && foundtxt[i] && output[i]==foundtxt[i]; i++)
;
output[i] = '\0';
}
found++;
}
if (!found)
return 0;
 
if (found > 1) {
printf("\n");
startpos = NULL;
while ((foundtxt = cmdtab_search_one(name, &startpos))) {
cmd_info_t *hlp;
hlp = list_get_instance(startpos, cmd_info_t, link);
printf("%s - %s\n", hlp->name, hlp->description);
startpos = startpos->next;
}
}
strncpy(name, output, MAX_SYMBOL_NAME);
return found;
}
 
static char * clever_readline(const char *prompt, chardev_t *input)
{
static int histposition = 0;
 
char tmp[MAX_CMDLINE+1];
int curlen = 0, position = 0;
char *current = history[histposition];
int i;
char c;
 
printf("%s> ", prompt);
while (1) {
c = _getc(input);
if (c == '\n') {
putchar(c);
break;
} if (c == '\b') {
if (position == 0)
continue;
for (i=position; i<curlen;i++)
current[i-1] = current[i];
curlen--;
position--;
putchar('\b');
for (i=position;i<curlen;i++)
putchar(current[i]);
putchar(' ');
rdln_print_c('\b',curlen-position+1);
continue;
}
if (c == '\t') {
int found;
 
/* Move to the end of the word */
for (;position<curlen && current[position]!=' ';position++)
putchar(current[position]);
/* Copy to tmp last word */
for (i=position-1;i >= 0 && current[i]!=' ' ;i--)
;
/* If word begins with * or &, skip it */
if (tmp[0] == '*' || tmp[0] == '&')
for (i=1;tmp[i];i++)
tmp[i-1] = tmp[i];
i++; /* I is at the start of the word */
strncpy(tmp, current+i, position-i+1);
 
if (i==0) { /* Command completion */
found = cmdtab_compl(tmp);
} else { /* Symtab completion */
found = symtab_compl(tmp);
}
 
if (found == 0)
continue;
for (i=0;tmp[i] && curlen < MAX_CMDLINE;i++,curlen++)
insert_char(current, tmp[i], i+position);
if (found == 1) { /* One match */
for (i=position;i<curlen;i++)
putchar(current[i]);
position += strlen(tmp);
/* Add space to end */
if (position == curlen && curlen < MAX_CMDLINE) {
current[position] = ' ';
curlen++;
position++;
putchar(' ');
}
} else {
printf("%s> ", prompt);
for (i=0; i<curlen;i++)
putchar(current[i]);
position += strlen(tmp);
}
rdln_print_c('\b', curlen-position);
continue;
}
if (c == 0x1b) {
c = _getc(input);
if (c!= 0x5b)
continue;
c = _getc(input);
if (c == 0x44) { /* Left */
if (position > 0) {
putchar('\b');
position--;
}
continue;
}
if (c == 0x43) { /* Right */
if (position < curlen) {
putchar(current[position]);
position++;
}
continue;
}
if (c == 0x41 || c == 0x42) { /* Up,down */
rdln_print_c('\b',position);
rdln_print_c(' ',curlen);
rdln_print_c('\b',curlen);
if (c == 0x41)
histposition--;
else
histposition++;
if (histposition < 0)
histposition = KCONSOLE_HISTORY -1 ;
else
histposition = histposition % KCONSOLE_HISTORY;
current = history[histposition];
printf("%s", current);
curlen = strlen(current);
position = curlen;
continue;
}
continue;
}
if (curlen >= MAX_CMDLINE)
continue;
 
insert_char(current, c, position);
 
curlen++;
for (i=position;i<curlen;i++)
putchar(current[i]);
position++;
rdln_print_c('\b',curlen-position);
}
histposition++;
histposition = histposition % KCONSOLE_HISTORY;
current[curlen] = '\0';
return current;
}
 
/** Kernel console managing thread.
*
* @param arg Not used.
143,9 → 368,9
*/
void kconsole(void *arg)
{
char cmdline[MAX_CMDLINE+1];
cmd_info_t *cmd_info;
count_t len;
char *cmdline;
 
if (!stdin) {
printf("%s: no stdin\n", __FUNCTION__);
153,10 → 378,10
}
while (true) {
printf("%s> ", __FUNCTION__);
if (!(len = gets(stdin, cmdline, sizeof(cmdline))))
cmdline = clever_readline(__FUNCTION__, stdin);
len = strlen(cmdline);
if (!len)
continue;
cmdline[len] = '\0';
cmd_info = parse_cmdline(cmdline, len);
if (!cmd_info)
continue;
/kernel/trunk/generic/src/debug/symtab.c
55,10 → 55,49
return NULL;
}
 
/** Find symbols that match the parameter forward and print them
*
* @param name - search string
* @param startpos - starting position, changes to found position
* @return Pointer to the part of string that should be completed or NULL
*/
static char * symtab_search_one(const char *name, int *startpos)
{
int namelen = strlen(name);
char *curname;
int i,j;
char *foundsym = NULL;
int foundpos = 0;
int colonoffset = -1;
 
for (i=0;name[i];i++)
if (name[i] == ':') {
colonoffset = i;
break;
}
 
for (i=*startpos;symbol_table[i].address_le;++i) {
/* Find a ':' in name */
curname = symbol_table[i].symbol_name;
for (j=0; curname[j] && curname[j] != ':'; j++)
;
if (!curname[j])
continue;
j -= colonoffset;
curname += j;
if (strlen(curname) < namelen)
continue;
if (strncmp(curname, name, namelen) == 0) {
*startpos = i;
return curname+namelen;
}
}
return NULL;
}
 
/** Return address that corresponds to the entry
*
* Search symbol table, and if the address ENDS with
* the parameter, return value
* Search symbol table, and if there is one match, return it
*
* @param name Name of the symbol
* @return 0 - Not found, -1 - Duplicate symbol, other - address of symbol
65,47 → 104,83
*/
__address get_symbol_addr(const char *name)
{
count_t i;
count_t found = 0;
count_t found_pos;
__address addr = NULL;
char *hint;
int i;
 
count_t nmlen = strlen(name);
count_t slen;
 
for (i=0;symbol_table[i].address_le;++i) {
slen = strlen(symbol_table[i].symbol_name);
if (slen < nmlen)
continue;
if (strncmp(name, symbol_table[i].symbol_name + (slen-nmlen),
nmlen) == 0) {
i = 0;
while ((hint=symtab_search_one(name, &i))) {
if (!strlen(hint)) {
addr = __u64_le2host(symbol_table[i].address_le);
found++;
found_pos = i;
}
i++;
}
if (found == 0)
return NULL;
if (found == 1)
return __u64_le2host(symbol_table[found_pos].address_le);
return ((__address) -1);
if (found > 1)
return ((__address) -1);
return addr;
}
 
/** Find symbols that match parameter and prints them */
void symtab_print_search(const char *name)
{
int i;
count_t nmlen = strlen(name);
count_t slen;
__address addr;
char *realname;
 
for (i=0;symbol_table[i].address_le;++i) {
slen = strlen(symbol_table[i].symbol_name);
if (slen < nmlen)
continue;
if (strncmp(name, symbol_table[i].symbol_name + (slen-nmlen),
nmlen) == 0) {
addr = __u64_le2host(symbol_table[i].address_le);
realname = symbol_table[i].symbol_name;
printf("0x%p: %s\n", addr, realname);
 
i = 0;
while (symtab_search_one(name, &i)) {
addr = __u64_le2host(symbol_table[i].address_le);
realname = symbol_table[i].symbol_name;
printf("0x%p: %s\n", addr, realname);
i++;
}
}
 
/** Symtab completion
*
* @param name - Search string, completes to symbol name
* @returns - 0 - nothing found, 1 - success, >1 print duplicates
*/
int symtab_compl(char *name)
{
char output[MAX_SYMBOL_NAME+1];
int startpos = 0;
char *foundtxt;
int found = 0;
int i;
 
/* Do not print everything */
if (!strlen(name))
return 0;
 
output[0] = '\0';
 
while ((foundtxt = symtab_search_one(name, &startpos))) {
startpos++;
if (!found)
strncpy(output, foundtxt, strlen(foundtxt)+1);
else {
for (i=0; output[i] && foundtxt[i] && output[i]==foundtxt[i]; i++)
;
output[i] = '\0';
}
found++;
}
if (!found)
return 0;
 
if (found > 1) {
printf("\n");
startpos = 0;
while ((foundtxt = symtab_search_one(name, &startpos))) {
printf("%s\n", symbol_table[startpos].symbol_name);
startpos++;
}
}
strncpy(name, output, MAX_SYMBOL_NAME);
return found;
}
/kernel/trunk/generic/src/lib/func.c
79,7 → 79,7
* @param dst Second string to compare.
* @param len Maximal length for comparison.
*
* @return 0 if the strings are equal, 1 otherwise.
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller.
*
*/
int strncmp(const char *src, const char *dst, size_t len)
87,11 → 87,16
int i;
i = 0;
while ((i < len) && (src[i] == dst[i])) {
if ((i == len - 1) || (src[i] == '\0'))
return 0;
i++;
for (;*src && *dst && i < len;src++,dst++,i++) {
if (*src < *dst)
return -1;
if (*src > *dst)
return 1;
}
if (i == len || *src == *dst)
return 0;
if (*src < *dst)
return -1;
return 1;
}
 
/kernel/trunk/arch/ia32/include/i8042.h
37,6 → 37,11
#define SC_LSHIFT 0x2a
#define SC_RSHIFT 0x36
#define SC_CAPSLOCK 0x3a
#define SC_SPEC_ESCAPE 0xe0
#define SC_LEFTARR 0x4b
#define SC_RIGHTARR 0x4d
#define SC_UPARR 0x48
#define SC_DOWNARR 0x50
 
extern void i8042_init(void);
 
/kernel/trunk/arch/ia32/src/drivers/i8042.c
303,14 → 303,36
 
spinlock_lock(&keylock);
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
case SC_LSHIFT:
case SC_RSHIFT:
keyflags |= PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
case SC_CAPSLOCK:
keyflags |= PRESSED_CAPSLOCK;
break;
default:
case SC_SPEC_ESCAPE:
break;
case SC_LEFTARR:
chardev_push_character(&kbrd, 0x1b);
chardev_push_character(&kbrd, 0x5b);
chardev_push_character(&kbrd, 0x44);
break;
case SC_RIGHTARR:
chardev_push_character(&kbrd, 0x1b);
chardev_push_character(&kbrd, 0x5b);
chardev_push_character(&kbrd, 0x43);
break;
case SC_UPARR:
chardev_push_character(&kbrd, 0x1b);
chardev_push_character(&kbrd, 0x5b);
chardev_push_character(&kbrd, 0x41);
break;
case SC_DOWNARR:
chardev_push_character(&kbrd, 0x1b);
chardev_push_character(&kbrd, 0x5b);
chardev_push_character(&kbrd, 0x42);
break;
default:
letter = is_lower(ascii);
capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK);
shift = keyflags & PRESSED_SHIFT;