CLI_Utils.cpp
3.32 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
/*
* CLI_Utils.cpp - CLI library for Arduino/ESP8266 and others utility functions
*
* Version 1.0, latest version, documentation and bugtracker available at:
* https://gitlab.lindenaar.net/arduino/CLI
*
* Copyright (c) 2019 Frederik Lindenaar
*
* This library is free software: you can redistribute it and/or modify it under
* the terms of version 3 of the GNU General Public License as published by the
* Free Software Foundation, or (at your option) a later version of the license.
*
* This code is distributed in the hope that it will be useful but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, visit <http://www.gnu.org/licenses/> to download it.
*/
#include <CLI.h>
const char *CLI_STR_skipSep(const char *str) {
while (*str == ' ') str++;
return str;
};
const char *CLI_STR_findSep(const char *str) {
while (*str && *str != ' ') str++;
return str;
};
const char *CLI_STR_parseInt(const char *str, int &value, int minvalue, int maxvalue) {
int v = 0;
const char *p = str;
bool negative = *p == '-';
if (negative || *p == '+') p++;
while (*p >= '0' && *p <= '9') {
v *= 10;
v += *(p++) - '0';
}
if (str != p && v >= minvalue && v <= maxvalue) {
value = (negative) ? -v : v;
return p;
}
return 0;
}
uint8_t parseHexNibble(char c) {
if(c >= 'a' && c <= 'f') {
return c - 'a' + 10;
} else if(c >= 'A' && c <= 'F') {
return c - 'A' + 10;
} else if(c >= '0' && c <= '9') {
return c - '0';
} else return 0xff;
}
const char *CLI_STR_parse_HEX_byte(const char *str, uint8_t &value) {
if (str) {
uint8_t v;
if((v = parseHexNibble(*(str++))) <= 0xf) {
value = v << 4;
if((v = parseHexNibble(*(str++))) <= 0xf) {
value |= v;
return str;
}
}
}
return NULL;
}
const struct CLI_Command_Param *CLI_STR_parseParam_P (const char *param, const struct CLI_Command_Param params[]) {
for (const struct CLI_Command_Param *p = params; pgm_read_ptr(&p->param); p++)
if (!strcmp_P(param, (char *)pgm_read_ptr(&p->param))) return p;
return NULL;
}
const char *CLI_STR_parseFlags_P (const char *str, const struct CLI_Command_Flags params[], uint8_t param_count, uint8_t mask, uint8_t *flags) {
uint8_t f = 0;
while (*str) {
const struct CLI_Command_Flags *p = params;
while (p <= ¶ms[param_count] && strncmp_P(str, pgm_read_word(&p->command), pgm_read_byte(&p->cmdlen)) ) p++;
uint8_t flags = pgm_read_byte(&p->flags);
if (p > ¶ms[param_count] || (f != 0 && ((f & mask) != (flags & mask)))) return 0;
f |= flags;
str = CLI_STR_skipSep(str + pgm_read_byte(&p->cmdlen));
if (uint8_t intparam = pgm_read_byte(&p->intparam)) {
int i;
if (str = CLI_STR_parseInt(str, i)) {
if (pgm_read_byte(&p->cmdlen) == 0)
if (int divider = pgm_read_word(&p->command)) {
i /= divider & 0xff;
i += divider >> 8;
}
if (i <= (intparam & 0x1f)) {
f |= i << (intparam >> 5);
str = CLI_STR_skipSep(str);
continue;
}
}
return 0;
}
}
if (*str) return 0;
*flags = f;
return str;
}