42-archive/42sh/src/builtin/builtin_read.c
2017-02-06 14:05:44 +01:00

107 lines
2.9 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* builtin_read.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/20 15:01:45 by jhalford #+# #+# */
/* Updated: 2017/02/06 14:02:17 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "builtin_read.h"
t_readopt g_readtab[] =
{
/* {'a', READ_OPT_LA, NULL}, */
{'d', READ_OPT_LD, bt_read_getdelim},
/* {'e', READ_OPT_LE, NULL}, */
/* {'i', READ_OPT_LI, NULL}, */
{'n', READ_OPT_LN, bt_read_getnchars},
/* {'N', READ_OPT_UN, bt_read_getnchars}, */
{'p', READ_OPT_LP, bt_read_getprompt},
{'r', READ_OPT_LR, NULL},
{'s', READ_OPT_LS, NULL},
{'t', READ_OPT_LT, bt_read_gettimeout},
{'u', READ_OPT_LU, bt_read_getfd},
{0, 0, 0},
};
int bt_read_loop(t_read *data)
{
int i;
int esc;
char buf[2];
esc = 0;
i = 0;
if (data->prompt)
ft_printf(data->prompt);
while (42)
{
if (read(data->fd, buf, 1) <= 0)
return (1);
buf[1] = 0;
DG("got input [%x]", *buf);
if (!esc && *buf == data->delim)
break ;
esc = esc ? 0 : !(data->opts & READ_OPT_LR) && (*buf == '\\');
ft_strappend(&data->input, buf);
if (*buf == '\n' && !(data->opts & READ_OPT_LR))
ft_putstr("> ");
if ((data->opts & READ_OPT_LN) && ++i >= data->nchars)
break ;
}
ft_putchar('\n');
return (0);
}
int bt_read_assign(t_read *data)
{
char *input;
char **names;
char *IFS;
char *start;
input = data->input;
names = data->names ? data->names : (char*[]){"REPLY", NULL};
IFS = ft_getenv(data_singleton()->env, "IFS");
start = input;
while (*start && *names)
{
if (!(names[1]) || !IFS)
{
DG("setting env: %s=%x%x%x", *names, *start, start[1],start[2]);
builtin_setenv("setenv", (char*[]){"setenv", *names, start}, NULL);
break ;
}
while (*input && !ft_strchr(IFS, *input))
input++;
while (input && ft_strchr(IFS, *input))
*(input++) = 0;
builtin_setenv("setenv", (char*[]){"setenv", *names, start}, NULL);
start = input;
names++;
}
return (0);
}
int builtin_read(const char *path, char *const av[], char *const envp[])
{
t_read data;
int ret;
(void)path;
(void)envp;
ret = 0;
if (bt_read_init(&data, (char **)av))
ret = 2;
else if (bt_read_loop(&data))
ret = 1;
else if (bt_read_assign(&data))
ret = 1;
bt_read_exit(&data);
return (ret);
}