-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommands.c
143 lines (117 loc) · 3.56 KB
/
commands.c
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include "env.h"
#include "commands.h"
extern const command_t command_help;
extern const command_t command_quit;
extern const command_t command_clear;
extern const command_t command_dseld;
extern const command_t command_upload;
extern const command_t command_download;
extern const command_t command_xxd;
extern const command_t command_exec;
extern const command_t command_echo;
extern const command_t command_env;
static const char *_command_status_convert(commands_status_t status);
const command_t *commands[SHELL_COMMAND_COUNT] = {
&command_help,
&command_clear,
&command_env,
&command_echo,
&command_dseld,
&command_exec,
&command_upload,
&command_download,
&command_xxd,
&command_quit,
NULL
};
void
commands_init(void)
{
const command_t **command;
command = &commands[0];
while (*command != NULL) {
object_t * const command_obj = object_new(OBJECT_TYPE_COMMAND);
command_obj->as.command = *command;
env_put((*command)->name, command_obj);
const char * const alias = (*command)->alias;
if ((alias != NULL) && (*alias != '\0')) {
env_put(alias, command_obj);
}
command++;
}
object_destructor_set(OBJECT_TYPE_COMMAND, NULL);
}
void
commands_deinit(void)
{
const command_t **command;
command = &commands[0];
while (*command != NULL) {
env_pair_t pair;
if (env_get((*command)->name, &pair)) {
object_t * const command_obj = pair.value;
object_delete(command_obj);
}
command++;
}
}
const command_t *
commands_find(const char *name)
{
assert(name != NULL);
const command_t **command;
command = &commands[0];
while (*command != NULL) {
if ((strcmp(name, (*command)->name)) == 0) {
return *command;
}
command++;
}
return NULL;
}
void
commands_printf(const char *format, ...)
{
va_list args;
va_start(args, format);
(void)vfprintf(stdout, format, args);
va_end(args);
}
void
commands_status_set(commands_status_t status)
{
(void)printf("%s\n", _command_status_convert(status));
}
static const char *
_command_status_convert(commands_status_t status)
{
switch (status) {
case COMMANDS_STATUS_EXPECTED_SYMBOL:
return "Invalid type. Expected type Symbol";
case COMMANDS_STATUS_EXPECTED_STRING:
return "Invalid type. Expected type String";
case COMMANDS_STATUS_EXPECTED_INTEGER:
return "Invalid type. Expected type Integer";
case COMMANDS_STATUS_ARGC_MISMATCH:
return "Mismatch in argument count";
case COMMANDS_STATUS_INSUFFICIENT_MEMORY:
return "Insufficient memory";
case COMMANDS_STATUS_INVALID_ADDRESS:
return "Invalid address";
case COMMANDS_STATUS_INVALID_SIZE:
return "Invalid size";
case COMMANDS_STATUS_FILE_NOT_FOUND:
return "File not found";
case COMMANDS_STATUS_NOT_A_FILE:
return "Not a file";
case COMMANDS_STATUS_ERROR:
return "Error";
default:
assert(false);
}
}