Select one of the symbols to view example projects that use it.
 
Outline
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define SS_FLAG_ESCAPE
split_state_t
esp_console_split_argv(char *, char **, size_t)
Files
loading...
SourceVuESP-IDF Framework and ExamplesESP-IDFcomponents/console/split_argv.c
 
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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* * SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 *//* ... */ #include <stdio.h> #include <ctype.h> #include <string.h> #define SS_FLAG_ESCAPE 0x8 typedef enum { /* parsing the space between arguments */ SS_SPACE = 0x0, /* parsing an argument which isn't quoted */ SS_ARG = 0x1, /* parsing a quoted argument */ SS_QUOTED_ARG = 0x2, /* parsing an escape sequence within unquoted argument */ SS_ARG_ESCAPED = SS_ARG | SS_FLAG_ESCAPE, /* parsing an escape sequence within a quoted argument */ SS_QUOTED_ARG_ESCAPED = SS_QUOTED_ARG | SS_FLAG_ESCAPE, }{ ... } split_state_t; /* helper macro, called when done with an argument */ #define END_ARG() do { \ char_out = 0; \ argv[argc++] = next_arg_start; \ state = SS_SPACE; \ }{...} while(0)... size_t esp_console_split_argv(char *line, char **argv, size_t argv_size) { const int QUOTE = '"'; const int ESCAPE = '\\'; const int SPACE = ' '; split_state_t state = SS_SPACE; size_t argc = 0; char *next_arg_start = line; char *out_ptr = line; for (char *in_ptr = line; argc < argv_size - 1; ++in_ptr) { int char_in = (unsigned char) * in_ptr; if (char_in == 0) { break; }{...} int char_out = -1; switch (state) { case SS_SPACE: if (char_in == SPACE) { /* skip space */ }{...} else if (char_in == QUOTE) { next_arg_start = out_ptr; state = SS_QUOTED_ARG; }{...} else if (char_in == ESCAPE) { next_arg_start = out_ptr; state = SS_ARG_ESCAPED; }{...} else { next_arg_start = out_ptr; state = SS_ARG; char_out = char_in; }{...} break; ... case SS_QUOTED_ARG: if (char_in == QUOTE) { END_ARG(); }{...} else if (char_in == ESCAPE) { state = SS_QUOTED_ARG_ESCAPED; }{...} else { char_out = char_in; }{...} break; ... case SS_ARG_ESCAPED: case SS_QUOTED_ARG_ESCAPED: if (char_in == ESCAPE || char_in == QUOTE || char_in == SPACE) { char_out = char_in; }{...} else { /* unrecognized escape character, skip */ }{...} state = (split_state_t)(state & (~SS_FLAG_ESCAPE)); break; ... case SS_ARG: if (char_in == SPACE) { END_ARG(); }{...} else if (char_in == ESCAPE) { state = SS_ARG_ESCAPED; }{...} else { char_out = char_in; }{...} break;... }{...} /* need to output anything? */ if (char_out >= 0) { *out_ptr = char_out; ++out_ptr; }{...} }{...} /* make sure the final argument is terminated */ *out_ptr = 0; /* finalize the last argument */ if (state != SS_SPACE && argc < argv_size - 1) { argv[argc++] = next_arg_start; }{...} /* add a NULL at the end of argv */ argv[argc] = NULL; return argc; }{ ... }
Details