ajout de la recherche recursive sur le globbing et du chemin absolu. (/*/*/*) toujours pas de gestion du double star (**)

This commit is contained in:
wescande 2017-01-24 20:44:14 +01:00 committed by Jack Halford
parent 6102eda2df
commit c556b0eea5
21 changed files with 342 additions and 212 deletions

View file

@ -143,20 +143,25 @@ exec/ft_cmd.c\
exec/ft_exec.c\
exec/ft_findexec.c\
exec/set_exitstatus.c\
glob/dir_glob.c\
glob/expand_brace.c\
glob/glob.c\
glob/glob_print.c\
glob/ld/ft_ld_back.c\
glob/ld/ft_ld_clear.c\
glob/ld/ft_ld_del.c\
glob/ld/ft_ld_front.c\
glob/ld/ft_ld_new.c\
glob/ld/ft_ld_pushback.c\
glob/ld/ft_ld_pushfront.c\
glob/ld/ft_ld_reverse.c\
glob/ld/ft_ld_size.c\
glob/ld/ft_ld_swap.c\
glob/ld/ft_ld_to_tab.c\
glob/lib_perso/ft_ld_back.c\
glob/lib_perso/ft_ld_clear.c\
glob/lib_perso/ft_ld_del.c\
glob/lib_perso/ft_ld_front.c\
glob/lib_perso/ft_ld_new.c\
glob/lib_perso/ft_ld_order.c\
glob/lib_perso/ft_ld_pushback.c\
glob/lib_perso/ft_ld_pushfront.c\
glob/lib_perso/ft_ld_reverse.c\
glob/lib_perso/ft_ld_size.c\
glob/lib_perso/ft_ld_swap.c\
glob/lib_perso/ft_ld_to_tab.c\
glob/lib_perso/ft_strjoinf.c\
glob/lib_perso/ft_tabdel.c\
glob/match_pattern.c\
lexer/ft_tokenize.c\
lexer/lexer_backslash.c\
lexer/lexer_default.c\

View file

@ -6,7 +6,7 @@
/* By: wescande <wescande@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/04 16:31:18 by wescande #+# #+# */
/* Updated: 2017/01/12 19:00:08 by wescande ### ########.fr */
/* Updated: 2017/01/24 19:27:53 by wescande ### ########.fr */
/* */
/* ************************************************************************** */
@ -25,6 +25,9 @@ typedef struct s_ld
char **glob(const char *str, char **env);
t_ld *expand_brace(const char *pat);
void glob_print(t_list *token, t_data *data);
int match_pattern(const char *pat, char *str, char *full_word, t_ld **match);
void dir_research(const char *pat, char *path, t_ld **match);
bool is_directory(const char *path);
/*
** LIST D:
@ -40,6 +43,13 @@ void ft_ld_reverse(t_ld **lst);
t_ld *ft_ld_back(t_ld *ld);
t_ld *ft_ld_swap(t_ld *l_cur);
char **ft_ld_to_tab(t_ld *ld);
t_ld *ft_ld_order(t_ld *ld, int (*f)(), void (*del)());
/*
** str:
*/
char *ft_strjoinf(char *str, char *str2, int mode);
void ft_tabdel(char ***mytab);
#endif

48
42sh/srcs/glob/dir_glob.c Normal file
View file

@ -0,0 +1,48 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* glob.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: wescande <wescande@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/04 16:29:54 by wescande #+# #+# */
/* Updated: 2017/01/24 19:10:52 by wescande ### ########.fr */
/* */
/* ************************************************************************** */
#include "glob.h"
bool is_directory(const char *path)
{
struct stat path_stat;
stat(path, &path_stat);
return (S_ISDIR(path_stat.st_mode));
}
void dir_research(const char *pat, char *p, t_ld **match)
{
DIR *dir;
struct dirent *in;
char *path_tmp;
if (ft_strlen(p) <= 1 || p[ft_strlen(p) - 1] != '.')
{
if (!(dir = opendir(p)))
return ;
while ((in = readdir(dir)))
{
if (ft_strcmp(in->d_name, ".") && ft_strcmp(in->d_name, ".."))
{
if (*p == '/' && !*(p + 1))
path_tmp = ft_strjoin(p, in->d_name);
else
path_tmp = ft_strjoinf(ft_strjoin(p, "/"), in->d_name, 1);
if (match_pattern(pat, in->d_name, path_tmp, match))
ft_ld_pushfront(match, ft_strdup(path_tmp + 2 *
(path_tmp[0] == '.' && path_tmp[1] == '/')));
ft_strdel(&path_tmp);
}
}
}
}

View file

@ -6,7 +6,7 @@
/* By: wescande <wescande@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/12 19:00:29 by wescande #+# #+# */
/* Updated: 2017/01/12 20:24:00 by wescande ### ########.fr */
/* Updated: 2017/01/24 19:15:35 by wescande ### ########.fr */
/* */
/* ************************************************************************** */
@ -20,36 +20,6 @@
** -char *pat -> pattern string to be looking for expand
*/
static char *ft_strjoinf(char *s1, char *s2, int state)
{
char *ans;
ans = ft_strjoin((const char *)s1, (const char *)s2);
if (state == 1 || state == 3)
ft_strdel(&s1);
if (state == 2 || state == 3)
ft_strdel(&s2);
return (ans);
}
static void ft_tabdel(char ***mytab)
{
char **erase;
int i;
if (!mytab || !*mytab)
return ;
erase = *mytab;
i = 0;
while (erase[i])
{
ft_strdel(&erase[i]);
++i;
}
free(*mytab);
*mytab = NULL;
}
static int search_brace(t_ld **wk, char *str, int index)
{
char *start;
@ -86,20 +56,19 @@ t_ld *expand_brace(const char *pat)
int do_it;
ret = NULL;
ft_ld_pushfront(&ret, ft_strdup(""));
ft_ld_pushfront(&ret, ft_strdup(pat));
do_it = 1;
while (do_it)
{
do_it = 0;
while (ret)
while (ret->next)
{
if ((tmp = ret) && search_brace(&ret, ret->content, -1))
{
ft_ld_del(&tmp, &ft_strdel);
do_it = 1;
}
if (!ret->next)
break;
ret = ret->next;
}
ret = ft_ld_front(ret);

View file

@ -6,7 +6,7 @@
/* By: wescande <wescande@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/04 16:29:54 by wescande #+# #+# */
/* Updated: 2017/01/12 19:00:12 by wescande ### ########.fr */
/* Updated: 2017/01/24 20:42:45 by wescande ### ########.fr */
/* */
/* ************************************************************************** */
@ -21,181 +21,48 @@
** to just expanse in local directory and not in path
*/
static void ft_tabdel(char ***mytab)
{
char **erase;
int i;
if (!mytab || !*mytab)
return ;
erase = *mytab;
i = 0;
while (erase[i])
{
ft_strdel(&erase[i]);
++i;
}
free(*mytab);
*mytab = NULL;
}
static int match_bracket_char(char **cmp, const char *pat, char c, int neg)
{
int dir;
char s;
if ((*cmp + 2) < pat && (*cmp)[1] == '-' && (s = (*cmp)[0]))
{
dir = s > (*cmp)[2];
while ((dir && s >= (*cmp)[2]) || (!dir && s <= (*cmp)[2]))
{
if (!neg && s == c)
return (1);
else if (neg && s == c)
return (0);
s += (dir * -2 + 1);
}
*cmp += 2;
}
else if (!neg && **cmp == c)
{
return (1);
}
else if (neg && **cmp == c)
{
return (0);
}
return (-1);
}
static int match_bracket(const char **pat, char c)
{
char *cmp;
int neg;
int ret;
cmp = (char *)*pat + 1;
while (**pat != ']')
{
if (!**pat)
return (0);
++*pat;
}
neg = 0;
if ((*cmp == '^' || *cmp == '!') && ++neg)
++cmp;
while (cmp < *pat)
{
ret = match_bracket_char(&cmp, *pat, c, neg);
if (ret != -1)
return (ret);
++cmp;
}
return (neg);
}
static int match_pattern(const char *pat, char *str);
static int match_star(const char *pat, char *str)
{
char *fix;
if (!pat[1])
return (1);
fix = str + ft_strlen(str);
while (fix > str)
{
if (match_pattern(pat + 1, fix))
return (1);
--fix;
}
return (0);
}
static int match_pattern(const char *pat, char *str)
{
while (*pat)
{
if (*pat == '?')
str++;
else if (*pat == '[')
{
if (!match_bracket(&pat, *str))
return (0);
}
else if (*pat == '*')
return (match_star(pat, str));
else if (*pat == '\\')
{
if (!*++pat || *str != *pat)
return (0);
}
else if (*pat != *str)
return (0);
++str;
++pat;
}
return (*str ? 0 : 1);
}
static void dir_research(const char *pat, char *path, t_ld **match)
{
DIR *dir;
struct dirent *inside;
if (!(dir = opendir(path)))
return ;
while ((inside = readdir(dir)))
{
if (match_pattern(pat, inside->d_name))
ft_ld_pushfront(match, ft_strdup(inside->d_name));
}
}
static void path_research(const char *pat, char **path, t_ld **match)
{
int i;
int len;
char *good_path;
i = -1;
good_path = NULL;
while (path[++i])
{
good_path = ft_strjoin(path[i], "/");
while ((len = ft_strlen(good_path)) && good_path[len - 1] == '/'
&& good_path[len - 2] == '/')
good_path[ft_strlen(good_path) - 1] = '\0';
dir_research(pat, good_path, match);
ft_strdel(&good_path);
dir_research(pat, path[i], match);
}
static char **treat_glob(t_ld **match)
{
char **gl;
gl = NULL;
ft_ld_reverse(match);
*match = ft_ld_order(*match, &ft_strcmp, &ft_strdel);
gl = ft_ld_to_tab(*match);
ft_ld_clear(match, &ft_strdel);
return (gl);
}
char **glob(const char *pat, char **env)
{
t_ld *match;
char **gl;
char **path;
t_ld *mul_pat;
match = NULL;
gl = NULL;
mul_pat = expand_brace(pat);
while (mul_pat)
while (mul_pat->next)
{
if (env && (path = ft_strsplit(ft_getenv(env, "PATH"), ':')))
{
path_research(mul_pat->content, path, &match);
ft_tabdel(&path);
}
dir_research(mul_pat->content, "./", &match);
if (((char *)mul_pat->content)[0] != '/')
dir_research(mul_pat->content, ".", &match);
else
dir_research(mul_pat->content + 1, "/", &match);
mul_pat = mul_pat->next;
}
ft_ld_clear(&mul_pat, &ft_strdel);
if (match)
{
gl = ft_ld_to_tab(match);
ft_ld_clear(&match, &ft_strdel);
}
return (gl);
return (treat_glob(&match));
}

View file

@ -0,0 +1,35 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_ld_order.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: wescande <wescande@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/24 19:20:45 by wescande #+# #+# */
/* Updated: 2017/01/24 19:40:54 by wescande ### ########.fr */
/* */
/* ************************************************************************** */
#include "glob.h"
t_ld *ft_ld_order(t_ld *ld, int (*f)(), void (*del)())
{
int swap;
swap = 1;
ld = ft_ld_front(ld);
while (swap)
{
swap = 0;
while (ld && ld->next)
{
if (f(ld->content, ld->next->content) > 0 && (swap = 1))
ld = ft_ld_swap(ld);
else if (!f(ld->content, ld->next->content))
ft_ld_del(&ld, del);
ld = ld->next;
}
ld = ft_ld_front(ld);
}
return (ld);
}

View file

@ -0,0 +1,25 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strjoinf.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: wescande <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/05 13:33:24 by wescande #+# #+# */
/* Updated: 2017/01/24 16:53:13 by wescande ### ########.fr */
/* */
/* ************************************************************************** */
#include "glob.h"
char *ft_strjoinf(char *s1, char *s2, int state)
{
char *ans;
ans = ft_strjoin((const char *)s1, (const char *)s2);
if (state == 1 || state == 3)
ft_strdel(&s1);
if (state == 2 || state == 3)
ft_strdel(&s2);
return (ans);
}

View file

@ -0,0 +1,31 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* glob.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: wescande <wescande@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/04 16:29:54 by wescande #+# #+# */
/* Updated: 2017/01/24 16:52:50 by wescande ### ########.fr */
/* */
/* ************************************************************************** */
#include "glob.h"
void ft_tabdel(char ***mytab)
{
char **erase;
int i;
if (!mytab || !*mytab)
return ;
erase = *mytab;
i = 0;
while (erase[i])
{
ft_strdel(&erase[i]);
++i;
}
free(*mytab);
*mytab = NULL;
}

View file

@ -0,0 +1,123 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* match_pattern.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: wescande <wescande@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/24 17:30:23 by wescande #+# #+# */
/* Updated: 2017/01/24 20:42:30 by wescande ### ########.fr */
/* */
/* ************************************************************************** */
#include "glob.h"
static int match_bracket_char(char **cmp, const char *pat, char c, int neg)
{
int dir;
char s;
if ((*cmp + 2) < pat && (*cmp)[1] == '-' && (s = (*cmp)[0]))
{
dir = s > (*cmp)[2];
while ((dir && s >= (*cmp)[2]) || (!dir && s <= (*cmp)[2]))
{
if (!neg && s == c)
return (1);
else if (neg && s == c)
return (0);
s += (dir * -2 + 1);
}
*cmp += 2;
}
else if (!neg && **cmp == c)
{
return (1);
}
else if (neg && **cmp == c)
{
return (0);
}
return (-1);
}
static int match_bracket(const char **pat, char c)
{
char *cmp;
int neg;
int ret;
cmp = (char *)*pat + 1;
while (**pat != ']')
{
if (!**pat)
return (0);
++*pat;
}
neg = 0;
if ((*cmp == '^' || *cmp == '!') && ++neg)
++cmp;
while (cmp < *pat)
{
ret = match_bracket_char(&cmp, *pat, c, neg);
if (ret != -1)
return (ret);
++cmp;
}
return (neg);
}
static int match_star(const char *pat, char *str,
char *full_word, t_ld **match)
{
char *fix;
if (!pat[1])
return (1);
fix = str + ft_strlen(str);
while (fix > str)
{
if (match_pattern(pat + 1, fix, full_word, match))
return (1);
--fix;
}
return (0);
}
const char *manage_pat(const char *pat, char *str)
{
if (pat[0] == '.' && pat[1] == '/'
&& ((str[0] == '.' && str[1] != '/') || str[0] != '.'))
return (pat + 2);
return (pat);
}
int match_pattern(const char *pat, char *str,
char *full_word, t_ld **match)
{
pat = manage_pat(pat, str);
while (*pat)
{
if (*pat == '?')
str++;
else if (*pat == '[')
{
if (!match_bracket(&pat, *str))
return (0);
}
else if (*pat == '*')
return (match_star(pat, str, full_word, match));
else if (*pat == '\\')
{
if (!*++pat || *str != *pat)
return (0);
}
else if (*pat == '/' && !*str && is_directory(full_word))
dir_research((pat + 1), full_word, match);
else if (*pat != *str)
return (0);
++str;
++pat;
}
return (*str ? 0 : 1);
}

17
42sh/update_makefile.sh Executable file
View file

@ -0,0 +1,17 @@
MYPATH=$(pwd)
CUR_MAKEFILE=$MYPATH/Makefile
if [ -e $CUR_MAKEFILE ]
then
echo "regenerate Makefile"
sed "`grep -n 'SRC_BASE =' $CUR_MAKEFILE | sed 's/:.*//'`, \$d" $CUR_MAKEFILE > NEWMAKEFILE
grep 'SRC_BASE =' $CUR_MAKEFILE >> NEWMAKEFILE
expr "$(find ./srcs | grep "\.c" | sed -e 's/srcs\///' -e 's/\.\///' -e 's/$/\\/')" : "\(.*\).$" >> NEWMAKEFILE
echo "" >> NEWMAKEFILE
grep 'SRCS =' $CUR_MAKEFILE >> NEWMAKEFILE
sed "1, `grep -n 'SRCS =' $CUR_MAKEFILE | sed 's/:.*//'`d" $CUR_MAKEFILE >> NEWMAKEFILE
mv $CUR_MAKEFILE ~/Documents/.OLDMakefile
mv NEWMAKEFILE $CUR_MAKEFILE
echo "Makefile done (copy still alive in ~/Documents/.OLDMakefile)"
else
echo "Makefile not found."
fi