[structs.h]
typedef struct s_tok
{
int len;
char *tok;
int type;
struct s_tok *next;
} t_tok;
typedef struct s_table{
char **paths;
char **reserved;
int q_c[2];
t_env *env;
t_tok *token;
} t_table;
[minishell.c]
#include "./includes/minishell_header.h"
int main(int argc, char *argv[], char *envp[])
{
t_table *table;
char *cmdline;
create_shell(envp, &table);
while(1)
{
cmdline = readline(SHELL);
add_history(cmdline);
lexical_analyzer(cmdline, table);
while(table->token != NULL)
{
printf("[%s] : %dn", table->token->tok, table->token->type);
table->token = table->token->next;
}
}
}
[lex_analyzer.c]
#include "minishell_header.h"
void lexical_analyzer(char *cmdline, t_table *table)
{
openquotes(cmdline);
if(quote_syntax_analyzer(cmdline, table->q_c))
{
cmdline = find_replace(cmdline, table->env);
token_replacment(cmdline, 4, '$');
token_replacment(cmdline, 3, ' ');
table->token = tokenization(cmdline);
}
else
printf("%s '%s'n", QUOTE_SYNTAX_ERR, "'");
free(cmdline);
}
[tokenization.c]
t_tok *tokenization(char *cmdline)
{
t_tok *tokens;
int i;
tokens = NULL;
i = -1;
while (cmdline[++i])
{
if (cmdline[i] && ft_iswordpart(cmdline[i]))
add_word(cmdline, &i, &tokens);
if(cmdline[i] && ft_isspace(cmdline[i]))
space(cmdline, &i, cmdline[i], &tokens);
if(cmdline[i] && (cmdline[i] == '"' || cmdline[i] == '''))
expansion(cmdline, &i, cmdline[i], &tokens);
if (cmdline[i] && (cmdline[i] == '>' || cmdline[i] == '<'))
redirection(cmdline, &i, cmdline[i], &tokens);
if (cmdline[i] && cmdline[i] == '|')
add_pipe(cmdline, &i, cmdline[i], &tokens);
}
return (tokens);
}
这是我的迷你狂欢项目。我有个问题,但我找不到它在哪里。
[mesticell-$]echo"$用户你好";世界
当我试图标记这个命令时,它应该会返回我:
[echo] : 4
[] : 3
[user hello ] : 7
[world] : 4
但在这种情况下,它会返回给我:
[echo] : 4
[] : 3
[user hello ] : 7
[world] : 4
[!] : 4
我不明白最后一个代币放在哪里?
我的函数用于将节点添加到t_tok列表中。
t_tok *new_token(int len, char *token, int type)
{
t_tok *tok;
tok = malloc(sizeof(t_tok));
if(!tok)
return (NULL);
tok->len = len;
tok->tok = ft_strdup(token);
tok->type = type;
tok->next = NULL;
return (tok);
}
void add(t_tok **lst, t_tok *new)
{
while(*lst)
lst = &(*lst)->next;
*lst = new;
}
问题出现在tokenization()
方法中的代码中;无论cmdline[i]
是否为空格,都要添加令牌:
if (cmdline[i])
add_word(cmdline, &i, &tokens);
相反,你应该测试空间的存在:
if (cmdline[i] && ft_iswordpart(cmdline[i]))
add_word(cmdline, &i, &tokens);
按照现在的方式,您的代码将继续将令牌添加到字符串的末尾。在您的示例中,当调用add_word()
时,cmdline[i]
是' '
,因此代码将读取超出缓冲区的末尾,然后在缓冲区的结尾之外写入,导致未定义的行为。