Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
Checks: >
bugprone-*,
clang-analyzer-*,
performance-*,
portability-*,
readability-*,
-readability-identifier-length,
-readability-magic-numbers,
-readability-isolate-declaration,
-readability-function-cognitive-complexity,
-bugprone-multi-level-implicit-pointer-conversion,
-bugprone-easily-swappable-parameters,
-bugprone-branch-clone,
-bugprone-implicit-widening-of-multiplication-result,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
-clang-analyzer-core.NonNullParamChecker,
-clang-analyzer-security.ArrayBound,
-clang-analyzer-unix.StdCLibraryFunctions,
-clang-analyzer-core.NullDereference
WarningsAsErrors: ''
Checks: >
bugprone-*,
clang-analyzer-*,
performance-*,
portability-*,
readability-*,
-readability-identifier-length,
-readability-magic-numbers,
-readability-isolate-declaration,
-readability-function-cognitive-complexity,
-bugprone-multi-level-implicit-pointer-conversion,
-bugprone-easily-swappable-parameters,
-bugprone-branch-clone,
-bugprone-implicit-widening-of-multiplication-result,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
-clang-analyzer-core.NonNullParamChecker,
-clang-analyzer-security.ArrayBound,
-clang-analyzer-unix.StdCLibraryFunctions,
-clang-analyzer-core.NullDereference
WarningsAsErrors: ''
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ jobs:
- name: Build and test
run: ./run_tests.sh

sanitize:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install cmake
run: |
sudo apt-get update
sudo apt-get install -y cmake
- name: Build and test with sanitizers
env:
ASAN_OPTIONS: detect_leaks=1
run: |
cmake -B cmake-build-debug -S . -DTRIGGER_SANITIZE=ON
cmake --build cmake-build-debug
cd cmake-build-debug && ctest --output-on-failure

lint:
runs-on: ubuntu-latest
steps:
Expand Down
35 changes: 29 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,46 @@ set(HEADERS
include/glob_expand.h
)

add_executable(shell src/main.c ${LIB_SOURCES} ${UTIL_SOURCES} ${HEADERS})
add_library(trigger_core STATIC ${LIB_SOURCES} ${UTIL_SOURCES})

option(TRIGGER_SANITIZE "Build with address and undefined behavior sanitizers" OFF)

if(TRIGGER_SANITIZE)
add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer -g)
add_link_options(-fsanitize=address,undefined)
endif()

target_compile_options(trigger_core PRIVATE -Wall -Wextra -Werror)

add_executable(shell src/main.c)
target_link_libraries(shell trigger_core)
target_compile_options(shell PRIVATE -Wall -Wextra -Werror)

enable_testing()

add_executable(test_input tests/test_input.c src/input.c ${UTIL_SOURCES})
add_executable(test_input tests/test_input.c)
target_link_libraries(test_input trigger_core)
target_compile_options(test_input PRIVATE -Wall -Wextra -Werror)
add_test(NAME InputTests COMMAND test_input)

add_executable(test_builtins tests/test_builtins.c src/builtins.c src/input.c ${UTIL_SOURCES})
add_executable(test_builtins tests/test_builtins.c)
target_link_libraries(test_builtins trigger_core)
target_compile_options(test_builtins PRIVATE -Wall -Wextra -Werror)
add_test(NAME BuiltinsTests COMMAND test_builtins)

add_executable(test_execute tests/test_execute.c src/execute.c src/builtins.c src/pipeline.c src/glob.c src/input.c ${UTIL_SOURCES})
add_executable(test_execute tests/test_execute.c)
target_link_libraries(test_execute trigger_core)
target_compile_options(test_execute PRIVATE -Wall -Wextra -Werror)
add_test(NAME ExecuteTests COMMAND test_execute)

add_executable(test_pipeline tests/test_pipeline.c src/pipeline.c src/execute.c src/builtins.c src/glob.c src/input.c ${UTIL_SOURCES})
add_executable(test_pipeline tests/test_pipeline.c)
target_link_libraries(test_pipeline trigger_core)
target_compile_options(test_pipeline PRIVATE -Wall -Wextra -Werror)
add_test(NAME PipelineTests COMMAND test_pipeline)

