tiny-shell 0.2
A mini shell project aiming to gain knowledge about Win32 and Linux API
Loading...
Searching...
No Matches
cmd.c File Reference
#include "cmd.h"
#include "args.h"
#include "io_wrap.h"
#include "utils.h"
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
Include dependency graph for cmd.c:

Go to the source code of this file.

Functions

bool is_minibat_file (const os_char *file)
 
void cmd_init_from_str (struct cmd *res, const char *str)
 Build command from raw input.
 
void cmd_destroy (struct cmd *obj)
 

Function Documentation

◆ cmd_destroy()

void cmd_destroy ( struct cmd * obj)

Definition at line 194 of file cmd.c.

194 {
195 switch(obj->type) {
196 case CMD_CHANGE_DIR:
197 free(obj->val.new_dir);
198 break;
199 case CMD_SET_ENV:
200 case CMD_UNSET_ENV:
201 case CMD_GET_ENV:
202 free(obj->val.env.name);
203 free(obj->val.env.val);
204 break;
205 case CMD_ADD_PATH:
206 free(obj->val.new_path);
207 break;
208 case CMD_DEL_FILE:
209 free(obj->val.filename);
210 break;
211 case CMD_LSDIR:
212 free(obj->val.dir);
213 break;
214 case CMD_MINIBAT:
216 args_destroy(&(obj->val.args));
217 break;
218 default:
219 break;
220 }
221}
void args_destroy(struct args *obj)
Definition args.c:135
@ CMD_ADD_PATH
Definition cmd.h:22
@ CMD_DEL_FILE
Definition cmd.h:23
@ CMD_LAUNCH_EXECUTABLE
Definition cmd.h:24
@ CMD_GET_ENV
Definition cmd.h:21
@ CMD_MINIBAT
Definition cmd.h:32
@ CMD_UNSET_ENV
Definition cmd.h:20
@ CMD_CHANGE_DIR
Definition cmd.h:14
@ CMD_SET_ENV
Definition cmd.h:18
@ CMD_LSDIR
Definition cmd.h:33
os_char * val
Definition cmd.h:49
enum cmd_type type
Definition cmd.h:40

References args_destroy(), CMD_ADD_PATH, CMD_CHANGE_DIR, CMD_DEL_FILE, CMD_GET_ENV, CMD_LAUNCH_EXECUTABLE, CMD_LSDIR, CMD_MINIBAT, CMD_SET_ENV, CMD_UNSET_ENV, cmd::type, and cmd::val.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cmd_init_from_str()

void cmd_init_from_str ( struct cmd * res,
const char * str )

Build command from raw input.

Definition at line 19 of file cmd.c.

