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/ip6.h>
42 
43 namespace ot {
44 namespace Utils {
45 namespace CmdLineParser {
46 
47 /**
48  * @addtogroup utils-parse-cmd-line
49  *
50  * @brief
51  *   This module includes definitions for command line parser.
52  *
53  * @{
54  */
55 
56 /**
57  * This function parses a string as a `uint8_t` value.
58  *
59  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
60  *
61  * @param[in]  aString   The string to parse.
62  * @param[out] aUint8    A reference to an `uint8_t` variable to output the parsed value.
63  *
64  * @retval kErrorNone         The string was parsed successfully.
65  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
66  *
67  */
68 otError ParseAsUint8(const char *aString, uint8_t &aUint8);
69 
70 /**
71  * This function parses a string as a `uint16_t` value.
72  *
73  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
74  *
75  * @param[in]  aString   The string to parse.
76  * @param[out] aUint16   A reference to an `uint16_t` variable to output the parsed value.
77  *
78  * @retval kErrorNone         The string was parsed successfully.
79  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
80  *
81  */
82 otError ParseAsUint16(const char *aString, uint16_t &aUint16);
83 
84 /**
85  * This function parses a string as a `uint32_t` value.
86  *
87  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
88  *
89  * @param[in]  aString   The string to parse.
90  * @param[out] aUint32   A reference to an `uint32_t` variable to output the parsed value.
91  *
92  * @retval kErrorNone         The string was parsed successfully.
93  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
94  *
95  */
96 otError ParseAsUint32(const char *aString, uint32_t &aUint32);
97 
98 /**
99  * This function parses a string as a `uint64_t` value.
100  *
101  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
102  *
103  * @param[in]  aString   The string to parse.
104  * @param[out] aUint64   A reference to an `uint64_t` variable to output the parsed value.
105  *
106  * @retval kErrorNone         The string was parsed successfully.
107  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
108  *
109  */
110 otError ParseAsUint64(const char *aString, uint64_t &aUint64);
111 
112 /**
113  * This function parses a string as a `int8_t` value.
114  *
115  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
116  * `+`/`-` sign.
117  *
118  * @param[in]  aString   The string to parse.
119  * @param[out] aInt8     A reference to an `int8_t` variable to output the parsed value.
120  *
121  * @retval kErrorNone         The string was parsed successfully.
122  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
123  *
124  */
125 otError ParseAsInt8(const char *aString, int8_t &aInt8);
126 
127 /**
128  * This function parses a string as a `int16_t` value.
129  *
130  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
131  * `+`/`-` sign.
132  *
133  * @param[in]  aString   The string to parse.
134  * @param[out] aInt16    A reference to an `int16_t` variable to output the parsed value.
135  *
136  * @retval kErrorNone         The string was parsed successfully.
137  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
138  *
139  */
140 otError ParseAsInt16(const char *aString, int16_t &aInt16);
141 
142 /**
143  * This function parses a string as a `int32_t` value.
144  *
145  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
146  * `+`/`-` sign.
147  *
148  * @param[in]  aString   The string to parse.
149  * @param[out] aInt32    A reference to an `int32_t` variable to output the parsed value.
150  *
151  * @retval kErrorNone         The string was parsed successfully.
152  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
153  *
154  */
155 otError ParseAsInt32(const char *aString, int32_t &aInt32);
156 
157 /**
158  * This function parses a string as a `bool` value.
159  *
160  * Zero value is treated as `false`, non-zero value as `true`.
161  *
162  * @param[in]  aString   The string to parse.
163  * @param[out] aBool     A reference to a `bool` variable to output the parsed value.
164  *
165  * @retval kErrorNone         The string was parsed successfully.
166  * @retval kErrorInvalidArgs  The string does not contain valid number.
167  *
168  */
169 otError ParseAsBool(const char *aString, bool &aBool);
170 
171 #if OPENTHREAD_FTD || OPENTHREAD_MTD
172 /**
173  * This function parses a string as an IPv6 address.
174  *
175  *
176  * @param[in]  aString   The string to parse.
177  * @param[out] aAddress  A reference to an `otIp6Address` to output the parsed IPv6 address.
178  *
179  * @retval kErrorNone         The string was parsed successfully.
180  * @retval kErrorInvalidArgs  The string does not contain valid IPv6 address.
181  *
182  */
183 otError ParseAsIp6Address(const char *aString, otIp6Address &aAddress);
184 
185 /**
186  * This function parses a string as an IPv6 prefix.
187  *
188  * The string is parsed as `{IPv6Address}/{PrefixLength}`.
189  *
190  * @param[in]  aString   The string to parse.
191  * @param[out] aPrefix   A reference to an `otIp6Prefix` to output the parsed IPv6 prefix.
192  *
193  * @retval kErrorNone         The string was parsed successfully.
194  * @retval kErrorInvalidArgs  The string does not contain a valid IPv6 prefix.
195  *
196  */
197 otError ParseAsIp6Prefix(const char *aString, otIp6Prefix &aPrefix);
198 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
199 
200 /**
201  * This function parses a hex string into a byte array of fixed expected size.
202  *
203  * This function returns `kErrorNone` only when the hex string contains exactly @p aSize bytes (after parsing). If
204  * there are fewer or more bytes in hex string that @p aSize, the parsed bytes (up to @p aSize) are copied into the
205  * `aBuffer` and `kErrorInvalidArgs` is returned.
206  *
207  * This function correctly handles hex strings with even or odd length. For example, "AABBCCDD" (with even length) is
208  * parsed as {0xaa, 0xbb, 0xcc, 0xdd} and "123" (with odd length) is parsed as {0x01, 0x23}.
209  *
210  * @param[in]  aString   The string to parse.
211  * @param[out] aBuffer   A pointer to a buffer to output the parsed byte sequence.
212  * @param[in]  aSize     The expected size of byte sequence (number of bytes after parsing).
213  *
214  * @retval kErrorNone         The string was parsed successfully.
215  * @retval kErrorInvalidArgs  The string does not contain valid hex bytes and/or not @p aSize bytes.
216  *
217  */
218 otError ParseAsHexString(const char *aString, uint8_t *aBuffer, uint16_t aSize);
219 
220 /**
221  * This template function parses a hex string into a a given fixed size array.
222  *
223  * This function returns `kErrorNone` only when the hex string contains exactly @p kBufferSize bytes (after parsing).
224  * If there are fewer or more bytes in hex string that @p kBufferSize, the parsed bytes (up to @p kBufferSize) are
225  * copied into the `aBuffer` and `kErrorInvalidArgs` is returned.
226  *
227  * This function correctly handles hex strings with even or odd length. For example, "AABBCCDD" (with even length) is
228  * parsed as {0xaa, 0xbb, 0xcc, 0xdd} and "123" (with odd length) is parsed as {0x01, 0x23}.
229  *
230  * @tparam kBufferSize   The byte array size (number of bytes).
231  *
232  * @param[in]  aString   The string to parse.
233  * @param[out] aBuffer   A reference to a byte array to output the parsed byte sequence.
234  *
235  * @retval kErrorNone         The string was parsed successfully.
236  * @retval kErrorInvalidArgs  The string does not contain valid hex bytes and/or not @p aSize bytes.
237  *
238  */
ParseAsHexString(const char * aString,uint8_t (& aBuffer)[kBufferSize])239 template <uint16_t kBufferSize> static otError ParseAsHexString(const char *aString, uint8_t (&aBuffer)[kBufferSize])
240 {
241     return ParseAsHexString(aString, aBuffer, kBufferSize);
242 }
243 
244 /**
245  * This function parses a hex string into a byte array.
246  *
247  * This function verifies that the parsed hex string bytes fit in @p aBuffer with its given @p aSize.
248  *
249  * This function correctly handles hex strings with even or odd length. For example, "AABBCCDD" (with even length) is
250  * parsed as {0xaa, 0xbb, 0xcc, 0xdd} and "123" (with odd length) is parsed as {0x01, 0x23}.
251  *
252  * @param[in]     aString   The string to parse.
253  * @param[inout]  aSize     On entry indicates the number of bytes in @p aBuffer (max size of @p aBuffer).
254  *                          On exit provides number of bytes parsed and copied into @p aBuffer.
255  * @param[out]    aBuffer   A pointer to a buffer to output the parsed byte sequence.
256  *
257  * @retval kErrorNone        The string was parsed successfully.
258  * @retval kErrorInvalidArgs The string does not contain valid format or too many bytes.
259  *
260  */
261 otError ParseAsHexString(const char *aString, uint16_t &aSize, uint8_t *aBuffer);
262 
263 /**
264  * This function parses a segment of a hex string up to a given size.
265  *
266  * This function allows a longer hex string to be parsed and read in smaller segments into a given buffer. If the
267  * entire hex string bytes can fit in the given @p aBuffer with its @p aSize, they are copied into @p aBuffer and
268  * function returns `kErrorNone`. Otherwise, @p aSize bytes are read and copied and function returns `kErrorPending`
269  * to indicate that there are more bytes to parse. The @p aString is also updated to skip over the parsed segment.
270  *
271  * This function correctly handles hex strings with even or odd length. For example, "AABBCCDD" (with even length) is
272  * parsed as {0xaa, 0xbb, 0xcc, 0xdd} and "123" (with odd length) is parsed as {0x01, 0x23}.
273  *
274  * @param[inout] aString     A reference to string to parse. On successful parse, updated to skip parsed digits.
275  * @param[inout] aSize       On entry indicates the segment size (number of bytes in @p aBuffer).
276  *                           On exit provides number of bytes parsed and copied into @p aBuffer.
277  * @param[out]   aBuffer     A pointer to a buffer to output the parsed byte sequence.
278  *
279  * @retval kErrorNone        The string was parsed successfully to the end of string.
280  * @retval kErrorPedning     The string segment was parsed successfully, but there are additional bytes remaining
281  *                           to be parsed.
282  * @retval kErrorInvalidArgs The string does not contain valid format hex digits.
283  *
284  */
285 otError ParseAsHexStringSegment(const char *&aString, uint16_t &aSize, uint8_t *aBuffer);
286 
287 /**
288  * This class represents a single argument from an argument list.
289  *
290  */
291 class Arg
292 {
293 public:
294     /**
295      * This method clears the argument.
296      *
297      */
Clear(void)298     void Clear(void) { mString = nullptr; }
299 
300     /**
301      * This method indicates whether or not the argument is empty (i.e., reached the end of argument list).
302      *
303      * @retval TRUE   The argument is empty.
304      * @retval FALSE  The argument is not empty.
305      *
306      */
IsEmpty(void) const307     bool IsEmpty(void) const { return (mString == nullptr); }
308 
309     /**
310      * This method returns the length (number of characters) in the argument C string.
311      *
312      * @returns The argument string length if argument is not empty, zero otherwise.
313      *
314      */
315     uint16_t GetLength(void) const;
316 
317     /**
318      * This method gets the argument as a C string.
319      *
320      * @returns A pointer to the argument as a C string, or `nullptr` if argument is empty.
321      *
322      */
GetCString(void) const323     const char *GetCString(void) const { return mString; }
324 
325     /**
326      * This method gets the argument as C string.
327      *
328      * @returns A pointer to the argument as a C string, or `nullptr` if argument is empty.
329      *
330      */
GetCString(void)331     char *GetCString(void) { return mString; }
332 
333     /**
334      * This method sets the argument with a given C string.
335      *
336      * @param[in] aString    A pointer to the new C string.
337      *
338      */
SetCString(char * aString)339     void SetCString(char *aString) { mString = aString; }
340 
341     /**
342      * This method overload the operator `==` to evaluate whether the argument is equal to a given C string.
343      *
344      * If the argument is empty (`IsEmpty()` is `true`) then comparing it using operator `==` with any C string will
345      * return false.
346      *
347      * @param[in] aString    The C string to compare with (MUST not be `nullptr`).
348      *
349      * @retval TRUE   If the argument is not empty and is equal to @p aString.
350      * @retval FALSE  If the argument is not equal to @p aString, or if the argument is empty.
351      *
352      */
353     bool operator==(const char *aString) const;
354 
355     /**
356      * This method overload the operator `!=` to evaluate whether the argument is unequal to a given C string.
357      *
358      * @param[in] aString    The C string to compare with (MUST not be `nullptr`).
359      *
360      * @retval TRUE   If the argument is not equal to @p aString, or if the argument is empty.
361      * @retval FALSE  If the argument is not empty and equal to @p aString.
362      *
363      */
operator !=(const char * aString) const364     bool operator!=(const char *aString) const { return !(*this == aString); }
365 
366     /**
367      * This method parses the argument as a `uint8_t` value.
368      *
369      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
370      *
371      * @param[out] aUint8    A reference to an `uint8_t` variable to output the parsed value.
372      *
373      * @retval kErrorNone         The argument was parsed successfully.
374      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid number (e.g., value out of range).
375      *
376      */
ParseAsUint8(uint8_t & aUint8) const377     otError ParseAsUint8(uint8_t &aUint8) const { return CmdLineParser::ParseAsUint8(mString, aUint8); }
378 
379     /**
380      * This method parses the argument as a `uint16_t` value.
381      *
382      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
383      *
384      * @param[out] aUint16   A reference to an `uint16_t` variable to output the parsed value.
385      *
386      * @retval kErrorNone         The argument was parsed successfully.
387      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid number (e.g., value out of range).
388      *
389      */
ParseAsUint16(uint16_t & aUint16) const390     otError ParseAsUint16(uint16_t &aUint16) const { return CmdLineParser::ParseAsUint16(mString, aUint16); }
391 
392     /**
393      * This method parses the argument as a `uint32_t` value.
394      *
395      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
396      *
397      * @param[out] aUint32   A reference to an `uint32_t` variable to output the parsed value.
398      *
399      * @retval kErrorNone         The argument was parsed successfully.
400      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid number (e.g., value out of range).
401      *
402      */
ParseAsUint32(uint32_t & aUint32) const403     otError ParseAsUint32(uint32_t &aUint32) const { return CmdLineParser::ParseAsUint32(mString, aUint32); }
404 
405     /**
406      * This method parses the argument as a `uint64_t` value.
407      *
408      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
409      *
410      * @param[out] aUint64   A reference to an `uint64_t` variable to output the parsed value.
411      *
412      * @retval kErrorNone         The argument was parsed successfully.
413      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid number (e.g., value out of range).
414      *
415      */
ParseAsUint64(uint64_t & aUint64) const416     otError ParseAsUint64(uint64_t &aUint64) const { return CmdLineParser::ParseAsUint64(mString, aUint64); }
417 
418     /**
419      * This method parses the argument as a `int8_t` value.
420      *
421      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
422      * `+`/`-` sign.
423      *
424      * @param[out] aInt8     A reference to an `int8_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      */
ParseAsInt8(int8_t & aInt8) const430     otError ParseAsInt8(int8_t &aInt8) const { return CmdLineParser::ParseAsInt8(mString, aInt8); }
431 
432     /**
433      * This method parses the argument as a `int16_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] aInt16    A reference to an `int16_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      */
ParseAsInt16(int16_t & aInt16) const444     otError ParseAsInt16(int16_t &aInt16) const { return CmdLineParser::ParseAsInt16(mString, aInt16); }
445 
446     /**
447      * This method parses the argument as a `int32_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] aInt32    A reference to an `int32_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      */
ParseAsInt32(int32_t & aInt32) const458     otError ParseAsInt32(int32_t &aInt32) const { return CmdLineParser::ParseAsInt32(mString, aInt32); }
459 
460     /**
461      * This method parses the argument as a `bool` value.
462      *
463      * Zero value is treated as `false`, non-zero value as `true`.
464      *
465      * @param[out] aBool     A reference to a `bool` variable to output the parsed value.
466      *
467      * @retval kErrorNone         The argument was parsed successfully.
468      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid number.
469      *
470      */
ParseAsBool(bool & aBool) const471     otError ParseAsBool(bool &aBool) const { return CmdLineParser::ParseAsBool(mString, aBool); }
472 
473 #if OPENTHREAD_FTD || OPENTHREAD_MTD
474     /**
475      * This method parses the argument as an IPv6 address.
476      *
477      * @param[out] aAddress  A reference to an `otIp6Address` to output the parsed IPv6 address.
478      *
479      * @retval kErrorNone         The argument was parsed successfully.
480      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid IPv6 address.
481      *
482      */
ParseAsIp6Address(otIp6Address & aAddress) const483     otError ParseAsIp6Address(otIp6Address &aAddress) const
484     {
485         return CmdLineParser::ParseAsIp6Address(mString, aAddress);
486     }
487 
488     /**
489      * This method parses the argument as an IPv6 prefix.
490      *
491      * The string is parsed as `{IPv6Address}/{PrefixLength}`.
492      *
493      * @param[out] aPrefix   A reference to an `otIp6Prefix` to output the parsed IPv6 prefix.
494      *
495      * @retval kErrorNone         The argument was parsed successfully.
496      * @retval kErrorInvalidArgs  The argument is empty or does not contain a valid IPv6 prefix.
497      *
498      */
ParseAsIp6Prefix(otIp6Prefix & aPrefix) const499     otError ParseAsIp6Prefix(otIp6Prefix &aPrefix) const { return CmdLineParser::ParseAsIp6Prefix(mString, aPrefix); }
500 
501 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
502 
503     /**
504      * This template method parses the argument as a specified value type.
505      *
506      * @tparam Type               The value type.
507      *
508      * @param[out] aValue         A reference to output the parsed value.
509      *
510      * @retval kErrorNone         The argument was parsed successfully.
511      * @retval kErrorInvalidArgs  The argument is empty or does not contain a valid value.
512      *
513      */
514     template <typename Type> otError ParseAs(Type &aValue) const;
515 
516     /**
517      * This method parses the argument as a hex string into a byte array of fixed expected size.
518      *
519      * This method returns `kErrorNone` only when the hex string contains exactly @p aSize bytes (after parsing). If
520      * there are fewer or more bytes in hex string that @p aSize, the parsed bytes (up to @p aSize) are copied into the
521      * `aBuffer` and `kErrorInvalidArgs` is returned.
522      *
523      * @param[out] aBuffer   A pointer to a buffer to output the parsed byte sequence.
524      * @param[in]  aSize     The expected size of byte sequence (number of bytes after parsing).
525      *
526      * @retval kErrorNone         The argument was parsed successfully.
527      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid hex bytes and/or not @p aSize bytes.
528      *
529      */
ParseAsHexString(uint8_t * aBuffer,uint16_t aSize) const530     otError ParseAsHexString(uint8_t *aBuffer, uint16_t aSize) const
531     {
532         return CmdLineParser::ParseAsHexString(mString, aBuffer, aSize);
533     }
534 
535     /**
536      * This template method parses the argument as a hex string into a a given fixed size array.
537      *
538      * This method returns `kErrorNone` only when the hex string contains exactly @p kBufferSize bytes (after parsing).
539      * If there are fewer or more bytes in hex string that @p kBufferSize, the parsed bytes (up to @p kBufferSize) are
540      * copied into the `aBuffer` and `kErrorInvalidArgs` is returned.
541      *
542      * @tparam kBufferSize   The byte array size (number of bytes).
543      *
544      * @param[out] aBuffer   A reference to a byte array to output the parsed byte sequence.
545      *
546      * @retval kErrorNone         The argument was parsed successfully.
547      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid hex bytes and/or not @p aSize bytes.
548      *
549      */
ParseAsHexString(uint8_t (& aBuffer)[kBufferSize])550     template <uint16_t kBufferSize> otError ParseAsHexString(uint8_t (&aBuffer)[kBufferSize])
551     {
552         return ParseAsHexString(aBuffer, kBufferSize);
553     }
554 
555     /**
556      * This method parses the argument as a hex string into a byte array.
557      *
558      * This method verifies that the parsed hex string bytes fit in @p aBuffer with its given @p aSize.
559      *
560      * @param[inout]  aSize     On entry indicates the number of bytes in @p aBuffer (max size of @p aBuffer).
561      *                          On exit provides number of bytes parsed and copied into @p aBuffer.
562      * @param[out]    aBuffer   A pointer to a buffer to output the parsed byte sequence.
563      *
564      * @retval kErrorNone        The argument was parsed successfully.
565      * @retval kErrorInvalidArgs The argument does not contain valid format or too many bytes.
566      *
567      */
ParseAsHexString(uint16_t & aSize,uint8_t * aBuffer)568     otError ParseAsHexString(uint16_t &aSize, uint8_t *aBuffer)
569     {
570         return CmdLineParser::ParseAsHexString(mString, aSize, aBuffer);
571     }
572 
573     /**
574      * This static method copies the argument string pointers from an `Arg` array to a C string array.
575      *
576      * @note this method only copies the string pointer value (i.e., `GetString()` pointer) from `aArgs` array to the
577      * @p aStrings array (the content of strings are not copied).
578      *
579      * @param[in]  aArgs        An `Arg` array.
580      * @param[out] aStrings     An `char *` array to populate with the argument string pointers. The @p aString array
581      *                          MUST contain at least same number of entries as in @p aArgs array.
582      *
583      */
584     static void CopyArgsToStringArray(Arg aArgs[], char *aStrings[]);
585 
586     /**
587      * This static method returns the length of argument array, i.e. number of consecutive non-empty arguments.
588      *
589      * @param[in] aArgs  An `Arg` array.
590      *
591      * @returns  Number of non-empty arguments in the array.
592      *
593      */
594     static uint8_t GetArgsLength(Arg aArgs[]);
595 
596 private:
597     char *mString;
598 };
599 
600 /**
601  * This function parses a given command line string and breaks it into an argument list.
602  *
603  * This function may change the input @p aCommandString, it will put a '\0' by the end of each argument, and @p aArgs
604  * will point to the arguments in the input @p aCommandString. Backslash ('\') can be used to escape separators
605  * (' ', '\t', '\r', '\n') and the backslash itself.
606  *
607  * As the arguments are parsed, the @p aArgs array entries are populated. Any remaining @p aArgs entries in the array
608  * will be cleared and marked as empty. So the number of arguments can be determined by going through @p aArgs array
609  * entries till we get to an empty `Arg` (i.e., `Arg::IsEmpty()` returns `true).
610  *
611  * This function ensures that the last entry in @p aArgs array is always used to indicate the end (always  marked as
612  * empty), so the @p aArgs array should have one more entry than the desired max number of arguments.
613  *
614  * @param[in]   aCommandString  A null-terminated input string.
615  * @param[out]  aArgs           The argument array.
616  * @param[in]   aArgsMaxLength  The max length of @p aArgs array.
617  *
618  * @retval OT_ERROR_NONE          The command line parsed successfully and @p aArgs array is populated.
619  * @retval OT_ERROR_INVALID_ARGS  Too many arguments in @p aCommandString and could not fit in @p aArgs array.
620  *
621  */
622 otError ParseCmd(char *aCommandString, Arg aArgs[], uint8_t aArgsMaxLength);
623 
ParseCmd(char * aCommandString,Arg (& aArgs)[kLength])624 template <uint8_t kLength> inline otError ParseCmd(char *aCommandString, Arg (&aArgs)[kLength])
625 {
626     return ParseCmd(aCommandString, aArgs, kLength);
627 }
628 
629 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
630 // Specializations of `Arg::ParseAs<Type>()` method.
631 
ParseAs(uint8_t & aValue) const632 template <> inline otError Arg::ParseAs(uint8_t &aValue) const
633 {
634     return ParseAsUint8(aValue);
635 }
636 
ParseAs(uint16_t & aValue) const637 template <> inline otError Arg::ParseAs(uint16_t &aValue) const
638 {
639     return ParseAsUint16(aValue);
640 }
641 
ParseAs(uint32_t & aValue) const642 template <> inline otError Arg::ParseAs(uint32_t &aValue) const
643 {
644     return ParseAsUint32(aValue);
645 }
646 
ParseAs(uint64_t & aValue) const647 template <> inline otError Arg::ParseAs(uint64_t &aValue) const
648 {
649     return ParseAsUint64(aValue);
650 }
651 
ParseAs(bool & aValue) const652 template <> inline otError Arg::ParseAs(bool &aValue) const
653 {
654     return ParseAsBool(aValue);
655 }
656 
ParseAs(int8_t & aValue) const657 template <> inline otError Arg::ParseAs(int8_t &aValue) const
658 {
659     return ParseAsInt8(aValue);
660 }
661 
ParseAs(int16_t & aValue) const662 template <> inline otError Arg::ParseAs(int16_t &aValue) const
663 {
664     return ParseAsInt16(aValue);
665 }
666 
ParseAs(int32_t & aValue) const667 template <> inline otError Arg::ParseAs(int32_t &aValue) const
668 {
669     return ParseAsInt32(aValue);
670 }
671 
672 #if OPENTHREAD_FTD || OPENTHREAD_MTD
673 
ParseAs(otIp6Address & aValue) const674 template <> inline otError Arg::ParseAs(otIp6Address &aValue) const
675 {
676     return ParseAsIp6Address(aValue);
677 }
678 
ParseAs(otIp6Prefix & aValue) const679 template <> inline otError Arg::ParseAs(otIp6Prefix &aValue) const
680 {
681     return ParseAsIp6Prefix(aValue);
682 }
683 
684 #endif
685 
686 /**
687  * @}
688  */
689 
690 } // namespace CmdLineParser
691 } // namespace Utils
692 } // namespace ot
693 
694 #endif // PARSE_CMD_LINE_HPP_
695