ccollins476ad closed pull request #934: util/parse - Additional parsing 
functions.
URL: https://github.com/apache/mynewt-core/pull/934
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/net/ip/mn_socket/include/mn_socket/mn_socket.h 
b/net/ip/mn_socket/include/mn_socket/mn_socket.h
index e44c46af7..42b0fefde 100644
--- a/net/ip/mn_socket/include/mn_socket/mn_socket.h
+++ b/net/ip/mn_socket/include/mn_socket/mn_socket.h
@@ -187,6 +187,10 @@ int mn_close(struct mn_socket *);
 /*
  * Address conversion
  */
+
+#define MN_INET_ADDRSTRLEN  16
+#define MN_INET6_ADDRSTRLEN 46
+
 int mn_inet_pton(int af, const char *src, void *dst);
 const char *mn_inet_ntop(int af, const void *src, void *dst, int len);
 
diff --git a/net/ip/mn_socket/src/mn_socket_aconv.c 
b/net/ip/mn_socket/src/mn_socket_aconv.c
index b7ce1e7a8..3339172bc 100644
--- a/net/ip/mn_socket/src/mn_socket_aconv.c
+++ b/net/ip/mn_socket/src/mn_socket_aconv.c
@@ -18,10 +18,194 @@
  */
 #include <ctype.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
 #include <string.h>
-#include "os/mynewt.h"
 #include "mn_socket/mn_socket.h"
 
