From 73bf2e5058fb46adf652cc823d2591995c7b2ee7 Mon Sep 17 00:00:00 2001
From: vyvyvyThao <wn73@drexel.edu>
Date: Wed, 12 Feb 2025 22:10:13 -0500
Subject: [PATCH] Upload A3

---
 3-Shell/.vscode/settings.json |   5 +
 3-Shell/dsh                   | Bin 0 -> 24856 bytes
 3-Shell/dsh_cli.c             |  84 ++++++++++++++
 3-Shell/dshlib.c              | 161 ++++++++++++++++++++++++++
 3-Shell/dshlib.h              |  50 ++++++++
 3-Shell/makefile.txt          |  27 +++++
 3-Shell/test.sh               | 212 ++++++++++++++++++++++++++++++++++
 7 files changed, 539 insertions(+)
 create mode 100644 3-Shell/.vscode/settings.json
 create mode 100755 3-Shell/dsh
 create mode 100644 3-Shell/dsh_cli.c
 create mode 100644 3-Shell/dshlib.c
 create mode 100644 3-Shell/dshlib.h
 create mode 100644 3-Shell/makefile.txt
 create mode 100644 3-Shell/test.sh

diff --git a/3-Shell/.vscode/settings.json b/3-Shell/.vscode/settings.json
new file mode 100644
index 0000000..d4a224b
--- /dev/null
+++ b/3-Shell/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+    "files.associations": {
+        "ctype.h": "c"
+    }
+}
\ No newline at end of file
diff --git a/3-Shell/dsh b/3-Shell/dsh
new file mode 100755
index 0000000000000000000000000000000000000000..a8c1465c640b180fbb9787195897c4d0481646df
GIT binary patch
literal 24856
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

literal 0
HcmV?d00001

