summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2013-11-08 15:32:28 +0800
committerb01902062 <b01902062@linux5.csie.ntu.edu.tw>2013-11-08 15:58:06 +0800
commit940aadde82dbe6bafcdda132c33f07d9b321f1a3 (patch)
tree4b16496e0f50a6c62737709246867d0e553c6608
parent2b896398274fbb2f47526c6a5607e5591801660d (diff)
downloadcn2013-940aadde82dbe6bafcdda132c33f07d9b321f1a3.tar.gz
cn2013-940aadde82dbe6bafcdda132c33f07d9b321f1a3.tar.zst
cn2013-940aadde82dbe6bafcdda132c33f07d9b321f1a3.zip
HW1: 修正輸入多個空白的問題並用 macro 取代重複的項目與宣告
-rw-r--r--hw1/shell-builtin.c41
-rw-r--r--hw1/shell-builtin.h26
-rw-r--r--hw1/shell.c20
3 files changed, 64 insertions, 23 deletions
diff --git a/hw1/shell-builtin.c b/hw1/shell-builtin.c
index 87d0632..ce73c5e 100644
--- a/hw1/shell-builtin.c
+++ b/hw1/shell-builtin.c
@@ -16,15 +16,18 @@
#include <unistd.h>
const RasShellBuiltin ras_shell_builtins[] = {
- { "cd", ras_shell_builtin_cd },
- { "echo", ras_shell_builtin_echo },
- { "exit", ras_shell_builtin_exit },
- { "logout", ras_shell_builtin_logout },
- { "printenv", ras_shell_builtin_printenv },
- { "pwd", ras_shell_builtin_pwd },
- { "setenv", ras_shell_builtin_setenv },
- { "umask", ras_shell_builtin_umask },
- { NULL, NULL }
+ RAS_SHELL_BUILTIN_ENTRY (cd),
+ RAS_SHELL_BUILTIN_ENTRY (echo),
+ RAS_SHELL_BUILTIN_ENTRY (exit),
+ RAS_SHELL_BUILTIN_ENTRY (logout),
+ RAS_SHELL_BUILTIN_ENTRY (printenv),
+ RAS_SHELL_BUILTIN_ENTRY (pwd),
+ RAS_SHELL_BUILTIN_ENTRY (set),
+ RAS_SHELL_BUILTIN_ENTRY (setenv),
+ RAS_SHELL_BUILTIN_ENTRY (umask),
+ RAS_SHELL_BUILTIN_ENTRY (unset),
+ RAS_SHELL_BUILTIN_ENTRY (unsetenv),
+ RAS_SHELL_BUILTIN_ENTRY_NULL
};
int ras_shell_builtin_cd (int argc, char* argv[], RasShell* shell) {
@@ -111,6 +114,11 @@ int ras_shell_builtin_pwd (int argc, char* argv[], RasShell* shell) {
return 0;
}
+int ras_shell_builtin_set (int argc, char* argv[], RasShell* shell) {
+ fputs ("This command has not been implemented. Try `setenv\' or `shopt\'.\n", stderr);
+ return 1;
+}
+
int ras_shell_builtin_setenv (int argc, char* argv[], RasShell* shell) {
if (argc != 3) {
fprintf (
@@ -141,3 +149,18 @@ int ras_shell_builtin_umask (int argc, char* argv[], RasShell* shell) {
}
return 0;
}
+
+int ras_shell_builtin_unset (int argc, char* argv[], RasShell* shell) {
+ fputs ("This command has not been implemented. Try `unsetenv\'.\n", stderr);
+ return 1;
+}
+
+int ras_shell_builtin_unsetenv (int argc, char* argv[], RasShell* shell) {
+ for (int i = 1; i < argc; i++) {
+ if (unsetenv (argv[i]) < 0) {
+ fprintf (stderr, "%s: %s: %s\n", argv[0], argv[i], strerror (errno));
+ return 1;
+ }
+ }
+ return 0;
+}
diff --git a/hw1/shell-builtin.h b/hw1/shell-builtin.h
index ebdec2f..c4dd8d9 100644
--- a/hw1/shell-builtin.h
+++ b/hw1/shell-builtin.h
@@ -10,13 +10,23 @@ typedef struct {
extern const RasShellBuiltin ras_shell_builtins[];
-int ras_shell_builtin_cd (int argc, char* argv[], RasShell* shell);
-int ras_shell_builtin_echo (int argc, char* argv[], RasShell* shell);
-int ras_shell_builtin_exit (int argc, char* argv[], RasShell* shell);
-int ras_shell_builtin_logout (int argc, char* argv[], RasShell* shell);
-int ras_shell_builtin_printenv (int argc, char* argv[], RasShell* shell);
-int ras_shell_builtin_pwd (int argc, char* argv[], RasShell* shell);
-int ras_shell_builtin_setenv (int argc, char* argv[], RasShell* shell);
-int ras_shell_builtin_umask (int argc, char* argv[], RasShell* shell);
+#define RAS_SHELL_BUILTIN_DECL(func) \
+ int ras_shell_builtin_##func(int argc, char* argv[], RasShell* shell)
+#define RAS_SHELL_BUILTIN_ENTRY(func) \
+ { #func, ras_shell_builtin_##func }
+#define RAS_SHELL_BUILTIN_ENTRY_NULL \
+ { NULL, NULL}
+
+RAS_SHELL_BUILTIN_DECL (cd);
+RAS_SHELL_BUILTIN_DECL (echo);
+RAS_SHELL_BUILTIN_DECL (exit);
+RAS_SHELL_BUILTIN_DECL (logout);
+RAS_SHELL_BUILTIN_DECL (printenv);
+RAS_SHELL_BUILTIN_DECL (pwd);
+RAS_SHELL_BUILTIN_DECL (set);
+RAS_SHELL_BUILTIN_DECL (setenv);
+RAS_SHELL_BUILTIN_DECL (umask);
+RAS_SHELL_BUILTIN_DECL (unset);
+RAS_SHELL_BUILTIN_DECL (unsetenv);
#endif /* RAS_SHELL_BUILTIN_H */
diff --git a/hw1/shell.c b/hw1/shell.c
index 7c67d91..f9728c4 100644
--- a/hw1/shell.c
+++ b/hw1/shell.c
@@ -88,7 +88,11 @@ static void ras_shell_cmd_comp_destroy (RasShellCmdComp* comp) {
}
static void complete_string (Array*** ws, int* append,
- RasShellCmdComp* comp, bool reinit) {
+ RasShellCmdComp* comp, bool allow_empty, bool reinit) {
+
+ if (!allow_empty && array_getmax (*ws[*append]) <= 0) {
+ return;
+ }
char zero = '\0';
array_pushback (*ws[*append], &zero);
@@ -103,9 +107,9 @@ static void complete_string (Array*** ws, int* append,
}
static void complete_component (Array*** ws, int* append,
- RasShellCmdComp* comp, RasShellCmd* cmd, bool reinit) {
+ RasShellCmdComp* comp, RasShellCmd* cmd, bool allow_empty, bool reinit) {
- complete_string (ws, append, comp, reinit);
+ complete_string (ws, append, comp, allow_empty, reinit);
char* null = NULL;
array_pushback (comp->arg, &null);
@@ -122,6 +126,7 @@ static int ras_shell_cmd_parse (
bool is_quoted = false;
bool is_escaped = false;
bool ignore_esc = false;
+ bool allow_empty = false;
char quote_char = '\0';
int append = APPEND_STR; /* current working string */
@@ -164,7 +169,8 @@ static int ras_shell_cmd_parse (
}
if (isspace (*p)) {
/* complete a string */
- complete_string (ws, &append, &comp, true);
+ complete_string (ws, &append, &comp, allow_empty, true);
+ allow_empty = false;
continue;
}
switch (*p) {
@@ -173,10 +179,12 @@ static int ras_shell_cmd_parse (
continue;
case PARSE_QUOTE_REGULAR:
is_quoted = true;
+ allow_empty = true;
quote_char = *p;
continue;
case PARSE_QUOTE_SUPER:
is_quoted = true;
+ allow_empty = true;
ignore_esc = true;
quote_char = *p;
continue;
@@ -191,7 +199,7 @@ static int ras_shell_cmd_parse (
append = APPEND_TAPIPE;
} else {
/* complete a component */
- complete_component (ws, &append, &comp, cmd, true);
+ complete_component (ws, &append, &comp, cmd, allow_empty, true);
}
continue;
default:
@@ -199,7 +207,7 @@ static int ras_shell_cmd_parse (
}
}
- complete_component (ws, &append, &comp, cmd, false);
+ complete_component (ws, &append, &comp, cmd, allow_empty, false);
return 0;
}