19 {
20 assert(res && "NULL input");
21 res->type = CMD_UNKNOWN;
22
23 struct args arguments;
24 const bool valid = args_init_from_str(&arguments, str);
25
26 if(!valid) {
27 res->type = CMD_NOOP;
28 return;
29 }
30
31 if(arguments.argc == 0) {
32 args_destroy(&arguments);
33 res->type = CMD_NOOP;
34 return;
35 }
36
37 const char *name = arguments.argv[0];
38
39 if(strcmp(name, "help") == 0) {
40 res->type = CMD_HELP;
41 } else if(strcmp(name, "list") == 0) {
42 res->type = CMD_LIST;
43 } else if(strcmp(name, "date") == 0) {
44 res->type = CMD_DATE;
45 } else if(strcmp(name, "time") == 0) {
46 res->type = CMD_TIME;
47 } else if(strcmp(name, "stop") == 0) {
48 if(arguments.argc != 2 || !is_number(arguments.argv[1])) {
49 format_usage("stop <process id>\n");
50 res->type = CMD_NOOP;
51 } else {
52 res->type = CMD_STOP_PROC;
53 res->val.proc_id = atoi(arguments.argv[1]);
54 }
55 } else if(strcmp(name, "exit") == 0) {
56 res->type = CMD_EXIT;
57 } else if(strcmp(name, "cd") == 0) {
58 res->type = CMD_CHANGE_DIR;
59 if(arguments.argc != 2) {
60 format_usage("cd <destination dir>\n");
61 res->type = CMD_NOOP;
62 } else {
63 const unsigned int len = strlen(arguments.argv[1]);
64 res->val.new_dir = malloc(len + 1);
65 memcpy(res->val.new_dir, arguments.argv[1], len);
66 res->val.new_dir[len] = '\0';
67 }
68 } else if(strcmp(name, "clear") == 0) {
69 res->type = CMD_CLEAR;
70 } else if(strcmp(name, "set") == 0) {
71 if(arguments.argc < 2 || arguments.argc > 3) {
72 format_usage("set <VAR> <value>\n");
73 res->type = CMD_NOOP;
74 } else if(arguments.argc == 2) {
75 res->type = CMD_SET_ENV;
76 const unsigned int name_len = strlen(arguments.argv[1]);
77 res->val.env.name = malloc(name_len + 1);
78 memcpy(res->val.env.name, arguments.argv[1], name_len);
79 res->val.env.name[name_len] = '\0';
80 res->val.env.val = NULL;
81 } else if(arguments.argc == 3) {
82 res->type = CMD_SET_ENV;
83 const unsigned int name_len = strlen(arguments.argv[1]);
84 res->val.env.name = malloc(name_len + 1);
85 memcpy(res->val.env.name, arguments.argv[1], name_len);
86 res->val.env.name[name_len] = '\0';
87
88 const unsigned int val_len = strlen(arguments.argv[2]);
89 res->val.env.val = malloc(val_len + 1);
90 memcpy(res->val.env.val, arguments.argv[2], val_len);
91 res->val.env.val[val_len] = '\0';
92 }
93 } else if(strcmp(name, "unset") == 0) {
94 if(arguments.argc != 2) {
95 format_usage("unset <VAR>\n");
96 res->type = CMD_NOOP;
97 } else {
98 res->type = CMD_UNSET_ENV;
99 const unsigned int len = strlen(arguments.argv[1]);
100 res->val.env.name = malloc(len + 1);
101 memcpy(res->val.env.name, arguments.argv[1], len);
102 res->val.env.name[len] = '\0';
103 res->val.env.val = NULL;
104 }
105 } else if(strcmp(name, "env") == 0) {
106 if(arguments.argc == 1) {
107 res->type = CMD_GET_ENV_ALL;
108 } else if(arguments.argc == 2) {
109 res->type = CMD_GET_ENV;
110 const unsigned int len = strlen(arguments.argv[1]);
111 res->val.env.name = malloc(len + 1);
112 memcpy(res->val.env.name, arguments.argv[1], len);
113 res->val.env.name[len] = '\0';
114 res->val.env.val = NULL;
115 } else {
116 format_usage("env [VAR]\n");
117 res->type = CMD_NOOP;
118 }
119 } else if(strcmp(name, "kill") == 0) {
120 if(arguments.argc != 2 || !is_number(arguments.argv[1])) {
121 format_usage("kill <process id>\n");
122 res->type = CMD_NOOP;
123 } else {
124 res->type = CMD_KILL;
125 res->val.proc_id = atoi(arguments.argv[1]);
126 }
127 } else if(strcmp(name, "resume") == 0) {
128 if(arguments.argc != 2 || !is_number(arguments.argv[1])) {
129 format_usage("resume <process id>\n");
130 res->type = CMD_NOOP;
131 } else {
132 res->type = CMD_RESUME;
133 res->val.proc_id = atoi(arguments.argv[1]);
134 }
135 } else if(strcmp(name, "child") == 0) {
136 if(arguments.argc != 2 || !is_number(arguments.argv[1])) {
137 format_usage("child <process id>\n");
138 res->type = CMD_NOOP;
139 } else {
141 res->val.proc_id = atoi(arguments.argv[1]);
142 }
143 } else if(strcmp(name, "addpath") == 0) {
144 if(arguments.argc != 2) {
145 format_usage("addpath <new path>\n");
146 res->type = CMD_NOOP;
147 } else {
148 res->type = CMD_ADD_PATH;
149 const size_t len = strlen(arguments.argv[1]);
150 res->val.new_path = (os_char *)malloc((len + 1) * sizeof(os_char));
151 res->val.new_path[len] = '\0';
152 memcpy(res->val.new_path, arguments.argv[1], strlen(arguments.argv[1]) * sizeof(os_char));
153 }
154 } else if(strcmp(name, "delete") == 0) {
155 if(arguments.argc > 2 || arguments.argc < 2) {
156 format_usage("delete <path to file>\n");
157 res->type = CMD_NOOP;
158 } else {
159 res->type = CMD_DEL_FILE;
160
161 const unsigned int dir_len = strlen(arguments.argv[1]);
162 res->val.filename = malloc(dir_len + 1);
163 memcpy(res->val.filename, arguments.argv[1], dir_len);
164 res->val.filename[dir_len] = '\0';
165 }
166 } else if(strcmp(name, "lsdir") == 0) {
167 if(arguments.argc != 2) {
168 format_usage("Usage: lsdir <dir>\n");
169 res->type = CMD_NOOP;
170 } else {
171 res->type = CMD_LSDIR;
172
173 const unsigned int dir_len = strlen(arguments.argv[1]);
174 res->val.dir = malloc(dir_len + 1);
175 memcpy(res->val.dir, arguments.argv[1], dir_len);
176 res->val.dir[dir_len] = '\0';
177 }
178 } else if(arguments.argc && is_minibat_file(arguments.argv[0])) {
179 if(arguments.argc != 1) {
180 format_error("Too many arguments\n");
182 } else {
183 res->type = CMD_MINIBAT;
184 args_deep_copy_init(&res->val.args, &arguments);
185 }
186 } else {
188 args_deep_copy_init(&res->val.args, &arguments);
189 }
190
191 args_destroy(&arguments);
192}
void args_deep_copy_init(struct args *obj, const struct args *source)
Initialize the object by deep copying source
Definition args.c:163
bool args_init_from_str(struct args *obj, const os_char *input)
Build args from an input string.
Definition args.c:117
bool is_minibat_file(const os_char *file)
Definition cmd.c:11
@ CMD_RESUME
Definition cmd.h:26
@ CMD_NOOP
Definition cmd.h:12
@ CMD_LIST
Definition cmd.h:28
@ CMD_EXIT
Definition cmd.h:16
@ CMD_KILL
Definition cmd.h:25
@ CMD_UNKNOWN
Definition cmd.h:10
@ CMD_CLEAR
Definition cmd.h:17
@ CMD_STOP_PROC
Definition cmd.h:31
@ CMD_DATE
Definition cmd.h:29
@ CMD_GET_ENV_ALL
Definition cmd.h:19
@ CMD_INVALID_SYNTAX
Definition cmd.h:11
@ CMD_HELP
Definition cmd.h:15
@ CMD_CHILD_PROCESSES
Definition cmd.h:27
@ CMD_TIME
Definition cmd.h:30
void format_usage(char *fmt,...)
Used format_xxx instead of printf and such for uniform output.
Definition io_wrap.c:57
void format_error(char *fmt,...)
Used format_xxx instead of printf and such for uniform output.
Definition io_wrap.c:89
Result after parsing an arbitrary string.
Definition args.h:10
bool is_number(const char *c)
Definition utils.c:8

References args::argc, args_deep_copy_init(), args_destroy(), args_init_from_str(), args::argv, CMD_ADD_PATH, CMD_CHANGE_DIR, CMD_CHILD_PROCESSES, CMD_CLEAR, CMD_DATE, CMD_DEL_FILE, CMD_EXIT, CMD_GET_ENV, CMD_GET_ENV_ALL, CMD_HELP, CMD_INVALID_SYNTAX, CMD_KILL, CMD_LAUNCH_EXECUTABLE, CMD_LIST, CMD_LSDIR, CMD_MINIBAT, CMD_NOOP, CMD_RESUME, CMD_SET_ENV, CMD_STOP_PROC, CMD_TIME, CMD_UNKNOWN, CMD_UNSET_ENV, format_error(), format_usage(), is_minibat_file(), is_number(), cmd::type, and cmd::val.

Referenced by scan_input().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_minibat_file()

bool is_minibat_file ( const os_char * file)

Definition at line 11 of file cmd.c.

11 {
12 const os_char *dot = strrchr(file, '.');
13 if(dot == NULL) {
14 return false;
15 }
16 return !strcmp(dot + 1, "mb");
17}

Referenced by cmd_init_from_str().

Here is the caller graph for this function: