• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 otError ParseAsUint8(const char *aString, uint8_t &aUint8);
70 
71 /**
72  * Parses a string as a `uint16_t` value.
73  *
74  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
75  *
76  * @param[in]  aString   The string to parse.
77  * @param[out] aUint16   A reference to an `uint16_t` variable to output the parsed value.
78  *
79  * @retval kErrorNone         The string was parsed successfully.
80  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
81  */
82 otError ParseAsUint16(const char *aString, uint16_t &aUint16);
83 
84 /**
85  * 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 otError ParseAsUint32(const char *aString, uint32_t &aUint32);
96 
97 /**
98  * Parses a string as a `uint64_t` value.
99  *
100  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
101  *
102  * @param[in]  aString   The string to parse.
103  * @param[out] aUint64   A reference to an `uint64_t` variable to output the parsed value.
104  *
105  * @retval kErrorNone         The string was parsed successfully.
106  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
107  */
108 otError ParseAsUint64(const char *aString, uint64_t &aUint64);
109 
110 /**
111  * Parses a string as a `int8_t` value.
112  *
113  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
114  * `+`/`-` sign.
115  *
116  * @param[in]  aString   The string to parse.
117  * @param[out] aInt8     A reference to an `int8_t` variable to output the parsed value.
118  *
119  * @retval kErrorNone         The string was parsed successfully.
120  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
121  */
122 otError ParseAsInt8(const char *aString, int8_t &aInt8);
123 
124 /**
125  * Parses a string as a `int16_t` value.
126  *
127  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
128  * `+`/`-` sign.
129  *
130  * @param[in]  aString   The string to parse.
131  * @param[out] aInt16    A reference to an `int16_t` variable to output the parsed value.
132  *
133  * @retval kErrorNone         The string was parsed successfully.
134  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
135  */
136 otError ParseAsInt16(const char *aString, int16_t &aInt16);
137 
138 /**
139  * Parses a string as a `int32_t` value.
140  *
141  * The number in string is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
142  * `+`/`-` sign.
143  *
144  * @param[in]  aString   The string to parse.
145  * @param[out] aInt32    A reference to an `int32_t` variable to output the parsed value.
146  *
147  * @retval kErrorNone         The string was parsed successfully.
148  * @retval kErrorInvalidArgs  The string does not contain valid number (e.g., value out of range).
149  */
150 otError ParseAsInt32(const char *aString, int32_t &aInt32);
151 
152 /**
153  * Parses a string as a `bool` value.
154  *
155  * Zero value is treated as `false`, non-zero value as `true`.
156  *
157  * @param[in]  aString   The string to parse.
158  * @param[out] aBool     A reference to a `bool` variable to output the parsed value.
159  *
160  * @retval kErrorNone         The string was parsed successfully.
161  * @retval kErrorInvalidArgs  The string does not contain valid number.
162  */
163 otError ParseAsBool(const char *aString, bool &aBool);
164 
165 #if OPENTHREAD_FTD || OPENTHREAD_MTD
166 /**
167  * Parses a string as an IPv6 address.
168  *
169  *
170  * @param[in]  aString   The string to parse.
171  * @param[out] aAddress  A reference to an `otIp6Address` to output the parsed IPv6 address.
172  *
173  * @retval kErrorNone         The string was parsed successfully.
174  * @retval kErrorInvalidArgs  The string does not contain valid IPv6 address.
175  */
176 otError ParseAsIp6Address(const char *aString, otIp6Address &aAddress);
177 
178 /**
179  * Parses a string as an IPv4 address.
180  *
181  * @param[in]  aString   The string to parse.
182  * @param[out] aAddress  A reference to an `otIp6Address` to output the parsed IPv6 address.
183  *
184  * @retval kErrorNone         The string was parsed successfully.
185  * @retval kErrorInvalidArgs  The string does not contain valid IPv4 address.
186  */
187 otError ParseAsIp4Address(const char *aString, otIp4Address &aAddress);
188 
189 /**
190  * Parses a string as an IPv6 prefix.
191  *
192  * The string is parsed as `{IPv6Address}/{PrefixLength}`.
193  *
194  * @param[in]  aString   The string to parse.
195  * @param[out] aPrefix   A reference to an `otIp6Prefix` to output the parsed IPv6 prefix.
196  *
197  * @retval kErrorNone         The string was parsed successfully.
198  * @retval kErrorInvalidArgs  The string does not contain a valid IPv6 prefix.
199  */
200 otError ParseAsIp6Prefix(const char *aString, otIp6Prefix &aPrefix);
201 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
202 
203 /**
204  * Parses a hex string into a byte array of fixed expected size.
205  *
206  * Returns `kErrorNone` only when the hex string contains exactly @p aSize bytes (after parsing). If
207  * there are fewer or more bytes in hex string that @p aSize, the parsed bytes (up to @p aSize) are copied into the
208  * `aBuffer` and `kErrorInvalidArgs` is returned.
209  *
210  * Correctly handles hex strings with even or odd length. For example, "AABBCCDD" (with even length) is
211  * parsed as {0xaa, 0xbb, 0xcc, 0xdd} and "123" (with odd length) is parsed as {0x01, 0x23}.
212  *
213  * @param[in]  aString   The string to parse.
214  * @param[out] aBuffer   A pointer to a buffer to output the parsed byte sequence.
215  * @param[in]  aSize     The expected size of byte sequence (number of bytes after parsing).
216  *
217  * @retval kErrorNone         The string was parsed successfully.
218  * @retval kErrorInvalidArgs  The string does not contain valid hex bytes and/or not @p aSize bytes.
219  */
220 otError ParseAsHexString(const char *aString, uint8_t *aBuffer, uint16_t aSize);
221 
222 /**
223  * This template function parses a hex string into a a given fixed size array.
224  *
225  * Returns `kErrorNone` only when the hex string contains exactly @p kBufferSize bytes (after parsing).
226  * If there are fewer or more bytes in hex string that @p kBufferSize, the parsed bytes (up to @p kBufferSize) are
227  * copied into the `aBuffer` and `kErrorInvalidArgs` is returned.
228  *
229  * Correctly handles hex strings with even or odd length. For example, "AABBCCDD" (with even length) is
230  * parsed as {0xaa, 0xbb, 0xcc, 0xdd} and "123" (with odd length) is parsed as {0x01, 0x23}.
231  *
232  * @tparam kBufferSize   The byte array size (number of bytes).
233  *
234  * @param[in]  aString   The string to parse.
235  * @param[out] aBuffer   A reference to a byte array to output the parsed byte sequence.
236  *
237  * @retval kErrorNone         The string was parsed successfully.
238  * @retval kErrorInvalidArgs  The string does not contain valid hex bytes and/or not @p aSize bytes.
239  */
ParseAsHexString(const char * aString,uint8_t (& aBuffer)[kBufferSize])240 template <uint16_t kBufferSize> static otError ParseAsHexString(const char *aString, uint8_t (&aBuffer)[kBufferSize])
241 {
242     return ParseAsHexString(aString, aBuffer, kBufferSize);
243 }
244 
245 /**
246  * Parses a hex string into a byte array.
247  *
248  * Verifies that the parsed hex string bytes fit in @p aBuffer with its given @p aSize.
249  *
250  * Correctly handles hex strings with even or odd length. For example, "AABBCCDD" (with even length) is
251  * parsed as {0xaa, 0xbb, 0xcc, 0xdd} and "123" (with odd length) is parsed as {0x01, 0x23}.
252  *
253  * @param[in]      aString   The string to parse.
254  * @param[in,out]  aSize     On entry indicates the number of bytes in @p aBuffer (max size of @p aBuffer).
255  *                           On exit provides number of bytes parsed and copied into @p aBuffer.
256  * @param[out]     aBuffer   A pointer to a buffer to output the parsed byte sequence.
257  *
258  * @retval kErrorNone        The string was parsed successfully.
259  * @retval kErrorInvalidArgs The string does not contain valid format or too many bytes.
260  */
261 otError ParseAsHexString(const char *aString, uint16_t &aSize, uint8_t *aBuffer);
262 
263 /**
264  * Parses a segment of a hex string up to a given size.
265  *
266  * 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  * 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[in,out] aString    A reference to string to parse. On successful parse, updated to skip parsed digits.
275  * @param[in,out] 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 kErrorPending     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 otError ParseAsHexStringSegment(const char *&aString, uint16_t &aSize, uint8_t *aBuffer);
285 
286 /**
287  * Represents a single argument from an argument list.
288  */
289 class Arg
290 {
291 public:
292     /**
293      * Clears the argument.
294      */
Clear(void)295     void Clear(void) { mString = nullptr; }
296 
297     /**
298      * Indicates whether or not the argument is empty (i.e., reached the end of argument list).
299      *
300      * @retval TRUE   The argument is empty.
301      * @retval FALSE  The argument is not empty.
302      */
IsEmpty(void) const303     bool IsEmpty(void) const { return (mString == nullptr); }
304 
305     /**
306      * Returns the length (number of characters) in the argument C string.
307      *
308      * @returns The argument string length if argument is not empty, zero otherwise.
309      */
310     uint16_t GetLength(void) const;
311 
312     /**
313      * Gets the argument as a C string.
314      *
315      * @returns A pointer to the argument as a C string, or `nullptr` if argument is empty.
316      */
GetCString(void) const317     const char *GetCString(void) const { return mString; }
318 
319     /**
320      * Gets the argument as C string.
321      *
322      * @returns A pointer to the argument as a C string, or `nullptr` if argument is empty.
323      */
GetCString(void)324     char *GetCString(void) { return mString; }
325 
326     /**
327      * Sets the argument with a given C string.
328      *
329      * @param[in] aString    A pointer to the new C string.
330      */
SetCString(char * aString)331     void SetCString(char *aString) { mString = aString; }
332 
333     /**
334      * Overload the operator `==` to evaluate whether the argument is equal to a given C string.
335      *
336      * If the argument is empty (`IsEmpty()` is `true`) then comparing it using operator `==` with any C string will
337      * return false.
338      *
339      * @param[in] aString    The C string to compare with (MUST not be `nullptr`).
340      *
341      * @retval TRUE   If the argument is not empty and is equal to @p aString.
342      * @retval FALSE  If the argument is not equal to @p aString, or if the argument is empty.
343      */
344     bool operator==(const char *aString) const;
345 
346     /**
347      * Overload the operator `!=` to evaluate whether the argument is unequal to a given C string.
348      *
349      * @param[in] aString    The C string to compare with (MUST not be `nullptr`).
350      *
351      * @retval TRUE   If the argument is not equal to @p aString, or if the argument is empty.
352      * @retval FALSE  If the argument is not empty and equal to @p aString.
353      */
operator !=(const char * aString) const354     bool operator!=(const char *aString) const { return !(*this == aString); }
355 
356     /**
357      * Parses the argument as a `uint8_t` value.
358      *
359      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
360      *
361      * @param[out] aUint8    A reference to an `uint8_t` variable to output the parsed value.
362      *
363      * @retval kErrorNone         The argument was parsed successfully.
364      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid number (e.g., value out of range).
365      */
ParseAsUint8(uint8_t & aUint8) const366     otError ParseAsUint8(uint8_t &aUint8) const { return CmdLineParser::ParseAsUint8(mString, aUint8); }
367 
368     /**
369      * Parses the argument as a `uint16_t` value.
370      *
371      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
372      *
373      * @param[out] aUint16   A reference to an `uint16_t` variable to output the parsed value.
374      *
375      * @retval kErrorNone         The argument was parsed successfully.
376      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid number (e.g., value out of range).
377      */
ParseAsUint16(uint16_t & aUint16) const378     otError ParseAsUint16(uint16_t &aUint16) const { return CmdLineParser::ParseAsUint16(mString, aUint16); }
379 
380     /**
381      * Parses the argument as a `uint32_t` value.
382      *
383      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
384      *
385      * @param[out] aUint32   A reference to an `uint32_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      */
ParseAsUint32(uint32_t & aUint32) const390     otError ParseAsUint32(uint32_t &aUint32) const { return CmdLineParser::ParseAsUint32(mString, aUint32); }
391 
392     /**
393      * Parses the argument as a `uint64_t` value.
394      *
395      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix).
396      *
397      * @param[out] aUint64   A reference to an `uint64_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      */
ParseAsUint64(uint64_t & aUint64) const402     otError ParseAsUint64(uint64_t &aUint64) const { return CmdLineParser::ParseAsUint64(mString, aUint64); }
403 
404     /**
405      * Parses the argument as a `int8_t` value.
406      *
407      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
408      * `+`/`-` sign.
409      *
410      * @param[out] aInt8     A reference to an `int8_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      */
ParseAsInt8(int8_t & aInt8) const415     otError ParseAsInt8(int8_t &aInt8) const { return CmdLineParser::ParseAsInt8(mString, aInt8); }
416 
417     /**
418      * Parses the argument as a `int16_t` value.
419      *
420      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
421      * `+`/`-` sign.
422      *
423      * @param[out] aInt16    A reference to an `int16_t` variable to output the parsed value.
424      *
425      * @retval kErrorNone         The argument was parsed successfully.
426      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid number (e.g., value out of range).
427      */
ParseAsInt16(int16_t & aInt16) const428     otError ParseAsInt16(int16_t &aInt16) const { return CmdLineParser::ParseAsInt16(mString, aInt16); }
429 
430     /**
431      * Parses the argument as a `int32_t` value.
432      *
433      * The number is parsed as decimal or hex format (if contains `0x` or `0X` prefix). The string can start with
434      * `+`/`-` sign.
435      *
436      * @param[out] aInt32    A reference to an `int32_t` variable to output the parsed value.
437      *
438      * @retval kErrorNone         The argument was parsed successfully.
439      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid number (e.g., value out of range).
440      */
ParseAsInt32(int32_t & aInt32) const441     otError ParseAsInt32(int32_t &aInt32) const { return CmdLineParser::ParseAsInt32(mString, aInt32); }
442 
443     /**
444      * Parses the argument as a `bool` value.
445      *
446      * Zero value is treated as `false`, non-zero value as `true`.
447      *
448      * @param[out] aBool     A reference to a `bool` variable to output the parsed value.
449      *
450      * @retval kErrorNone         The argument was parsed successfully.
451      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid number.
452      */
ParseAsBool(bool & aBool) const453     otError ParseAsBool(bool &aBool) const { return CmdLineParser::ParseAsBool(mString, aBool); }
454 
455 #if OPENTHREAD_FTD || OPENTHREAD_MTD
456     /**
457      * Parses the argument as an IPv6 address.
458      *
459      * @param[out] aAddress  A reference to an `otIp6Address` to output the parsed IPv6 address.
460      *
461      * @retval kErrorNone         The argument was parsed successfully.
462      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid IPv6 address.
463      */
ParseAsIp6Address(otIp6Address & aAddress) const464     otError ParseAsIp6Address(otIp6Address &aAddress) const
465     {
466         return CmdLineParser::ParseAsIp6Address(mString, aAddress);
467     }
468 
469     /**
470      * Parses the argument as an IPv4 address.
471      *
472      * @param[out] aAddress  A reference to an `otIp4Address` to output the parsed IPv4 address.
473      *
474      * @retval kErrorNone         The argument was parsed successfully.
475      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid IPv4 address.
476      */
ParseAsIp4Address(otIp4Address & aAddress) const477     otError ParseAsIp4Address(otIp4Address &aAddress) const
478     {
479         return CmdLineParser::ParseAsIp4Address(mString, aAddress);
480     }
481 
482     /**
483      * Parses the argument as an IPv6 prefix.
484      *
485      * The string is parsed as `{IPv6Address}/{PrefixLength}`.
486      *
487      * @param[out] aPrefix   A reference to an `otIp6Prefix` to output the parsed IPv6 prefix.
488      *
489      * @retval kErrorNone         The argument was parsed successfully.
490      * @retval kErrorInvalidArgs  The argument is empty or does not contain a valid IPv6 prefix.
491      */
ParseAsIp6Prefix(otIp6Prefix & aPrefix) const492     otError ParseAsIp6Prefix(otIp6Prefix &aPrefix) const { return CmdLineParser::ParseAsIp6Prefix(mString, aPrefix); }
493 
494 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
495 
496     /**
497      * Parses the argument as a specified value type.
498      *
499      * @tparam Type               The value type.
500      *
501      * @param[out] aValue         A reference to output the parsed value.
502      *
503      * @retval kErrorNone         The argument was parsed successfully.
504      * @retval kErrorInvalidArgs  The argument is empty or does not contain a valid value.
505      */
506     template <typename Type> otError ParseAs(Type &aValue) const;
507 
508     /**
509      * Parses the argument as a hex string into a byte array of fixed expected size.
510      *
511      * Returns `kErrorNone` only when the hex string contains exactly @p aSize bytes (after parsing). If
512      * there are fewer or more bytes in hex string that @p aSize, the parsed bytes (up to @p aSize) are copied into the
513      * `aBuffer` and `kErrorInvalidArgs` is returned.
514      *
515      * @param[out] aBuffer   A pointer to a buffer to output the parsed byte sequence.
516      * @param[in]  aSize     The expected size of byte sequence (number of bytes after parsing).
517      *
518      * @retval kErrorNone         The argument was parsed successfully.
519      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid hex bytes and/or not @p aSize bytes.
520      */
ParseAsHexString(uint8_t * aBuffer,uint16_t aSize) const521     otError ParseAsHexString(uint8_t *aBuffer, uint16_t aSize) const
522     {
523         return CmdLineParser::ParseAsHexString(mString, aBuffer, aSize);
524     }
525 
526     /**
527      * Parses the argument as a hex string into a a given fixed size array.
528      *
529      * Returns `kErrorNone` only when the hex string contains exactly @p kBufferSize bytes (after parsing).
530      * If there are fewer or more bytes in hex string that @p kBufferSize, the parsed bytes (up to @p kBufferSize) are
531      * copied into the `aBuffer` and `kErrorInvalidArgs` is returned.
532      *
533      * @tparam kBufferSize   The byte array size (number of bytes).
534      *
535      * @param[out] aBuffer   A reference to a byte array to output the parsed byte sequence.
536      *
537      * @retval kErrorNone         The argument was parsed successfully.
538      * @retval kErrorInvalidArgs  The argument is empty or does not contain valid hex bytes and/or not @p aSize bytes.
539      */
ParseAsHexString(uint8_t (& aBuffer)[kBufferSize])540     template <uint16_t kBufferSize> otError ParseAsHexString(uint8_t (&aBuffer)[kBufferSize])
541     {
542         return ParseAsHexString(aBuffer, kBufferSize);
543     }
544 
545     /**
546      * Parses the argument as a hex string into a byte array.
547      *
548      * Verifies that the parsed hex string bytes fit in @p aBuffer with its given @p aSize.
549      *
550      * @param[in,out]  aSize    On entry indicates the number of bytes in @p aBuffer (max size of @p aBuffer).
551      *                          On exit provides number of bytes parsed and copied into @p aBuffer.
552      * @param[out]     aBuffer  A pointer to a buffer to output the parsed byte sequence.
553      *
554      * @retval kErrorNone        The argument was parsed successfully.
555      * @retval kErrorInvalidArgs The argument does not contain valid format or too many bytes.
556      */
ParseAsHexString(uint16_t & aSize,uint8_t * aBuffer)557     otError ParseAsHexString(uint16_t &aSize, uint8_t *aBuffer)
558     {
559         return CmdLineParser::ParseAsHexString(mString, aSize, aBuffer);
560     }
561 
562     /**
563      * Copies the argument string pointers from an `Arg` array to a C string array.
564      *
565      * @note this method only copies the string pointer value (i.e., `GetString()` pointer) from `aArgs` array to the
566      * @p aStrings array (the content of strings are not copied).
567      *
568      * @param[in]  aArgs        An `Arg` array.
569      * @param[out] aStrings     An `char *` array to populate with the argument string pointers. The @p aString array
570      *                          MUST contain at least same number of entries as in @p aArgs array.
571      */
572     static void CopyArgsToStringArray(Arg aArgs[], char *aStrings[]);
573 
574     /**
575      * Returns the length of argument array, i.e. number of consecutive non-empty arguments.
576      *
577      * @param[in] aArgs  An `Arg` array.
578      *
579      * @returns  Number of non-empty arguments in the array.
580      */
581     static uint8_t GetArgsLength(Arg aArgs[]);
582 
583 private:
584     char *mString;
585 };
586 
587 /**
588  * Parses a given command line string and breaks it into an argument list.
589  *
590  * May change the input @p aCommandString, it will put a '\0' by the end of each argument, and @p aArgs
591  * will point to the arguments in the input @p aCommandString. Backslash ('\') can be used to escape separators
592  * (' ', '\t', '\r', '\n') and the backslash itself.
593  *
594  * As the arguments are parsed, the @p aArgs array entries are populated. Any remaining @p aArgs entries in the array
595  * will be cleared and marked as empty. So the number of arguments can be determined by going through @p aArgs array
596  * entries till we get to an empty `Arg` (i.e., `Arg::IsEmpty()` returns `true).
597  *
598  * Ensures that the last entry in @p aArgs array is always used to indicate the end (always  marked as
599  * empty), so the @p aArgs array should have one more entry than the desired max number of arguments.
600  *
601  * @param[in]   aCommandString  A null-terminated input string.
602  * @param[out]  aArgs           The argument array.
603  * @param[in]   aArgsMaxLength  The max length of @p aArgs array.
604  *
605  * @retval OT_ERROR_NONE          The command line parsed successfully and @p aArgs array is populated.
606  * @retval OT_ERROR_INVALID_ARGS  Too many arguments in @p aCommandString and could not fit in @p aArgs array.
607  */
608 otError ParseCmd(char *aCommandString, Arg aArgs[], uint8_t aArgsMaxLength);
609 
ParseCmd(char * aCommandString,Arg (& aArgs)[kLength])610 template <uint8_t kLength> inline otError ParseCmd(char *aCommandString, Arg (&aArgs)[kLength])
611 {
612     return ParseCmd(aCommandString, aArgs, kLength);
613 }
614 
615 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
616 // Specializations of `Arg::ParseAs<Type>()` method.
617 
ParseAs(uint8_t & aValue) const618 template <> inline otError Arg::ParseAs(uint8_t &aValue) const { return ParseAsUint8(aValue); }
619 
ParseAs(uint16_t & aValue) const620 template <> inline otError Arg::ParseAs(uint16_t &aValue) const { return ParseAsUint16(aValue); }
621 
ParseAs(uint32_t & aValue) const622 template <> inline otError Arg::ParseAs(uint32_t &aValue) const { return ParseAsUint32(aValue); }
623 
ParseAs(uint64_t & aValue) const624 template <> inline otError Arg::ParseAs(uint64_t &aValue) const { return ParseAsUint64(aValue); }
625 
ParseAs(bool & aValue) const626 template <> inline otError Arg::ParseAs(bool &aValue) const { return ParseAsBool(aValue); }
627 
ParseAs(int8_t & aValue) const628 template <> inline otError Arg::ParseAs(int8_t &aValue) const { return ParseAsInt8(aValue); }
629 
ParseAs(int16_t & aValue) const630 template <> inline otError Arg::ParseAs(int16_t &aValue) const { return ParseAsInt16(aValue); }
631 
ParseAs(int32_t & aValue) const632 template <> inline otError Arg::ParseAs(int32_t &aValue) const { return ParseAsInt32(aValue); }
633 
ParseAs(const char * & aValue) const634 template <> inline otError Arg::ParseAs(const char *&aValue) const
635 {
636     return IsEmpty() ? OT_ERROR_INVALID_ARGS : (aValue = GetCString(), OT_ERROR_NONE);
637 }
638 
639 #if OPENTHREAD_FTD || OPENTHREAD_MTD
640 
ParseAs(otIp6Address & aValue) const641 template <> inline otError Arg::ParseAs(otIp6Address &aValue) const { return ParseAsIp6Address(aValue); }
642 
ParseAs(otIp6Prefix & aValue) const643 template <> inline otError Arg::ParseAs(otIp6Prefix &aValue) const { return ParseAsIp6Prefix(aValue); }
644 
645 #endif
646 
647 /**
648  * @}
649  */
650 
651 } // namespace CmdLineParser
652 } // namespace Utils
653 } // namespace ot
654 
655 #endif // PARSE_CMD_LINE_HPP_
656