diff options
Diffstat (limited to 'src/u_vars.c')
-rw-r--r-- | src/u_vars.c | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/src/u_vars.c b/src/u_vars.c new file mode 100644 index 0000000..2a78f3d --- /dev/null +++ b/src/u_vars.c @@ -0,0 +1,183 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* u_vars.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdlib.h> +#include <stdint.h> + +#include "d_define.h" +#include "f_fail.h" +#include "s_destroy.h" +#include "s_lcom.h" +#include "s_struct.h" + +static char + *u_set_rva(const char varname[], + t_msh *msh) +{ + char *rvarname; + + if (!(rvarname = (char*)malloc((ft_strlen(varname) + 1) * sizeof(char)))) + { + lcom_clear(&msh->curr); + s_destroy(msh); + f_fail_alloc(msh); + } + (void)ft_memcpy((char*)rvarname, (const char*)varname + 1, + ft_strlen(varname + 1)); + *(rvarname + ft_strlen(varname + 1)) = '='; + *(rvarname + ft_strlen(varname + 1) + 1) = '\0'; + return (rvarname); +} + +static char + *u_dup_env(char *p_env, + char *rvarname, + t_msh *msh) +{ + char *varval; + + if (!(varval = ft_strdup(p_env))) + { + ft_memdel((void*)&rvarname); + lcom_clear(&msh->curr); + s_destroy(msh); + f_fail_alloc(msh); + } + ft_memdel((void*)&rvarname); + return (varval); +} + +static char + *u_get_frm_env(char rvarname[], + t_msh *msh) +{ + char **p_env; + char *pp_env; + char *varval; + + p_env = msh->envp; + while (*p_env) + { + if (!ft_strncmp(rvarname, *p_env, ft_strclen(*p_env, '='))) + { + pp_env = *p_env; + while (*pp_env != '\0' && *pp_env != '=') + pp_env += 1; + if (*pp_env == '=') + pp_env += 1; + varval = u_dup_env(pp_env, rvarname, msh); + return (varval); + } + p_env += 1; + } + ft_memdel((void*)&rvarname); + return (NULL); +} + +static char + *u_get_special_var(const char varname[], + t_msh *msh) +{ + char *varval; + + if (ft_strncmp(varname, FT_RET_VAR, 3) == 0) + { + if ((varval = ft_uitoa(msh->ret)) == NULL) + { + lcom_clear(&msh->curr); + s_destroy(msh); + f_fail_alloc(msh); + } + return (varval); + } + else if (ft_strncmp(varname, FT_ZER_VAR, 3) == 0) + { + if ((varval = ft_strdup(msh->shname)) == NULL) + { + lcom_clear(&msh->curr); + s_destroy(msh); + f_fail_alloc(msh); + } + return (varval); + } + return (NULL); +} + +char + *u_get_cstm_vr(const char varname[], + t_msh *msh) +{ + t_lvars *ptr; + char *varval; + + ptr = msh->vars; + while (ptr != NULL && + ft_strncmp(varname + 1, ptr->name, ft_strlen(varname + 1) + 1) != 0) + { + ptr = ptr->next; + } + if (ptr != NULL) + { + if (!(varval = ft_strdup(ptr->val))) + { + lcom_clear(&msh->curr); + s_destroy(msh); + f_fail_alloc(msh); + } + return (varval); + } + else + { + return (NULL); + } +} + +/* +** char* +** u_get_var_value(const char varname[], t_msh *msh); +** +** DESCRIPTION +** The u_get_var_value() function returns +** a heap-allocated, null-terminated string +** that may later be free'd containing the +** value of the variable varname[] including +** the '$' prefix. NULL is returned if varname[] +** wasn't found. +*/ + +char + *u_get_var_value(const char varname[], + t_msh *msh) +{ + /* TODO: check behaviour on empty vars -> "QWE=" */ + /* TODO: add support for global variables -> "$hey $nigga..." */ + char *varval; + char *rvarname; + + varval = NULL; + if ((varval = u_get_special_var(varname, msh)) != NULL) + { + return (varval); + } + else if ((varval = u_get_cstm_vr(varname, msh)) != NULL) + { + return (varval); + } + else + { + rvarname = u_set_rva(varname, msh); + varval = u_get_frm_env(rvarname, msh); + return (varval); + } + return (NULL); +} |