feat(dev): expansion

This commit is contained in:
william.valenduc 2026-01-22 12:09:18 +00:00
parent 609c1667af
commit 4fc43e4678
8 changed files with 36 additions and 32 deletions

View file

@ -18,8 +18,8 @@ bin_PROGRAMS = 42sh
parser/libparser.a \
lexer/liblexer.a \
io_backend/libio_backend.a \
expansion/libexpansion.a \
execution/libexecution.a \
expansion/libexpansion.a \
utils/libutils.a
# ================ TESTS ================

View file

@ -9,7 +9,9 @@
#include <sys/wait.h>
#include <unistd.h>
#include "../expansion/expansion.h"
#include "../utils/ast/ast.h"
#include "../utils/hash_map/hash_map.h"
// --- Helpers ---
@ -205,7 +207,7 @@ static int exec_command(struct ast_command *command)
* @param ast The AST to execute
* @return int The exit status of the last executed command.
*/
int execution(struct ast *ast)
int execution(struct ast *ast, struct hash_map *vars)
{
if (!ast)
{
@ -219,18 +221,20 @@ int execution(struct ast *ast)
}
case AST_CMD: {
struct ast_command *command = ast_get_command(ast);
if (!expand(command, vars))
fprintf(stderr, "Error: Variable expansion failed\n");
return exec_command(command);
}
case AST_IF: {
struct ast_if *if_node = ast_get_if(ast);
int cond = execution(if_node->condition);
int cond = execution(if_node->condition, vars);
if (cond == 0) // True
{
return execution(if_node->then_clause);
return execution(if_node->then_clause, vars);
}
else // False
{
return execution(if_node->else_clause);
return execution(if_node->else_clause, vars);
}
}
case AST_LIST: {
@ -240,25 +244,25 @@ int execution(struct ast *ast)
while (cur)
{
struct ast *child = (struct ast *)cur->data;
ret = execution(child);
ret = execution(child, vars);
cur = cur->next;
}
return ret;
}
case AST_AND_OR: {
struct ast_and_or *ao_node = ast_get_and_or(ast);
int left_ret = execution(ao_node->left);
int left_ret = execution(ao_node->left, vars);
if (ao_node->type == AST_AND_OR_TYPE_AND)
{
if (left_ret == 0)
return execution(ao_node->right);
return execution(ao_node->right, vars);
return left_ret;
}
else // OR
{
if (left_ret != 0)
return execution(ao_node->right);
return execution(ao_node->right, vars);
return left_ret;
}
}
@ -335,7 +339,7 @@ int execution(struct ast *ast)
close(new_fd);
}
int ret = execution(redir->child);
int ret = execution(redir->child, vars);
if (saved_fd != -1)
{

View file

@ -3,6 +3,7 @@
#include "../utils/ast/ast.h"
#include "../utils/lists/lists.h"
#include "../utils/hash_map/hash_map.h"
/**
* @brief Execute the AST
@ -10,6 +11,6 @@
* @param ast Pointer to the AST structure
* @return int Execution status code of the last command
*/
int execution(struct ast *ast);
int execution(struct ast *ast, struct hash_map *vars);
#endif /* ! EXECUTION_H */

View file

@ -115,11 +115,10 @@ static bool expand_var(char **str, size_t pos, const struct hash_map *vars)
return false;
}
struct ast_command *expand(struct ast_command *command,
const struct hash_map *vars)
bool expand(struct ast_command *command, const struct hash_map *vars)
{
if (command == NULL)
return NULL;
return false;
char *str;
size_t len;
@ -150,7 +149,7 @@ struct ast_command *expand(struct ast_command *command,
// variable expansion
bool r = expand_var(&str, i, vars);
if (r == false || str == NULL)
return NULL;
return false;
i--; // -1 because loop will increment i
}
@ -160,7 +159,7 @@ struct ast_command *expand(struct ast_command *command,
{
// error: quote not closed
fprintf(stderr, "Error: quote not closed in string: %s\n", str);
return NULL;
return false;
}
if (len != strlen(str))
@ -169,12 +168,12 @@ struct ast_command *expand(struct ast_command *command,
if (new_str == NULL)
{
// error: realloc fail
return NULL;
return false;
}
l->data = new_str;
}
l = l->next;
}
return command;
return true;
}

View file

@ -1,6 +1,7 @@
#ifndef EXPANSION_H
#define EXPANSION_H
#include <stdbool.h>
#include <stddef.h>
#include "../utils/hash_map/hash_map.h"
@ -20,7 +21,6 @@ size_t parse_var_name(char *str, char **res);
* @param vars The hash map containing variables.
* @return A new AST command with variables expanded, or NULL on error.
*/
struct ast_command *expand(struct ast_command *command,
const struct hash_map *vars);
bool expand(struct ast_command *command, const struct hash_map *vars);
#endif /* ! EXPANSION_H */

View file

@ -85,7 +85,9 @@ int main(int argc, char **argv)
while (command_ast != NULL && command_ast->type != AST_END)
{
// Execute AST
return_code = execution(command_ast);
return_code = execution(command_ast, vars);
// set $? variable
ast_free(&command_ast);

View file

@ -12,12 +12,7 @@
#define VARS_INITIAL_SIZE 16
struct hash_map *vars_init(void)
{
return hash_map_init(VARS_INITIAL_SIZE);
}
void vars_default(struct hash_map *vars)
static void vars_default(struct hash_map *vars)
{
set_var_copy(vars, "?", "0");
pid_t pid = getpid();
@ -26,6 +21,14 @@ void vars_default(struct hash_map *vars)
set_var_copy(vars, "$", pid_str);
}
struct hash_map *vars_init(void)
{
struct hash_map *vars = hash_map_init(VARS_INITIAL_SIZE);
if (vars != NULL)
vars_default(vars);
return vars;
}
short short_random(void)
{
static bool seeded = false;

View file

@ -10,11 +10,6 @@
*/
struct hash_map *vars_init(void);
/**
* Set default variables.
*/
void vars_default(struct hash_map *vars);
/**
* Generate a random short integer (16 bits positive [0-32767]).
*/