add_executable(test_glob tests/test_glob.c src/glob.c src/input.c ${UTIL_SOURCES})
add_executable(test_glob tests/test_glob.c)
target_link_libraries(test_glob trigger_core)
target_compile_options(test_glob PRIVATE -Wall -Wextra -Werror)
add_test(NAME GlobTests COMMAND test_glob)

add_custom_target(run_tests
Expand Down
36 changes: 20 additions & 16 deletions include/builtins.h
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
#ifndef BUILTINS_H
#define BUILTINS_H

int trigger_cd(char **args);
int trigger_help(char **args);
int trigger_exit(char **args);
int trigger_pwd(char **args);
int trigger_echo(char **args);
int trigger_export(char **args);
int trigger_unset(char **args);
int trigger_num_builtins(void);

extern char *builtin_str[];
extern int (*builtin_func[])(char **);

#endif
#ifndef BUILTINS_H
#define BUILTINS_H

typedef struct {
const char *name;
int (*fn)(char **);
} Builtin;

int trigger_cd(char **args);
int trigger_help(char **args);
int trigger_exit(char **args);
int trigger_pwd(char **args);
int trigger_echo(char **args);
int trigger_export(char **args);
int trigger_unset(char **args);

int trigger_num_builtins(void);
const Builtin *find_builtin(const char *name);

#endif
26 changes: 16 additions & 10 deletions include/execute.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
#ifndef EXECUTE_H
#define EXECUTE_H

#define CHILD_PROCESS_EXITED 0
#define EXEC_RETURNED_FAILURE (-1)

int trigger_launch(char **args);
int trigger_execute(char ***args_ptr, int **glob_eligible_ptr);

#endif
#ifndef EXECUTE_H
#define EXECUTE_H

#include <stdbool.h>

typedef struct TokenList TokenList;

typedef struct {
int status;
bool should_exit;
} ExecuteResult;

int trigger_launch(char **args);
ExecuteResult trigger_execute(TokenList *tl);

#endif
14 changes: 8 additions & 6 deletions include/glob_expand.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef GLOB_EXPAND_H
#define GLOB_EXPAND_H

char **expand_globs(char **argv, int **glob_eligible_ptr);

#endif
#ifndef GLOB_EXPAND_H
#define GLOB_EXPAND_H

typedef struct TokenList TokenList;

void expand_globs(TokenList *tl);

#endif
20 changes: 8 additions & 12 deletions include/input.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
#ifndef INPUT_H
#define INPUT_H

#define TRIGGER_AUTOMATIC_BUFFER_SIZE 0
#define GET_LINE_REACHED_END_OF_FILE_OR_ERROR (-1)
#define TRIGGER_TOK_DELIM " \t\r\n\a"

char *trigger_read_line(void);
char **trigger_split_line(const char *line);
char **trigger_split_line_ex(const char *line, int **out_glob_eligible);

#endif
#ifndef INPUT_H
#define INPUT_H

char *trigger_read_line(void);
char **trigger_split_line(const char *line);
char **trigger_split_line_ex(const char *line, int **out_glob_eligible);

#endif
39 changes: 25 additions & 14 deletions include/pipeline.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
#ifndef PIPELINE_H
#define PIPELINE_H

typedef struct {
char **argv;
char *infile;
char *outfile;
int append;
} PipelineStage;

PipelineStage *trigger_parse_pipeline(char **tokens, int *num_stages);
int trigger_execute_pipeline(PipelineStage *stages, int num_stages);

#endif
#ifndef PIPELINE_H
#define PIPELINE_H

#define FILE_MODE 0644

typedef enum { OP_NONE, OP_PIPE, OP_REDIR_IN, OP_REDIR_OUT, OP_REDIR_APPEND } Operator;

typedef struct {
char **argv;
char *infile;
char *outfile;
int append;
} PipelineStage;

typedef struct {
int last_status;
} PipelineResult;

Operator classify_operator(const char *token);

PipelineStage *trigger_parse_pipeline(char **tokens, const int *glob_eligible, int *num_stages);
PipelineResult trigger_execute_pipeline(PipelineStage *stages, int num_stages);
void trigger_free_pipeline(PipelineStage *stages, int num_stages);

#endif
Loading
Loading