42-archive/42sh/srcs/glob/glob.c
2017-01-26 19:24:00 +01:00

133 lines
3 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* glob.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: wescande <wescande@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/04 16:29:54 by wescande #+# #+# */
/* Updated: 2017/01/05 20:09:14 by wescande ### ########.fr */
/* */
/* ************************************************************************** */
#include "glob.h"
/*
** glob return expansion of a string.
** pattern searched are ~, *, ?, [a-z], [!a-z], [^a-z], {ab}.
** input parameters are :
** -char *pat -> pattern string to be looking for match
** -char **env -> env var. could be NULL
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(const char **pat, char **str)
{
return (1);
}
static int match_star(const char *pat, char *str)
{
char *fix;
fix = str + ft_strlen(str);
return (1);
}
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;
}
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);
}
}
char **glob(const char *pat, char **env)
{
t_ld *match;
char **gl;
char **path;
match = NULL;
gl = NULL;
if (env && (path = ft_strsplit(ft_getenv(env, "PATH"), ':')))
{
path_research(pat, path, &match);
ft_tabdel(&path);
}
dir_research(pat, "./", &match);
if (match)
{
gl = ft_ld_to_tab(match);
ft_ld_clear(&match, &ft_strdel);
}
return (gl);
}