mirror of
https://github.com/Savapitech/42sh.git
synced 2026-03-18 21:50:35 +01:00
[ADD] while passed as builtins and break builtins
This commit is contained in:
@@ -107,8 +107,6 @@ ast_t *parse_condition(ast_ctx_t *ctx)
|
||||
|
||||
if (l_node == NULL)
|
||||
return NULL;
|
||||
if (ctx->act_tok.type & (T_WHILE))
|
||||
ctx->ast = parse_loop(ctx);
|
||||
else {
|
||||
switch (ctx->act_tok.type) {
|
||||
case T_PIPE:
|
||||
|
||||
138
src/ast/loop.c
138
src/ast/loop.c
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2025
|
||||
** 42sh
|
||||
** File description:
|
||||
** loop
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "ast.h"
|
||||
#include "builtins.h"
|
||||
#include "common.h"
|
||||
#include "exec.h"
|
||||
#include "redirects.h"
|
||||
#include "u_str.h"
|
||||
#include "u_mem.h"
|
||||
|
||||
//TODO: need to know how to get the next arg
|
||||
ast_t *parse_loop(ast_ctx_t *ctx)
|
||||
{
|
||||
ast_t *node = create_node(ctx);
|
||||
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
node->type = N_LOP;
|
||||
node->tok = ctx->act_tok;
|
||||
node->loop.cap = 2;
|
||||
node->loop.buffers = NULL;
|
||||
node->loop.sz = 0;
|
||||
node->loop.condition = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
static
|
||||
ast_t *buffers_realloc(ast_t *node)
|
||||
{
|
||||
char **new_buffers = u_realloc(node->loop.buffers, sizeof
|
||||
*node->loop.buffers * node->loop.sz, sizeof
|
||||
*node->loop.buffers * (node->loop.cap << 1));
|
||||
|
||||
if (new_buffers == NULL)
|
||||
return NULL;
|
||||
node->loop.buffers = new_buffers;
|
||||
node->loop.cap <<= 1;
|
||||
return node;
|
||||
}
|
||||
|
||||
static
|
||||
ast_t *get_first_cmd(ast_t *node, char prompt[], size_t *bf_len)
|
||||
{
|
||||
printf("%s", prompt);
|
||||
node->loop.buffers[node->loop.sz] = NULL;
|
||||
getline(&(node->loop.buffers[node->loop.sz]), bf_len, stdin);
|
||||
*bf_len = u_strlen(node->loop.buffers[node->loop.sz]);
|
||||
node->loop.buffers[node->loop.sz][*bf_len - 1] = '\0';
|
||||
node->loop.sz += 1;
|
||||
return node;
|
||||
}
|
||||
|
||||
static
|
||||
ast_t *increase_buffers(ast_t *node, size_t *buffer_len)
|
||||
{
|
||||
node->loop.buffers[node->loop.sz] = NULL;
|
||||
getline(&(node->loop.buffers[node->loop.sz]), buffer_len, stdin);
|
||||
*buffer_len = u_strlen(node->loop.buffers[node->loop.sz]);
|
||||
node->loop.buffers[node->loop.sz][*buffer_len - 1] = '\0';
|
||||
node->loop.sz++;
|
||||
return node;
|
||||
}
|
||||
|
||||
static
|
||||
ast_t *get_usr_loop_cmd(ast_t *node)
|
||||
{
|
||||
char prompt[] = "while? ";
|
||||
size_t buffer_len;
|
||||
|
||||
node->loop.buffers = malloc(sizeof(char *) * node->loop.cap);
|
||||
node = get_first_cmd(node, prompt, &buffer_len);
|
||||
while (strcmp("end", node->loop.buffers[node->loop.sz - 1])){
|
||||
printf("%s", prompt);
|
||||
if (node->loop.sz >= node->loop.cap)
|
||||
node = buffers_realloc(node);
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
increase_buffers(node, &buffer_len);
|
||||
}
|
||||
free(node->loop.buffers[node->loop.sz]);
|
||||
node->loop.sz--;
|
||||
node->loop.buffers[node->loop.sz] = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
void exit_child(int sig __attribute__((unused)))
|
||||
{
|
||||
_exit(sig);
|
||||
}
|
||||
|
||||
//TODO: need to change the while true by a check_condition
|
||||
static
|
||||
void launch_loop(ef_t *ef, ast_t *node)
|
||||
{
|
||||
int status;
|
||||
|
||||
signal(SIGINT, exit_child);
|
||||
signal(EOF, exit_child);
|
||||
node = get_usr_loop_cmd(node);
|
||||
if (node == NULL)
|
||||
exit(84);
|
||||
while (true)
|
||||
for (size_t i = 0; i < node->loop.sz; i++)
|
||||
status = visitor(node->loop.buffers[i], ef->exec_ctx);
|
||||
free_array(node->loop.buffers);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
int visit_loop(ef_t *ef, ast_t *node)
|
||||
{
|
||||
int status;
|
||||
pid_t pid = fork();
|
||||
|
||||
if (pid == 0)
|
||||
launch_loop(ef, node);
|
||||
else
|
||||
wait(&status);
|
||||
if (WIFEXITED(status))
|
||||
ef->history->last_exit_code =
|
||||
ef->history->last_exit_code ?: WEXITSTATUS(status);
|
||||
return status;
|
||||
}
|
||||
@@ -28,7 +28,6 @@ const tokens_list_t TOKENS_LIST[] = {
|
||||
{ T_REDIRECT, ">", 1, "T_REDIRECT" },
|
||||
{ T_HEREDOC, "<<", 2, "T_HEREDOC" },
|
||||
{ T_IN_REDIRECT, "<", 1, "T_IN_REDIRECT" },
|
||||
{ T_WHILE, "while", 5, "T_WHILE"},
|
||||
{ T_IF, "if", 2, "T_IF"},
|
||||
{ T_THEN, "then", 4, "T_THEN"},
|
||||
{ T_ELSE, "else", 4, "T_ELSE"},
|
||||
|
||||
@@ -31,8 +31,10 @@ int builtins_display_alias(alias_t *alias);
|
||||
int builtins_repeat(ef_t *ef, char **args);
|
||||
int builtins_yes(ef_t *ef, char **args);
|
||||
int builtins_foreach(ef_t *ef, char **args);
|
||||
int builtins_while(ef_t *ef, char **args);
|
||||
int builtins_set(ef_t *ef, char **args);
|
||||
int builtins_unset(ef_t *ef, char **args);
|
||||
int builtins_where(ef_t *ef, char **args);
|
||||
int builtins_which(ef_t *ef, char **args);
|
||||
int builtins_break(ef_t *ef, char **args);
|
||||
#endif /* BUILTIND_H */
|
||||
|
||||
33
src/builtins/break.c
Normal file
33
src/builtins/break.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2025
|
||||
** 42sh
|
||||
** File description:
|
||||
** break
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ast.h"
|
||||
#include "builtins.h"
|
||||
#include "common.h"
|
||||
#include "exec.h"
|
||||
#include "u_str.h"
|
||||
|
||||
bool checking_error(ef_t *ef, char **args)
|
||||
{
|
||||
if (args[1])
|
||||
return (WRITE_CONST(STDERR_FILENO, "break: Too many arguments.\n"),
|
||||
RETURN_FAILURE);
|
||||
if (!ef->exec_ctx->local->in_a_loop)
|
||||
return (WRITE_CONST(STDERR_FILENO, "break: Not in while/foreach.\n"),
|
||||
RETURN_FAILURE);
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
int builtins_break(ef_t *ef, char **args)
|
||||
{
|
||||
if (ef->exec_ctx->local->in_a_loop)
|
||||
exit(checking_error(ef, args));
|
||||
return checking_error(ef, args);
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2025
|
||||
** 42sh
|
||||
** File description:
|
||||
** foreach
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "ast.h"
|
||||
#include "builtins.h"
|
||||
#include "common.h"
|
||||
#include "exec.h"
|
||||
#include "redirects.h"
|
||||
#include "u_str.h"
|
||||
#include "u_mem.h"
|
||||
#include "loop.h"
|
||||
#include "local.h"
|
||||
|
||||
static
|
||||
bool checking_error(ef_t *ef, char **args)
|
||||
{
|
||||
if (my_array_len(args) < 3)
|
||||
return (WRITE_CONST(STDERR_FILENO, "foreach: Too few arguments.\n"),
|
||||
true);
|
||||
if (check_local_var(args[1], args[0]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
usr_cmd_t *buffers_realloc(usr_cmd_t *usr)
|
||||
{
|
||||
char **new_buffers = u_realloc(usr->local_var, sizeof
|
||||
*usr->local_var * usr->sz, sizeof
|
||||
*usr->local_var * (usr->cap << 1));
|
||||
|
||||
if (new_buffers == NULL)
|
||||
return NULL;
|
||||
usr->local_var = new_buffers;
|
||||
usr->cap <<= 1;
|
||||
return usr;
|
||||
}
|
||||
|
||||
static
|
||||
usr_cmd_t *get_first_cmd(usr_cmd_t *usr, char prompt[], size_t *bf_len)
|
||||
{
|
||||
printf("%s", prompt);
|
||||
usr->local_var[usr->sz] = NULL;
|
||||
getline(&(usr->local_var[usr->sz]), bf_len, stdin);
|
||||
*bf_len = u_strlen(usr->local_var[usr->sz]);
|
||||
usr->local_var[usr->sz][*bf_len - 1] = '\0';
|
||||
usr->sz += 1;
|
||||
return usr;
|
||||
}
|
||||
|
||||
static
|
||||
usr_cmd_t *increase_buffers(usr_cmd_t *usr, size_t *buffer_len)
|
||||
{
|
||||
usr->local_var[usr->sz] = NULL;
|
||||
getline(&(usr->local_var[usr->sz]), buffer_len, stdin);
|
||||
*buffer_len = u_strlen(usr->local_var[usr->sz]);
|
||||
usr->local_var[usr->sz][*buffer_len - 1] = '\0';
|
||||
usr->sz++;
|
||||
return usr;
|
||||
}
|
||||
|
||||
static
|
||||
usr_cmd_t *handle_end(usr_cmd_t *us, char prompt[])
|
||||
{
|
||||
us->sz--;
|
||||
if (!us->local_var[us->sz] ||
|
||||
strcmp("end", us->local_var[us->sz])){
|
||||
printf("%s: end not found.\n", prompt);
|
||||
free_array(us->local_var);
|
||||
us->local_var = NULL;
|
||||
exit(RETURN_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
free(us->local_var[us->sz]);
|
||||
us->local_var[us->sz] = NULL;
|
||||
return us;
|
||||
}
|
||||
|
||||
static
|
||||
usr_cmd_t *get_usr_loop_cmd(usr_cmd_t *usr_cmd)
|
||||
{
|
||||
char prompt[] = "foreach? ";
|
||||
size_t buffer_len;
|
||||
|
||||
usr_cmd->local_var = malloc(sizeof(char *) * usr_cmd->cap);
|
||||
if (usr_cmd->local_var == NULL)
|
||||
return NULL;
|
||||
usr_cmd = get_first_cmd(usr_cmd, prompt, &buffer_len);
|
||||
while (strcmp("end", usr_cmd->local_var[usr_cmd->sz - 1])){
|
||||
printf("foreach? ");
|
||||
if (usr_cmd->sz >= usr_cmd->cap)
|
||||
usr_cmd = buffers_realloc(usr_cmd);
|
||||
if (usr_cmd == NULL)
|
||||
return NULL;
|
||||
increase_buffers(usr_cmd, &buffer_len);
|
||||
}
|
||||
usr_cmd = handle_end(usr_cmd, prompt);
|
||||
return usr_cmd;
|
||||
}
|
||||
|
||||
static
|
||||
int do_a_lap(ef_t *ef, char **args)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
for (int i = 0; args[i]; i++)
|
||||
status = visitor(args[i], ef->exec_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
int foreach_loop(ef_t *ef, char **args, usr_cmd_t *usr_cmds)
|
||||
{
|
||||
int status = 0;
|
||||
char **save_cmds = arraydup(usr_cmds->local_var);
|
||||
|
||||
if (save_cmds == NULL)
|
||||
exit(84);
|
||||
for (int i = 2; args[i]; i++){
|
||||
if (!set_local(ef->exec_ctx->local, args[1], args[i]))
|
||||
exit(84);
|
||||
status = do_a_lap(ef, usr_cmds->local_var);
|
||||
free_array(usr_cmds->local_var);
|
||||
usr_cmds->local_var = arraydup(save_cmds);
|
||||
}
|
||||
free_array(save_cmds);
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
void launch_loop(ef_t *ef, char **args)
|
||||
{
|
||||
int status = RETURN_FAILURE;
|
||||
usr_cmd_t *usr_cmds = malloc(sizeof(usr_cmd_t));
|
||||
|
||||
if (usr_cmds == NULL)
|
||||
exit(84);
|
||||
usr_cmds->cap = 2;
|
||||
usr_cmds->sz = 0;
|
||||
signal(SIGINT, exit_child);
|
||||
signal(EOF, exit_child);
|
||||
usr_cmds = get_usr_loop_cmd(usr_cmds);
|
||||
if (usr_cmds == NULL)
|
||||
exit(84);
|
||||
status = foreach_loop(ef, args, usr_cmds);
|
||||
free_array(usr_cmds->local_var);
|
||||
free(usr_cmds);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
int builtins_foreach(ef_t *ef, char **args)
|
||||
{
|
||||
int status = 0;
|
||||
pid_t pid;
|
||||
|
||||
if (checking_error(ef, args))
|
||||
return RETURN_FAILURE;
|
||||
pid = fork();
|
||||
if (pid == 0)
|
||||
launch_loop(ef, args);
|
||||
else
|
||||
wait(&status);
|
||||
if (WIFEXITED(status))
|
||||
ef->history->last_exit_code =
|
||||
ef->history->last_exit_code ?: WEXITSTATUS(status);
|
||||
return status;
|
||||
}
|
||||
104
src/builtins/get_loop_cmd.c
Normal file
104
src/builtins/get_loop_cmd.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2025
|
||||
** 42sh
|
||||
** File description:
|
||||
** get_loop_cmd
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "ast.h"
|
||||
#include "builtins.h"
|
||||
#include "common.h"
|
||||
#include "exec.h"
|
||||
#include "redirects.h"
|
||||
#include "u_str.h"
|
||||
#include "u_mem.h"
|
||||
#include "loop.h"
|
||||
#include "local.h"
|
||||
|
||||
static
|
||||
usr_cmd_t *buffers_realloc(usr_cmd_t *usr)
|
||||
{
|
||||
char **new_buffers = u_realloc(usr->cmds, sizeof
|
||||
*usr->cmds * usr->sz, sizeof
|
||||
*usr->cmds * (usr->cap << 1));
|
||||
|
||||
if (new_buffers == NULL)
|
||||
return NULL;
|
||||
usr->cmds = new_buffers;
|
||||
usr->cap <<= 1;
|
||||
return usr;
|
||||
}
|
||||
|
||||
static
|
||||
usr_cmd_t *increase_buffers(usr_cmd_t *usr, size_t *buffer_len)
|
||||
{
|
||||
usr->cmds[usr->sz] = NULL;
|
||||
getline(&(usr->cmds[usr->sz]), buffer_len, stdin);
|
||||
*buffer_len = u_strlen(usr->cmds[usr->sz]);
|
||||
usr->cmds[usr->sz][*buffer_len - 1] = '\0';
|
||||
usr->sz++;
|
||||
return usr;
|
||||
}
|
||||
|
||||
static
|
||||
usr_cmd_t *handle_end(usr_cmd_t *us, char prompt[])
|
||||
{
|
||||
us->sz--;
|
||||
if (!us->cmds[us->sz] || strcmp("end", us->cmds[us->sz])){
|
||||
printf("%s: end not found.\n", prompt);
|
||||
free_array(us->cmds);
|
||||
us->cmds = NULL;
|
||||
exit(RETURN_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
free(us->cmds[us->sz]);
|
||||
us->cmds[us->sz] = NULL;
|
||||
return us;
|
||||
}
|
||||
|
||||
static
|
||||
usr_cmd_t *get_first_cmd(usr_cmd_t *usr, char prompt[], size_t *bf_len)
|
||||
{
|
||||
if (isatty(STDIN_FILENO))
|
||||
printf("%s? ", prompt);
|
||||
usr->cmds[usr->sz] = NULL;
|
||||
getline(&(usr->cmds[usr->sz]), bf_len, stdin);
|
||||
*bf_len = u_strlen(usr->cmds[usr->sz]);
|
||||
usr->cmds[usr->sz][*bf_len - 1] = '\0';
|
||||
usr->sz += 1;
|
||||
return usr;
|
||||
}
|
||||
|
||||
usr_cmd_t *get_usr_loop_cmd(usr_cmd_t *usr_cmd, char prompt[])
|
||||
{
|
||||
size_t buffer_len;
|
||||
|
||||
if (usr_cmd == NULL)
|
||||
return NULL;
|
||||
usr_cmd->cmds = malloc(sizeof(char *) * usr_cmd->cap);
|
||||
if (usr_cmd->cmds == NULL)
|
||||
return NULL;
|
||||
usr_cmd = get_first_cmd(usr_cmd, prompt, &buffer_len);
|
||||
while (strcmp("end", usr_cmd->cmds[usr_cmd->sz - 1])){
|
||||
if (isatty(STDIN_FILENO))
|
||||
printf("%s? ", prompt);
|
||||
if (usr_cmd->sz >= usr_cmd->cap)
|
||||
usr_cmd = buffers_realloc(usr_cmd);
|
||||
if (usr_cmd == NULL)
|
||||
return NULL;
|
||||
increase_buffers(usr_cmd, &buffer_len);
|
||||
}
|
||||
usr_cmd = handle_end(usr_cmd, prompt);
|
||||
return usr_cmd;
|
||||
}
|
||||
166
src/builtins/loop.c
Normal file
166
src/builtins/loop.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2025
|
||||
** 42sh
|
||||
** File description:
|
||||
** foreach
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "ast.h"
|
||||
#include "builtins.h"
|
||||
#include "common.h"
|
||||
#include "exec.h"
|
||||
#include "redirects.h"
|
||||
#include "u_str.h"
|
||||
#include "u_mem.h"
|
||||
#include "loop.h"
|
||||
#include "local.h"
|
||||
|
||||
void exit_child(int sig __attribute__((unused)))
|
||||
{
|
||||
_exit(sig);
|
||||
}
|
||||
|
||||
static
|
||||
bool checking_for_error(ef_t *ef, char **args)
|
||||
{
|
||||
if (my_array_len(args) < 3)
|
||||
return (WRITE_CONST(STDERR_FILENO, "foreach: Too few arguments.\n"),
|
||||
true);
|
||||
if (check_local_var(args[1], args[0]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
bool checking_while_error(ef_t *ef, char **args)
|
||||
{
|
||||
if (my_array_len(args) < 2)
|
||||
return (WRITE_CONST(STDERR_FILENO, "while: Too few arguments.\n"),
|
||||
true);
|
||||
if (my_array_len(args) > 2)
|
||||
return (WRITE_CONST(STDERR_FILENO, "while: Expression Syntax.\n"),
|
||||
true);
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
int do_a_lap(ef_t *ef, char **args)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
for (int i = 0; args[i]; i++)
|
||||
status = visitor(args[i], ef->exec_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
int foreach_loop(ef_t *ef, char **args, usr_cmd_t *usr_cmds)
|
||||
{
|
||||
int status = 0;
|
||||
char **save_cmds = arraydup(usr_cmds->cmds);
|
||||
|
||||
if (save_cmds == NULL)
|
||||
exit(84);
|
||||
for (int i = 2; args[i]; i++){
|
||||
if (!set_local(ef->exec_ctx->local, args[1], args[i]))
|
||||
exit(84);
|
||||
status = do_a_lap(ef, usr_cmds->cmds);
|
||||
free_array(usr_cmds->cmds);
|
||||
usr_cmds->cmds = arraydup(save_cmds);
|
||||
}
|
||||
free_array(save_cmds);
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
int while_loop(ef_t *ef, usr_cmd_t *usr_cmds)
|
||||
{
|
||||
int status = 0;
|
||||
char **save_cmds = arraydup(usr_cmds->cmds);
|
||||
|
||||
if (save_cmds == NULL)
|
||||
exit(84);
|
||||
while (true){
|
||||
status = do_a_lap(ef, usr_cmds->cmds);
|
||||
free_array(usr_cmds->cmds);
|
||||
usr_cmds->cmds = arraydup(save_cmds);
|
||||
}
|
||||
free_array(save_cmds);
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
int choose_loop(ef_t *ef, char **args, usr_cmd_t *usr_cmd, char prompt[])
|
||||
{
|
||||
if (strcmp(prompt, "foreach") == 0)
|
||||
return foreach_loop(ef, args, usr_cmd);
|
||||
return while_loop(ef, usr_cmd);
|
||||
}
|
||||
|
||||
static
|
||||
void launch_loop(ef_t *ef, char **args, char prompt[])
|
||||
{
|
||||
int status = RETURN_FAILURE;
|
||||
usr_cmd_t *usr_cmds = malloc(sizeof(usr_cmd_t));
|
||||
|
||||
ef->exec_ctx->local->in_a_loop = true;
|
||||
if (usr_cmds == NULL)
|
||||
exit(84);
|
||||
usr_cmds->cap = 2;
|
||||
usr_cmds->sz = 0;
|
||||
signal(SIGINT, exit_child);
|
||||
signal(EOF, exit_child);
|
||||
usr_cmds = get_usr_loop_cmd(usr_cmds, prompt);
|
||||
if (usr_cmds == NULL)
|
||||
exit(84);
|
||||
status = choose_loop(ef, args, usr_cmds, prompt);
|
||||
free_array(usr_cmds->cmds);
|
||||
free(usr_cmds);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
int builtins_foreach(ef_t *ef, char **args)
|
||||
{
|
||||
int status = 0;
|
||||
pid_t pid;
|
||||
|
||||
if (checking_for_error(ef, args))
|
||||
return RETURN_FAILURE;
|
||||
pid = fork();
|
||||
if (pid == 0)
|
||||
launch_loop(ef, args, "foreach");
|
||||
else
|
||||
wait(&status);
|
||||
if (WIFEXITED(status))
|
||||
ef->history->last_exit_code =
|
||||
ef->history->last_exit_code ?: WEXITSTATUS(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
int builtins_while(ef_t *ef, char **args)
|
||||
{
|
||||
int status = 0;
|
||||
pid_t pid;
|
||||
|
||||
if (checking_while_error(ef, args))
|
||||
return RETURN_FAILURE;
|
||||
pid = fork();
|
||||
if (pid == 0)
|
||||
launch_loop(ef, args, "while");
|
||||
else
|
||||
wait(&status);
|
||||
if (WIFEXITED(status))
|
||||
ef->history->last_exit_code =
|
||||
ef->history->last_exit_code ?: WEXITSTATUS(status);
|
||||
return status;
|
||||
}
|
||||
@@ -40,10 +40,12 @@ const builtins_funcs_t BUILTINS[] = {
|
||||
{ "alias", &builtins_alias},
|
||||
{ "yes", &builtins_yes },
|
||||
{ "foreach", &builtins_foreach },
|
||||
{ "while", &builtins_while },
|
||||
{ "set", &builtins_set },
|
||||
{ "unset", &builtins_unset },
|
||||
{ "where", &builtins_where },
|
||||
{ "which", &builtins_which }
|
||||
{ "which", &builtins_which },
|
||||
{ "break", &builtins_break }
|
||||
};
|
||||
|
||||
const size_t BUILTINS_SZ = sizeof BUILTINS / sizeof *BUILTINS;
|
||||
|
||||
@@ -14,6 +14,7 @@ typedef struct {
|
||||
size_t sz;
|
||||
size_t cap;
|
||||
char **local_var;
|
||||
bool in_a_loop;
|
||||
} local_t;
|
||||
|
||||
bool set_local(local_t *local, char *var, char *value);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
typedef struct {
|
||||
size_t sz;
|
||||
size_t cap;
|
||||
char **local_var;
|
||||
char **cmds;
|
||||
} usr_cmd_t;
|
||||
|
||||
usr_cmd_t *get_usr_loop_cmd(usr_cmd_t *usr_cmd, char prompt[]);
|
||||
#endif /* LOOP_H */
|
||||
|
||||
@@ -146,8 +146,6 @@ int visit_expression(ef_t *ef, ast_t *node)
|
||||
{
|
||||
int result = RETURN_FAILURE;
|
||||
|
||||
if (node->type == N_LOP)
|
||||
result = visit_loop(ef, node);
|
||||
if (node->tok.type == T_SEMICOLON)
|
||||
result = visit_semi(ef, node);
|
||||
if (node->tok.type & (T_IF | T_AND | T_OR))
|
||||
|
||||
Reference in New Issue
Block a user