/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); |
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) { |
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')) |
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; |
i++; |
} |
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 |
---|
310,6 → 310,28 |
case SC_CAPSLOCK: |
keyflags |= PRESSED_CAPSLOCK; |
break; |
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); |