fix: now compiles and works for simple commands + clang format
This commit is contained in:
parent
e9b6d39760
commit
c299882586
23 changed files with 168 additions and 150 deletions
26
README.md
26
README.md
|
|
@ -7,26 +7,22 @@
|
|||
TODO
|
||||
|
||||
### Build
|
||||
run theses commands:
|
||||
`autoreconf --force --verbose --install && ./configure`
|
||||
run this command:
|
||||
`autoreconf --force --verbose --install`
|
||||
|
||||
### Test
|
||||
run this command:
|
||||
`./configure CFLAGS='-std=c99 -Werror -Wall -Wextra -Wvla'`
|
||||
then:
|
||||
`make`
|
||||
`./src/42sh --help`
|
||||
|
||||
### Testing
|
||||
|
||||
#### asan
|
||||
run this command:
|
||||
`./configure CFLAGS='-std=c99 -Werror -Wall -Wextra -Wvla -g -fsanitize=address'`
|
||||
|
||||
then:
|
||||
`make check`
|
||||
|
||||
#### debug (asan)
|
||||
|
||||
run this command:
|
||||
`./src/debug`
|
||||
|
||||
#### testsuite
|
||||
|
||||
run this command:
|
||||
`./src/testsuite`
|
||||
|
||||
## Authors
|
||||
|
||||
- Matteo Flebus
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ bin_PROGRAMS = 42sh
|
|||
|
||||
check_PROGRAMS = testsuite
|
||||
|
||||
testsuite_CFLAGS = $(42sh_CFLAGS)
|
||||
testsuite_CFLAGS += $(CRITERION_CFLAGS)
|
||||
#testsuite_CFLAGS = $(42sh_CFLAGS)
|
||||
#testsuite_CFLAGS += $(CRITERION_CFLAGS)
|
||||
|
||||
testsuite_SOURCES = ../tests/unit/lexer/lexer_tests.c \
|
||||
../tests/unit/utils/utils_tests.c
|
||||
|
|
@ -42,8 +42,8 @@ testsuite_LDADD = $(42sh_LDADD) $(CRITERION_LIBS)
|
|||
|
||||
check_PROGRAMS += debug
|
||||
|
||||
debug_CFLAGS = $(42sh_CFLAGS)
|
||||
debug_CFLAGS += -fsanitize=address -g
|
||||
#debug_CFLAGS = $(42sh_CFLAGS)
|
||||
#debug_CFLAGS += -fsanitize=address -g
|
||||
|
||||
debug_SOURCES = $(42sh_SOURCES)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
#include "execution.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../utils/ast/ast.h"
|
||||
|
||||
|
|
@ -262,7 +262,9 @@ int execution(struct ast *ast)
|
|||
int fd_target = redir->io_number;
|
||||
if (fd_target == -1)
|
||||
{
|
||||
if (redir->type == AST_REDIR_TYPE_LESS || redir->type == AST_REDIR_TYPE_DLESS || redir->type == AST_REDIR_TYPE_LESSAND)
|
||||
if (redir->type == AST_REDIR_TYPE_LESS
|
||||
|| redir->type == AST_REDIR_TYPE_DLESS
|
||||
|| redir->type == AST_REDIR_TYPE_LESSAND)
|
||||
fd_target = 0;
|
||||
else
|
||||
fd_target = 1;
|
||||
|
|
@ -274,7 +276,8 @@ int execution(struct ast *ast)
|
|||
int flags = 0;
|
||||
int mode = 0644;
|
||||
|
||||
if (redir->type == AST_REDIR_TYPE_GREAT || redir->type == AST_REDIR_TYPE_CLOBBER)
|
||||
if (redir->type == AST_REDIR_TYPE_GREAT
|
||||
|| redir->type == AST_REDIR_TYPE_CLOBBER)
|
||||
{
|
||||
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
new_fd = open(redir->filename, flags, mode);
|
||||
|
|
@ -289,7 +292,8 @@ int execution(struct ast *ast)
|
|||
flags = O_RDONLY;
|
||||
new_fd = open(redir->filename, flags);
|
||||
}
|
||||
else if (redir->type == AST_REDIR_TYPE_GREATAND || redir->type == AST_REDIR_TYPE_LESSAND)
|
||||
else if (redir->type == AST_REDIR_TYPE_GREATAND
|
||||
|| redir->type == AST_REDIR_TYPE_LESSAND)
|
||||
{
|
||||
// Simple fd duplication
|
||||
new_fd = atoi(redir->filename);
|
||||
|
|
@ -297,7 +301,8 @@ int execution(struct ast *ast)
|
|||
if (dup2(new_fd, fd_target) == -1)
|
||||
{
|
||||
perror("dup2");
|
||||
if (saved_fd != -1) close(saved_fd);
|
||||
if (saved_fd != -1)
|
||||
close(saved_fd);
|
||||
return 1;
|
||||
}
|
||||
new_fd = -2; // Mark as "already duped"
|
||||
|
|
@ -306,7 +311,8 @@ int execution(struct ast *ast)
|
|||
if (new_fd == -1)
|
||||
{
|
||||
perror("open");
|
||||
if (saved_fd != -1) close(saved_fd);
|
||||
if (saved_fd != -1)
|
||||
close(saved_fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -316,7 +322,8 @@ int execution(struct ast *ast)
|
|||
{
|
||||
perror("dup2");
|
||||
close(new_fd);
|
||||
if (saved_fd != -1) close(saved_fd);
|
||||
if (saved_fd != -1)
|
||||
close(saved_fd);
|
||||
return 1;
|
||||
}
|
||||
close(new_fd);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define IO_BACKEND_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "utils/args/args.h"
|
||||
|
||||
// Error codes
|
||||
|
|
|
|||
|
|
@ -69,9 +69,14 @@ int main(int argc, char **argv)
|
|||
// Execute AST
|
||||
return_code = execution(command_ast);
|
||||
|
||||
ast_free(&command_ast);
|
||||
|
||||
// Retrieve and build next AST
|
||||
command_ast = get_ast();
|
||||
}
|
||||
|
||||
ast_free(&command_ast);
|
||||
|
||||
if (command_ast == NULL)
|
||||
return ERR_INPUT_PROCESSING;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "lexer/lexer.h"
|
||||
#include "utils/lists/lists.h"
|
||||
#include "parser/parsing_utils.h"
|
||||
#include "utils/lists/lists.h"
|
||||
|
||||
// === Static functions
|
||||
// ...
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
// === Includes
|
||||
#include "parsing_utils.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lexer/lexer.h"
|
||||
#include "utils/ast/ast.h"
|
||||
|
|
@ -58,7 +60,8 @@ struct ast *parse_simple_command(void)
|
|||
while (!isterminator(token))
|
||||
{
|
||||
token = POP_TOKEN();
|
||||
command_elements = list_append(command_elements, token->data);
|
||||
char *word = strdup(token->data);
|
||||
command_elements = list_append(command_elements, word);
|
||||
token = PEEK_TOKEN();
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +89,7 @@ struct ast *parse_list(void)
|
|||
}
|
||||
token = PEEK_TOKEN();
|
||||
}
|
||||
result_list = list_append(result_list, current_node);
|
||||
|
||||
return ast_create_list(result_list);
|
||||
}
|
||||
|
|
@ -163,7 +167,9 @@ struct ast *parse_compound_list(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
command_elements = list_append(command_elements, token->data);
|
||||
char *word = strdup(token->data);
|
||||
|
||||
command_elements = list_append(command_elements, word);
|
||||
token = POP_TOKEN();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,14 +39,14 @@ struct ast *parse_shell_command(void);
|
|||
/* @brief parses commands inside if/else clauses and returns the corresponding
|
||||
* AST list
|
||||
*/
|
||||
struct ast* parse_compound_list(void);
|
||||
struct ast *parse_compound_list(void);
|
||||
|
||||
/*
|
||||
*/
|
||||
struct ast* parse_and_or(void);
|
||||
struct ast *parse_and_or(void);
|
||||
|
||||
/*
|
||||
*/
|
||||
struct ast* parse_else_clause(void);
|
||||
struct ast *parse_else_clause(void);
|
||||
|
||||
#endif /* ! PARSING_UTILS_H */
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
#ifndef AST_H
|
||||
#define AST_H
|
||||
|
||||
#include "utils/ast/ast_and_or.h"
|
||||
#include "utils/ast/ast_base.h"
|
||||
#include "utils/ast/ast_command.h"
|
||||
#include "utils/ast/ast_if.h"
|
||||
#include "utils/ast/ast_and_or.h"
|
||||
#include "utils/ast/ast_redir.h"
|
||||
#include "utils/ast/ast_list.h"
|
||||
#include "utils/ast/ast_end.h"
|
||||
#include "utils/ast/ast_if.h"
|
||||
#include "utils/ast/ast_list.h"
|
||||
#include "utils/ast/ast_redir.h"
|
||||
#include "utils/ast/ast_void.h"
|
||||
|
||||
#endif /* ! AST_H */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "utils/ast/ast_and_or.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
bool ast_is_and_or(struct ast *node)
|
||||
|
|
@ -13,7 +14,8 @@ struct ast_and_or *ast_get_and_or(struct ast *node)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct ast *ast_create_and_or(struct ast *left, struct ast *right, enum ast_and_or_type type)
|
||||
struct ast *ast_create_and_or(struct ast *left, struct ast *right,
|
||||
enum ast_and_or_type type)
|
||||
{
|
||||
struct ast_and_or *and_or = malloc(sizeof(struct ast_and_or));
|
||||
if (!and_or)
|
||||
|
|
|
|||
|
|
@ -2,14 +2,17 @@
|
|||
#define AST_AND_OR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "utils/ast/ast_base.h"
|
||||
|
||||
enum ast_and_or_type {
|
||||
enum ast_and_or_type
|
||||
{
|
||||
AST_AND_OR_TYPE_AND,
|
||||
AST_AND_OR_TYPE_OR
|
||||
};
|
||||
|
||||
struct ast_and_or {
|
||||
struct ast_and_or
|
||||
{
|
||||
struct ast *left;
|
||||
struct ast *right;
|
||||
enum ast_and_or_type type;
|
||||
|
|
@ -17,7 +20,8 @@ struct ast_and_or {
|
|||
|
||||
bool ast_is_and_or(struct ast *node);
|
||||
struct ast_and_or *ast_get_and_or(struct ast *node);
|
||||
struct ast *ast_create_and_or(struct ast *left, struct ast *right, enum ast_and_or_type type);
|
||||
struct ast *ast_create_and_or(struct ast *left, struct ast *right,
|
||||
enum ast_and_or_type type);
|
||||
void ast_free_and_or(struct ast_and_or *and_or);
|
||||
|
||||
#endif /* ! AST_AND_OR_H */
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#include "utils/ast/ast_command.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "utils/lists/lists.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "utils/lists/lists.h"
|
||||
#include "utils/ast/ast_base.h"
|
||||
#include "utils/lists/lists.h"
|
||||
|
||||
struct ast_command
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#include "utils/ast/ast_end.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
bool ast_is_end(struct ast *node)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "utils/lists/lists.h"
|
||||
#include "utils/ast/ast_base.h"
|
||||
#include "utils/lists/lists.h"
|
||||
|
||||
/**
|
||||
* Checks if the given AST node is of type AST_END.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#include "utils/ast/ast_if.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct ast *ast_create_if(struct ast *condition, struct ast *then_clause,
|
||||
struct ast *else_clause)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "utils/ast/ast.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "utils/ast/ast.h"
|
||||
|
||||
struct ast *ast_create_list(struct list *list)
|
||||
{
|
||||
struct ast_list *ast_list = malloc(sizeof(struct ast_list));
|
||||
|
|
@ -16,7 +16,7 @@ struct ast *ast_create_list(struct list *list)
|
|||
struct ast_list *ast_get_list(struct ast *node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
return (struct ast_list*)node->data;
|
||||
return (struct ast_list *)node->data;
|
||||
}
|
||||
|
||||
bool ast_is_list(struct ast *node)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "utils/ast/ast_redir.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
bool ast_is_redir(struct ast *node)
|
||||
|
|
@ -13,13 +14,16 @@ struct ast_redir *ast_get_redir(struct ast *node)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct ast *ast_create_redir(struct ast *child, char *filename, int io_number, enum ast_redir_type type)
|
||||
struct ast *ast_create_redir(struct ast *child, char *filename, int io_number,
|
||||
enum ast_redir_type type)
|
||||
{
|
||||
struct ast_redir *redir = malloc(sizeof(struct ast_redir));
|
||||
if (!redir)
|
||||
return NULL;
|
||||
redir->child = child;
|
||||
redir->filename = filename; // Takes ownership? Usually yes in simple ASTs, or dup. Let's assume pointer copy for now, but user must manage memory.
|
||||
redir->filename =
|
||||
filename; // Takes ownership? Usually yes in simple ASTs, or dup. Let's
|
||||
// assume pointer copy for now, but user must manage memory.
|
||||
redir->io_number = io_number;
|
||||
redir->type = type;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
#define AST_REDIR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "utils/ast/ast_base.h"
|
||||
|
||||
enum ast_redir_type {
|
||||
enum ast_redir_type
|
||||
{
|
||||
AST_REDIR_TYPE_LESS, // <
|
||||
AST_REDIR_TYPE_GREAT, // >
|
||||
AST_REDIR_TYPE_DLESS, // <<
|
||||
|
|
@ -14,16 +16,19 @@ enum ast_redir_type {
|
|||
AST_REDIR_TYPE_CLOBBER // >|
|
||||
};
|
||||
|
||||
struct ast_redir {
|
||||
struct ast_redir
|
||||
{
|
||||
struct ast *child;
|
||||
char *filename;
|
||||
int io_number; // The FD being redirected (default -1 if not specified, implies 0 or 1 based on type)
|
||||
int io_number; // The FD being redirected (default -1 if not specified,
|
||||
// implies 0 or 1 based on type)
|
||||
enum ast_redir_type type;
|
||||
};
|
||||
|
||||
bool ast_is_redir(struct ast *node);
|
||||
struct ast_redir *ast_get_redir(struct ast *node);
|
||||
struct ast *ast_create_redir(struct ast *child, char *filename, int io_number, enum ast_redir_type type);
|
||||
struct ast *ast_create_redir(struct ast *child, char *filename, int io_number,
|
||||
enum ast_redir_type type);
|
||||
void ast_free_redir(struct ast_redir *redir);
|
||||
|
||||
#endif /* ! AST_REDIR_H */
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#include "utils/ast/ast_void.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
bool ast_is_void(struct ast *node)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "utils/lists/lists.h"
|
||||
#include "utils/ast/ast_base.h"
|
||||
#include "utils/lists/lists.h"
|
||||
|
||||
/**
|
||||
* Checks if the given AST node is of type AST_VOID.
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "lexer/lexer.h"
|
||||
#include "io_backend/io_backend.h"
|
||||
#include "lexer/lexer.h"
|
||||
|
||||
TestSuite(peek_token);
|
||||
|
||||
|
|
@ -14,11 +14,7 @@ Test(peek_token, basic_empty)
|
|||
{
|
||||
// simulates input
|
||||
char command[] = "";
|
||||
struct iob_context context =
|
||||
{
|
||||
IOB_MODE_CMD,
|
||||
command
|
||||
};
|
||||
struct iob_context context = { IOB_MODE_CMD, command };
|
||||
iob_init(&context);
|
||||
|
||||
// test
|
||||
|
|
@ -38,11 +34,7 @@ Test(peek_token, basic_word)
|
|||
{
|
||||
// simulates input
|
||||
char command[] = "hello";
|
||||
struct iob_context context =
|
||||
{
|
||||
IOB_MODE_CMD,
|
||||
command
|
||||
};
|
||||
struct iob_context context = { IOB_MODE_CMD, command };
|
||||
iob_init(&context);
|
||||
|
||||
// test
|
||||
|
|
@ -60,11 +52,7 @@ Test(peek_token, basic_words)
|
|||
{
|
||||
// simulates input
|
||||
char command[] = "echo hello there";
|
||||
struct iob_context context =
|
||||
{
|
||||
IOB_MODE_CMD,
|
||||
command
|
||||
};
|
||||
struct iob_context context = { IOB_MODE_CMD, command };
|
||||
iob_init(&context);
|
||||
|
||||
// ======= echo
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue