From 00d7dcfa88c08357d6f9be6b75968565ea872c31 Mon Sep 17 00:00:00 2001 From: djairoh Date: Fri, 16 Feb 2024 15:34:28 +0100 Subject: [PATCH] assignment 1 --- Makefile | 12 ++ README.md | 157 +++++++++++++++++++++++ assets/cd.png | Bin 0 -> 43834 bytes assets/prompt.png | Bin 0 -> 51227 bytes assets/starship.png | Bin 0 -> 23052 bytes cmd.c | 300 ++++++++++++++++++++++++++++++++++++++++++++ cmd.h | 49 ++++++++ main.c | 163 ++++++++++++++++++++++++ scanner.c | 203 ++++++++++++++++++++++++++++++ scanner.h | 37 ++++++ shell | Bin 0 -> 22496 bytes shell.c | 249 ++++++++++++++++++++++++++++++++++++ shell.h | 9 ++ 13 files changed, 1179 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 assets/cd.png create mode 100644 assets/prompt.png create mode 100644 assets/starship.png create mode 100644 cmd.c create mode 100644 cmd.h create mode 100644 main.c create mode 100644 scanner.c create mode 100644 scanner.h create mode 100755 shell create mode 100644 shell.c create mode 100644 shell.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a6d3928 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +all: shell + +shell: + gcc -std=c99 -Wall -pedantic main.c scanner.c shell.c cmd.c -o shell + +bonus: + gcc -std=c99 -Wall -DEXT_PROMPT -pedantic main.c scanner.c shell.c cmd.c -o shell + +clean: + rm -f *~ + rm -f *.o + rm -f shell diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ac6f86 --- /dev/null +++ b/README.md @@ -0,0 +1,157 @@ +# general code structure +The main objective of this assignment was to tokenize given inputs and process the resulting tokens according to the given grammar. We decided to seperate the two steps of tokenizing and processing almost entirely, which decouples the input parser from the execution very neatly. The one drawback of this method is that each input is, more or less, processed twice - but we considered this a fair trade-off, as the input for a shell can generally be expected to not be incredulously large. + +The crux of our approach lies in a slight addition to the `ListNode` struct: we have added a single `Enum Type` attribute which places each token within one of a few categories, roughly mapping to the grammar we are implementing. + +The possible values of the `Type` enum are: +Value | Definition | meaning +--- | --- | --- +EXECUTABLE | any non-[operator](#operators) | A command in either `$CWD` or `$PATH`. +OPTION | any non-[operator](#operators) | Any options to pass to an `EXECUTABLE` or `BUILTIN`. +COMPOSITION | '&&', '\|\|', ';', '\n' | Special characters which signal the end of a chain. +BUILTIN | a [builtin](#builtins) | One of a few pre-defined builtin executables. +PIPELINE | '\|' | A pipeline, indicating the preceding and following commands ought to be piped together. +REDIRECT | '<', '>' | Signals `stdin` and/or `stdout` should be handled differently. +BACKGROUND | '&' | Tells the shell to run a given chain as non-blocking (run in the background). +FILENAME | any non[-operator](#operators) | A file (for redirection). + + +### builtins +A builtin for our shell means any specific command which should be handled by the shell internally, as opposed to calling an external executable. +So far, we have implemented: +Builtin | Result +--- | --- +status | prints the return status of the last run command. +exit | exits the shell. +true | sets status to `0`. +false | sets status to `-1`. +cd | changes the current working directory. +debug | prints debugging information to `stdout`. + +### operators +An operator is a special token which tells the shell to process the preceding (and following) chain differently. +The standard operators are (or will be) implemented by this shell: +Operator | Name | Effect +--- | --- | --- +"&" | Background operator | Tells the shell ro run a chain in the background. +"&&" | Conditional and | Tells the shell to execute the next chain iff the status of the previous chain equals `0`. +"\|\|" | Conditional or | Tells the shell to execute the next chain iff the status of the previous chain does not equal `0`. +";" | Seperator | Tells the shell when a chain ends. +"<" | Redirect in | Tells the shell to take input from a non-`stdin` stream. +">" | Redirect out | Tells the shell to print output to a non-`stdout` stream. +"\|" | Pipe operator | Tells the shell to chain commands together. + + +## processing +After parsing a complete line and assigning each token a Type, the next step of the program is the actual processing. +To aid in this, we have constructed a few different types - defined in `cmd.h` - which model various parts of a typical shell execution. + +The `Command` struct models one executable and its' options, arranged in `char *` and `char **` to easily pass them to an `exec()` system call. +```c +typedef struct Command { + char **arguments; + char *command; + int capacity; + int numArguments; +} Command; +``` + +The `CommandList` struct models a list of Commands, and will be used when multiple commands are to be executed together (as is the case when piping commands, or using the background operator). +```c +typedef struct CommandList { + Command *commands; + int capacity; + int numCommands; +} CommandList; +``` + +The `Chain` struct models one complete chain to be executed. It is currently a bit barebones, but will be expanded when we implement piping, redirection, and running in the background. +```c +typedef struct Chain { + CommandList commands; + bool runInBackground; +} Chain; +``` + +These structs all come with some library functions for ease of use, which allow us to build up commands and chains, and execute them appropriately. + + +## main +The driver code behind the program lives (obviously) in `main()`. + +//TODO you were writing here + + +# bonuses +We have enhanced the functionality of our shell by implementing a few bonuses. These are described in this section. + +## cd builtin +Any self-respecting shell needs a way to change the current working directory. Luckily for the end-user, we have implemented exactly that! +Use the builtin `cd` to move around the system. We even added support for moving to the `$HOME` directory - accomplished by witholding any command options (just `cd` will get you home). + +Note that this builtin has side-effects, and might therefore edit `status`. If changing directories fails for whatever reason (insufficient permissions, destination doesn't exist, etc), `status` *will* be set to -1. + +This builtin provides interactions like these ('>' is input, added in post): +```shell +>realpath . +/home/djairoh/Nextcloud/opsys/assignments/1/src +>cd /home/djairoh/Documents +>realpath . +/home/djairoh/Documents +>cd +>realpath . +/home/djairoh +``` + +## debug mode +To get an insight into how the shell works under the hood, we've added a custom builtin: +with the `debug` flag, all executed commands will be laid out in glorious JSON format. + +This builtin is a toggle, meaning a second use will disable it once more. Provided below is some example input/output with this builtin on. Lines starting with '>' are input (the '>' was manually added post-fact). + +```shell +>debug +Toggled debug to 1. +>echo "hello, world!" +{ +"commandList": { + "commands": [ + { + "arguments": [ + "echo", + "hello, world!", + "(null)" + ], + "command": "echo", + "capacity": 4, + "numArguments": 3 + }], + "capacity": 4, + "numCommands": 1 + }, +"runInBackground": 0 +} +hello, world! +``` + +## shell prompt (coloured) +Standard in any shell is a prompt. These can range from minimalist (the `sh` prompt only shows the current version of the shell), to things as complicated and customizable as the [Starship](https://starship.rs/) prompt - of which an example is provided here: + +![An example of a Starship prompt](./assets/starship.png) + +While we didn't quite get around to this level of complexity, we have implemented a little prompt consisting of three components: + * the username of the person who started the shell + * the current working directory + * the status/status of the last command, indicated by '>' + +The end result looks like this: + +![Our own (less impressive) prompt](./assets/prompt.png) + +## true / false +The smallest of our extra implementations, we have added two `builtin`s which directly modify `status`. + + * The builtin `true` will set `status` to `0`. + * The builtin `false` will set `status` to `-1`. + + Really this was more of an implementation to allow us to do proper debugging, but it's still something we added to the shell that was not specifically part of the assignment, so we decided we may as well document it here. diff --git a/assets/cd.png b/assets/cd.png new file mode 100644 index 0000000000000000000000000000000000000000..2c23c068c6e0d97d4e3cbb48034038c5e951476d GIT binary patch literal 43834 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 pMpL=COY$VARTLdadR-y97Mp;aUy)5GL!uz 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 literal 0 HcmV?d00001 diff --git a/assets/starship.png b/assets/starship.png new file mode 100644 index 0000000000000000000000000000000000000000..9c6b19be33743f7019d614fab17d266f499944bf GIT binary patch literal 23052 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 +#include +#include +#include +#include +#include "scanner.h" + +/** + * This function instantiates an empty command. + */ +Command _newCommand() { + Command cmd; + cmd.capacity = INITIAL_ARRAY_SIZE; + cmd.arguments = calloc(INITIAL_ARRAY_SIZE, sizeof(char**)); + cmd.numArguments = 0; + return cmd; +} + +/** + * This function instantiates an empty commandlist. + */ +CommandList _newCommandList() { + CommandList list; + list.capacity = INITIAL_ARRAY_SIZE; + list.commands = calloc(INITIAL_ARRAY_SIZE, sizeof(Command)); + list.numCommands = 0; + return list; +} + +/** + * This function instantiates an empty chain. + */ +Chain _newChain() { + Chain chain; + chain.commands = _newCommandList(); + chain.runInBackground = false; + return chain; +} + +/** + * This function frees a command. + * Note that it only frees the char**, not the strings/char*s themselves, as these are part of the TokenList. + */ +void freeCommand(Command cmd) { + free(cmd.arguments); +} + +/** + * This function frees a commandlist. + * To do so, it frees all commands in .numCommands + */ +void _freeCommandList(CommandList list) { + for (int i=0; i < list.numCommands; i++) { + freeCommand(list.commands[i]); + } + free(list.commands); +} + +// This function frees a chain. +void freeChain(Chain chain) { + _freeCommandList(chain.commands); +} + + +/** + * This function inserts a given argument into a given command. + * @param cmd the command to insert the argument into. + * @param str the argument to be inserted. + */ +void insertArgument_(Command *cmd, char* str) { + //resize arguments pointer if necessary. + if (cmd->numArguments >= cmd->capacity) { + cmd->arguments = realloc(cmd->arguments, 2*cmd->capacity*sizeof(Command)); + cmd->capacity *= 2; + } + cmd->arguments[cmd->numArguments++] = str; +} + +/** + * This function builds a command from a given listPointer. + * It expects the current listPointer to be either of type EXECUTABLE of BUILTIN, + * followed by any number of OPTIONs. + * @param lp the list to read from. + * @return a new Command. + */ +Command buildCommand(List *lp) { + Command cmd = _newCommand(); + + //exit on invalid syntax. This should not be reachable, if our parser is correct. + if ((*lp)->type != EXECUTABLE && (*lp)->type != BUILTIN) exit(1); + + // insert command as first entry + insertArgument_(&cmd, (*lp)->t); + *lp = (*lp)->next; + + //insert rest of arguments + while (*lp != NULL && (*lp)->type == OPTION) { + insertArgument_(&cmd, (*lp)->t); + *lp = (*lp)->next; + } + + // execvp() expects a NULL terminated list of options. + insertArgument_(&cmd, NULL); + + //for ease of access we define the command attribute as pointing towards the first arguments entry (which contains the command to be executed) + cmd.command = cmd.arguments[0]; + return cmd; +} + +/** + * This function inserts a command into a given commandList. + * @param cmd the Command to insert. + * @param List the commandList to insert the command into. + */ +void _insertCommand(Command cmd, CommandList *list) { + //resize commands pointer if necessary. + if (list->numCommands >= list->capacity) { + list->commands = realloc(list->commands, 2*list->capacity*sizeof(Command)); + list->capacity *= 2; + } + list->commands[list->numCommands++] = cmd; +} + +/** + * This function build up one chain of commands from a given listPointer. + * It parses one 'unit' of executables, meaning any number of commands+options chained together by pipes and redirects. + * It closely models the given grammar for a chain, witth the exception of also parsing the background operator '&'. (and it doesn't like builtins either, we handle those seperately). + * @param lp the list to construct a chain from. + * @return a new Chain. + */ +Chain buildChain(List *lp) { + Chain chain = _newChain(); + Command cmd; + + //exit on invalid syntax. This should not be reachable, if our parser is correct. + if ((*lp) == NULL || (*lp)->type != EXECUTABLE) exit(1); + + // so long as we have tokens to parse, do so. We exit from within the loop if: + // we encounter a syntax error (OPTION, BUILTIN, or FILENAME - these should be consumed as we construct the Chain) or + // we encounter a COMPOSITION operator - meaning this chain is complete, and the remainder of lp is to be processed elsewhere. + while ((*lp) != NULL) { + switch ((*lp)->type) { + // finding a command means we must insert it into the commandList. + case EXECUTABLE: + cmd = buildCommand(lp); + _insertCommand(cmd, &chain.commands); + break; + + //finding a chain operator means we want to continue evaluating, so we consume the operator. + case PIPELINE: + *lp = (*lp)->next; + break; + + // finding a redirect means a bunch of things we haven't thought out yet. + case REDIRECT: + //TODO: implement redirect + break; + + // finding a background operator means two things: + // 1. we must run this chain in the background. + // 2. we have reached the end of this chain. + case BACKGROUND: + chain.runInBackground = true; + *lp = (*lp)->next; + + // finding a COMPOSITION operator indicates we reached the end of this chain. + case COMPOSITION: + return chain; + + // finding any of an OPTION, BUILTIN, or FILENAME means a syntax error (and thus a faulty parser)- these should not be reachable. + case OPTION: + case BUILTIN: + case FILENAME: + freeChain(chain); + exit(1); + } + } + return chain; +} + +/** + * This function executes a given command in a child process. + * To make this a blocking operation, the parent process will wait until the child exits - simultaneously updating the status variable. + * @param cmd the Command to execute. + * @param status variable which will contain the exit status of the command. + */ +void _executeCommand(Command cmd, int* status) { + pid_t pid = fork(); + + switch (pid) { + // fork failed. + case -1: + printf("ERROR: failed to create child!\n"); + *status = -1; + break; + case 0: + // child process + execvp(cmd.command, cmd.arguments); + //this line is only ever reached if execvp fails (for example, when an executable can't be found). + exit(127); + break; + default:; + // parent process; wait for child and update status. + int stat; + wait(&stat); + if (WIFEXITED(stat)) { + *status = WEXITSTATUS(stat); + } + } +} + +// TODO: extend to include I/O redirection and background operation +/** + * This function executes all commands in a given chain. + * It updates the status as it does so. + * This function is barebones at the moment, but will be expanded to include support for redirection and non-blocking execution. + * @param chain the Chain to execute. + * @param status variable which will contain the exit status after execution. +*/ +void executeChain(Chain chain, int* status) { + for (int i=0; i < chain.commands.numCommands; i++) { + _executeCommand(chain.commands.commands[i], status); + } +} + +/** + * This function executes a BUILTIN. + * BUILTINs are pre-defined commands ran within the shell itself, as opposed to executables found in $PATH or $CWD. + * @param cmd the BUILTIN to execute. + * @param status the return status of the last run command. + * @return a boolean which indicates whether to keep running the shell or not. + */ +#if EXT_PROMPT +bool executeBuiltin(Command cmd, int *status, bool *debug) { +#else +bool executeBuiltin(Command cmd, int *status) { +#endif + if (!strcmp(cmd.command, "status")) { + printf("The most recent exit code is: %d.\n", *status); + } else if (!strcmp(cmd.command, "exit")) { + return false; + } else if (!strcmp(cmd.command, "true")) { + *status = 0; + } else if (!strcmp(cmd.command, "false")) { + *status = 1; + #if EXT_PROMPT + } else if (!strcmp(cmd.command, "debug")) { + *debug = ! *debug; + printf("Toggled debug to %d.\n", *debug); + } else if (!strcmp(cmd.command, "cd")) { + if (cmd.numArguments == 2) { + char *PWD = getenv("HOME"); + *status = chdir(PWD); + } else { + *status = chdir(cmd.arguments[1]); + } + #endif + }// can be expanded by growing the if/else chain. + return true; +} + +/** + * This function prints one Command in json. + * Intended to be used in tandem with printChain and printCommandList. + * @param cmd the command to print. + */ +void _printCommand(Command cmd) { + printf("{\n \"arguments\": [\n"); + for (int i=0; i < cmd.numArguments; i++) { + printf(" \"%s\"", cmd.arguments[i]); + if (i < cmd.numArguments-1) printf(",\n"); + } + printf("\n ],\n \"command\": \"%s\",\n \"capacity\": %d,\n \"numArguments\": %d\n }", cmd.command, cmd.capacity, cmd.numArguments); +} + +/** + * This function prints a commandList in json. + * Intended to be used with printCommand and printChain. + * @param list the list to print. + */ +void _printCommandList(CommandList list) { + printf("{\n \"commands\": [\n "); + for (int i=0; i < list.numCommands; i++) { + _printCommand(list.commands[i]); + if (i < list.numCommands-1) printf(", "); + } + printf("],\n \"capacity\": %d,\n \"numCommands\": %d\n }", list.capacity, list.numCommands); +} + +/** + * This function prints a Chain in json. + * Intended to be used with printCommand and printCommandList. + * @param chain the chain to print. + */ +void printChain(Chain chain) { + printf("{\n\"commandList\": "); + _printCommandList(chain.commands); + printf(",\n\"runInBackground\": %d\n}\n", chain.runInBackground); +} diff --git a/cmd.h b/cmd.h new file mode 100644 index 0000000..cfa7d33 --- /dev/null +++ b/cmd.h @@ -0,0 +1,49 @@ +#ifndef CMD_H +#define CMD_H + +#include +#include "scanner.h" +#define INITIAL_ARRAY_SIZE 4 + +// models one executable + options +// thanks to the use of pointers, not as wasteful of memory as it might at first appear. +// this struct makes it much easier to pass a TokenList to an exec() system call. +typedef struct Command { + char **arguments; + char *command; + int capacity; + int numArguments; +} Command; + +// models a list of commands +// used to properly handle piping. +typedef struct CommandList { + Command *commands; + int capacity; + int numCommands; +} CommandList; + +// models one complete chain of numCommands +// For lab1, somewhat barebones. +// Will be expanded upon when we implement redirection/background processes/piping +typedef struct Chain { + CommandList commands; + bool runInBackground; +} Chain; + + +void freeCommand(Command cmd); +void freeChain(Chain chain); + +Command buildCommand(List *lp); +Chain buildChain(List *lp); + +void executeChain(Chain chain, int* status); +#if EXT_PROMPT +bool executeBuiltin(Command cmd, int *status, bool *debug); +#else +bool executeBuiltin(Command cmd, int *status); +#endif + +void printChain(Chain chain); +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..99ea954 --- /dev/null +++ b/main.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "scanner.h" +#include "shell.h" +#include "cmd.h" + +// general TODO: +// * properly bind stdin/stdout for piped commands +// * run chains in bg if given '&' +// * manage < and > redirects +// * signal handling +// * builtins - 'kill' + +/** + * This function skips one COMMAND, including redirects and pipes (if any). + * This is used to move to the next command when a COMPOSITION operator fails. + * @param lp ListPointer containing remaining Tokens, + */ +void skipCommand(List *lp) { + *lp = (*lp)->next; + while (*lp != NULL) { + switch ((*lp)->type) { + case PIPELINE: + case REDIRECT: + case FILENAME: + case OPTION: + case EXECUTABLE: + case BUILTIN: + *lp = (*lp)->next; + break; + case COMPOSITION: + case BACKGROUND: + *lp = (*lp)->next; + return; + } + } +} + +/** + * This function checks whether the current COMPOSITION operator passes (and thus should execute the next function). + * @param s the COMPOSITION operator. + * @param status the exit status of the last ran command. + * @return whether the COMPOSITION succeeds/whether to execute the next command. + */ +bool compositionPasses(char *s, int status) { + if (!strcmp(s, "&&") && ! status) return true; + else if (!strcmp(s, "||") && status) return true; + else if (s[0] == ';' || s[0] == '\n') return true; + + return false; +} + +/** + * Driver function. Contains the main loop which collects and parses input, and decides what and how to execute + output. + */ +int main(int argc, char *argv[]) { + char *inputLine; + List tokenList; + int status = 0; + bool do_loop = true; + #if EXT_PROMPT + bool debug = false; + char cwd[101], *usr; + #endif + + // Disable buffering so we don't have to deal with out-of-order prints. + setbuf(stdin, NULL); + setbuf(stdout, NULL); + + // The main loop body. Each iteration means one line of input. + // Will run until either EOF or the BUILTIN exit is given. + while (do_loop) { + #if EXT_PROMPT + getcwd(cwd, sizeof(cwd)); + usr = getlogin(); + if (!status) printf("\x1b[33m%s \x1b[36m%s \x1b[32m>\x1b[0m ", usr, cwd); + if ( status) printf("\x1b[33m%s \x1b[36m%s \x1b[31m>\x1b[0m ", usr, cwd); + #endif + inputLine = readInputLine(); + // We have modified the readInputLine function to return NULL on EOF. + if (inputLine == NULL) { + do_loop = false; + break; + } + tokenList = getTokenList(inputLine); + + // Because lists are pointers, we need copies so we can access the list later. + List cpy = tokenList, og = tokenList; + if (parseInputLine(&tokenList) && tokenList == NULL ) { + // Consume the entire tokenList (through cpy). + while (cpy != NULL) { + switch (cpy->type) { + // A BUILTIN needs to be executed slightly differently than a COMMAND: + // BUILTINS cannot be redirected/piped. + case BUILTIN:; + Command cmd = buildCommand(&cpy); + // If execcuteBuiltin returns false, the BUILTIN was 'exit' and we should stop the shell. + #if EXT_PROMPT + if (! executeBuiltin(cmd, &status, &debug)) { + #else + if (!executeBuiltin(cmd, &status)) { + #endif + do_loop = false; + cpy = NULL; + } + freeCommand(cmd); + break; + + // Finding an EXECUTABLE means we need to construct the appropriate chain (in case of redirects/pipes), and then run it. + case EXECUTABLE:; + Chain chain = buildChain(&cpy); + #if EXT_PROMPT + if (debug) printChain(chain); + #endif + executeChain(chain, &status); + freeChain(chain); + // Status 127 is returned when an EXECUTABLE cannot be found. This requires an extra line to stdout. + if (status == 127) { + printf("Error: command not found!\n"); + } + break; + + // Upon finding a COMPOSITION, we check if it succeeds. if yes, we consume the operator and continue. + // If not, we skip the next command entirely. + case COMPOSITION:; + if (compositionPasses(cpy->t, status)) { + cpy = cpy->next; + } else { + skipCommand(&cpy); + } + break; + + // Encountering any of BACKGROUND, OPTION, PIPELINE, REDIRECT, or FILENAME here means either we are dealing with incorrect syntax, + // or a function did not correctly consume tokens. + case BACKGROUND: + case OPTION: + case PIPELINE: + case REDIRECT: + case FILENAME: + printf("Error: invalid syntax!\n"); + cpy = NULL; + break; + } + } + } else { + // If tokenList was not parsed successfully, the syntax must be incorrect. + printf("Error: invalid syntax!\n"); + } + + // Memory. + free(inputLine); + freeTokenList(og); + } + + return 0; +} diff --git a/scanner.c b/scanner.c new file mode 100644 index 0000000..ad590b7 --- /dev/null +++ b/scanner.c @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include +#include + +#include "scanner.h" + +//TODO: handle EOF more completely (currently only EOF at the start of the line is handled) +/** + * Reads an inputline from stdin. + * @return a string containing the inputline. + */ +char *readInputLine() { + int strLen = INITIAL_STRING_SIZE; + int c = getchar(); + int i = 0; + + // part of EOF handling; return NULL when EOF is encountered at the start of input. + // this is further handled in main(). + if (c == -1) { + return NULL; + } + + char *s = malloc((strLen + 1) * sizeof(*s)); + assert(s != NULL); + + bool quoteStarted = false; + while (c != '\n' || quoteStarted) { // Ensure that newlines in strings are accepted + if (c == '\"') { + quoteStarted = !quoteStarted; + } + s[i++] = c; + + if (i >= strLen) { // Resize the string if necessary + strLen = 2 * strLen; + s = realloc(s, (strLen + 1) * sizeof(*s)); + assert(s != NULL); + } + c = getchar(); + } + s[i] = '\0'; + return s; +} + +/** + * The function isOperatorCharacter checks whether the input paramater \param c is an operator. + * @param c input character. + * @return a bool denoting whether \param c is an operator. + */ +bool _isOperatorCharacter(char c) { + return c == '&' || c == '|' || c == ';' || c == '<' || c == '>'; +} + +/** + * Reads an identifier in string \param s starting at index \param start. + * @param s input string. + * @param start starting index in string \param s. + * @return a pointer to the start of the identifier string + */ +char *_matchIdentifier(char *s, int *start) { + int strLen = INITIAL_STRING_SIZE; + int pos = 0, offset = 0; + + char *ident = malloc((strLen + 1) * sizeof(*ident)); + assert(ident != NULL); + + bool quoteStarted = false; + size_t lenS = strlen(s); + while ((*start + offset <= lenS && !isspace(s[*start + offset]) && !_isOperatorCharacter(s[*start + offset])) || quoteStarted) { // Ensure that whitespace in strings is accepted + if (s[*start + offset] == '\"') { // Strip the quotes from the input before storing in the identifier + quoteStarted = !quoteStarted; + offset++; + continue; + } + ident[pos++] = s[*start + offset++]; + if (pos >= strLen) { // Resize the string if necessary + strLen = 2 * strLen; + ident = realloc(ident, (strLen + 1) * sizeof(*ident)); + assert(ident != NULL); + } + } + ident[pos] = '\0'; + *start = *start + offset; + return ident; +} + +/** + * The function newNode makes a new node for the token list and fills it with the token that + * has been read. Precondition: !isspace(a[*ip]). + * @param s input string. + * @param start starting index in string \param s. + * @return a list node that contains the current token. + */ +List _newNode(char *s, int *start) { + List node = malloc(sizeof(*node)); + assert(node != NULL); + node->next = NULL; + node->t = _matchIdentifier(s, start); + return node; +} + +/** + * Reads an operator in string \param s starting at index \param start. + * @param s input string. + * @param start starting index in string \param s. + * @return a pointer to the start of the operator string. + */ +char *_matchOperator(char *s, int *start) { + int strLen = 2; // the operator consists of *at most* 2 characters + int pos = 0, offset = 0; + + char *op = malloc((strLen + 1) * sizeof(*op)); + assert(op != NULL); + + while (_isOperatorCharacter(s[*start + offset])) { + op[pos++] = s[*start + offset++]; + } + op[pos] = '\0'; + *start = *start + offset; + return op; +} + +/** + * The function newOperatorNode makes a new operator node for the token list and fills it with the token that + * has been read. Precondition: !isspace(a[*ip]). + * @param s input string. + * @param start starting index in string \param s. + * @return a list node that contains the current token. + */ +List _newOperatorNode(char *s, int *start) { + List node = malloc(sizeof(*node)); + assert(node != NULL); + node->next = NULL; + node->t = _matchOperator(s, start); + return node; +} + +/** + * The function tokenList reads an array and puts the tokens that are read in a list. + * @param s input string. + * @return a pointer to the beginning of the list. + */ +List getTokenList(char *s) { + List lastNode = NULL; + List node = NULL; + List tl = NULL; + int i = 0; + int length = strlen(s); + while (i < length) { + if (isspace(s[i])) { // spaces are skipped + i++; + }else { + node = _isOperatorCharacter(s[i]) ? _newOperatorNode(s, &i) : _newNode(s, &i); + if (lastNode == NULL) { // there is no list yet + tl = node; + } else { // a list already exists; add current node at the end + (lastNode)->next = node; + } + lastNode = node; + } + } + return tl; +} + +/** + * Checks whether list \param l is empty. + * @param l input list. + * @return a bool denoting whether \param l is empty. + */ +bool isEmpty(List l) { + return l == NULL; +} + +/** + * The function printList prints the tokens in a token list, separated by commas. + * @param li the input list to be printed. + */ +void printList(List li) { + if (li == NULL) return; + printf("(\"%s\", \"%d\")", li->t, li->type); + li = li->next; + while (li != NULL) { + printf("(\"%s\", \"%d\")", li->t, li->type); + li = li->next; + } + printf("\n"); +} + +/** + * The function freeTokenlist frees the memory of the nodes of the list, and of the strings + * in the nodes. + * @param li the starting node of a list. + */ +void freeTokenList(List li) { + if (li == NULL) { + return; + } + free(li->t); + freeTokenList(li->next); + free(li); +} diff --git a/scanner.h b/scanner.h new file mode 100644 index 0000000..68b0496 --- /dev/null +++ b/scanner.h @@ -0,0 +1,37 @@ +#ifndef SCANNER_H +#define SCANNER_H + +#define INITIAL_STRING_SIZE 10 + +// This enum denotes what type of variable a token is. +enum Type { + EXECUTABLE, // a command in either $CWD or $PATH + OPTION, // any options to pass to an executable or builtin + COMPOSITION, // '&&', '||', ';', '\n' + BUILTIN, // one of a few pre-defined builtin executables + PIPELINE, // '|' + REDIRECT, // '<' or '>' + BACKGROUND, // '&' + FILENAME // a file (for redirection) +}; + +typedef struct ListNode *List; + +typedef struct ListNode { + char *t; + enum Type type; + List next; +} ListNode; + + +char *readInputLine(); + +List getTokenList(char *s); + +bool isEmpty(List l); + +void printList(List l); + +void freeTokenList(List l); + +#endif diff --git a/shell b/shell new file mode 100755 index 0000000000000000000000000000000000000000..3f2b44ec9d6c5a156a24ce65ed1176732d386a9c GIT binary patch literal 22496 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 Z_p;(o*Q=;>Rx`MK1^45mEP +#include + +#include "scanner.h" + +/** + * The function _acceptToken checks whether the current token matches a target identifier. + * if this is the case, it will mark this token as the given Type, then move to the next token. + * @param lp List pointer to the start of the tokenlist. + * @param ident target identifier + * @param type enum describing the nature to assign if the token is accepted. + * @return a bool denoting whether the current token matches the target identifier. + */ +bool _acceptToken(List *lp, char *ident, enum Type type) { + if (*lp != NULL && strcmp(((*lp)->t), ident) == 0) { + (*lp)->type = type; + *lp = (*lp)->next; + return true; + } + return false; +} + +/** + * The function parseExecutable parses an executable. + * @param lp List pointer to the start of the tokenlist. + * @return a bool denoting whether the executable was parsed successfully. + */ +bool _parseExecutable(List *lp) { + char s = (*lp)->t[0]; + // Right now we only check if the first character is illegal (to prevent an operator token from mistakenly being assigned a COMMAND type.) + switch (s) { + case '|': + case '&': + case ';': + case '\n': + case '>': + case '<': + return false; + } + + (*lp)->type = EXECUTABLE; + *lp = (*lp)->next; + return true; +} + +/** + * Checks whether the input string \param s is an operator. + * @param s input string. + * @return a bool denoting whether the current string is an operator. + */ +//bool isOperator(char *s) { +bool _isOperator(List *lp) { + // NULL-terminated array makes it easy to expand this array later + // without changing the code at other places. + char *operators[] = { + "&", + "&&", + "||", + ";", + "<", + ">", + "|", + NULL + }; + + for (int i = 0; operators[i] != NULL; i++) { + if (strcmp((*lp)->t, operators[i]) == 0) { + return true; + } + } + return false; +} + +/** + * The function parseOptions parses options. + * @param lp List pointer to the start of the tokenlist. + * @return a bool denoting whether the options were parsed successfully. + */ +bool _parseOptions(List *lp) { + while (*lp != NULL && !_isOperator(lp)) { + (*lp)->type = OPTION; + (*lp) = (*lp)->next; + } + return true; +} + +/** + * The function parseRedirections parses a command according to the grammar: + * + * ::= + * + * @param lp List pointer to the start of the tokenlist. + * @return a bool denoting whether the command was parsed successfully. + */ +bool _parseCommand(List *lp) { + return _parseExecutable(lp) && _parseOptions(lp); +} + +/** + * The function parsePipeline parses a pipeline according to the grammar: + * + * ::= "|" + * | + * + * @param lp List pointer to the start of the tokenlist. + * @return a bool denoting whether the pipeline was parsed successfully. + */ +bool _parsePipeline(List *lp) { + if (!_parseCommand(lp)) { + return false; + } + + if (_acceptToken(lp, "|", PIPELINE)) { + return _parsePipeline(lp); + } + + return true; +} + +/** + * The function parseFileName parses a filename. + * @param lp List pointer to the start of the tokenlist. + * @return a bool denoting whether the filename was parsed successfully. + */ +bool _parseFilename(List *lp) { + //we run a POSIX compliant system, meaning all characters save '/' and NULL are allowed in filenames. + //NULL is already taken care of by the List library, and / just means the file is located in a directory. + //as a result the only limit we place on filenames are the reserved (operator) characters. + switch ((*lp)->t[0]) { + case '|': + case '&': + case ';': + case '\n': + case '>': + case '<': + return false; + } + (*lp)->type = FILENAME; + *lp = (*lp)->next; + return true; +} + +/** + * The function parseRedirections parses redirections according to the grammar: + * + * ::= + * | + * + * @param lp List pointer to the start of the tokenlist. + * @return a bool denoting whether the redirections were parsed successfully. + */ +bool _parseRedirections(List *lp) { + if (isEmpty(*lp)) { + return true; + } + + if (_acceptToken(lp, "<", REDIRECT)) { + if (!_parseFilename(lp)) return false; + if (_acceptToken(lp, ">", REDIRECT)) return _parseFilename(lp); + else return true; + } else if (_acceptToken(lp, ">", REDIRECT)) { + if (!_parseFilename(lp)) return false; + if (_acceptToken(lp, "<", REDIRECT)) return _parseFilename(lp); + else return true; + } + + return true; +} + +/** + * The function parseBuiltIn parses a builtin. + * @param lp List pointer to the start of the tokenlist. + * @return a bool denoting whether the builtin was parsed successfully. + */ +bool _parseBuiltIn(List *lp) { + // NULL-terminated array makes it easy to expand this array later + // without changing the code at other places. + char *builtIns[] = { + "exit", + "status", + "true", + "false", + #if EXT_PROMPT + "debug", + "cd", + #endif + NULL + }; + + for (int i = 0; builtIns[i] != NULL; i++) { + if (_acceptToken(lp, builtIns[i], BUILTIN)) { + return true; + } + } + + return false; +} + +/** + * The function parseChain parses a chain according to the grammar: + * + * ::= + * | + * + * @param lp List pointer to the start of the tokenlist. + * @return a bool denoting whether the chain was parsed successfully. + */ +bool _parseChain(List *lp) { + if (_parseBuiltIn(lp)) { + return _parseOptions(lp); + } + if (_parsePipeline(lp)) { + return _parseRedirections(lp); + } + return false; +} + +/** + * The function parseInputLine parses an inputline according to the grammar: + * + * ::= & + * | && + * | || + * | ; + * | + * | + * + * @param lp List pointer to the start of the tokenlist. + * @return a bool denoting whether the inputline was parsed successfully. + */ +bool parseInputLine(List *lp) { + if (isEmpty(*lp)) { + return true; + } + + if (!_parseChain(lp)) { + return false; + } + + if (_acceptToken(lp, "&", BACKGROUND) || _acceptToken(lp, "&&", COMPOSITION)) { + return parseInputLine(lp); + } else if (_acceptToken(lp, "||", COMPOSITION)) { + return parseInputLine(lp); + } else if (_acceptToken(lp, ";", COMPOSITION)) { + return parseInputLine(lp); + } + + return true; +} diff --git a/shell.h b/shell.h new file mode 100644 index 0000000..0837c44 --- /dev/null +++ b/shell.h @@ -0,0 +1,9 @@ +#ifndef SHELL_SHELL_H +#define SHELL_SHELL_H + +#include "scanner.h" +#include + +bool parseInputLine(List *lp); + +#endif