feat(expansion): parse_var_name and tests

This commit is contained in:
william.valenduc 2026-01-16 21:48:27 +00:00
parent ccb9438d69
commit dadbebfceb
3 changed files with 223 additions and 28 deletions

View file

@ -1,3 +1,4 @@
#define _POSIX_C_SOURCE 200809L
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
@ -6,13 +7,75 @@
#include "../utils/ast/ast.h"
// static size_t var_len(char *start)
// {
// char *iter = start;
// while (*iter != ' ' && *iter != 0)
// *iter++;
// return iter - start;
// }
static bool is_var_start_char(char c)
{
return isalpha(c) || c == '_';
}
static bool is_var_char(char c)
{
return isalnum(c) || c == '_';
}
static bool is_special_var_char(char c)
{
return c == '@' || c == '*' || c == '?' || c == '$' || isdigit(c)
|| c == '#';
}
size_t parse_var_name(char *str, char **res)
{
char *brace = NULL;
size_t i = 1; // skip the '$'
if (str[i] == '{' && str[i + 1] != 0 && str[i + 1] != '}')
{
if (is_special_var_char(str[i + 1]) && str[i + 2] == '}')
{
// Special variable like ${1}, ${?}
*res = strndup(str + i + 1, 1);
return 4; // length of ${X}
}
brace = str + i;
i++; // skip the '{'
}
else if (is_special_var_char(str[i]))
{
*res = strndup(str + i, 1);
return 2; // length of $X
}
if (!is_var_start_char(str[i]))
{
// Not a valid variable start
*res = NULL;
return 0;
}
while (1)
{
if (str[i] == '}' && *brace == '{')
{
*res = strndup(str + 2, i - 2);
return i + 1;
}
else if (!is_var_char(str[i]))
{
if (brace != NULL)
{
// Missing closing '}'
*res = NULL;
return 0;
}
break;
}
i++;
}
*res = strndup(str + 1, i - 1);
return i;
}
struct ast_command *expand(struct ast_command *command)
{
@ -34,21 +97,18 @@ struct ast_command *expand(struct ast_command *command)
{
if (in_quotes)
{
// do nothing
continue; // do nothing
}
else if (str[i] == '\'')
{
// remove quote
in_quotes = !in_quotes;
memmove(&str[i], &str[i + 1], strlen(&str[i + 1]) + 1);
i--;
}
else if (str[i] == '$' && str[i + 1] != 0 && !isspace(str[i + 1]))
{
// size_t len = var_len(str + i + 1);
// char *end = str + i + len + 1;
// char c = *end;
// *end = 0;
// printf("var: %s\n", str + i + 1);
// *end = c;
// variable expansion
}
}
@ -71,17 +131,3 @@ struct ast_command *expand(struct ast_command *command)
}
return command;
}
// int main()
// {
// printf("Expansion module test\n");
// struct ast_command ast_command;
// // char str[] = "echo Hello $?";
// char str[] = "echo Hello $AE86";
// ast_command.command = list_append(NULL, str);
// struct ast_command *command2 = expand(&ast_command);
// printf("command2: %s\n", (char *)command2->command->data);
// return 0;
// }