1 /*
2 * Copyright (c) 2018, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /**
30 * @file
31 * This file includes definitions for command line parser.
32 */
33
34 #ifndef PARSE_CMD_LINE_HPP_
35 #define PARSE_CMD_LINE_HPP_
36
37 #include <stdint.h>
38 #include <string.h>
39
40 #include <openthread/error.h>
41 #include <openthread/instance.h>
42 #include <openthread/ip6.h>
43 #include <openthread/nat64.h>
44
45 namespace ot {
46 namespace Utils {
47 namespace CmdLineParser {
48
49 /**
50 * @addtogroup utils-parse-cmd-line
51 *
52 * @brief
53 * This module includes definitions for command line parser.
54 *
55 * @{
56 */
57
58 /**
59 * Parses a string as a `uint8_t` value.
60 *
61 * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
62 *
63 * @param[in] aString The string to parse.
64 * @param[out] aUint8 A reference to an `uint8_t` variable to output the parsed value.
65 *
66 * @retval kErrorNone The string was parsed successfully.
67 * @retval kErrorInvalidArgs The string does not contain valid number (e.g., value out of range).
68 *
69 */
70 otError ParseAsUint8(const char *aString, uint8_t &aUint8);
71
72 /**
73 * Parses a string as a `uint16_t` value.
74 *
75 * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
76 *
77 * @param[in] aString The string to parse.
78 * @param[out] aUint16 A reference to an `uint16_t` variable to output the parsed value.
79 *
80 * @retval kErrorNone The string was parsed successfully.
81 * @retval kErrorInvalidArgs The string does not contain valid number (e.g., value out of range).
82 *
83 */
84 otError ParseAsUint16(const char *aString, uint16_t &aUint16);
85
86 /**
87 * Parses a string as a `uint32_t` value.
88 *
89 * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
90 *
91 * @param[in] aString The string to parse.
92 * @param[out] aUint32 A reference to an `uint32_t` variable to output the parsed value.
93 *
94 * @retval kErrorNone The string was parsed successfully.
95 * @retval kErrorInvalidArgs The string does not contain valid number (e.g., value out of range).
96 *
97 */
98 otError ParseAsUint32(const char *aString, uint32_t &aUint32);
99
100 /**
101 * Parses a string as a `uint64_t` value.
102 *
103 * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
104 *
105 * @param[in] aString The string to parse.
106 * @param[out] aUint64 A reference to an `uint64_t` variable to output the parsed value.
107 *
108 * @retval kErrorNone The string was parsed successfully.
109 * @retval kErrorInvalidArgs The string does not contain valid number (e.g., value out of range).
110 *
111 */
112 otError ParseAsUint64(const char *aString, uint64_t &aUint64);
113
114 /**
115 * Parses a string as a `int8_t` value.
116 *
117 * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
118 * `+`/`-` sign.
119 *
120 * @param[in] aString The string to parse.
121 * @param[out] aInt8 A reference to an `int8_t` variable to output the parsed value.
122 *
123 * @retval kErrorNone The string was parsed successfully.
124 * @retval kErrorInvalidArgs The string does not contain valid number (e.g., value out of range).
125 *
126 */
127 otError ParseAsInt8(const char *aString, int8_t &aInt8);
128
129 /**
130 * Parses a string as a `int16_t` value.
131 *
132 * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
133 * `+`/`-` sign.
134 *
135 * @param[in] aString The string to parse.
136 * @param[out] aInt16 A reference to an `int16_t` variable to output the parsed value.
137 *
138 * @retval kErrorNone The string was parsed successfully.
139 * @retval kErrorInvalidArgs The string does not contain valid number (e.g., value out of range).
140 *
141 */
142 otError ParseAsInt16(const char *aString, int16_t &aInt16);
143
144 /**
145 * Parses a string as a `int32_t` value.
146 *
147 * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
148 * `+`/`-` sign.
149 *
150 * @param[in] aString The string to parse.
151 * @param[out] aInt32 A reference to an `int32_t` variable to output the parsed value.
152 *
153 * @retval kErrorNone The string was parsed successfully.
154 * @retval kErrorInvalidArgs The string does not contain valid number (e.g., value out of range).
155 *
156 */
157 otError ParseAsInt32(const char *aString, int32_t &aInt32);
158
159 /**
160 * Parses a string as a `bool` value.
161 *
162 * Zero value is treated as `false`, non-zero value as `true`.
163 *
164 * @param[in] aString The string to parse.
165 * @param[out] aBool A reference to a `bool` variable to output the parsed value.
166 *
167 * @retval kErrorNone The string was parsed successfully.
168 * @retval kErrorInvalidArgs The string does not contain valid number.
169 *
170 */
171 otError ParseAsBool(const char *aString, bool &aBool);
172
173 #if OPENTHREAD_FTD || OPENTHREAD_MTD
174 /**
175 * Parses a string as an IPv6 address.
176 *
177 *
178 * @param[in] aString The string to parse.
179 * @param[out] aAddress A reference to an `otIp6Address` to output the parsed IPv6 address.
180 *
181 * @retval kErrorNone The string was parsed successfully.
182 * @retval kErrorInvalidArgs The string does not contain valid IPv6 address.
183 *
184 */
185 otError ParseAsIp6Address(const char *aString, otIp6Address &aAddress);
186
187 /**
188 * Parses a string as an IPv4 address.
189 *
190 * @param[in] aString The string to parse.
191 * @param[out] aAddress A reference to an `otIp6Address` to output the parsed IPv6 address.
192 *
193 * @retval kErrorNone The string was parsed successfully.
194 * @retval kErrorInvalidArgs The string does not contain valid IPv4 address.
195 *
196 */
197 otError ParseAsIp4Address(const char *aString, otIp4Address &aAddress);
198
199 /**
200 * Parses a string as an IPv6 prefix.
201 *
202 * The string is parsed as `{IPv6Address}/{PrefixLength}`.
203 *
204 * @param[in] aString The string to parse.
205 * @param[out] aPrefix A reference to an `otIp6Prefix` to output the parsed IPv6 prefix.
206 *
207 * @retval kErrorNone The string was parsed successfully.
208 * @retval kErrorInvalidArgs The string does not contain a valid IPv6 prefix.
209 *
210 */
211 otError ParseAsIp6Prefix(const char *aString, otIp6Prefix &aPrefix);
212 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
213
214 /**
215 * Parses a hex string into a byte array of fixed expected size.
216 *
217 * Returns `kErrorNone` only when the hex string contains exactly @p aSize bytes (after parsing). If
218 * there are fewer or more bytes in hex string that @p aSize, the parsed bytes (up to @p aSize) are copied into the
219 * `aBuffer` and `kErrorInvalidArgs` is returned.
220 *
221 * Correctly handles hex strings with even or odd length. For example, "AABBCCDD" (with even length) is
222 * parsed as {0xaa, 0xbb, 0xcc, 0xdd} and "123" (with odd length) is parsed as {0x01, 0x23}.
223 *
224 * @param[in] aString The string to parse.
225 * @param[out] aBuffer A pointer to a buffer to output the parsed byte sequence.
226 * @param[in] aSize The expected size of byte sequence (number of bytes after parsing).
227 *
228 * @retval kErrorNone The string was parsed successfully.
229 * @retval kErrorInvalidArgs The string does not contain valid hex bytes and/or not @p aSize bytes.
230 *
231 */
232 otError ParseAsHexString(const char *aString, uint8_t *aBuffer, uint16_t aSize);
233
234 /**
235 * This template function parses a hex string into a a given fixed size array.
236 *
237 * Returns `kErrorNone` only when the hex string contains exactly @p kBufferSize bytes (after parsing).
238 * If there are fewer or more bytes in hex string that @p kBufferSize, the parsed bytes (up to @p kBufferSize) are
239 * copied into the `aBuffer` and `kErrorInvalidArgs` is returned.
240 *
241 * Correctly handles hex strings with even or odd length. For example, "AABBCCDD" (with even length) is
242 * parsed as {0xaa, 0xbb, 0xcc, 0xdd} and "123" (with odd length) is parsed as {0x01, 0x23}.
243 *
244 * @tparam kBufferSize The byte array size (number of bytes).
245 *
246 * @param[in] aString The string to parse.
247 * @param[out] aBuffer A reference to a byte array to output the parsed byte sequence.
248 *
249 * @retval kErrorNone The string was parsed successfully.
250 * @retval kErrorInvalidArgs The string does not contain valid hex bytes and/or not @p aSize bytes.
251 *
252 */
ParseAsHexString(const char * aString,uint8_t (& aBuffer)[kBufferSize])253 template <uint16_t kBufferSize> static otError ParseAsHexString(const char *aString, uint8_t (&aBuffer)[kBufferSize])
254 {
255 return ParseAsHexString(aString, aBuffer, kBufferSize);
256 }
257
258 /**
259 * Parses a hex string into a byte array.
260 *
261 * Verifies that the parsed hex string bytes fit in @p aBuffer with its given @p aSize.
262 *
263 * Correctly handles hex strings with even or odd length. For example, "AABBCCDD" (with even length) is
264 * parsed as {0xaa, 0xbb, 0xcc, 0xdd} and "123" (with odd length) is parsed as {0x01, 0x23}.
265 *
266 * @param[in] aString The string to parse.
267 * @param[in,out] aSize On entry indicates the number of bytes in @p aBuffer (max size of @p aBuffer).
268 * On exit provides number of bytes parsed and copied into @p aBuffer.
269 * @param[out] aBuffer A pointer to a buffer to output the parsed byte sequence.
270 *
271 * @retval kErrorNone The string was parsed successfully.
272 * @retval kErrorInvalidArgs The string does not contain valid format or too many bytes.
273 *
274 */
275 otError ParseAsHexString(const char *aString, uint16_t &aSize, uint8_t *aBuffer);
276
277 /**
278 * Parses a segment of a hex string up to a given size.
279 *
280 * Allows a longer hex string to be parsed and read in smaller segments into a given buffer. If the
281 * entire hex string bytes can fit in the given @p aBuffer with its @p aSize, they are copied into @p aBuffer and
282 * function returns `kErrorNone`. Otherwise, @p aSize bytes are read and copied and function returns `kErrorPending`
283 * to indicate that there are more bytes to parse. The @p aString is also updated to skip over the parsed segment.
284 *
285 * Correctly handles hex strings with even or odd length. For example, "AABBCCDD" (with even length) is
286 * parsed as {0xaa, 0xbb, 0xcc, 0xdd} and "123" (with odd length) is parsed as {0x01, 0x23}.
287 *
288 * @param[in,out] aString A reference to string to parse. On successful parse, updated to skip parsed digits.
289 * @param[in,out] aSize On entry indicates the segment size (number of bytes in @p aBuffer).
290 * On exit provides number of bytes parsed and copied into @p aBuffer.
291 * @param[out] aBuffer A pointer to a buffer to output the parsed byte sequence.
292 *
293 * @retval kErrorNone The string was parsed successfully to the end of string.
294 * @retval kErrorPending The string segment was parsed successfully, but there are additional bytes remaining
295 * to be parsed.
296 * @retval kErrorInvalidArgs The string does not contain valid format hex digits.
297 *
298 */
299 otError ParseAsHexStringSegment(const char *&aString, uint16_t &aSize, uint8_t *aBuffer);
300
301 /**
302 * Represents a single argument from an argument list.
303 *
304 */
305 class Arg
306 {
307 public:
308 /**
309 * Clears the argument.
310 *
311 */
Clear(void)312 void Clear(void) { mString = nullptr; }
313
314 /**
315 * Indicates whether or not the argument is empty (i.e., reached the end of argument list).
316 *
317 * @retval TRUE The argument is empty.
318 * @retval FALSE The argument is not empty.
319 *
320 */
IsEmpty(void) const321 bool IsEmpty(void) const { return (mString == nullptr); }
322
323 /**
324 * Returns the length (number of characters) in the argument C string.
325 *
326 * @returns The argument string length if argument is not empty, zero otherwise.
327 *
328 */
329 uint16_t GetLength(void) const;
330
331 /**
332 * Gets the argument as a C string.
333 *
334 * @returns A pointer to the argument as a C string, or `nullptr` if argument is empty.
335 *
336 */
GetCString(void) const337 const char *GetCString(void) const { return mString; }
338
339 /**
340 * Gets the argument as C string.
341 *
342 * @returns A pointer to the argument as a C string, or `nullptr` if argument is empty.
343 *
344 */
GetCString(void)345 char *GetCString(void) { return mString; }
346
347 /**
348 * Sets the argument with a given C string.
349 *
350 * @param[in] aString A pointer to the new C string.
351 *
352 */
SetCString(char * aString)353 void SetCString(char *aString) { mString = aString; }
354
355 /**
356 * Overload the operator `==` to evaluate whether the argument is equal to a given C string.
357 *
358 * If the argument is empty (`IsEmpty()` is `true`) then comparing it using operator `==` with any C string will
359 * return false.
360 *
361 * @param[in] aString The C string to compare with (MUST not be `nullptr`).
362 *
363 * @retval TRUE If the argument is not empty and is equal to @p aString.
364 * @retval FALSE If the argument is not equal to @p aString, or if the argument is empty.
365 *
366 */
367 bool operator==(const char *aString) const;
368
369 /**
370 * Overload the operator `!=` to evaluate whether the argument is unequal to a given C string.
371 *
372 * @param[in] aString The C string to compare with (MUST not be `nullptr`).
373 *
374 * @retval TRUE If the argument is not equal to @p aString, or if the argument is empty.
375 * @retval FALSE If the argument is not empty and equal to @p aString.
376 *
377 */
operator !=(const char * aString) const378 bool operator!=(const char *aString) const { return !(*this == aString); }
379
380 /**
381 * Parses the argument as a `uint8_t` value.
382 *
383 * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
384 *
385 * @param[out] aUint8 A reference to an `uint8_t` variable to output the parsed value.
386 *
387 * @retval kErrorNone The argument was parsed successfully.
388 * @retval kErrorInvalidArgs The argument is empty or does not contain valid number (e.g., value out of range).
389 *
390 */
ParseAsUint8(uint8_t & aUint8) const391 otError ParseAsUint8(uint8_t &aUint8) const { return CmdLineParser::ParseAsUint8(mString, aUint8); }
392
393 /**
394 * Parses the argument as a `uint16_t` value.
395 *
396 * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
397 *
398 * @param[out] aUint16 A reference to an `uint16_t` variable to output the parsed value.
399 *
400 * @retval kErrorNone The argument was parsed successfully.
401 * @retval kErrorInvalidArgs The argument is empty or does not contain valid number (e.g., value out of range).
402 *
403 */
ParseAsUint16(uint16_t & aUint16) const404 otError ParseAsUint16(uint16_t &aUint16) const { return CmdLineParser::ParseAsUint16(mString, aUint16); }
405
406 /**
407 * Parses the argument as a `uint32_t` value.
408 *
409 * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
410 *
411 * @param[out] aUint32 A reference to an `uint32_t` variable to output the parsed value.
412 *
413 * @retval kErrorNone The argument was parsed successfully.
414 * @retval kErrorInvalidArgs The argument is empty or does not contain valid number (e.g., value out of range).
415 *
416 */
ParseAsUint32(uint32_t & aUint32) const417 otError ParseAsUint32(uint32_t &aUint32) const { return CmdLineParser::ParseAsUint32(mString, aUint32); }
418
419 /**
420 * Parses the argument as a `uint64_t` value.
421 *
422 * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
423 *
424 * @param[out] aUint64 A reference to an `uint64_t` variable to output the parsed value.
425 *
426 * @retval kErrorNone The argument was parsed successfully.
427 * @retval kErrorInvalidArgs The argument is empty or does not contain valid number (e.g., value out of range).
428 *
429 */
ParseAsUint64(uint64_t & aUint64) const430 otError ParseAsUint64(uint64_t &aUint64) const { return CmdLineParser::ParseAsUint64(mString, aUint64); }
431
432 /**
433 * Parses the argument as a `int8_t` value.
434 *
435 * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
436 * `+`/`-` sign.
437 *
438 * @param[out] aInt8 A reference to an `int8_t` variable to output the parsed value.
439 *
440 * @retval kErrorNone The argument was parsed successfully.
441 * @retval kErrorInvalidArgs The argument is empty or does not contain valid number (e.g., value out of range).
442 *
443 */
ParseAsInt8(int8_t & aInt8) const444 otError ParseAsInt8(int8_t &aInt8) const { return CmdLineParser::ParseAsInt8(mString, aInt8); }
445
446 /**
447 * Parses the argument as a `int16_t` value.
448 *
449 * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
450 * `+`/`-` sign.
451 *
452 * @param[out] aInt16 A reference to an `int16_t` variable to output the parsed value.
453 *
454 * @retval kErrorNone The argument was parsed successfully.
455 * @retval kErrorInvalidArgs The argument is empty or does not contain valid number (e.g., value out of range).
456 *
457 */
ParseAsInt16(int16_t & aInt16) const458 otError ParseAsInt16(int16_t &aInt16) const { return CmdLineParser::ParseAsInt16(mString, aInt16); }
459
460 /**
461 * Parses the argument as a `int32_t` value.
462 *
463 * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
464 * `+`/`-` sign.
465 *
466 * @param[out] aInt32 A reference to an `int32_t` variable to output the parsed value.
467 *
468 * @retval kErrorNone The argument was parsed successfully.
469 * @retval kErrorInvalidArgs The argument is empty or does not contain valid number (e.g., value out of range).
470 *
471 */
ParseAsInt32(int32_t & aInt32) const472 otError ParseAsInt32(int32_t &aInt32) const { return CmdLineParser::ParseAsInt32(mString, aInt32); }
473
474 /**
475 * Parses the argument as a `bool` value.
476 *
477 * Zero value is treated as `false`, non-zero value as `true`.
478 *
479 * @param[out] aBool A reference to a `bool` variable to output the parsed value.
480 *
481 * @retval kErrorNone The argument was parsed successfully.
482 * @retval kErrorInvalidArgs The argument is empty or does not contain valid number.
483 *
484 */
ParseAsBool(bool & aBool) const485 otError ParseAsBool(bool &aBool) const { return CmdLineParser::ParseAsBool(mString, aBool); }
486
487 #if OPENTHREAD_FTD || OPENTHREAD_MTD
488 /**
489 * Parses the argument as an IPv6 address.
490 *
491 * @param[out] aAddress A reference to an `otIp6Address` to output the parsed IPv6 address.
492 *
493 * @retval kErrorNone The argument was parsed successfully.
494 * @retval kErrorInvalidArgs The argument is empty or does not contain valid IPv6 address.
495 *
496 */
ParseAsIp6Address(otIp6Address & aAddress) const497 otError ParseAsIp6Address(otIp6Address &aAddress) const
498 {
499 return CmdLineParser::ParseAsIp6Address(mString, aAddress);
500 }
501
502 /**
503 * Parses the argument as an IPv4 address.
504 *
505 * @param[out] aAddress A reference to an `otIp4Address` to output the parsed IPv4 address.
506 *
507 * @retval kErrorNone The argument was parsed successfully.
508 * @retval kErrorInvalidArgs The argument is empty or does not contain valid IPv4 address.
509 *
510 */
ParseAsIp4Address(otIp4Address & aAddress) const511 otError ParseAsIp4Address(otIp4Address &aAddress) const
512 {
513 return CmdLineParser::ParseAsIp4Address(mString, aAddress);
514 }
515
516 /**
517 * Parses the argument as an IPv6 prefix.
518 *
519 * The string is parsed as `{IPv6Address}/{PrefixLength}`.
520 *
521 * @param[out] aPrefix A reference to an `otIp6Prefix` to output the parsed IPv6 prefix.
522 *
523 * @retval kErrorNone The argument was parsed successfully.
524 * @retval kErrorInvalidArgs The argument is empty or does not contain a valid IPv6 prefix.
525 *
526 */
ParseAsIp6Prefix(otIp6Prefix & aPrefix) const527 otError ParseAsIp6Prefix(otIp6Prefix &aPrefix) const { return CmdLineParser::ParseAsIp6Prefix(mString, aPrefix); }
528
529 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
530
531 /**
532 * Parses the argument as a specified value type.
533 *
534 * @tparam Type The value type.
535 *
536 * @param[out] aValue A reference to output the parsed value.
537 *
538 * @retval kErrorNone The argument was parsed successfully.
539 * @retval kErrorInvalidArgs The argument is empty or does not contain a valid value.
540 *
541 */
542 template <typename Type> otError ParseAs(Type &aValue) const;
543
544 /**
545 * Parses the argument as a hex string into a byte array of fixed expected size.
546 *
547 * Returns `kErrorNone` only when the hex string contains exactly @p aSize bytes (after parsing). If
548 * there are fewer or more bytes in hex string that @p aSize, the parsed bytes (up to @p aSize) are copied into the
549 * `aBuffer` and `kErrorInvalidArgs` is returned.
550 *
551 * @param[out] aBuffer A pointer to a buffer to output the parsed byte sequence.
552 * @param[in] aSize The expected size of byte sequence (number of bytes after parsing).
553 *
554 * @retval kErrorNone The argument was parsed successfully.
555 * @retval kErrorInvalidArgs The argument is empty or does not contain valid hex bytes and/or not @p aSize bytes.
556 *
557 */
ParseAsHexString(uint8_t * aBuffer,uint16_t aSize) const558 otError ParseAsHexString(uint8_t *aBuffer, uint16_t aSize) const
559 {
560 return CmdLineParser::ParseAsHexString(mString, aBuffer, aSize);
561 }
562
563 /**
564 * Parses the argument as a hex string into a a given fixed size array.
565 *
566 * Returns `kErrorNone` only when the hex string contains exactly @p kBufferSize bytes (after parsing).
567 * If there are fewer or more bytes in hex string that @p kBufferSize, the parsed bytes (up to @p kBufferSize) are
568 * copied into the `aBuffer` and `kErrorInvalidArgs` is returned.
569 *
570 * @tparam kBufferSize The byte array size (number of bytes).
571 *
572 * @param[out] aBuffer A reference to a byte array to output the parsed byte sequence.
573 *
574 * @retval kErrorNone The argument was parsed successfully.
575 * @retval kErrorInvalidArgs The argument is empty or does not contain valid hex bytes and/or not @p aSize bytes.
576 *
577 */
ParseAsHexString(uint8_t (& aBuffer)[kBufferSize])578 template <uint16_t kBufferSize> otError ParseAsHexString(uint8_t (&aBuffer)[kBufferSize])
579 {
580 return ParseAsHexString(aBuffer, kBufferSize);
581 }
582
583 /**
584 * Parses the argument as a hex string into a byte array.
585 *
586 * Verifies that the parsed hex string bytes fit in @p aBuffer with its given @p aSize.
587 *
588 * @param[in,out] aSize On entry indicates the number of bytes in @p aBuffer (max size of @p aBuffer).
589 * On exit provides number of bytes parsed and copied into @p aBuffer.
590 * @param[out] aBuffer A pointer to a buffer to output the parsed byte sequence.
591 *
592 * @retval kErrorNone The argument was parsed successfully.
593 * @retval kErrorInvalidArgs The argument does not contain valid format or too many bytes.
594 *
595 */
ParseAsHexString(uint16_t & aSize,uint8_t * aBuffer)596 otError ParseAsHexString(uint16_t &aSize, uint8_t *aBuffer)
597 {
598 return CmdLineParser::ParseAsHexString(mString, aSize, aBuffer);
599 }
600
601 /**
602 * Copies the argument string pointers from an `Arg` array to a C string array.
603 *
604 * @note this method only copies the string pointer value (i.e., `GetString()` pointer) from `aArgs` array to the
605 * @p aStrings array (the content of strings are not copied).
606 *
607 * @param[in] aArgs An `Arg` array.
608 * @param[out] aStrings An `char *` array to populate with the argument string pointers. The @p aString array
609 * MUST contain at least same number of entries as in @p aArgs array.
610 *
611 */
612 static void CopyArgsToStringArray(Arg aArgs[], char *aStrings[]);
613
614 /**
615 * Returns the length of argument array, i.e. number of consecutive non-empty arguments.
616 *
617 * @param[in] aArgs An `Arg` array.
618 *
619 * @returns Number of non-empty arguments in the array.
620 *
621 */
622 static uint8_t GetArgsLength(Arg aArgs[]);
623
624 private:
625 char *mString;
626 };
627
628 /**
629 * Parses a given command line string and breaks it into an argument list.
630 *
631 * May change the input @p aCommandString, it will put a '\0' by the end of each argument, and @p aArgs
632 * will point to the arguments in the input @p aCommandString. Backslash ('\') can be used to escape separators
633 * (' ', '\t', '\r', '\n') and the backslash itself.
634 *
635 * As the arguments are parsed, the @p aArgs array entries are populated. Any remaining @p aArgs entries in the array
636 * will be cleared and marked as empty. So the number of arguments can be determined by going through @p aArgs array
637 * entries till we get to an empty `Arg` (i.e., `Arg::IsEmpty()` returns `true).
638 *
639 * Ensures that the last entry in @p aArgs array is always used to indicate the end (always marked as
640 * empty), so the @p aArgs array should have one more entry than the desired max number of arguments.
641 *
642 * @param[in] aCommandString A null-terminated input string.
643 * @param[out] aArgs The argument array.
644 * @param[in] aArgsMaxLength The max length of @p aArgs array.
645 *
646 * @retval OT_ERROR_NONE The command line parsed successfully and @p aArgs array is populated.
647 * @retval OT_ERROR_INVALID_ARGS Too many arguments in @p aCommandString and could not fit in @p aArgs array.
648 *
649 */
650 otError ParseCmd(char *aCommandString, Arg aArgs[], uint8_t aArgsMaxLength);
651
ParseCmd(char * aCommandString,Arg (& aArgs)[kLength])652 template <uint8_t kLength> inline otError ParseCmd(char *aCommandString, Arg (&aArgs)[kLength])
653 {
654 return ParseCmd(aCommandString, aArgs, kLength);
655 }
656
657 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
658 // Specializations of `Arg::ParseAs<Type>()` method.
659
ParseAs(uint8_t & aValue) const660 template <> inline otError Arg::ParseAs(uint8_t &aValue) const { return ParseAsUint8(aValue); }
661
ParseAs(uint16_t & aValue) const662 template <> inline otError Arg::ParseAs(uint16_t &aValue) const { return ParseAsUint16(aValue); }
663
ParseAs(uint32_t & aValue) const664 template <> inline otError Arg::ParseAs(uint32_t &aValue) const { return ParseAsUint32(aValue); }
665
ParseAs(uint64_t & aValue) const666 template <> inline otError Arg::ParseAs(uint64_t &aValue) const { return ParseAsUint64(aValue); }
667
ParseAs(bool & aValue) const668 template <> inline otError Arg::ParseAs(bool &aValue) const { return ParseAsBool(aValue); }
669
ParseAs(int8_t & aValue) const670 template <> inline otError Arg::ParseAs(int8_t &aValue) const { return ParseAsInt8(aValue); }
671
ParseAs(int16_t & aValue) const672 template <> inline otError Arg::ParseAs(int16_t &aValue) const { return ParseAsInt16(aValue); }
673
ParseAs(int32_t & aValue) const674 template <> inline otError Arg::ParseAs(int32_t &aValue) const { return ParseAsInt32(aValue); }
675
ParseAs(const char * & aValue) const676 template <> inline otError Arg::ParseAs(const char *&aValue) const
677 {
678 return IsEmpty() ? OT_ERROR_INVALID_ARGS : (aValue = GetCString(), OT_ERROR_NONE);
679 }
680
681 #if OPENTHREAD_FTD || OPENTHREAD_MTD
682
ParseAs(otIp6Address & aValue) const683 template <> inline otError Arg::ParseAs(otIp6Address &aValue) const { return ParseAsIp6Address(aValue); }
684
ParseAs(otIp6Prefix & aValue) const685 template <> inline otError Arg::ParseAs(otIp6Prefix &aValue) const { return ParseAsIp6Prefix(aValue); }
686
687 #endif
688
689 /**
690 * @}
691 */
692
693 } // namespace CmdLineParser
694 } // namespace Utils
695 } // namespace ot
696
697 #endif // PARSE_CMD_LINE_HPP_
698