+/**
+ * Indicates the length of an IPv6 address segment (i.e., 0 to 4 characters
+ * enclosed by ':').
+ */
+static int
+mn_inet6_segment_len(const char *s)
+{
+    int i;
+
+    for (i = 0; s[i] != '\0'; i++) {
+        if (s[i] == ':') {
+            break;
+        }
+    }
+
+    return i;
+}
+
+
+/**
+ * Counts the number of segments in the specified IPv6 address string.
+ *
+ * @param s                     The input string to parse.
+ * @param pre                   On success, the number of segments before the
+ *                                  "::" string gets written here.  8 if there
+ *                                  is no "::" string.
+ * @param mid                   On success, the number of segments compressed
+ *                                  by a "::" string gets written here.  0 If
+ *                                  there is no "::" string.
+ * @param post                  On success, the number of segments after
+ *                                  the "::" string gets written here.  0 If
+ *                                  there is no "::" string.
+ *
+ * @return                      0 on success; -1 on failure.
+ */
+static int
+mn_inet6_segment_count(const char *s, int *pre, int *mid, int *post)
+{
+    bool compressed;
+    int total_segs;
+    int seglen;
+    int off;
+
+    *pre = 0;
+    *mid = 0;
+    *post = 0;
+    compressed = false;
+
+    off = 0;
+    while (1) {
+        if (s[off] == ':') {
+            off++;
+        }
+
+        seglen = mn_inet6_segment_len(s + off);
+        if (seglen == 0) {
+            if (s[off] == '\0') {
+                break;
+            }
+
+            if (compressed) {
+                return -1;
+            }
+
+            compressed = true;
+        } else if (!compressed) {
+            (*pre)++;
+        } else {
+            (*post)++;
+        }
+
+        off += seglen;
+    }
+
+    total_segs = *pre + *post;
+    if (!compressed) {
+        if (total_segs != 8) {
+            return -1;
+        }
+    } else {
+        *mid = 8 - total_segs;
+        if (*mid <= 0) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+/**
+ * Converts a single IPv6 address segment string to four-byte array.
+ */
+static int
+mn_inet6_pton_segment(const char *s, void *dst)
+{
+    uint16_t u16;
+    char buf[5];
+    char *endptr;
+    int seglen;
+
+    seglen = mn_inet6_segment_len(s);
+    if (seglen == 0 || seglen > 4) {
+        return -1;
+    }
+
+    memcpy(buf, s, seglen);
+    buf[seglen] = '\0';
+
+    u16 = strtoul(buf, &endptr, 16);
+    if (*endptr != '\0') {
+        return -1;
+    }
+
+    u16 = htons(u16);
+    memcpy(dst, &u16, sizeof u16);
+
+    return seglen;
+}
+
+/**
+ * Converts an IPv6 address string to its binary representation.
+ */
+static int
+mn_inet6_pton(const char *s, void *dst)
+{
+    uint8_t *u8p;
+    int post;
+    int mid;
+    int pre;
+    int soff;
+    int doff;
+    int rc;
+    int i;
+
+    rc = mn_inet6_segment_count(s, &pre, &mid, &post);
+    if (rc != 0) {
+        return rc;
+    }
+
+    u8p = dst;
+    soff = 0;
+    doff = 0;
+
+    for (i = 0; i < pre; i++) {
+        rc = mn_inet6_pton_segment(s + soff, u8p + doff);
+        if (rc == -1) {
+            return rc;
+        }
+
+        soff += rc + 1;
+        doff += 2;
+    }
+
+    if (mid == 0) {
+        return 0;
+    }
+
+    /* If the string started with a double-colon, skip one of the colons now.
+     * Normally this gets skipped during parsing of a leading segment.
+     */
+    if (pre == 0) {
+        soff++;
+    }
+
+    /* Skip the second colon. */
+    soff++;
+
+    memset(u8p + doff, 0, mid * 2);
+    doff += mid * 2;
+
+    for (i = 0; i < post; i++) {
+        rc = mn_inet6_pton_segment(s + soff, u8p + doff);
+        if (rc == -1) {
+            return rc;
+        }
+
+        soff += rc + 1;
+        doff += 2;
+    }
+
+    return 0;
+}
+
 int
 mn_inet_pton(int af, const char *src, void *dst)
 {
@@ -29,6 +213,7 @@ mn_inet_pton(int af, const char *src, void *dst)
     uint8_t *ch_tgt;
     int val;
     int cnt;
+    int rc;
 
     if (af == MN_PF_INET) {
         cnt = 0;
@@ -54,10 +239,11 @@ mn_inet_pton(int af, const char *src, void *dst)
         }
         return 1;
     } else {
-        /*
-         * Add code here. XXX
-         */
-        return 0;
+        rc = mn_inet6_pton(src, dst);
+        if (rc != 0) {
+            return 0;
+        }
+        return 1;
     }
 }
 
diff --git a/net/ip/mn_socket/test/src/mn_sock_test.c 
b/net/ip/mn_socket/test/src/mn_sock_test.c
index b3c7845bf..034443a75 100644
--- a/net/ip/mn_socket/test/src/mn_sock_test.c
+++ b/net/ip/mn_socket/test/src/mn_sock_test.c
@@ -38,6 +38,7 @@ static struct os_mempool test_mbuf_mpool;
 static struct os_mbuf_pool test_mbuf_pool;
 
 TEST_CASE_DECL(inet_pton_test)
+TEST_CASE_DECL(inet6_pton_test)
 TEST_CASE_DECL(inet_ntop_test)
 TEST_CASE_DECL(socket_tests)
 
@@ -55,6 +56,7 @@ TEST_SUITE(mn_socket_test_all)
     TEST_ASSERT(rc == 0);
 
     inet_pton_test();
+    inet6_pton_test();
     inet_ntop_test();
     socket_tests();
 }
diff --git a/net/ip/mn_socket/test/src/testcases/inet6_pton_test.c 
b/net/ip/mn_socket/test/src/testcases/inet6_pton_test.c
new file mode 100644
index 000000000..b7e21deef
--- /dev/null
+++ b/net/ip/mn_socket/test/src/testcases/inet6_pton_test.c
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "mn_sock_test.h"
+
+TEST_CASE(inet6_pton_test)
+{
+    uint8_t addr_bytes[32];
+    int rc;
+    int i;
+
+    struct test_vec {
+        const char *str;
+        struct mn_in6_addr addr;
+    };
+
+    static const struct test_vec ok_vec[] = {
+        {
+            "::",
+            { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
+        },
+        {
+            "1::",
+            { { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
+        },
+        {
+            "1::f",
+            { { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xf } }
+        },
+        {
+            "1234:5678::abcd:ef01",
+            { { 0x12, 0x34, 0x56, 0x78, 0, 0, 0, 0,
+                0, 0, 0, 0, 0xab, 0xcd, 0xef, 0x01 } }
+        },
+        {
+            "5315:afaa:985e:72ca:9889:1632:8775:bbba",
+            { { 0x53, 0x15, 0xaf, 0xaa, 0x98, 0x5e, 0x72, 0xca,
+                0x98, 0x89, 0x16, 0x32, 0x87, 0x75, 0xbb, 0xba } }
+        },
+        {
+            "::1:2:3:4",
+            { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 4 } }
+        },
+        {
+            "::1:2:3",
+            { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3 } }
+        },
+    };
+
+    static const struct test_vec invalid_vec[] = {
+        { "" },
+        { ":" },
+        { "1::2::3" },
+        { "11111:43:a:b:c:d:e:f" },
+        { "g::a" },
+    };
+
+
+    for (i = 0; i < sizeof(ok_vec) / sizeof(ok_vec[0]); i++) {
+        memset(addr_bytes, 0xa5, sizeof(addr_bytes));
+        rc = mn_inet_pton(MN_PF_INET6, ok_vec[i].str, addr_bytes);
+        TEST_ASSERT_FATAL(rc == 1,
+                          "inet_pton(\"%s\")", ok_vec[i].str);
+        TEST_ASSERT(memcmp(addr_bytes, &ok_vec[i].addr, 16) == 0,
+                    "inet_pton(\"%s\")", ok_vec[i].str);
+        TEST_ASSERT(addr_bytes[16] == 0xa5,
+                    "inet_pton(\"%s\")", ok_vec[i].str);
+    }
+
+    for (i = 0; i < sizeof(invalid_vec) / sizeof(invalid_vec[0]); i++) {
+        rc = mn_inet_pton(MN_PF_INET6, invalid_vec[i].str, addr_bytes);
+        TEST_ASSERT(rc == 0,
+                    "inet_pton(\"%s\")", invalid_vec[i].str);
+    }
+}
diff --git a/util/parse/include/parse/parse.h b/util/parse/include/parse/parse.h
index dbeca867d..d659cdd4f 100644
--- a/util/parse/include/parse/parse.h
+++ b/util/parse/include/parse/parse.h
@@ -17,31 +17,259 @@
  * under the License.
  */
 
+/*
+ * @file
+ * @brief Utility functions for parsing text.
+ */
+
 #ifndef H_UTIL_PARSE_
 #define H_UTIL_PARSE_
 
+#include <inttypes.h>
+#include <stdbool.h>
+struct mn_in6_addr;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Parses a long long within an imposed range.
+ *
+ * @param sval                  The string to parse.
+ * @param min                   Values less than this are rejected.
+ * @param max                   Values greater than this are rejected.
+ * @param out_status            Written on completion;
+ *                                  0: success;
+ *                                  SYS_EINVAL: invalid string or number out of
+ *                                      range.
+ *
+ * @return                      The parsed number on success;
+ *                              unspecified on error.
+ */
 long long
 parse_ll_bounds(const char *sval, long long min, long long max,
                 int *out_status);
 
+/**
+ * Parses an unsigned long long within an imposed range.
+ *
+ * @param sval                  The string to parse.
+ * @param min                   Values less than this are rejected.
+ * @param max                   Values greater than this are rejected.
+ * @param out_status            Written on completion;
+ *                                  0: success;
+ *                                  SYS_EINVAL: invalid string or number out of
+ *                                      range.
+ *
+ * @return                      The parsed number on success;
+ *                              unspecified on error.
+ */
 unsigned long long
 parse_ull_bounds(const char *sval,
                  unsigned long long min, unsigned long long max,
                  int *out_status);
+
+/**
+ * Parses a long long.
+ *
+ * @param sval                  The string to parse.
+ * @param out_status            Written on completion;
+ *                                  0: success;
+ *                                  SYS_EINVAL: invalid string or number out of
+ *                                      range.
+ *
+ * @return                      The parsed number on success;
+ *                              unspecified on error.
+ */
 long long
 parse_ll(const char *sval, int *out_status);
 
+/**
+ * Parses an unsigned long long.
+ *
+ * @param sval                  The string to parse.
+ * @param out_status            Written on completion;
+ *                                  0: success;
+ *                                  SYS_EINVAL: invalid string or number out of
+ *                                      range.
+ *
+ * @return                      The parsed number on success;
+ *                              unspecified on error.
+ */
 unsigned long long
 parse_ull(const char *sval, int *out_status);
 
+/**
+ * @brief Parses a stream of bytes with the specified delimiter(s) and using
+ * the specified base.
+ *
+ * @param sval                  The string to parse.
+ * @param delims                String containing delimiters; each character
+ *                                  can act as a delimiter.
+ * @param base                  The base to use while parsing each byte string
+ *                                  (valid values are: 10, 16, and 0).
+ * @param max_len               The maximum number of bytes to write.
+ * @param dst                   The destination buffer to write bytes to.
+ * @param out_len               Written on success; total number of bytes
+ *                                  written to the destination buffer.
+ *
+ * @return                      0 on success;
+ *                              SYS_EINVAL on invalid byte stream;
+ *                              SYS_ERANGE if result only partially written to
+ *                                  buffer due to insufficient space.
+ */
+int
+parse_byte_stream_delim_base(const char *sval, const char *delims, int base,
+                             int max_len, uint8_t *dst, int *out_len);
+
+/**
+ * @brief Parses a stream of bytes with the specified delimiter(s).
+ *
+ * Parses a stream of bytes with the specified delimiter(s).  The base of each
+ * byte string is inferred from the text (base 16 if prefixed with "0x", base
+ * 10 otherwise).
+ *
+ * @param sval                  The string to parse.
+ * @param delims                String containing delimiters; each character
+ *                                  can act as a delimiter.
+ * @param max_len               The maximum number of bytes to write.
+ * @param dst                   The destination buffer to write bytes to.
+ * @param out_len               Written on success; total number of bytes
+ *                                  written to the destination buffer.
+ *
+ * @return                      0 on success;
+ *                              SYS_EINVAL on invalid byte stream;
+ *                              SYS_ERANGE if result only partially written to
+ *                                  buffer due to insufficient space.
+ */
 int
 parse_byte_stream_delim(const char *sval, const char *delims, int max_len,
                         uint8_t *dst, int *out_len);
 
+/**
+ * @brief Parses a stream of bytes using the specified base.
+ *
+ * @param sval                  The string to parse.
+ * @param base                  The base to use while parsing each byte string
+ *                                  (valid values are: 10, 16, and 0).
+ * @param max_len               The maximum number of bytes to write.
+ * @param dst                   The destination buffer to write bytes to.
+ * @param out_len               Written on success; total number of bytes
+ *                                  written to the destination buffer.
+ *
+ * @return                      0 on success;
+ *                              SYS_EINVAL on invalid byte stream;
+ *                              SYS_ERANGE if result only partially written to
+ *                                  buffer due to insufficient space.
+ */
+int
+parse_byte_stream_base(const char *sval, int base, int max_len,
+                       uint8_t *dst, int *out_len);
+
+/**
+ * @brief Parses a stream of bytes using ':' or '-' as delimiters.
+ *
+ * Parses a stream of bytes using ':' or '-' as delimiters.
+ * The base of each byte string is inferred from the text (base 16 if prefixed
+ * with "0x", base 10 otherwise).
+ *
+ * @param sval                  The string to parse.
+ * @param max_len               The maximum number of bytes to write.
+ * @param dst                   The destination buffer to write bytes to.
+ * @param out_len               Written on success; total number of bytes
+ *                                  written to the destination buffer.
+ *
+ * @return                      0 on success;
+ *                              SYS_EINVAL on invalid byte stream;
+ *                              SYS_ERANGE if result only partially written to
+ *                                  buffer due to insufficient space.
+ */
 int
 parse_byte_stream(const char *sval, int max_len, uint8_t *dst, int *out_len);
 
+/**
+ * @brief Parses a stream of bytes using the specified base.
+ *
+ * Parses a stream of bytes using the specified base.  If the length of the
+ * resulting byte array is not equal to the specified length, a SYS_EINVAL
+ * failure is reported.
+ *
+ * @param sval                  The string to parse.
+ * @param base                  The base to use while parsing each byte string
+ *                                  (valid values are: 10, 16, and 0).
+ * @param dst                   The destination buffer to write bytes to.
+ * @param len                   The exact number of bytes the result is
+ *                                  expected to contain.
+ *
+ * @return                      0 on success;
+ *                              SYS_EINVAL on invalid byte stream or if source
+ *                                  string specifies an unexpected number of
+ *                                  bytes;
+ */
+int
+parse_byte_stream_exact_length_base(const char *sval, int base,
+                                    uint8_t *dst, int len);
+
+/**
+ * @brief Parses a stream of bytes using ':' or '-' as delimiters.
+ *
+ * Parses a stream of bytes using ':' or '-' as delimiters.  If the length of
+ * the resulting byte array is not equal to the specified length, a SYS_EINVAL
+ * failure is reported.  The base of each byte string is inferred from the text
+ * (base 16 if prefixed with "0x", base 10 otherwise).
+ *
+ * @param sval                  The string to parse.
+ * @param dst                   The destination buffer to write bytes to.
+ * @param len                   The exact number of bytes the result is
+ *                                  expected to contain.
+ *
+ * @return                      0 on success;
+ *                              SYS_EINVAL on invalid byte stream or if source
+ *                                  string specifies an unexpected number of
+ *                                  bytes;
+ */
 int
 parse_byte_stream_exact_length(const char *sval, uint8_t *dst, int len);
 
+/**
+ * @brief Parses a boolean string.
+ *
+ * Parses a boolean string.  Valid boolean strings are: "true", "false", and
+ * numeric representations of 1 and 0.
+ *
+ * @param sval                  The string to parse.
+ * @param out_status            Written on completion;
+ *                                  0: success;
+ *                                  SYS_EINVAL: invalid boolean string.
+ *
+ * @return                      The parsed boolean on success;
+ *                              unspecified on error.
+ */
+bool
+parse_bool(const char *sval, int *out_status);
+
+/**
+ * @brief Parses an IPv6 network string.  The string 
+ *
+ * Parses an IPv6 network string.  The string must have the following form:
+ * <ipv6-address>/<prefix-length>.
+ *
+ * @param sval                  The string to parse.
+ * @param out_addr              The parsed IPv6 address is written here on
+ *                                  success.
+ * @param out_prefix_len        The parsed prefix length is written here on
+ *                                  success.
+ *
+ * @return                      0 on success;
+ *                              SYS_EINVAL if the IPv6 network string is
+ *                                  invalid.
+ */
+int
+parse_ip6_net(const char *sval,
+              struct mn_in6_addr *out_addr, uint8_t *out_prefix_len);
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/util/parse/pkg.yml b/util/parse/pkg.yml
index 38bcfba7c..615a35be6 100644
--- a/util/parse/pkg.yml
+++ b/util/parse/pkg.yml
@@ -18,7 +18,7 @@
 #
 
 pkg.name: util/parse
-pkg.description: Library containing miscellaneous utilities.
+pkg.description: Utility functions for parsing text.
 pkg.author: "Apache Mynewt <d...@mynewt.apache.org>"
 pkg.homepage: "http://mynewt.apache.org/";
 pkg.keywords:
diff --git a/util/parse/src/parse.c b/util/parse/src/parse.c
index e2c013613..626a97eab 100644
--- a/util/parse/src/parse.c
+++ b/util/parse/src/parse.c
@@ -25,6 +25,8 @@
 #include <errno.h>
 #include <assert.h>
 #include "os/mynewt.h"
+#include "mn_socket/mn_socket.h"
+#include "parse/parse.h"
 
 /**
  * Determines which numeric base the specified string should be parsed with.
@@ -45,20 +47,6 @@ parse_num_base(const char *sval)
     }
 }
 
-/**
- * Parses a long long within an imposed range.
- *
- * @param sval                  The string to parse.
- * @param min                   Values less than this are rejected.
- * @param max                   Values greater than this are rejected.
- * @param out_status            Written on completion;
- *                                  0: success;
- *                                  SYS_EINVAL: invalid string or number out of
- *                                      range.
- *
- * @return                      The parsed number on success;
- *                              unspecified on error.
- */
 long long
 parse_ll_bounds(const char *sval, long long min, long long max,
                 int *out_status)
@@ -78,20 +66,6 @@ parse_ll_bounds(const char *sval, long long min, long long 
max,
     return 0;
 }
 
-/**
- * Parses an unsigned long long within an imposed range.
- *
- * @param sval                  The string to parse.
- * @param min                   Values less than this are rejected.
- * @param max                   Values greater than this are rejected.
- * @param out_status            Written on completion;
- *                                  0: success;
- *                                  SYS_EINVAL: invalid string or number out of
- *                                      range.
- *
- * @return                      The parsed number on success;
- *                              unspecified on error.
- */
 unsigned long long
 parse_ull_bounds(const char *sval,
                  unsigned long long min, unsigned long long max,
@@ -112,65 +86,26 @@ parse_ull_bounds(const char *sval,
     return 0;
 }
 
-/**
- * Parses a long long.
- *
- * @param sval                  The string to parse.
- * @param out_status            Written on completion;
- *                                  0: success;
- *                                  SYS_EINVAL: invalid string or number out of
- *                                      range.
- *
- * @return                      The parsed number on success;
- *                              unspecified on error.
- */
 long long
 parse_ll(const char *sval, int *out_status)
 {
     return parse_ll_bounds(sval, LLONG_MIN, LLONG_MAX, out_status);
 }
 
-/**
- * Parses an unsigned long long.
- *
- * @param sval                  The string to parse.
- * @param out_status            Written on completion;
- *                                  0: success;
- *                                  SYS_EINVAL: invalid string or number out of
- *                                      range.
- *
- * @return                      The parsed number on success;
- *                              unspecified on error.
- */
 unsigned long long
 parse_ull(const char *sval, int *out_status)
 {
     return parse_ull_bounds(sval, 0, ULLONG_MAX, out_status);
 }
 
-/**
- * Parses a stream of bytes with the specified delimiter(s).
- *
- * @param sval                  The string to parse.
- * @param delims                String containing delimiters; each character
- *                                  can act as a delimiter.
- * @param max_len               The maximum number of bytes to write.
- * @param dst                   The destination buffer to write bytes to.
- * @param out_len               Written on success; total number of bytes
- *                                  written to the destination buffer.
- *
- * @return                      0 on success;
- *                              SYS_EINVAL on invalid byte stream;
- *                              SYS_ERANGE if result only partially written to
- *                                  buffer due to insufficient space.
- */
 int
-parse_byte_stream_delim(const char *sval, const char *delims, int max_len,
-                        uint8_t *dst, int *out_len)
+parse_byte_stream_delim_base(const char *sval, const char *delims, int base,
+                             int max_len, uint8_t *dst, int *out_len)
 {
     unsigned long ul;
     const char *cur;
     char *endptr;
+    int cur_base;
     int i;
 
     i = 0;
@@ -180,7 +115,13 @@ parse_byte_stream_delim(const char *sval, const char 
*delims, int max_len,
             return SYS_ERANGE;
         }
 
-        ul = strtoul(cur, &endptr, parse_num_base(cur));
+        if (base == 0) {
+            cur_base = parse_num_base(cur);
+        } else {
+            cur_base = base;
+        }
+
+        ul = strtoul(cur, &endptr, cur_base);
         if (endptr == cur) {
             return SYS_EINVAL;
         }
@@ -210,47 +151,36 @@ parse_byte_stream_delim(const char *sval, const char 
*delims, int max_len,
     return 0;
 }
 
-/**
- * Parses a stream of bytes using ':' or '-' as delimiters.
- *
- * @param sval                  The string to parse.
- * @param max_len               The maximum number of bytes to write.
- * @param dst                   The destination buffer to write bytes to.
- * @param out_len               Written on success; total number of bytes
- *                                  written to the destination buffer.
- *
- * @return                      0 on success;
- *                              SYS_EINVAL on invalid byte stream;
- *                              SYS_ERANGE if result only partially written to
- *                                  buffer due to insufficient space.
- */
+int
+parse_byte_stream_delim(const char *sval, const char *delims, int max_len,
+                        uint8_t *dst, int *out_len)
+{
+    return parse_byte_stream_delim_base(sval, delims, max_len, 0, dst,
+                                        out_len);
+}
+
+int
+parse_byte_stream_base(const char *sval, int base, int max_len,
+                       uint8_t *dst, int *out_len)
+{
+    return parse_byte_stream_delim_base(sval, ":-", base, max_len, dst,
+                                        out_len);
+}
+
 int
 parse_byte_stream(const char *sval, int max_len, uint8_t *dst, int *out_len)
 {
-    return parse_byte_stream_delim(sval, ":-", max_len, dst, out_len);
+    return parse_byte_stream_base(sval, 0, max_len, dst, out_len);
 }
 
-/**
- * Parses a stream of bytes using ':' or '-' as delimiters.  The number of
- * bytes must be the exact value specified.
- *
- * @param sval                  The string to parse.
- * @param max_len               The maximum number of bytes to write.
- * @param dst                   The destination buffer to write bytes to.
- * @param len                   Number of bytes to parse.
- *
- * @return                      0 on success;
- *                              SYS_EINVAL on invalid byte stream or if source
- *                                  string contains an unexpected number of
- *                                  bytes;
- */
 int
-parse_byte_stream_exact_length(const char *sval, uint8_t *dst, int len)
+parse_byte_stream_exact_length_base(const char *sval, int base,
+                                    uint8_t *dst, int len)
 {
     int actual_len;
     int rc;
 
-    rc = parse_byte_stream(sval, len, dst, &actual_len);
+    rc = parse_byte_stream_base(sval, base, len, dst, &actual_len);
     if (rc != 0) {
         return rc;
     }
@@ -261,3 +191,67 @@ parse_byte_stream_exact_length(const char *sval, uint8_t 
*dst, int len)
 
     return 0;
 }
+
+int
+parse_byte_stream_exact_length(const char *sval, uint8_t *dst, int len)
+{
+    return parse_byte_stream_exact_length_base(sval, 0, dst, len);
+}
+
+bool
+parse_bool(const char *sval, int *out_status)
+{
+    if (strcasecmp(sval, "false") == 0) {
+        *out_status = 0;
+        return false;
+    } else if (strcasecmp(sval, "true") == 0) {
+        *out_status = 0;
+        return true;
+    } else {
+        return parse_ll_bounds(sval, 0, 1, out_status);
+    }
+}
+
+int
+parse_ip6_net(const char *sval,
+              struct mn_in6_addr *out_addr, uint8_t *out_prefix_len)
+{
+    struct mn_in6_addr addr;
+    const char *slash;
+    uint8_t prefix_len;
+    char buf[MN_INET6_ADDRSTRLEN];
+    int rc;
+
+    slash = strchr(sval, '/');
+    if (slash == NULL) {
+        return SYS_EINVAL;
+    }
+    if (slash - sval > MN_INET6_ADDRSTRLEN) {
+        return SYS_EINVAL;
+    }
+
+    /* Copy the address portion of the network string so that we can
+     * null-terminate it.
+     */
+    memcpy(buf, sval, slash - sval);
+    buf[slash - sval] = '\0';
+
+    rc = mn_inet_pton(MN_AF_INET6, buf, &addr);
+    if (rc != 1) {
+        return SYS_EINVAL;
+    }
+
+    prefix_len = parse_ull_bounds(slash + 1, 0, 128, &rc);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (out_addr != NULL) {
+        *out_addr = addr;
+    }
+    if (out_prefix_len != NULL) {
+        *out_prefix_len = prefix_len;
+    }
+
+    return 0;
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to