1 // Copyright 2016-2017 Espressif Systems (Shanghai) PTE LTD
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
19 #define SS_FLAG_ESCAPE 0x8
22 /* parsing the space between arguments */
24 /* parsing an argument which isn't quoted */
26 /* parsing a quoted argument */
28 /* parsing an escape sequence within unquoted argument */
29 SS_ARG_ESCAPED = SS_ARG | SS_FLAG_ESCAPE,
30 /* parsing an escape sequence within a quoted argument */
31 SS_QUOTED_ARG_ESCAPED = SS_QUOTED_ARG | SS_FLAG_ESCAPE,
34 size_t esp_console_split_argv(char *line, char **argv, size_t argv_size)
36 const int QUOTE = '"';
37 const int ESCAPE = '\\';
38 const int SPACE = ' ';
39 split_state_t state = SS_SPACE;
41 char *next_arg_start = line;
43 for (char *in_ptr = line; argc < argv_size - 1; ++in_ptr) {
44 int char_in = (unsigned char) *in_ptr;
50 /* helper function, called when done with an argument */
53 argv[argc++] = next_arg_start;
59 if (char_in == SPACE) {
61 } else if (char_in == QUOTE) {
62 next_arg_start = out_ptr;
63 state = SS_QUOTED_ARG;
64 } else if (char_in == ESCAPE) {
65 next_arg_start = out_ptr;
66 state = SS_ARG_ESCAPED;
68 next_arg_start = out_ptr;
75 if (char_in == QUOTE) {
77 } else if (char_in == ESCAPE) {
78 state = SS_QUOTED_ARG_ESCAPED;
85 case SS_QUOTED_ARG_ESCAPED:
86 if (char_in == ESCAPE || char_in == QUOTE || char_in == SPACE) {
89 /* unrecognized escape character, skip */
91 state = (split_state_t) (state & (~SS_FLAG_ESCAPE));
95 if (char_in == SPACE) {
97 } else if (char_in == ESCAPE) {
98 state = SS_ARG_ESCAPED;
104 /* need to output anything? */
110 /* make sure the final argument is terminated */
112 /* finalize the last argument */
113 if (state != SS_SPACE && argc < argv_size - 1) {
114 argv[argc++] = next_arg_start;
116 /* add a NULL at the end of argv */