-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.c
More file actions
167 lines (150 loc) · 5.22 KB
/
parser.c
File metadata and controls
167 lines (150 loc) · 5.22 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "parser.h"
char* strncat_safe(char *dst, const char *src, size_t dstsize)
{
size_t dst_len = 0;
while (dst_len < dstsize && dst[dst_len] != '\0') {
dst_len++;
}
if (dst_len == dstsize) {
return dst;
}
size_t ind = 0;
while (src[ind] != '\0' && (dst_len + ind) < (dstsize - 1))
{
dst[dst_len + ind] = src[ind];
ind++;
}
dst[dst_len + ind] = '\0';
return dst;
}
size_t strncpy_safe(char * dst, const char * src, size_t maxlen)
{
if (maxlen == 0) {
return 0;
}
size_t ind = 0;
for (ind = 0; ind < maxlen - 1 && src[ind] != '\0'; ind++) {
dst[ind] = src[ind];
}
dst[ind] = '\0'; // Ensure null-termination
return ind;
}
void parse_cli(char *command_args[], char *line, const bool *str_map, bool *args_map)
{
// Parse the input into command arguments.
int ctr = 0; // Counter for the number of arguments parsed.
int ptr = 0; // Pointer to track the start of the current argument.
for (int i = 0; i < (int)strlen(line); i++)
{
// Check if the current character is a space or null terminator.
if (line[i] == ' ' || line[i] == '\0')
{
// If there is a valid segment between ptr and i, allocate memory and store it.
if (i > ptr)
{
size_t len = (size_t)(i - ptr);
command_args[ctr] = (char *)malloc((len + 1) * sizeof(char));
if (command_args[ctr] == NULL)
{
perror("malloc failed");
exit(1);
}
strncpy_safe(command_args[ctr], line + ptr, len + 1);
if(str_map[i-1])
{
args_map[ctr] = true; // mark this spot as string, will be used in exec() in main.c
}
ctr++;
}
ptr = i + 1; // Move the pointer to the next character after the space.
// Check if the current character is a redirection symbol '<'.
}
else if (line[i] == '<' && !str_map[i])
{
// If there is a valid segment before '<', allocate memory and store it.
if (i > ptr)
{
size_t len = (size_t)(i - ptr);
command_args[ctr] = (char *)malloc((len + 1) * sizeof(char));
if (command_args[ctr] == NULL)
{
perror("malloc failed");
exit(1);
}
strncpy_safe(command_args[ctr], line + ptr, len + 1);
ctr++;
}
command_args[ctr] = (char *)malloc(2 * sizeof(char));
if (command_args[ctr] == NULL)
{
perror("malloc failed");
exit(1);
}
strncpy_safe(command_args[ctr], "<", 2);
ctr++;
ptr = i + 1; // Move the pointer to the next character after '<'.
// Check if the current character is a redirection symbol '>'.
}
else if (line[i] == '>' && !str_map[i])
{
// If there is a valid segment before '>', allocate memory and store it.
if (i > ptr)
{
size_t len = (size_t)(i - ptr);
command_args[ctr] = (char *)malloc((len + 1) * sizeof(char));
if (command_args[ctr] == NULL)
{
perror("malloc failed");
exit(1);
}
strncpy_safe(command_args[ctr], line + ptr, len + 1);
ctr++;
}
// Check if the next character is also '>', indicating '>>' append redirection.
if (line[i + 1] == '>')
{
command_args[ctr] = (char *)malloc(3 * sizeof(char));
if (command_args[ctr] == NULL)
{
perror("malloc failed");
exit(1);
}
strncpy_safe(command_args[ctr], ">>", 3);
ctr++;
i++; // Skip the next '>' character.
}
else
{
// Allocate memory for the '>' symbol and store it as an argument.
command_args[ctr] = (char *)malloc(2 * sizeof(char));
if (command_args[ctr] == NULL)
{
perror("malloc failed");
exit(1);
}
strncpy_safe(command_args[ctr], ">", 2);
ctr++;
}
ptr = i + 1; // Move the pointer to the next character after '>'.
}
}
// Add the last part of the input if it exists.
if (ptr < (int)strlen(line))
{
size_t len = (size_t)(strlen(line) - (uint64_t)ptr);
command_args[ctr] = (char *)malloc((len + 1) * sizeof(char));
if (command_args[ctr] == NULL)
{
perror("malloc failed");
exit(1);
}
strncpy_safe(command_args[ctr], line + ptr, len + 1); // Copy the last argument.
ctr++;
}
// Set the last argument to NULL to indicate the end of the arguments.
command_args[ctr] = NULL;
}