From 9eefade7c68ce58cff47a854680f84ba110876fd Mon Sep 17 00:00:00 2001 From: Rushil Umaretiya Date: Thu, 25 Apr 2024 22:56:40 -0400 Subject: [PATCH] finished parse --- shell.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/shell.c b/shell.c index 9e1bb12..f4fe04e 100644 --- a/shell.c +++ b/shell.c @@ -20,7 +20,73 @@ void cleanup(command_t* p_cmd) { } } -void parse(char* line, command_t* p_cmd) {} +/** + * Parses line (input from user) into command_t* p_cmd. + * + * Determine the number of arguments via string parsing. + * Then, set p_cmd->argc to the correct value, + * and allocate memory for p_cmd->argv. + * Finally, ***copy*** the arguments from line into p_cmd->argv. + * + * When copying the arguments, do not simply assign pointers. You must + * use str(n)cpy (or reimplement its logic) to copy the arguments. + * + * p_cmd is NULL when this function is called (see main.c). + * + * Example 1: If line is "cd /mnt/cdrom", then the fields in p_cmd should be + * {argc = 2, argv = {"cd", "mnt/cdrom", NULL}} + * + * Example 2: If line is "ls -la", then the fields in p_cmd should be + * {argc = 2, argv = {"ls, "-la", NULL}} + * + * Example 3: If line is NULL, then the fields in p_cmd should be {argc = + * 0, argv = {NULL}} + * + * Example 4: If line is " ls -la ", then the fields in p_cmd should be + * the same as in example 2. Note the additional whitespace in the input. + * + * We recommend using strtok to handle this parsing. + * https://systems-encyclopedia.cs.illinois.edu/articles/c-strtok/ + * + * strtok's functionality is similar to that of split in Python or Java. + * For example, in Python, we can do + * + * >>> "cd /mnt/cdrom".split(" ") + * ['cd', '/mnt/cdrom'] + * + * When used correctly, strtok will handle all of the above cases correctly. + * Alternatively, you may reimplement tokenizing logic yourself, but be sure to + * handle example 4 (extra whitespace) correctly. + * + * NOTE: strtok mutates the input char* (by inserting null terminators). So, to + * be safe, you should use strtok on a clone of the input char*. You can create + * a clone using strdup. + * + * @param line string input from user + * @param p_cmd pointer to struct that will store the parsed command + * @return void + */ + +void parse(char* line, command_t* p_cmd) { + char* line_copy = strdup(line); + char* argc_token = strtok(line_copy, " "); + p_cmd->argc = 0; + + while (argc_token != NULL) { + p_cmd->argc++; + argc_token = strtok(NULL, " "); + } + + alloc_mem_for_argv(p_cmd); + + line_copy = strdup(line); + char* argv_token = strtok(line_copy, " "); + + for (int i = 0; i < p_cmd->argc; i++) { + strcpy(p_cmd->argv[i], argv_token); + argv_token = strtok(NULL, " "); + } +} bool find_full_path(command_t* p_cmd) { // TODO: