Skip to content
Snippets Groups Projects
Commit c26407ee authored by luishernandez's avatar luishernandez
Browse files

5-ShellP3

parent d359501f
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env bats
############################ DO NOT EDIT THIS FILE #####################################
# File: assignement_tests.sh
#
# DO NOT EDIT THIS FILE
#
# Add/Edit Student tests in student_tests.sh
#
# All tests in this file must pass - it is used as part of grading!
########################################################################################
@test "Pipes" {
run "./dsh" <<EOF
ls | grep dshlib.c
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="dshlib.cdsh3>dsh3>cmdloopreturned0"
# 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"
echo "${stripped_output} -> ${expected_output}"
# Check exact match
[ "$stripped_output" = "$expected_output" ]
# Assertions
[ "$status" -eq 0 ]
}
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dshlib.h"
/* DO NOT EDIT
* main() logic moved to exec_local_cmd_loop() in dshlib.c
*/
int main(){
int rc = exec_local_cmd_loop();
printf("cmd loop returned %d\n", rc);
}
\ No newline at end of file
#ifndef __DSHLIB_H__
#define __DSHLIB_H__
//Constants for command structure sizes
#define EXE_MAX 64
#define ARG_MAX 256
#define CMD_MAX 8
#define CMD_ARGV_MAX (CMD_MAX + 1)
// 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 cmd_buff
{
int argc;
char *argv[CMD_ARGV_MAX];
char *_cmd_buffer;
} cmd_buff_t;
/* WIP - Move to next assignment
#define N_ARG_MAX 15 //MAX number of args for a command
typedef struct command{
char exe [EXE_MAX];
char args[ARG_MAX];
int argc;
char *argv[N_ARG_MAX + 1]; //last argv[LAST] must be \0
}command_t;
*/
typedef struct command_list{
int num;
cmd_buff_t commands[CMD_MAX];
}command_list_t;
//Special character #defines
#define SPACE_CHAR ' '
#define PIPE_CHAR '|'
#define PIPE_STRING "|"
#define SH_PROMPT "dsh3> "
#define EXIT_CMD "exit"
#define EXIT_SC 99
//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
#define ERR_CMD_ARGS_BAD -4 //for extra credit
#define ERR_MEMORY -5
#define ERR_EXEC_CMD -6
#define OK_EXIT -7
//prototypes
int alloc_cmd_buff(cmd_buff_t *cmd_buff);
int free_cmd_buff(cmd_buff_t *cmd_buff);
int clear_cmd_buff(cmd_buff_t *cmd_buff);
int build_cmd_buff(char *cmd_line, cmd_buff_t *cmd_buff);
int close_cmd_buff(cmd_buff_t *cmd_buff);
int build_cmd_list(char *cmd_line, command_list_t *clist);
int free_cmd_list(command_list_t *cmd_lst);
//built in command stuff
typedef enum {
BI_CMD_EXIT,
BI_CMD_DRAGON,
BI_CMD_CD,
BI_NOT_BI,
BI_EXECUTED,
} Built_In_Cmds;
Built_In_Cmds match_command(const char *input);
Built_In_Cmds exec_built_in_cmd(cmd_buff_t *cmd);
//main execution context
int exec_local_cmd_loop();
int exec_cmd(cmd_buff_t *cmd);
int execute_pipeline(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
# 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)
TESTS = student_tests.sh assignment_tests.sh
.PHONY: test
test:
@for t in $(TESTS); do \
chmod +x $$t; \
echo "Running $$t..."; \
./$$t || exit 1; \
done
valgrind:
echo "pwd\nexit" | valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 ./$(TARGET)
echo "pwd\nexit" | valgrind --tool=helgrind --error-exitcode=1 ./$(TARGET)
# Phony targets
.PHONY: all clean test
\ No newline at end of file
#!/usr/bin/env bats
@test "Example: check ls runs without errors" {
run ./dsh <<EOF
ls
exit
EOF
[ "$status" -eq 0 ]
}
@test "Pipeline: ls | grep \".c\" shows only .c files" {
run ./dsh <<EOF
ls | grep ".c"
exit
EOF
[ "$status" -eq 0 ]
# Remove prompt lines and termination messages.
result=$(echo "$output" | sed '/^dsh3>/d' | grep -v -E '^(exiting|cmd loop returned)')
# Iterate over each line in the result.
while IFS= read -r line; do
# Skip empty lines.
[ -z "$line" ] && continue
# Each line should contain ".c"
[[ "$line" =~ \.c ]]
done <<< "$result"
}
@test "Redirection: echo with > and cat with <" {
run ./dsh <<EOF
echo "hello, class" > out.txt
cat < out.txt
exit
EOF
[ "$status" -eq 0 ]
echo "$output" | grep -q "hello, class"
}
@test "Append redirection: echo with >> then cat" {
run ./dsh <<EOF
echo "hello, class" > out.txt
echo "this is line 2" >> out.txt
cat < out.txt
exit
EOF
[ "$status" -eq 0 ]
echo "$output" | grep -q "hello, class"
echo "$output" | grep -q "this is line 2"
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment