summaryrefslogtreecommitdiffstats
path: root/debug/console.c
blob: cb8aeb3559653868e2e89d85f5ccc914eecaa55c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#ifdef DEBUG_CONSOLE
#include "debug/console.h"
#include "lib/string.h"
#include "lib/printf.h"
#include "api/process.h"
#include "proc/process.h"
#include "sys/objdir.h"

struct con_command {
    char *name;
    void (*func)(int, char*[]);
};

#define MAX_ARGS 8
static int
s_tokenize_buffer(char *buffer, char *argv[])
{
    int argc = 1;

    //Populate the arguments buffer.
    argv[0] = buffer;
    for(char *s = buffer; *s; s++) {
        if(*s == ' ') {
            *s = 0;
            argv[argc++] = s + 1;
        }
    }
    return argc;
}

static int
atoi(const char *cstr)
{
    int ret = 0;
    for(const char *c = cstr; *c; c++) {
        if(*c < '0' || *c > '9') return ret;
        ret *= 10;
        ret += *c - '0';
    }
    return ret;
}

static void
s_command_dir_printdir(jove_obj_t *dir)
{
    jove_objdir_t *objdir = obj_deref((jove_owned_obj_t*)dir);
    for(size_t i = 0; i < OBJDIR_ENTRIES; i++) {
        jove_owned_obj_t *entry = (jove_owned_obj_t*)&objdir->entries[i];
        if(obj_gettype(entry) == JOVE_OBJ_NONE) continue;
        kprintf("%3i %16s %p\n", i, obj_gettypename(entry), obj_getvalue(entry));
    }
}

static void
s_command_dir(int argc, char *argv[])
{
    pid_t target_pid = 1;
    if(argc > 1) {
        if(argc > 2) {
            kprintf("Too many arguments for 'dir': expected 2, got %i\n", argc);
            return;
        }
        target_pid = atoi(argv[1]);
    }
    pcb_t *pcb = pcb_frompid(target_pid);
    if(pcb == NULL) {
        kprintf("Invalid PCB: '%i'\n", pcb);
        return;
    }
    kprintf("Root directory for PID %i\n", target_pid);

    jove_obj_t *rootdir = pcb_getrootdir(pcb);

    while(1) {
        s_command_dir_printdir(rootdir);
read_input:
        debug_console_readinput(argv[0], 128);
        argc = s_tokenize_buffer(argv[0], argv);

        if(strncmp(argv[0], "x", 1) == 0) return;
        int traversi = atoi(argv[0]);

        if(traversi > OBJDIR_ENTRIES) {
            kprintf("Bad entry index: %i", traversi);
            goto read_input; 
        }
        if(obj_gettype(objdir_getlocal(rootdir, traversi)) != JOVE_OBJ_OBJDIR) {
            kprintf("Bad subdirectory index: %i is not an objdir\n", traversi);
            goto read_input;
        }
        rootdir = obj_release(objdir_getlocal(rootdir, traversi));
        kprintf("\nSubdirectory %i\n", traversi);
    }
}

static struct con_command s_console_commands[] = {
    { "dir", s_command_dir }
};
static size_t s_console_commands_count = sizeof(s_console_commands) / sizeof(struct con_command);

void debug_console_parsecmd(char *buffer)
{
    char *argv[MAX_ARGS];
    int argc = s_tokenize_buffer(buffer, argv);

    for(size_t i = 0; i < s_console_commands_count; i++) {
        struct con_command *command = &s_console_commands[i];
        if(strncmp(command->name, argv[0], 128) == 0) {
            command->func(argc, argv);
            return;
        }
    }
    kprintf("Unknown command %s\n", argv[0]);
}

#endif