42-archive/42sh/src/completion/c_pathsolver.c

134 lines
3.6 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* c_pathsolver.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/10/25 18:21:54 by alao #+# #+# */
/* Updated: 2017/02/16 22:17:53 by alao ### ########.fr */
/* */
/* ************************************************************************** */
#include "completion.h"
/*
** Solve the tilde pattern in the path
*/
static char *tilde(t_comp *c, char *cmd)
{
char *t_home;
char *t_sub;
char *rt;
int l_cmd;
t_home = NULL;
t_sub = NULL;
rt = NULL;
l_cmd = ft_strlen(cmd);
if ((t_home = ft_strdup(c->home)))
if ((t_sub = ft_strsub(cmd, 1, (l_cmd - 1))))
rt = ft_strjoin(t_home, t_sub);
t_home ? ft_memdel((void *)&t_home) : (0);
t_sub ? ft_memdel((void *)&t_sub) : (0);
return (rt);
}
/*
** Advanced dots purge if the first is not enough. Remove a /path/ from
** the raw command if .. is found. Delete the . .
*/
static char *dots_purge(char **scwd, char **scmd, int i)
{
char *tmp;
char *rt;
int j;
tmp = NULL;
rt = NULL;
((j = ft_sstrlen(scwd)) > 0) ? (j--) : (0);
(!(scwd[1])) ? (scwd[0] = ft_strdup("/")) : (0);
while (scmd[i] && scwd[0])
{
if (!(ft_strcmp(scmd[i], ".")) || !(ft_strcmp(scmd[i], scwd[j])) ||
!(ft_strcmp(scmd[i], "..")))
(!(ft_strcmp(scmd[i], ".."))) ? (ft_memdel((void *)&scwd[j])) : (0);
else if ((scwd[j + 1] = ft_strdup(scmd[i])))
scwd[j + 2] = NULL;
i++;
((j = ft_sstrlen(scwd)) > 0) ? (j--) : (0);
(!(scwd[0])) ? (scwd[0] = ft_strdup("/")) : (0);
}
rt = ft_sstrtostr(scwd, "/");
tmp = ft_strjoin("/", rt);
tmp ? ft_memdel((void *)&rt) : (0);
rt = ft_strsub(tmp, 0, (ft_strlen(tmp) - 1));
tmp ? ft_memdel((void *)&tmp) : (0);
return (rt);
}
/*
** Solve the dots pattern in the path
*/
static char *dots(char *cmd, char *cwd, int i)
{
char *tmp;
char **scmd;
char **scwd;
tmp = NULL;
if (!(ft_strcmp(cmd, ".")) || !(ft_strcmp(cmd, "./")))
return (ft_strdup(cwd));
if (!ft_strcmp(cmd, "..") && cwd && (i = ft_strlen(cwd)))
{
while (cwd[i] != '/')
i--;
(i) ? (tmp = ft_strncpy(ft_strnew(i), cwd, i)) : (0);
}
if (!tmp && cwd && (i = ft_strlen(cwd)))
{
scmd = ft_strsplit(cmd, '/');
scwd = ft_strsplit(cwd, '/');
tmp = dots_purge(scwd, scmd, 0);
scmd ? ft_sstrfree(scmd) : (0);
scwd ? ft_sstrfree(scwd) : (0);
}
if (!cwd)
tmp = ft_strdup("/");
return (tmp);
}
/*
** Path solving function. Turn any abstract path to the full version.
*/
char *path_solver(t_comp *c, char *cmd, char *cwd)
{
char *dir;
char *tmp;
char *ncmd;
dir = NULL;
tmp = NULL;
ncmd = (cmd != NULL) ? ft_strtrim(cmd) : NULL;
cwd = getcwd(cwd, 512);
!cwd ? cwd = ft_strdup(c->pwd) : (0);
if (!ncmd || (*ncmd != '.' && *ncmd != '~' && *ncmd != '/'))
{
tmp = ft_strjoin(cwd, "/");
dir = ncmd ? ft_strjoin(tmp, ncmd) : ft_strdup(cwd);
tmp ? ft_memdel((void *)&tmp) : (0);
}
else
{
(*ncmd == '~') ? (dir = tilde(c, ncmd)) : (0);
(*ncmd == '.') ? (dir = dots(ncmd, cwd, 0)) : (0);
(*ncmd == '/') ? (dir = ft_strdup(ncmd)) : (0);
}
cwd ? ft_memdel((void *)&cwd) : (0);
ncmd ? ft_memdel((void *)&ncmd) : (0);
return (dir);
}