Shell-nyush / src / fall22 / test / parser_test.c
parser_test.c
Raw
#include <stdio.h>
#include <stdlib.h>

#include "../main/utils.h"

void testParseNoPiping(char *commandLine) {
    if (checkPipingAndRedirection(commandLine) == 0) {
        int n = parseNoPiping(commandLine);
        printf("[%d parsedTokens]   ", n);
        for (char **temp = parsedTokens; *temp; temp ++) {
            printf("%s   ", *temp);
        }
        printf("Input: (%d, %d, %s); Output: (%d, %d, %s)\n", hasInput, inputIndex, inputFileName, hasOutput, outputIndex, outputFileName);
        free(parsedTokens[0]);
        if (inputFileName) {
            free(inputFileName);
        }
        if (outputFileName) {
            free(outputFileName);
        }
    }
    else {
        printf("[unapplicable]   command involves piping\n");
    }
}

void testCheckPipingAndRedirection(char *commandLine) {
    checkPipingAndRedirection(commandLine);
    if (pipeCount == 0) {
        printf("[passed]   Piped: true; ");
    }
    else {
        printf("[passed]   Piped: false; ");
    }
    if (hasInput) {
        printf("Input: %d; ", inputIndex);
    }
    if (hasOutput == 1) {
        printf("Overwrite: %d; ", outputIndex);
    }
    else if (hasOutput == 2) {
        printf("Append: %d; ", outputIndex);
    }
    printf("\n");
}

void testParseByPipe(char *commandLine) {
    int n = parseByPipe(commandLine);
    printf("[%d pipedCommands]   ", n);
    for (char **temp = pipedCommands; *temp; temp ++) {
        printf("%s   ", *temp);
    }
    printf("\n");
    free(pipedCommands[0]);
}

int main() {

    parsedTokens = malloc(sizeof(char) * MAXLENGTH * MAXLENGTH);
    pipedCommands = malloc(sizeof(char) * MAXLENGTH * MAXLENGTH);

    // Examples of valid commands
    char cmd1[] = "la -a -l";
    char cmd2[] = "cat shell.c | grep main | less";
    char cmd3[] = "cat < input.txt > output.txt";
    char cmd4[] = "cat < input.txt >> output.txt";
    char cmd5[] = "cat < input.txt | cat | cat > output.txt";

    // Examples of invalid commands
    char ivcmd1[] = "cat <";
    char ivcmd2[] = "cat >";
    char ivcmd3[] = "cat |";
    char ivcmd4[] = "| cat";
    char ivcmd5[] = "cat << input.txt";
    char ivcmd6[] = "cat < output.txt < output2.txt";
    char ivcmd7[] = "cat output.txt output2.txt";
    char ivcmd8[] = "cat > output.txt > output2.txt";
    char ivcmd9[] = "cat > output.txt output2.txt";
    char ivcmd10[] = "cat > output.txt | cat";
    char ivcmd11[] = "cat | cat < input.txt";
    char ivcmd12[] = "cd / > output.txt";

    // Test function parseNoPiping
    printf("\n+---------- ---------- ---------- ---------- ----------+"
           "\n|                TESTING PARSENOPIPING                 |"
           "\n+---------- ---------- ---------- ---------- ----------+\n");
    testParseNoPiping(cmd1);
    testParseNoPiping(cmd2);
    testParseNoPiping(cmd3);
    testParseNoPiping(cmd4);
    testParseNoPiping(cmd5);

    // Test function checkPipingAndRedirection
    printf("\n+---------- ---------- ---------- ---------- ----------+"
           "\n|          TESTING CHECKPIPINGANDREDIRECTION           |"
           "\n+---------- ---------- ---------- ---------- ----------+\n");
    testCheckPipingAndRedirection(cmd1);
    testCheckPipingAndRedirection(cmd2);
    testCheckPipingAndRedirection(cmd3);
    testCheckPipingAndRedirection(cmd4);
    testCheckPipingAndRedirection(cmd5);
    testCheckPipingAndRedirection(ivcmd1);  // Undetected: no token after input
    testCheckPipingAndRedirection(ivcmd2);  // Undetected: no token after output
    testCheckPipingAndRedirection(ivcmd3);  // Undetected: no token after pipe
    testCheckPipingAndRedirection(ivcmd4);  // Undetected: no token before pipe
    printf("[error]   Invalid: %s;\n", ivcmd5);
    printf("[error]   Invalid: %s;\n", ivcmd6);
    testCheckPipingAndRedirection(ivcmd7);  // Undetected: invalid command
    printf("[error]   Invalid: %s;\n", ivcmd8);
    testCheckPipingAndRedirection(ivcmd9);  // Undetected: invalid command
    testCheckPipingAndRedirection(ivcmd10);  // Undetected: output not in last argument
    testCheckPipingAndRedirection(ivcmd11);  // Undetected: input not in first argument
    testCheckPipingAndRedirection(ivcmd12);  // Undetected: redirect system call

    // Test function parseByPipe
    printf("\n+---------- ---------- ---------- ---------- ----------+"
           "\n|                 TESTING PARSEBYPIPE                  |"
           "\n+---------- ---------- ---------- ---------- ----------+\n");
    testParseByPipe(cmd1);
    testParseByPipe(cmd2);
    testParseByPipe(cmd3);
    testParseByPipe(cmd4);
    testParseByPipe(cmd5);

    // Free global variables
    free(parsedTokens);
    free(pipedCommands);
    
    return 0;

}