-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
113 lines (92 loc) · 3.12 KB
/
main.c
File metadata and controls
113 lines (92 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "list.h"
#include "tree.h"
#include "exec.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
/* Обработчик SIGINT (Ctrl+C) */
void sigint_handler(int sig) {
printf("\n");
fflush(stdout);
}
/* Чтение строки с поддержкой Ctrl+D */
char* read_line(void) {
static char buffer[4096];
printf("$ "); // Простое приглашение
fflush(stdout);
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
if (feof(stdin)) {
printf("\n");
return NULL; /* Ctrl+D */
}
return NULL;
}
/* Убираем перевод строки */
size_t len = strlen(buffer);
if (len > 0 && buffer[len-1] == '\n') {
buffer[len-1] = '\0';
}
return buffer;
}
/* Главный цикл */
int main(int argc, char **argv) {
/* Настройка сигналов */
signal(SIGINT, sigint_handler);
printf("MyShell v1.0 (Ctrl+D to exit)\n");
/* Режим выполнения команды из аргументов */
if (argc > 1) {
char cmd[4096] = "";
for (int i = 1; i < argc; i++) {
strcat(cmd, argv[i]);
strcat(cmd, " ");
}
TokenList *list = tokenize_to_list(cmd);
if (list) {
substitute_env_vars_in_list(list);
/* Создаём структуру TokenList из указателя */
TokenList token_struct = {list->tokens, list->count, list->capacity};
Command *tree = parse_tokens(token_struct);
if (tree) {
execute_command(tree);
free_command(tree);
}
/* Очищаем список */
for (int i = 0; i < list->count; i++) {
free(list->tokens[i]);
}
free(list->tokens);
free(list);
}
return 0;
}
/* Интерактивный режим */
while (1) {
/* Запрос строки */
char *line = read_line();
if (!line) break; /* Ctrl+D */
if (strlen(line) == 0) continue;
/* Лексический анализ */
TokenList *list = tokenize_to_list(line);
if (!list) continue;
/* Подстановка переменных */
substitute_env_vars_in_list(list);
/* Синтаксический анализ - передаём структуру, а не указатель */
TokenList token_struct = {list->tokens, list->count, list->capacity};
Command *cmd_tree = parse_tokens(token_struct);
if (cmd_tree) {
/* Выполнение */
execute_command(cmd_tree);
free_command(cmd_tree);
}
/* Очистка списка */
for (int i = 0; i < list->count; i++) {
free(list->tokens[i]);
}
free(list->tokens);
free(list);
}
printf("\nGoodbye!\n");
return 0;
}