Add some more hashmap functions
And port kernel console command lookup to use a hashmap.
This commit is contained in:
parent
204d9bb6ce
commit
902b0342b9
@ -1,5 +1,6 @@
|
||||
#include <system.h>
|
||||
#include <logging.h>
|
||||
#include <list.h>
|
||||
#include <hashmap.h>
|
||||
|
||||
static unsigned int hashmap_default_hash(char * key) {
|
||||
@ -122,3 +123,42 @@ int hashmap_has(hashmap_t * map, char * key) {
|
||||
|
||||
}
|
||||
|
||||
list_t * hashmap_keys(hashmap_t * map) {
|
||||
list_t * l = list_create();
|
||||
|
||||
for (unsigned int i = 0; i < map->size; ++i) {
|
||||
hashmap_entry_t * x = map->entries[i];
|
||||
while (x) {
|
||||
list_insert(l, x->key);
|
||||
x = x->next;
|
||||
}
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
list_t * hashmap_values(hashmap_t * map) {
|
||||
list_t * l = list_create();
|
||||
|
||||
for (unsigned int i = 0; i < map->size; ++i) {
|
||||
hashmap_entry_t * x = map->entries[i];
|
||||
while (x) {
|
||||
list_insert(l, x->value);
|
||||
x = x->next;
|
||||
}
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void hashmap_free(hashmap_t * map) {
|
||||
for (unsigned int i = 0; i < map->size; ++i) {
|
||||
hashmap_entry_t * x = map->entries[i], * p;
|
||||
while (x) {
|
||||
p = x;
|
||||
x = x->next;
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
free(map->entries);
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef KL_HASHMAP_H
|
||||
#define KL_HASHMAP_H
|
||||
|
||||
#include <list.h>
|
||||
|
||||
typedef unsigned int (*hashmap_hash_t) (char * key);
|
||||
|
||||
typedef struct hashmap_entry {
|
||||
@ -20,5 +22,8 @@ void * hashmap_set(hashmap_t * map, char * key, void * value);
|
||||
void * hashmap_get(hashmap_t * map, char * key);
|
||||
void * hashmap_remove(hashmap_t * map, char * key);
|
||||
int hashmap_has(hashmap_t * map, char * key);
|
||||
list_t * hashmap_keys(hashmap_t * map);
|
||||
list_t * hashmap_values(hashmap_t * map);
|
||||
void hashmap_free(hashmap_t * map);
|
||||
|
||||
#endif
|
||||
|
@ -116,8 +116,7 @@ struct shell_command {
|
||||
char * description;
|
||||
};
|
||||
|
||||
#define NUM_COMMANDS 8
|
||||
static struct shell_command shell_commands[NUM_COMMANDS];
|
||||
hashmap_t * shell_commands_map = NULL;
|
||||
|
||||
/*
|
||||
* Shell commands
|
||||
@ -139,11 +138,18 @@ static int shell_echo(fs_node_t * tty, int argc, char * argv[]) {
|
||||
}
|
||||
|
||||
static int shell_help(fs_node_t * tty, int argc, char * argv[]) {
|
||||
struct shell_command * sh = &shell_commands[0];
|
||||
while (sh->name) {
|
||||
fs_printf(tty, "%s - %s\n", sh->name, sh->description);
|
||||
sh++;
|
||||
list_t * hash_keys = hashmap_keys(shell_commands_map);
|
||||
|
||||
foreach(_key, hash_keys) {
|
||||
char * key = (char *)_key->value;
|
||||
struct shell_command * c = hashmap_get(shell_commands_map, key);
|
||||
|
||||
fs_printf(tty, "%s - %s\n", c->name, c->description);
|
||||
}
|
||||
|
||||
list_free(hash_keys);
|
||||
free(hash_keys);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -197,6 +203,32 @@ static int shell_test_hash(fs_node_t * tty, int argc, char * argv[]) {
|
||||
fs_printf(tty, "value at b: %d\n", (int)hashmap_get(map, "b"));
|
||||
fs_printf(tty, "value at c: %d\n", (int)hashmap_get(map, "c"));
|
||||
|
||||
hashmap_set(map, "b", (void *)42);
|
||||
|
||||
fs_printf(tty, "value at a: %d\n", (int)hashmap_get(map, "a"));
|
||||
fs_printf(tty, "value at b: %d\n", (int)hashmap_get(map, "b"));
|
||||
fs_printf(tty, "value at c: %d\n", (int)hashmap_get(map, "c"));
|
||||
|
||||
hashmap_remove(map, "a");
|
||||
|
||||
fs_printf(tty, "value at a: %d\n", (int)hashmap_get(map, "a"));
|
||||
fs_printf(tty, "value at b: %d\n", (int)hashmap_get(map, "b"));
|
||||
fs_printf(tty, "value at c: %d\n", (int)hashmap_get(map, "c"));
|
||||
fs_printf(tty, "map contains a: %s\n", hashmap_has(map, "a") ? "yes" : "no");
|
||||
fs_printf(tty, "map contains b: %s\n", hashmap_has(map, "b") ? "yes" : "no");
|
||||
fs_printf(tty, "map contains c: %s\n", hashmap_has(map, "c") ? "yes" : "no");
|
||||
|
||||
list_t * hash_keys = hashmap_keys(map);
|
||||
foreach(_key, hash_keys) {
|
||||
char * key = (char *)_key->value;
|
||||
fs_printf(tty, "map[%s] = %d\n", key, (int)hashmap_get(map, key));
|
||||
}
|
||||
list_free(hash_keys);
|
||||
free(hash_keys);
|
||||
|
||||
hashmap_free(map);
|
||||
free(map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -210,7 +242,7 @@ static int shell_log_on(fs_node_t * tty, int argc, char * argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shell_command shell_commands[NUM_COMMANDS] = {
|
||||
static struct shell_command shell_commands[] = {
|
||||
{"shell", &shell_create_userspace_shell,
|
||||
"Runs a userspace shell on this tty."},
|
||||
{"echo", &shell_echo,
|
||||
@ -362,6 +394,16 @@ void debug_shell_run(void * data, char * name) {
|
||||
/* Set the device to be the actual TTY slave */
|
||||
tty = current_process->fds->entries[slave];
|
||||
|
||||
/* Initialize the shell commands map */
|
||||
if (!shell_commands_map) {
|
||||
shell_commands_map = hashmap_create(10);
|
||||
struct shell_command * sh = &shell_commands[0];
|
||||
while (sh->name) {
|
||||
hashmap_set(shell_commands_map, sh->name, sh);
|
||||
sh++;
|
||||
}
|
||||
}
|
||||
|
||||
int retval = 0;
|
||||
|
||||
while (1) {
|
||||
@ -384,15 +426,10 @@ void debug_shell_run(void * data, char * name) {
|
||||
if (!argc) continue;
|
||||
|
||||
/* Parse the command string */
|
||||
struct shell_command * sh = &shell_commands[0];
|
||||
while (sh->name) {
|
||||
if (!strcmp(sh->name, argv[0])) {
|
||||
retval = sh->function(tty, argc, argv);
|
||||
break;
|
||||
}
|
||||
sh++;
|
||||
}
|
||||
if (sh->name == NULL) {
|
||||
struct shell_command * sh = hashmap_get(shell_commands_map, argv[0]);
|
||||
if (sh) {
|
||||
retval = sh->function(tty, argc, argv);
|
||||
} else {
|
||||
fs_printf(tty, "Unrecognized command: %s\n", argv[0]);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user