save commit
This commit is contained in:
113
minishell-codex/src/parser/expand.c
Normal file
113
minishell-codex/src/parser/expand.c
Normal file
@@ -0,0 +1,113 @@
|
||||
#include "minishell.h"
|
||||
|
||||
static void buf_append(char **buf, size_t *len, size_t *cap, const char *s)
|
||||
{
|
||||
size_t slen;
|
||||
char *newbuf;
|
||||
|
||||
if (!s)
|
||||
return;
|
||||
slen = strlen(s);
|
||||
if (*len + slen + 1 > *cap)
|
||||
{
|
||||
*cap = (*len + slen + 1) * 2;
|
||||
newbuf = (char *)realloc(*buf, *cap);
|
||||
if (!newbuf)
|
||||
return;
|
||||
*buf = newbuf;
|
||||
}
|
||||
memcpy(*buf + *len, s, slen);
|
||||
*len += slen;
|
||||
(*buf)[*len] = '\0';
|
||||
}
|
||||
|
||||
static void buf_append_char(char **buf, size_t *len, size_t *cap, char c)
|
||||
{
|
||||
char tmp[2];
|
||||
tmp[0] = c;
|
||||
tmp[1] = '\0';
|
||||
buf_append(buf, len, cap, tmp);
|
||||
}
|
||||
|
||||
static char *expand_word(const char *word, t_shell *sh)
|
||||
{
|
||||
int in_single = 0;
|
||||
int in_double = 0;
|
||||
size_t i = 0;
|
||||
char *out = NULL;
|
||||
size_t len = 0, cap = 0;
|
||||
|
||||
while (word && word[i])
|
||||
{
|
||||
if (word[i] == '\'' && !in_double)
|
||||
{
|
||||
in_single = !in_single;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (word[i] == '"' && !in_single)
|
||||
{
|
||||
in_double = !in_double;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (word[i] == '$' && !in_single)
|
||||
{
|
||||
if (word[i + 1] == '?')
|
||||
{
|
||||
char *v = ms_itoa(sh->last_status);
|
||||
buf_append(&out, &len, &cap, v);
|
||||
free(v);
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
if (ms_is_alpha((unsigned char)word[i + 1]))
|
||||
{
|
||||
size_t j = i + 1;
|
||||
while (word[j] && ms_is_alnum((unsigned char)word[j]))
|
||||
j++;
|
||||
char *name = ms_strndup(word + i + 1, j - (i + 1));
|
||||
char *val = env_get(sh, name);
|
||||
buf_append(&out, &len, &cap, val ? val : "");
|
||||
free(name);
|
||||
i = j;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
buf_append_char(&out, &len, &cap, word[i]);
|
||||
i++;
|
||||
}
|
||||
if (!out)
|
||||
out = ms_strdup("");
|
||||
return out;
|
||||
}
|
||||
|
||||
int expand_pipeline(t_pipeline *p, t_shell *sh)
|
||||
{
|
||||
size_t i;
|
||||
int j;
|
||||
for (i = 0; i < p->count; i++)
|
||||
{
|
||||
for (j = 0; p->cmds[i]->argv && p->cmds[i]->argv[j]; j++)
|
||||
{
|
||||
char *neww = expand_word(p->cmds[i]->argv[j], sh);
|
||||
free(p->cmds[i]->argv[j]);
|
||||
p->cmds[i]->argv[j] = neww;
|
||||
}
|
||||
if (p->cmds[i]->redirs)
|
||||
{
|
||||
t_redir *r = p->cmds[i]->redirs;
|
||||
while (r)
|
||||
{
|
||||
if (r->target)
|
||||
{
|
||||
char *nt = expand_word(r->target, sh);
|
||||
free(r->target);
|
||||
r->target = nt;
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user