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