Commit cd0809ca authored by Seblu's avatar Seblu

big work

parent de22dd53
......@@ -19,7 +19,12 @@ bin_PROGRAMS=42sh
src/ast/ast_while.c \
src/builtin/builtin.h \
src/builtin/builtin.c \
src/builtin/builtin_alias.c \
src/builtin/builtin_cd.c \
src/builtin/builtin_echo.c \
src/builtin/builtin_exit.c \
src/builtin/builtin_unalias.c \
src/builtin/builtin_shopt.c \
src/common/basename.c \
src/common/constant.h \
src/common/env.c \
......@@ -34,6 +39,8 @@ bin_PROGRAMS=42sh
src/exec/exec.h \
src/exec/exec_and.c \
src/exec/exec_bang.c \
src/exec/exec_cmd.c \
src/exec/exec_funcdec.c \
src/exec/exec_node.c \
src/exec/exec_or.c \
src/exec/exec_if.c \
......@@ -41,13 +48,13 @@ bin_PROGRAMS=42sh
src/exec/exec_sep.c \
src/exec/exec_sepand.c \
src/exec/exec_while.c \
src/parser/alias.c \
src/parser/alias.h \
src/parser/getline.c \
src/parser/getline.h \
src/parser/parser.c \
src/parser/parser.h \
src/parser/lexer.c \
src/shell/alias.c \
src/shell/alias.h \
src/shell/func.c \
src/shell/func.h \
src/shell/getoptions.c \
......
......@@ -2,6 +2,7 @@
-- Voir probleme de syntax que j'accepte lorsque un EOF apparait avant une quote
fermante. Le token est valide alors que sous bash non. faire un test avant.
Maintenant il renvoie EOF a la place du token.
-- verifier toto \2>sex fonctionne.
- Parser
-- aliases
......
......@@ -112,7 +112,8 @@ AC_ARG_WITH([efence],
[AS_HELP_STRING([--with-efence], [link with lib efence])],
[dnl action-if-given
LDFLAGS="$LDFLAGS -lefence"
CFLAGS="$CFLAGS -include stdlib.h -include efence.h"
test -r "/usr/include/efence.h" &&
CFLAGS="$CFLAGS -include stdlib.h -include efence.h"
],
[dnl action-if-not-given
true
......
......@@ -5,7 +5,7 @@
** Login <seblu@epita.fr>
**
** Started on Sun Jul 30 04:40:03 2006 Seblu
** Last update Tue Oct 17 17:14:49 2006 seblu
** Last update Thu Nov 16 17:01:11 2006 seblu
*/
#ifndef AST_H_
......@@ -179,6 +179,12 @@ struct ast_node
u_node_item body;
};
/*
** =================
** FILE: ast_print.c
** =================
*/
/*!
** Print an ast to @arg filename file
**
......@@ -197,6 +203,12 @@ void ast_print(s_ast_node *ast, const char *filename);
*/
void ast_print_node(s_ast_node *ast, FILE *fs, unsigned int *node_id);
/*
** ====================
** FILE: ast_destruct.c
** ====================
*/
/*!
** Destroy node and all its childs
**
......@@ -213,6 +225,12 @@ void ast_destruct(s_ast_node *ast);
*/
void ast_destruct_node(s_ast_node *ast);
/*
** ===========
** ast_if.c
** ===========
*/
/*!
** Create an if ast node
**
......@@ -248,6 +266,12 @@ void ast_if_destruct_node(s_ast_node *node);
*/
void ast_if_destruct(s_ast_node *node);
/*
** ===============
** FILE: ast_for.c
** ===============
*/
/*!
** Create a for ast node
**
......@@ -285,6 +309,12 @@ void ast_for_destruct_node(s_ast_node *node);
*/
void ast_for_destruct(s_ast_node *node);
/*
** ================
** FILE: ast_case.c
** ================
*/
/*!
** Create a case ast node
**
......@@ -329,6 +359,12 @@ void ast_case_destruct_node(s_ast_node *node);
*/
void ast_case_destruct(s_ast_node *node);
/*
** =================
** FILE: ast_while.c
** =================
*/
/*!
** Create a while ast node
**
......@@ -362,6 +398,12 @@ void ast_while_destruct_node(s_ast_node *node);
*/
void ast_while_destruct(s_ast_node *node);
/*
** ===============
** FILE: ast_red.c
** ===============
*/
/*!
** Create a redirection ast node
**
......@@ -405,6 +447,12 @@ void ast_red_destruct_node(s_ast_node *node);
*/
void ast_red_destruct(s_ast_node *node);
/*
** ===============
** FILE: ast_cmd.c
** ===============
*/
/*!
** Create a cmd ast node
**
......@@ -451,6 +499,12 @@ void ast_cmd_destruct_node(s_ast_node *node);
*/
void ast_cmd_destruct(s_ast_node *node);
/*
** ===============
** FILE: ast_and.c
** ===============
*/
/*!
** Create an and (&&) ast node
**
......@@ -484,6 +538,12 @@ void ast_and_destruct_node(s_ast_node *node);
*/
void ast_and_destruct(s_ast_node *node);
/*
** ==============
** FILE: ast_or.c
** ==============
*/
/*!
** Create an or (||) ast node
**
......@@ -517,6 +577,12 @@ void ast_or_destruct_node(s_ast_node *node);
*/
void ast_or_destruct(s_ast_node *node);
/*
** ====================
** FILE: ast_subshell.c
** ====================
*/
/*!
** Create a subshell (()) ast node
**
......@@ -549,6 +615,12 @@ void ast_subshell_destruct_node(s_ast_node *node);
*/
void ast_subshell_destruct(s_ast_node *node);
/*
** ===================
** FILE: ast_funcdec.c
** ===================
*/
/*!
** Create a funcdec (function declaration) ast node
**
......@@ -582,6 +654,12 @@ void ast_funcdec_destruct_node(s_ast_node *node);
*/
void ast_funcdec_destruct(s_ast_node *node);
/*
** ================
** FILE: ast_bang.c
** ================
*/
/*!
** Create a bang (!) ast node
**
......@@ -614,6 +692,12 @@ void ast_bang_destruct_node(s_ast_node *node);
*/
void ast_bang_destruct(s_ast_node *node);
/*
** ================
** FILE: ast_pipe.c
** ================
*/
/*!
** Create a pipe (|) ast node
**
......@@ -646,6 +730,12 @@ void ast_pipe_destruct_node(s_ast_node *node);
*/
void ast_pipe_destruct(s_ast_node *node);
/*
** ===============
** FILE: ast_sep.c
** ===============
*/
/*!
** Create a separtor (;) ast node
**
......@@ -678,6 +768,12 @@ void ast_sep_destruct_node(s_ast_node *node);
*/
void ast_sep_destruct(s_ast_node *node);
/*
** ==================
** FILE: ast_sepand.c
** ==================
*/
/*!
** Create a sepand (&) ast node
**
......
......@@ -5,7 +5,7 @@
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Wed Oct 18 17:14:16 2006 seblu
** Last update Thu Nov 16 17:07:14 2006 seblu
*/
#include "ast.h"
......@@ -38,7 +38,8 @@ void ast_funcdec_destruct_node(s_ast_node *node)
{
if (node->type != T_FUNCDEC)
return;
free(node->body.child_funcdec.name);
if (node->body.child_funcdec.name)
free(node->body.child_funcdec.name);
free(node);
}
......@@ -46,7 +47,9 @@ void ast_funcdec_destruct(s_ast_node *node)
{
if (node->type != T_FUNCDEC)
return;
free(node->body.child_funcdec.name);
ast_destruct(node->body.child_funcdec.body);
if (node->body.child_funcdec.name)
free(node->body.child_funcdec.name);
if (node->body.child_funcdec.body)
ast_destruct(node->body.child_funcdec.body);
free(node);
}
......@@ -5,49 +5,50 @@
** Login <seblu@epita.fr>
**
** Started on Tue Apr 11 00:22:44 2006 Seblu
** Last update Sun Nov 12 19:56:53 2006 Seblu
** Last update Thu Nov 16 18:59:29 2006 seblu
*/
#include <string.h>
#include <assert.h>
#include "builtin.h"
enum { BUILTIN_COUNT = 7 };
enum { BUILTIN_COUNT = 10 };
typedef int (*f_builtin)(char *argv[]);
struct builtin_table
struct builtin_table
{
const char *name;
f_builtin func;
const char *name;
f_builtin func;
};
static struct builtin_table builtin_table[BUILTIN_COUNT] =
{
{"cd", NULL}, //builtin_cd},
{"echo", NULL}, //builtin_echo},
{"cd", builtin_cd},
{"echo", builtin_echo},
{"exit", builtin_exit},
{"shopt", NULL}, //builtin_shopt},
{"shopt", builtin_shopt},
{"alias", builtin_alias},
{"unalias", builtin_unalias},
{"source", NULL}, //builtin_source},
{"set", NULL}, //builtin_set},
{"unset", NULL}, //builtin_unset},
{"export", NULL}, //builtin_export}
};
int is_a_builtin(const char *name)
{
register int i;
for (i = 0; i < BUILTIN_COUNT; ++i)
for (register int i = 0; i < BUILTIN_COUNT; ++i)
if (!strcmp(name, builtin_table[i].name))
return 1;
return 0;
}
int exec_builtin(s_cmd_node *cmd)
f_builtin get_builtin(const char *name)
{
register int i;
for (i = 0; i < BUILTIN_COUNT; ++i)
if (!strcmp(cmd->argv[0], builtin_table[i].name))
return builtin_table[i].func(cmd->argv);
return 0;
for (register int i = 0; i < BUILTIN_COUNT; ++i)
if (!strcmp(name, builtin_table[i].name)) {
assert(builtin_table[i].func);
return builtin_table[i].func;
}
assert(0);
return NULL;
}
......@@ -5,26 +5,75 @@
** Login <seblu@epita.fr>
**
** Started on Sun Nov 12 16:46:24 2006 Seblu
** Last update Sun Nov 12 19:55:03 2006 Seblu
** Last update Thu Nov 16 17:49:13 2006 seblu
*/
#ifndef BUILTIN_H_
# define BUILTIN_H_
# include <assert.h>
# include "../ast/ast.h"
# include "../shell/shell.h"
typedef int (*f_builtin)(char *argv[]);
int is_a_builtin(const char *name);
int exec_builtin(s_cmd_node *cmd);
/*!
** Says if @var name is a builtin.
**
** @param name builtin name
**
** @return boolean existance
*/
int is_a_builtin(const char *name);
/*!
** Return a pointer on a builtin function
**
** @param name builtin name
**
** @return pointer on the builtin function @var name
*/
f_builtin get_builtin(const char *name);
/*!
** Builtin Change Directory
**
** @param argv argument vector
**
** @return success status
*/
int builtin_cd(char *argv[]);
/*!
** Echo show all element on her line
**
** @param argc number of argument given
**
** @return sucess status
*/
int builtin_echo(char *argv[]);
/*!
** This builtin change local setting of the shell
**
** @param argv argument vector
**
** @return success status
*/
int builtin_shopt(char *argv[]);
/*!
** Builtin exit :)
**
** @param argv argument vector
**
** @return success status
*/
int builtin_exit(char *argv[]);
int builtin_source(char *argv[]);
int builtin_unset(char *argv[]);
int builtin_export(char *argv[]);
int builtin_alias(char *argv[]);
int builtin_unalias(char *argv[]);
int builtin_cd(char *argv[]);
int builtin_echo(char *argv[]);
int builtin_shopt(char *argv[]);
int builtin_exit(char *argv[]);
int builtin_source(char *argv[]);
int builtin_unset(char *argv[]);
int builtin_export(char *argv[]);
/*
** Bonus builtin
......
/*
** builtin_alias.c for 42sh
**
** Made by seblu
** Login <seblu@epita.fr>
**
** Started on Thu Nov 16 17:18:24 2006 seblu
** Last update Thu Nov 16 19:27:01 2006 seblu
*/
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "builtin.h"
#include "../shell/shell.h"
static int show_all_alias(void);
static int show_alias(const char *name);
static int getoption(char *argv[], int *argp, int *p);
int builtin_alias(char *argv[])
{
int argp;
char *carg;
char *equal;
int show = 0;
assert(argv && argv[0]);
if (!getoption(argv, &argp, &show))
return 2;
if (argv[1] == NULL || show)
return show_all_alias();
for (; (carg = argv[argp]); ++argp) {
if (!(equal = strchr(carg, '=')))
show_alias(carg);
else {
*equal = 0;
alias_add(shell->alias, strdup(carg), strdup(equal + 1));
*equal = '=';
}
}
return 0;
}
static int getoption(char *argv[], int *argp, int *p)
{
char *carg;
for (*argp = 1; (carg = argv[*argp]); ++*argp)
if (*carg == '-')
for (++carg; *carg; ++carg)
if (*carg == 'p')
*p = 1;
else {
fprintf(stderr, "%s: alias: -%c: invalid option.\n",
shell->name, *carg);
fprintf(stderr, "alias: usage: alias [-p] [name[=value]] ... ]\n");
return 0;
}
return 1;
}
static int show_alias(const char *name)
{
for (size_t i = 0; i < shell->alias->count; ++i)
if (!strcmp(shell->alias->table[i].name, name)) {
printf("alias %s=%s\n", shell->alias->table[i].name,
shell->alias->table[i].value);
return 1;
}
printf("%s: alias: %s: not found.\n", shell->name, name);
return 0;
}
static int show_all_alias(void)
{
for (size_t i = 0; i < shell->alias->count; ++i)
printf("alias %s=%s\n", shell->alias->table[i].name,
shell->alias->table[i].value);
return 0;
}
......@@ -5,107 +5,82 @@
** Login <seblu@epita.fr>
**
** Started on Tue Apr 11 00:23:47 2006 Seblu
** Last update Sun Nov 12 19:55:57 2006 Seblu
** Last update Thu Nov 16 16:57:54 2006 seblu
*/
#include <ctype.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../main/42sh.h"
#include "builtin.h"
#include "../var/var.h"
#include "../common/function.h"
#include "../shell/shell.h"
#include "../shell/var.h"
static int cd_var(struct s_42sh *sh, const char *name);
static int cd_minus(struct s_42sh *sh);
static int secure_chdir(const char *path);
/*
** ============
** DECLARATIONS
** ============
*/
/*!
** Builtin cd.
** @param argv The tab of args: terminated by NULL, argv[0] = "cd"
** @param sh The 42sh structure
** Change directory to home directory
**
** @param name env var
**
** @return success status
*/
int builtin_cd(char **argv)
static int cd_var(const char *name);
/*!
** Change of directory and on error, print good error.
**
** @param path new path
**
** @return error status with error code (0 is good)
*/
static int secure_chdir(const char *path);
/*
** ===========
** DEFINITIONS
** ===========
*/
int builtin_cd(char **argv)
{
assert(sh && argv && argv[0]);
assert(argv && argv[0]);
if (!argv[1])
return cd_var(sh, "HOME");
return cd_var("HOME");
if (!strcmp("-", argv[1]))
return cd_minus(sh);
return cd_var("OLDPWD");
return secure_chdir(argv[1]);
}
/*!
** Change directory to home directory
**
** @param sh shell env
** @param name env var
**
** @return exit status
*/
static int cd_var(struct s_42sh *sh, const char *name)
static int cd_var(const char *name)
{
const char *new_dir;
if (!(new_dir = var_get(sh->vars, name)))
{
fprintf(stderr, "42sh: cd: %s not set\n", name);
if (!(new_dir = var_get(shell->var, name))) {
fprintf(stderr, "%s: cd: %s not set\n", shell->name, name);
return 1;
}
return secure_chdir(new_dir);
}
/*!
** Return in previous directory
**
** @param sh shell info
**
** @return return status
*/
static int cd_minus(struct s_42sh *sh)
{
if (cd_var(sh, "OLDPWD"))
return 1;
return 0;
}
/*!
** Change of directory and on error, print good error.
**
** @param path new path
**
** @return error status with error code (0 is good)
*/
static int secure_chdir(const char *path)
{
const char *errormsg = "";
char *tmp;
errno = 0;
if (chdir(path))
{
if (errno == ENOENT)
errormsg = "No such file or directory";
else if (errno == EACCES)
errormsg = "Permission denied";
else if (errno == ENAMETOOLONG)
errormsg = "File name too long";
else if (errno == ENOTDIR)
errormsg = "Not a directory";
else if (errno == ELOOP)
errormsg = "Too many levels of symbolic links";
else
assert(0);
fprintf(stderr, "42sh: cd %s: %s\n", path, errormsg);
if (chdir(path)) {
fprintf(stderr, "%s: cd %s: %s\n", shell->name, path, strerror(errno));
return 1;
}
//FIXME: getenv return name=val and setenv2 take cut arguments
if ((tmp = getenv("PWD")))
var_setenv("OLDPWD", tmp, !0);
var_setenv("PWD", (tmp = var_getcwd()), !0);
free(tmp);
setenv2("OLDPWD", tmp, !0);
setenv2("PWD", (tmp = getcwd2()), !0);
return 0;
}
/*
** builtin_echo.c for 42sh in /goinfre/seblu/builtins
** builtin_echo.c for 42sh
**
** Made by Seblu
** Login <luttri_s@epita.fr>
** Login <seblu@epita.fr>
**
** Started on Tue Mar 14 20:57:07 2006 Seblu
** Last update Wed Apr 12 02:02:07 2006 Seblu
** Last update Wed Nov 15 15:34:18 2006 seblu
*/
#include <ctype.h>
......@@ -13,64 +13,113 @@
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "../main/42sh.h"
#include "../opt/opt.h"
#include "../shell/shell.h"
#include "../shell/option.h"
#include "mem.h"
/*
** ======
** MACROS
** ======
*/
#define isoctale(x) (((x) >= '0' && (x) <= '7') ? 1 : 0)
static int builtin_echo_ext(const char *);
static void builtin_echo_ext2(const char **, int *);
static void print_hex(const char **);
static void print_oct(const char **);
static void getoption(char *argv[], int *argp, int *line, int *ext);
static int fisdigit(const int c);
static int fisxdigit(const int c);
/*
** ============
** DECLARATIONS
** ============
*/
/*!
** Retreive command line option
**
** @param argv argument vector
** @param argp argument position
** @param line line flag
** @param ext extended flag
*/
static void getoption(char *argv[], int *argp, int *line, int *ext);
/*!
** Echo show all element on her line
**
** @param argc number of argument given
** @param argv vector to argument
** @param shopt option structure of shell
**
** @return sucess status
** @param msg
**
** @return if return 0, builtin must quit immediatly, else ok.
*/
static int builtin_echo_ext(const char *msg);
/*!
** Print hexa number on stdout a number