Repository navigation
Expand file tree
/
Copy pathtokenizer.c
More file actions
76 lines (71 loc) · 2.06 KB
/
Copy pathtokenizer.c
File metadata and controls
76 lines (71 loc) · 2.06 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
#include "shell/tokenizer/tokenizer.h"
#include <ctype.h>
#include <stddef.h>
#include <stdlib.h>
int shell_parse_args_inplace(char *cmd, char *argv[], int maxargs) {
int argc = 0;
char *p = cmd;
char *dst = cmd; /* write pointer */
while (*p != '\0' && argc < maxargs - 1) {
/* skip leading whitespace */
while (*p == ' ' || *p == '\t')
p++;
if (*p == '\0')
break;
/* start a new arg */
argv[argc++] = dst;
while (*p != '\0') {
/* Backslash escaping (only outside quotes): copy next char literally */
if (*p == '\\') {
p++; /* skip backslash */
if (*p != '\0') {
*dst++ = *p++;
}
continue;
}
if (*p == '\'') {
/* single-quoted sequence: copy literally until next single quote */
p++; /* skip opening quote */
while (*p != '\0' && *p != '\'') {
*dst++ = *p++;
}
if (*p == '\'')
p++; /* skip closing quote if present */
continue;
}
if (*p == '"') {
/* double-quoted sequence: copy literally until next double quote,
but allow \" and \\ escapes inside double quotes (they become " and \) */
p++; /* skip opening quote */
while (*p != '\0' && *p != '"') {
if (*p == '\\') {
/* If next char is " or \\, treat it as escaped and copy the char without the backslash
*/
if (p[1] == '"' || p[1] == '\\') {
p++; /* skip backslash */
*dst++ = *p++; /* copy escaped char */
} else {
/* Backslash followed by other char: backslash is literal */
*dst++ = *p++;
}
continue;
}
*dst++ = *p++;
}
if (*p == '"')
p++; /* skip closing quote if present */
continue;
}
if (*p == ' ' || *p == '\t') {
/* end of this arg */
p++;
break;
}
/* normal character */
*dst++ = *p++;
}
*dst++ = '\0';
}
argv[argc] = NULL;
return argc;
}