diff --git a/3-Shell/dsh_cli.c b/3-Shell/dsh_cli.c
new file mode 100644
index 0000000..4b3b192
--- /dev/null
+++ b/3-Shell/dsh_cli.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dshlib.h"
+
+/*
+ * Implement your main function by building a loop that prompts the
+ * user for input.  Use the SH_PROMPT constant from dshlib.h and then
+ * use fgets to accept user input.  Since we want fgets to also handle
+ * end of file so we can run this headless for testing we need to check
+ * the return code of fgets.  I have provided an example below of how
+ * to do this assuming you are storing user input inside of the cmd_buff
+ * variable.
+ *
+ *      while(1){
+ *        printf("%s", SH_PROMPT);
+ *        if (fgets(cmd_buff, ARG_MAX, stdin) == NULL){
+ *           printf("\n");
+ *           break;
+ *        }
+ *        //remove the trailing \n from cmd_buff
+ *        cmd_buff[strcspn(cmd_buff,"\n")] = '\0';
+ *
+ *        //IMPLEMENT THE REST OF THE REQUIREMENTS
+ *      }
+ *
+ *   Also, use the constants in the dshlib.h in this code.
+ *      SH_CMD_MAX              maximum buffer size for user input
+ *      EXIT_CMD                constant that terminates the dsh program
+ *      SH_PROMPT               the shell prompt
+ *      OK                      the command was parsed properly
+ *      WARN_NO_CMDS            the user command was empty
+ *      ERR_TOO_MANY_COMMANDS   too many pipes used
+ *
+ *   Expected output:
+ *
+ *      CMD_OK_HEADER      if the command parses properly. You will
+ *                         follow this by the command details
+ *
+ *      CMD_WARN_NO_CMD    if the user entered a blank command
+ *      CMD_ERR_PIPE_LIMIT if the user entered too many commands using
+ *                         the pipe feature, e.g., cmd1 | cmd2 | ... |
+ *
+ *  See the provided test cases for output expectations.
+ */
+void _exit(char *buff) {
+    free(buff);
+    exit(OK);
+}
+
+int main()
+{
+    char *cmd_buff = malloc(ARG_MAX);
+    command_list_t *clist = malloc(sizeof(command_list_t));
+    int commandCount = 0;
+
+    int code = 0;
+    
+    while(1){
+        clist->num = 0;
+    
+        printf("%s", SH_PROMPT);
+        if (fgets(cmd_buff, ARG_MAX, stdin) == NULL){
+            break;
+        }
+
+        //remove the trailing \n from cmd_buff
+        cmd_buff[strcspn(cmd_buff,"\n")] = '\0';
+    
+        //IMPLEMENT THE REST OF THE REQUIREMENTS
+        if (strcmp(cmd_buff, EXIT_CMD) == 0) {
+            _exit(cmd_buff);
+        }
+
+        else {
+            // printf("Command line: %s\n", cmd_buff);
+            code = build_cmd_list(cmd_buff, clist);
+        }
+
+    }
+
+    free(clist);
+}
\ No newline at end of file
diff --git a/3-Shell/dshlib.c b/3-Shell/dshlib.c
new file mode 100644
index 0000000..abe3c79
--- /dev/null
+++ b/3-Shell/dshlib.c
@@ -0,0 +1,161 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "dshlib.h"
+
+/*
+ *  build_cmd_list
+ *    cmd_line:     the command line from the user
+ *    clist *:      pointer to clist structure to be populated
+ *
+ *  This function builds the command_list_t structure passed by the caller
+ *  It does this by first splitting the cmd_line into commands by spltting
+ *  the string based on any pipe characters '|'.  It then traverses each
+ *  command.  For each command (a substring of cmd_line), it then parses
+ *  that command by taking the first token as the executable name, and
+ *  then the remaining tokens as the arguments.
+ *
+ *  NOTE your implementation should be able to handle properly removing
+ *  leading and trailing spaces!
+ *
+ *  errors returned:
+ *
+ *    OK:                      No Error
+ *    ERR_TOO_MANY_COMMANDS:   There is a limit of CMD_MAX (see dshlib.h)
+ *                             commands.
+ *    ERR_CMD_OR_ARGS_TOO_BIG: One of the commands provided by the user
+ *                             was larger than allowed, either the
+ *                             executable name, or the arg string.
+ *
+ *  Standard Library Functions You Might Want To Consider Using
+ *      memset(), strcmp(), strcpy(), strtok(), strlen(), strchr()
+ */
+void printDragon(){
+    const char dragon[39][103] = {
+"                                                                        @%%%%                       \n",                       
+"                                                                     %%%%%%                         \n",                         
+"                                                                    %%%%%%                          \n",                          
+"                                                                 % %%%%%%%           @              \n",              
+"                                                                %%%%%%%%%%        %%%%%%%           \n",           
+"                                       %%%%%%%  %%%%@         %%%%%%%%%%%%@    %%%%%%  @%%%%        \n",        
+"                                  %%%%%%%%%%%%%%%%%%%%%%      %%%%%%%%%%%%%%%%%%%%%%%%%%%%          \n",          
+"                                %%%%%%%%%%%%%%%%%%%%%%%%%%   %%%%%%%%%%%% %%%%%%%%%%%%%%%           \n",           
+"                               %%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%     %%%            \n",            
+"                             %%%%%%%%%%%%%%%%%%%%%%%%%%%%@ @%%%%%%%%%%%%%%%%%%        %%            \n",            
+"                            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%                \n",                
+"                            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%              \n",              
+"                            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@%%%%%%@              \n",              
+"      %%%%%%%%@           %%%%%%%%%%%%%%%%        %%%%%%%%%%%%%%%%%%%%%%%%%%      %%                \n",                
+"    %%%%%%%%%%%%%         %%@%%%%%%%%%%%%           %%%%%%%%%%% %%%%%%%%%%%%      @%                \n",                
+"  %%%%%%%%%%   %%%        %%%%%%%%%%%%%%            %%%%%%%%%%%%%%%%%%%%%%%%                        \n",                        
+" %%%%%%%%%       %         %%%%%%%%%%%%%             %%%%%%%%%%%%@%%%%%%%%%%%                       \n",                   
+"%%%%%%%%%@                % %%%%%%%%%%%%%            @%%%%%%%%%%%%%%%%%%%%%%%%%                     \n",              
+"%%%%%%%%@                 %%@%%%%%%%%%%%%            @%%%%%%%%%%%%%%%%%%%%%%%%%%%%                  \n",         
+"%%%%%%%@                   %%%%%%%%%%%%%%%           %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%              \n",    
+"%%%%%%%%%%                  %%%%%%%%%%%%%%%          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%      %%%%  \n",
+"%%%%%%%%%@                   @%%%%%%%%%%%%%%         %%%%%%%%%%%%@ %%%% %%%%%%%%%%%%%%%%%   %%%%%%%%\n",
+"%%%%%%%%%%                  %%%%%%%%%%%%%%%%%        %%%%%%%%%%%%%      %%%%%%%%%%%%%%%%%% %%%%%%%%%\n",
+"%%%%%%%%%@%%@                %%%%%%%%%%%%%%%%@       %%%%%%%%%%%%%%     %%%%%%%%%%%%%%%%%%%%%%%%  %%\n",
+" %%%%%%%%%%                  % %%%%%%%%%%%%%%@        %%%%%%%%%%%%%%   %%%%%%%%%%%%%%%%%%%%%%%%%% %%\n",
+"  %%%%%%%%%%%%  @           %%%%%%%%%%%%%%%%%%        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%% \n",
+"   %%%%%%%%%%%%% %%  %  %@ %%%%%%%%%%%%%%%%%%          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    %%% \n",
+"    %%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%           @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    %%%%%%% \n",
+"     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%              %%%%%%%%%%%%%%%%%%%%%%%%%%%%        %%%   \n",
+"      @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                  %%%%%%%%%%%%%%%%%%%%%%%%%               \n",
+"        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                      %%%%%%%%%%%%%%%%%%%  %%%%%%%          \n",
+"           %%%%%%%%%%%%%%%%%%%%%%%%%%                           %%%%%%%%%%%%%%%  @%%%%%%%%%         \n",
+"              %%%%%%%%%%%%%%%%%%%%           @%@%                  @%%%%%%%%%%%%%%%%%%   %%%        \n",
+"                  %%%%%%%%%%%%%%%        %%%%%%%%%%                    %%%%%%%%%%%%%%%    %         \n",
+"                %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                      %%%%%%%%%%%%%%            \n",
+"                %%%%%%%%%%%%%%%%%%%%%%%%%%  %%%% %%%                      %%%%%%%%%%  %%%@          \n",
+"                     %%%%%%%%%%%%%%%%%%% %%%%%% %%                          %%%%%%%%%%%%%@          \n",
+"                                                                                 %%%%%%%@           \n"
+    };
+
+
+    for (int i = 0; i < sizeof(dragon) / sizeof(dragon[0]); i++) {
+        for (int j = 0; j < sizeof(dragon[0]) / sizeof(dragon[0][0]); j++) {
+            if (dragon[i][j] == 0) break;
+            putchar((char)dragon[i][j]);
+        }
+    }
+}
+
+
+int build_cmd_list(char *cmd_line, command_list_t *clist)
+{
+    if (strlen(cmd_line) == 0) {
+        printf(CMD_WARN_NO_CMD);
+        return OK;
+    }
+
+    // get the first command
+    char* token;
+
+    token = strtok(cmd_line, PIPE_STRING);
+    
+
+    //  keep getting commands until token is NULL
+    while (token != 0) {
+
+        // trim empty space at the start and end of command
+        while (*token == SPACE_CHAR) token++;
+        
+        if (token[strlen(token) - 1] == SPACE_CHAR) token[strlen(token) - 1] = '\0';
+
+        command_t* command = malloc(sizeof(command_t));
+
+        if (strlen(token) > SH_CMD_MAX) {
+            return ERR_CMD_OR_ARGS_TOO_BIG;
+        }
+
+        strcpy(command->exe,token);
+
+        clist->commands[clist->num] = *command;
+        clist->num += 1;
+
+        // printf("Current: %s\n", token);
+        token = strtok(0, PIPE_STRING);
+    }
+
+    if (clist->num > CMD_MAX) {
+        printf("dsh> ");
+        printf(CMD_ERR_PIPE_LIMIT, CMD_MAX);
+        return ERR_TOO_MANY_COMMANDS;
+    }
+
+
+    printf(CMD_OK_HEADER, clist->num);
+
+    // printf("Number of commands read in: %d\n", clist->num);
+    for (int i = 0; i < clist->num; i++){
+        // printf("Command #%d: %s\n", i+1, clist->commands[i].exe);
+        // char *exe = malloc(EXE_MAX * sizeof(char));
+        // char *args = malloc(ARG_MAX * sizeof(char));
+
+        // exe = strtok(clist->commands[i].exe, " ");
+        // args = strtok(0, "");
+
+        char *exe = strtok(clist->commands[i].exe, " ");
+        char *args = strtok(NULL, "");
+
+        if (exe) {
+            if (strcmp(exe, "dragon") == 0) {
+                printDragon();
+            }
+            strcpy(clist->commands[i].exe, exe);
+        }
+
+        if (args) {
+            strcpy(clist->commands[i].args, args);
+            printf("<%d> %s [%s]\n", i+1, clist->commands[i].exe, clist->commands[i].args);
+        } else {
+            printf("<%d> %s\n", i+1, clist->commands[i].exe);
+        }
+        // printf("Exe: %s\t Arguments: %s\n", clist->commands[i].exe, clist->commands[i].args);
+    }
+    
+    return OK;
+}
\ No newline at end of file
diff --git a/3-Shell/dshlib.h b/3-Shell/dshlib.h
new file mode 100644
index 0000000..1353bbd
--- /dev/null
+++ b/3-Shell/dshlib.h
@@ -0,0 +1,50 @@
+#ifndef __DSHLIB_H__
+#define __DSHLIB_H__
+
+// Constants for command structure sizes
+#define EXE_MAX 64
+#define ARG_MAX 256
+#define CMD_MAX 8
+// Longest command that can be read from the shell
+#define SH_CMD_MAX EXE_MAX + ARG_MAX
+
+typedef struct command
+{
+    char exe[EXE_MAX];
+    char args[ARG_MAX];
+} command_t;
+
+typedef struct command_list
+{
+    int num;
+    command_t commands[CMD_MAX];
+} command_list_t;
+
+// Special character #defines
+#define SPACE_CHAR ' '
+#define PIPE_CHAR '|'
+#define PIPE_STRING "|"
+
+#define SH_PROMPT "dsh> "
+#define EXIT_CMD "exit"
+
+// Standard Return Codes
+#define OK 0
+#define WARN_NO_CMDS -1
+#define ERR_TOO_MANY_COMMANDS -2
+#define ERR_CMD_OR_ARGS_TOO_BIG -3
+
+// starter code
+#define M_NOT_IMPL "The requested operation is not implemented yet!\n"
+#define EXIT_NOT_IMPL 3
+#define NOT_IMPLEMENTED_YET 0
+
+// prototypes
+int build_cmd_list(char *cmd_line, command_list_t *clist);
+
+// output constants
+#define CMD_OK_HEADER "PARSED COMMAND LINE - TOTAL COMMANDS %d\n"
+#define CMD_WARN_NO_CMD "warning: no commands provided\n"
+#define CMD_ERR_PIPE_LIMIT "error: piping limited to %d commands\n"
+
+#endif
\ No newline at end of file
diff --git a/3-Shell/makefile.txt b/3-Shell/makefile.txt
new file mode 100644
index 0000000..9d20e5b
--- /dev/null
+++ b/3-Shell/makefile.txt
@@ -0,0 +1,27 @@
+# Compiler settings
+CC = gcc
+CFLAGS = -Wall -Wextra -g
+
+# Target executable name
+TARGET = dsh
+
+# Find all source and header files
+SRCS = $(wildcard *.c)
+HDRS = $(wildcard *.h)
+
+# Default target
+all: $(TARGET)
+
+# Compile source to executable
+$(TARGET): $(SRCS) $(HDRS)
+	$(CC) $(CFLAGS) -o $(TARGET) $(SRCS)
+
+# Clean up build files
+clean:
+	rm -f $(TARGET)
+
+test:
+	./test.sh
+
+# Phony targets
+.PHONY: all clean
\ No newline at end of file
diff --git a/3-Shell/test.sh b/3-Shell/test.sh
new file mode 100644
index 0000000..6d586db
--- /dev/null
+++ b/3-Shell/test.sh
@@ -0,0 +1,212 @@
+#!/usr/bin/env bats
+
+@test "Simple Command" {
+    run ./dsh <<EOF                
+test_command
+exit
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '[:space:]')
+
+    # Expected output with all whitespace removed for easier matching
+    expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS1<1>test_commanddsh>"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+
+    # Assertions
+    [ "$status" -eq 0 ]
+
+}
+
+@test "Simple Command with Args" {
+    run ./dsh <<EOF                
+cmd -a1 -a2
+exit
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '[:space:]')
+
+    # Expected output 
+    expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS1<1>cmd[-a1-a2]dsh>"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+
+    # Assertions
+    [ "$status" -eq 0 ]
+
+}
+
+
+@test "No command provided" {
+    run ./dsh <<EOF                
+
+exit
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '[:space:]')
+
+    # Expected output with all whitespace removed for easier matching
+    expected_output="dsh>warning:nocommandsprovideddsh>"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+
+    # Assertions
+    [ "$status" -eq 0 ]
+
+}
+
+@test "Two commands" {
+    run ./dsh <<EOF                
+command_one | command_two
+exit
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '[:space:]')
+
+    # Expected output with all whitespace removed for easier matching
+    expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS2<1>command_one<2>command_twodsh>"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+
+    # Assertions
+    [ "$status" -eq 0 ]
+
+}
+
+@test "three commands with args" {
+    run ./dsh <<EOF                
+cmd1 a1 a2 a3 | cmd2 a4 a5 a6 | cmd3 a7 a8 a9
+exit
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '[:space:]')
+
+    # Expected output with all whitespace removed for easier matching
+    expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS3<1>cmd1[a1a2a3]<2>cmd2[a4a5a6]<3>cmd3[a7a8a9]dsh>"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+
+    # Assertions
+    [ "$status" -eq 0 ]
+
+}
+
+@test "try max (8) commands" {
+    run ./dsh <<EOF                
+cmd1 | cmd2 | cmd3 | cmd4 | cmd5 | cmd6 | cmd7 | cmd8
+exit
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '[:space:]')
+
+    # Expected output with all whitespace removed for easier matching
+    expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS8<1>cmd1<2>cmd2<3>cmd3<4>cmd4<5>cmd5<6>cmd6<7>cmd7<8>cmd8dsh>"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+
+    # Assertions
+    [ "$status" -eq 0 ]
+
+}
+
+@test "try too many commands" {
+    run ./dsh <<EOF                
+cmd1 | cmd2 | cmd3 | cmd4 | cmd5 | cmd6 | cmd7 | cmd8 | cmd9
+exit
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '[:space:]')
+
+    # Expected output with all whitespace removed for easier matching
+    expected_output="dsh>error:pipinglimitedto8commandsdsh>"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+
+    # Assertions
+    [ "$status" -eq 0 ]
+
+}
+
+@test "kitchen sink - multiple commands" {
+    run ./dsh <<EOF                
+cmd1
+cmd2 arg arg2
+p1 | p2
+p3 p3a1 p3a2 | p4 p4a1 p4a2
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '[:space:]')
+
+    # Expected output with all whitespace removed for easier matching
+    expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS1<1>cmd1dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS1<1>cmd2[argarg2]dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS2<1>p1<2>p2dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS2<1>p3[p3a1p3a2]<2>p4[p4a1p4a2]dsh>"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+
+    # Assertions
+    [ "$status" -eq 0 ]
+
+}
\ No newline at end of file
-- 
GitLab