feat(expansion): expand_var and expand
This commit is contained in:
parent
a16712e802
commit
34c741d86e
4 changed files with 276 additions and 14 deletions
|
|
@ -6,6 +6,9 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "../utils/ast/ast.h"
|
||||
#include "../utils/hash_map/hash_map.h"
|
||||
#include "../utils/string_utils/string_utils.h"
|
||||
#include "../utils/vars/vars.h"
|
||||
|
||||
static bool is_var_start_char(char c)
|
||||
{
|
||||
|
|
@ -77,14 +80,39 @@ size_t parse_var_name(char *str, char **res)
|
|||
return i;
|
||||
}
|
||||
|
||||
struct ast_command *expand(struct ast_command *command)
|
||||
static bool expand_var(char **str, size_t pos, const struct hash_map *vars)
|
||||
{
|
||||
char *var_name = NULL;
|
||||
size_t r = parse_var_name(*str + pos, &var_name);
|
||||
if (r > 0 && var_name != NULL)
|
||||
{
|
||||
char *value = get_var_or_env(vars, var_name);
|
||||
if (value == NULL)
|
||||
// Undefined variable: expand to empty string
|
||||
value = "";
|
||||
|
||||
char *p = insert_into(*str, value, pos, r);
|
||||
free(var_name);
|
||||
if (p == NULL)
|
||||
{
|
||||
// error: insertion failed
|
||||
return false;
|
||||
}
|
||||
*str = p;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct ast_command *expand(struct ast_command *command,
|
||||
const struct hash_map *vars)
|
||||
{
|
||||
if (command == NULL)
|
||||
return NULL;
|
||||
|
||||
bool in_quotes = false;
|
||||
char *str;
|
||||
size_t len;
|
||||
bool in_quotes;
|
||||
struct list *l = command->command;
|
||||
|
||||
while (l != NULL)
|
||||
|
|
@ -93,28 +121,35 @@ struct ast_command *expand(struct ast_command *command)
|
|||
str = (char *)l->data;
|
||||
len = strlen(str);
|
||||
|
||||
for (size_t i = 0; str[i] != '\0'; i++)
|
||||
for (size_t i = 0; str[i] != 0; i++)
|
||||
{
|
||||
if (in_quotes)
|
||||
{
|
||||
continue; // do nothing
|
||||
}
|
||||
else if (str[i] == '\'')
|
||||
if (str[i] == '\'')
|
||||
{
|
||||
// remove quote
|
||||
in_quotes = !in_quotes;
|
||||
memmove(&str[i], &str[i + 1], strlen(&str[i + 1]) + 1);
|
||||
memmove(str + i, str + i + 1, strlen(str + i + 1) + 1);
|
||||
i--;
|
||||
}
|
||||
else if (in_quotes)
|
||||
{
|
||||
continue; // do nothing
|
||||
}
|
||||
else if (str[i] == '$' && str[i + 1] != 0 && !isspace(str[i + 1]))
|
||||
{
|
||||
// variable expansion
|
||||
bool r = expand_var(&str, i, vars);
|
||||
if (r == false || str == NULL)
|
||||
return NULL;
|
||||
|
||||
i--; // -1 because loop will increment i
|
||||
}
|
||||
}
|
||||
|
||||
if (in_quotes)
|
||||
{
|
||||
// error: quote not closed
|
||||
fprintf(stderr, "Error: quote not closed in string: %s\n", str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len != strlen(str))
|
||||
|
|
@ -123,6 +158,7 @@ struct ast_command *expand(struct ast_command *command)
|
|||
if (new_str == NULL)
|
||||
{
|
||||
// error: realloc fail
|
||||
return NULL;
|
||||
}
|
||||
l->data = new_str;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue