diff options
author | LAN-TW <lantw44@gmail.com> | 2013-11-08 15:32:28 +0800 |
---|---|---|
committer | b01902062 <b01902062@linux5.csie.ntu.edu.tw> | 2013-11-08 15:58:06 +0800 |
commit | 940aadde82dbe6bafcdda132c33f07d9b321f1a3 (patch) | |
tree | 4b16496e0f50a6c62737709246867d0e553c6608 | |
parent | 2b896398274fbb2f47526c6a5607e5591801660d (diff) | |
download | cn2013-940aadde82dbe6bafcdda132c33f07d9b321f1a3.tar.gz cn2013-940aadde82dbe6bafcdda132c33f07d9b321f1a3.tar.zst cn2013-940aadde82dbe6bafcdda132c33f07d9b321f1a3.zip |
HW1: 修正輸入多個空白的問題並用 macro 取代重複的項目與宣告
-rw-r--r-- | hw1/shell-builtin.c | 41 | ||||
-rw-r--r-- | hw1/shell-builtin.h | 26 | ||||
-rw-r--r-- | hw1/shell.c | 20 |
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; } |