MiniDevil As beautiful as a shell
expander.c
Go to the documentation of this file.
1 /* ************************************************************************** */
2 /* */
3 /* ::: :::::::: */
4 /* expander.c :+: :+: :+: */
5 /* +:+ +:+ +:+ */
6 /* By: baelgadi <baelgadi@student.42.fr> +#+ +:+ +#+ */
7 /* +#+#+#+#+#+ +#+ */
8 /* Created: 2025/12/06 16:47:17 by zotaj-di #+# #+# */
9 /* Updated: 2026/03/04 04:43:45 by baelgadi ### ########.fr */
10 /* */
11 /* ************************************************************************** */
12 
13 #include "token.h"
14 #include "env.h"
15 #include "libft.h"
16 
25 static int handle_special_var(char *str, char **result, int exit_status)
26 {
27  char *value;
28 
29  if (str[1] == '?')
30  {
31  value = ft_itoa(exit_status);
32  *result = append_str(*result, value);
33  free(value);
34  return (2);
35  }
36  return (0);
37 }
38 
51 static int process_dollar(char *str, int i, char **result, t_env *env_list)
52 {
53  char *var_name;
54  char *var_value;
55  int len;
56 
57  var_name = extract_var_name(str + i + 1, &len);
58  if (!var_name)
59  return (1);
60  if (len == 0)
61  {
62  *result = append_char(*result, '$');
63  free(var_name);
64  return (1);
65  }
66  if (ft_isdigit(var_name[0]) && var_name[0] == '0')
67  {
68  free(var_name);
69  *result = append_str(*result, "minidevil");
70  return (2);
71  }
72  var_value = get_env_value(env_list, var_name);
73  if (var_value)
74  *result = append_str(*result, var_value);
75  free(var_name);
76  return (len + 1);
77 }
78 
88 static int handle_dollar_sign(char *str, char **result, t_env *env_list,
89  int exit_status)
90 {
91  int skip;
92 
93  skip = handle_special_var(str, result, exit_status);
94  if (skip > 0)
95  return (skip);
96  if (is_var_char(str[1]))
97  return (process_dollar(str, 0, result, env_list));
98  *result = append_char(*result, '$');
99  return (1);
100 }
101 
111 char *expand_variables(char *str, t_env *env_list, t_quote_type quote_type,
112  int exit_status)
113 {
114  char *result;
115  int i;
116 
117  if (quote_type == QUOTE_SINGLE)
118  return (ft_strdup(str));
119  result = ft_strdup("");
120  if (!result)
121  return (NULL);
122  i = 0;
123  while (str[i])
124  {
125  if (str[i] == '$' && str[i + 1])
126  i += handle_dollar_sign(str + i, &result, env_list, exit_status);
127  else
128  {
129  result = append_char(result, str[i]);
130  i++;
131  }
132  if (!result)
133  return (NULL);
134  }
135  return (result);
136 }
137 
150 int expand_all_tokens(t_token *tokens, t_shell *shell)
151 {
152  char *expanded;
153  t_token *prev;
154 
155  prev = NULL;
156  while (tokens)
157  {
158  if (tokens->type == TOKEN_WORD)
159  {
160  if (tokens->quote_type == QUOTE_SINGLE || (prev
161  && prev->type == TOKEN_HEREDOC))
162  expanded = ft_strdup(tokens->value);
163  else if (is_dollar_quote(tokens))
164  expanded = ft_strdup("");
165  else
166  expanded = expand_full(tokens->value, shell->env,
167  tokens->quote_type, shell->exit_status);
168  if (!expanded)
169  return (-1);
170  free(tokens->value);
171  tokens->value = expanded;
172  }
173  prev = tokens;
174  tokens = tokens->next;
175  }
176  return (0);
177 }
Environment variable management prototypes.
char * get_env_value(t_env *env_list, char *key)
Look up an environment variable's value by its key.
char * expand_variables(char *str, t_env *env_list, t_quote_type quote_type, int exit_status)
Expand all $VARIABLE in a string.
Definition: expander.c:111
static int process_dollar(char *str, int i, char **result, t_env *env_list)
Process a normal $VARIABLE expansion.
Definition: expander.c:51
static int handle_special_var(char *str, char **result, int exit_status)
Handle $? expansion (last exit status)
Definition: expander.c:25
static int handle_dollar_sign(char *str, char **result, t_env *env_list, int exit_status)
Dispatch $ expansion (special vars then normal)
Definition: expander.c:88
int expand_all_tokens(t_token *tokens, t_shell *shell)
Expand all token values before parsing.
Definition: expander.c:150
int is_var_char(char c)
Check if a character is valid in a variable name.
int is_dollar_quote(t_token *token)
Check if a token is a $ connected to a quoted token.
char * extract_var_name(char *str, int *len)
Extract a variable name from after the $
char * append_str(char *s1, char *s2)
Concatenates 2 strings and frees the first.
char * append_char(char *str, char c)
Append a single character to an allocated string.
@ TOKEN_WORD
Definition: structs.h:25
@ TOKEN_HEREDOC
Definition: structs.h:30
t_quote_type
Quote context of a token.
Definition: structs.h:41
@ QUOTE_SINGLE
Definition: structs.h:43
Environment variable (doubly linked list)
Definition: structs.h:87
Shell state.
Definition: structs.h:164
t_env * env
Environment linked list.
Definition: structs.h:165
int exit_status
Last command's exit status.
Definition: structs.h:166
Lexer token (singly linked list)
Definition: structs.h:71
char * value
Text content (allocated)
Definition: structs.h:73
t_token_type type
Token type (word, pipe, redir)
Definition: structs.h:72
struct s_token * next
Next token.
Definition: structs.h:76
t_quote_type quote_type
Quote context.
Definition: structs.h:74
char * expand_full(char *str, t_env *env, t_quote_type qt, int exit_status)
Handles variable expansion and tilde expansion.
Definition: tilde_expand.c:60
Lexer, tokenizer, expander, and quote handling prototypes.