PatchworkOS
Loading...
Searching...
No Matches
argsplit.c
Go to the documentation of this file.
1#include "argsplit.h"
2
4{
5 state->isNewArg = false;
6
7 if (!state->isFirst)
8 {
9 state->current++;
10 state->processedChars++;
11
12 if (state->maxLen != 0 && state->processedChars >= state->maxLen)
13 {
14 return false;
15 }
16 }
17 else
18 {
19 state->isNewArg = true;
20 }
21 state->isFirst = false;
22
23 while (true)
24 {
25 if (state->escaped != 0)
26 {
27 state->escaped--;
28 }
29
30 if (!state->escaped && !state->inQuote && isspace(*state->current))
31 {
32 state->isNewArg = true;
33 while (isspace(*state->current))
34 {
35 state->current++;
36 state->processedChars++;
37 if (state->maxLen != 0 && state->processedChars >= state->maxLen)
38 {
39 return false;
40 }
41 }
42 }
43
44 if (*state->current == '\\' && !state->escaped)
45 {
46 state->escaped = 2;
47 }
48 else if (*state->current == '"')
49 {
50 state->inQuote = !state->inQuote;
51 state->isNewArg = true;
52 }
53 else if (*state->current == '\0')
54 {
55 return false;
56 }
57 else
58 {
59 return true;
60 }
61
62 state->current++;
63 state->processedChars++;
64
65 if (state->maxLen != 0 && state->processedChars >= state->maxLen)
66 {
67 return false;
68 }
69 }
70}
71
72uint64_t _argsplit_count_chars_and_args(const char* str, uint64_t* argc, uint64_t* totalChars, uint64_t maxLen)
73{
74 *argc = 0;
75 *totalChars = 0;
76
77 _argsplit_state_t state = _ARGSPLIT_CREATE(str, maxLen);
78 while (true)
79 {
80 if (!_argsplit_step_state(&state))
81 {
82 break;
83 }
84
85 if (state.isNewArg)
86 {
87 (*argc)++;
88 }
89 (*totalChars)++;
90 }
91
92 if (state.inQuote || state.escaped)
93 {
94 return UINT64_MAX;
95 }
96
97 return 0;
98}
99
100const char** _argsplit_backend(const char** argv, const char* str, uint64_t argc, uint64_t maxLen)
101{
102 uint64_t argvSize = sizeof(char*) * (argc + 1);
103 char* strings = (char*)((uintptr_t)argv + argvSize);
104 argv[0] = strings;
105 argv[argc] = NULL;
106
107 _argsplit_state_t state = _ARGSPLIT_CREATE(str, maxLen);
108 uint64_t stringIndex = 0;
109 char* out = strings;
110 while (true)
111 {
112 if (!_argsplit_step_state(&state))
113 {
114 break;
115 }
116
117 if (state.isNewArg)
118 {
119 if (out > strings && *(out - 1) != '\0')
120 {
121 *out++ = '\0';
122 }
123 argv[stringIndex++] = out;
124 }
125 *out++ = *state.current;
126 }
127
128 if (out > strings && *(out - 1) != '\0')
129 {
130 *out++ = '\0';
131 }
132
133 if (state.inQuote || state.escaped)
134 {
135 return NULL;
136 }
137
138 return (const char**)argv;
139}
uint64_t _argsplit_count_chars_and_args(const char *str, uint64_t *argc, uint64_t *totalChars, uint64_t maxLen)
Definition argsplit.c:72
const char ** _argsplit_backend(const char **argv, const char *str, uint64_t argc, uint64_t maxLen)
Definition argsplit.c:100
bool _argsplit_step_state(_argsplit_state_t *state)
Definition argsplit.c:3
_PUBLIC int isspace(int c)
Definition isspace.c:5
#define NULL
Pointer error value.
Definition NULL.h:23
#define _ARGSPLIT_CREATE(str, maxLen)
Definition argsplit.h:22
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
#define UINT64_MAX
Definition stdint.h:74
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
const char * current
Definition argsplit.h:13
uint64_t processedChars
Definition argsplit.h:18
uint8_t escaped
Definition argsplit.h:14
uint64_t maxLen
Definition argsplit.h:19