From 8df6b6b4fb26c4914e2a3451c41ade0a78f390cb Mon Sep 17 00:00:00 2001 From: alistair Date: Sat, 13 Jun 2020 19:54:52 +1000 Subject: [PATCH] cleanup --- Makefile | 1 - README.md | 10 +++-- main.c | 128 +++++++++++++++++++++++++++++++++++++----------------- util.c | 17 ++++---- 4 files changed, 103 insertions(+), 53 deletions(-) diff --git a/Makefile b/Makefile index a61230c..d02527b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ - GCC=gcc -g -lreadline .PHONY default: build diff --git a/README.md b/README.md index 0cb51ba..9e30484 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,16 @@ _ ## To-Do -1. Pipes +1. [done] Pipes 2. Exclude things inside quote marks from string splitting and substitutions 3. Interrupts ^C and ^Z, bg, fg - & and &&, ; 4. Wildcard substitutions *, ? etc -5. tab completion, handling escape sequences like ^[[D -6. Functions and variables -7. PS1 +5. tab completion +6. Functions and variables -> program return value +7. better PS1 + - probably just a script that can be executed to display the prompt +8. History _file_ diff --git a/main.c b/main.c index 77f92fc..cb1cb8f 100644 --- a/main.c +++ b/main.c @@ -17,8 +17,7 @@ int repl(State* state, FILE *input); int run_command(State *state, int argc, char *argv[]); int get_array_element(ArrayElement **ret, GrowingArray* array, char* key); int del_array_element(GrowingArray* array, char* key); - -const int GLOB_DEBUG; +int expand_command(State *state, int *argc, char** ret_argv[]); GrowingArray get_growing_array(size_t num_elements, size_t size_elem) { GrowingArray arr; @@ -260,6 +259,7 @@ int run_pipes(State *state, int num_args, char *args []) { for (int i = 0; i < num_commands; i++) { char **command; int words; + int err = split_string(&command, &words, sep_commands[i], ' '); if (i == 0) { @@ -273,12 +273,26 @@ int run_pipes(State *state, int num_args, char *args []) { out = pipes[2*i + 1]; } - printf("in %d out: %d exec: ", in, out); - for (int i = 0; i < words; i++) { + int command_len = 0; + for (int i = 0; command[i] != 0; i++) { + command_len++; + } + //free(command[i]); // free the null pointer on the end + expand_command(state, &command_len, &command); + for (int i = 0; i < command_len; i++) { + printf("%s ", command[i]); } printf("\n"); + command = reallocarray(command, command_len+1, sizeof(char*)); + command[command_len] = 0; + execute(in, out, command, &child); + + for (int i = 0; i < command_len; i++) { + free(command[i]); + } + free(command); } int status; @@ -294,7 +308,6 @@ int run_pipes(State *state, int num_args, char *args []) { return ER_SUCCESS; } - int check_builtins(State *state, int num_args, char *args[]) { char *builtins[NUM_BUILTINS] = { "cd", @@ -372,6 +385,7 @@ int check_builtins(State *state, int num_args, char *args[]) { int err = join_string(&substitution, num_args - 1, args + 1, " "); if (err) { + free(substitution); return err; } int eqcount = 0; @@ -380,10 +394,22 @@ int check_builtins(State *state, int num_args, char *args[]) { // exit if alias contains an = if (num_parts != 2 || err) { + free(substitution); + for (int i =0; i < num_parts; i++) { + free(new_split[i]); + } + free(new_split); return ER_FAILURE; } err = add_alias(state, new_split[0], new_split[1]); + + free(substitution); + for (int i =0; i < num_parts; i++) { + free(new_split[i]); + } + free(new_split); + return err; } } @@ -427,7 +453,7 @@ int check_builtins(State *state, int num_args, char *args[]) { return ER_NOT_EXISTS; } -int check_aliases(State *state, char **substitution, char *name) { +int check_aliase(State *state, char **substitution, char *name) { Alias alias; for (int i = 0; i < state->num_aliases; i++) { if (!get_alias(&alias, state, name)) { @@ -438,32 +464,40 @@ int check_aliases(State *state, char **substitution, char *name) { return ER_FAILURE; } -int expand_command(State *state, int argc, char* argv[]) { - if (argc == 0) { +int expand_command(State *state, int* argc, char** ret_argv[]) { + if (*argc == 0) { return ER_FAILURE; } + char **argv = *ret_argv; + char *substitution; - if (!check_aliases(state, &substitution, argv[0])) { - strip_char(argv[0], ' '); - argv[0] = reallocarray(argv[0], strlen(substitution) + 1, sizeof(char)); - strcpy(argv[0], substitution); - char *joined; - char **new_argv; - int len; - join_string(&joined, argc, argv, " "); - split_string(&new_argv, &len, joined, ' '); - - run_command(state, len, new_argv); - - for (int i = 0 ; i < len; i ++) { - free(new_argv[i]); - } - free(new_argv); - return ER_SUCCESS; - } else { - run_command(state, argc, argv); + for (int i = 0; i < *argc; i++) { + if (!check_aliase(state, &substitution, argv[i])) { + + strip_char(argv[i], ' '); + + // copy substitution into argv array + *ret_argv[i] = reallocarray(*ret_argv[i], strlen(substitution) + 1, sizeof(char)); + strcpy(*ret_argv[0], substitution); + + // expand substituted piece into the erray splitting over spaces + char *joined; + char **new_argv; + join_string(&joined, *argc, *ret_argv, " "); + split_string(&new_argv, argc, joined, ' '); + + for (int j = 0 ; j < *argc;j ++) { + free(*ret_argv[j]); + } + free(*ret_argv); + + *ret_argv = new_argv; + /***************************************/ + + } } + return ER_SUCCESS; } @@ -476,19 +510,33 @@ int run_command(State *state, int argc, char *argv[]) { return ER_SUCCESS; } -/* read eval print loop until EOF */ +/* read eval print loop until SIGTERM or end of non-interact file*/ int repl(State* state, FILE *input) { while (true) { char *line; if (state->interactive) { - line = readline(state->ps1); - if (!line) - continue; + + char ** ps1_sep; + int num; + split_string(&ps1_sep, &num, state->ps1, ' '); + run_command(state, num, ps1_sep); + for (int i = 0; i < num; i ++) { + free(ps1_sep[i]); + } + free(ps1_sep); + + line = readline("$ "); + if (!line) { + printf("EOF\n"); + return ER_SUCCESS; + } add_history(line); } else { if (get_line(input, &line)) { + if (line) + free(line); return ER_SUCCESS; } } @@ -497,27 +545,27 @@ int repl(State* state, FILE *input) { int num_words; split_string(&sep_string, &num_words, line, ' '); + free(line); - if (num_words == 0) { + if (num_words == 0 // line is empty + || sep_string[0][0] == '#') { // line is comment for (int i = 0; i <= num_words; i ++) free(sep_string[i]); free(sep_string); - free(line); - continue; + continue; // skip execution } -// int err = check_pipes(state, num_words, sep_string); + int err = run_pipes(state, num_words, sep_string); if (err == ER_NOT_EXISTS) { - expand_command(state, num_words, sep_string); + expand_command(state, &num_words, &sep_string); + run_command(state, num_words, sep_string); } - - for (int i = 0; i <= num_words; i ++) { + for (int i = 0; i < num_words; i ++) { free(sep_string[i]); } free(sep_string); - free(line); } } @@ -525,7 +573,7 @@ int startup(State *state, int argc, char **argv) { state->output = stdout; state->ps1 = calloc(3, sizeof(char)); - strcpy(state->ps1, "$ "); + strcpy(state->ps1, "pwd"); state->variables = get_growing_array(INITIAL_NUM_VARIABLES, sizeof(char*)); diff --git a/util.c b/util.c index 8f83e2a..b6da728 100644 --- a/util.c +++ b/util.c @@ -168,14 +168,15 @@ int split_string(char **sep_string[], int *num, char *string, char delim) { int print_chicken(State *state) { char *chicken[] = { - " _\n", - " (o)\n", - " / |\n", - " / |==========\n", - " \\ CHSH /\n", - " \\______/\n", - " |\n", - " _|\n"}; + " _\n", + " (o)\n", + " / |\n", + " / |==========\n", + " \\ CHSH /\n", + "o____o \\______/\n", + " |||| |\n", + " |||| _|\n", + " ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\n\n"}; for (int i = 0; i < 8; i ++) {