You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ja...@apache.org on 2017/05/08 14:31:57 UTC
[02/40] incubator-mynewt-core git commit: MYNEWT-740 Rudimentary Text
parsing package.
MYNEWT-740 Rudimentary Text parsing package.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/46d08164
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/46d08164
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/46d08164
Branch: refs/heads/bluetooth5
Commit: 46d08164db6c21c4c6dc9e8b871b54c1d3eecabf
Parents: 5ec317d
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Apr 24 19:13:53 2017 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon Apr 24 19:33:16 2017 -0700
----------------------------------------------------------------------
util/parse/include/parse/parse.h | 47 ++++++
util/parse/pkg.yml | 32 +++++
util/parse/src/parse.c | 263 ++++++++++++++++++++++++++++++++++
3 files changed, 342 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/46d08164/util/parse/include/parse/parse.h
----------------------------------------------------------------------
diff --git a/util/parse/include/parse/parse.h b/util/parse/include/parse/parse.h
new file mode 100644
index 0000000..39be885
--- /dev/null
+++ b/util/parse/include/parse/parse.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef H_UTIL_PARSE_
+#define H_UTIL_PARSE_
+
+long long
+parse_ll_bounds(const char *sval, long long min, long long max,
+ int *out_status);
+
+unsigned long long
+parse_ull_bounds(const char *sval,
+ unsigned long long min, unsigned long long max,
+ int *out_status);
+long long
+parse_ll(const char *sval, int *out_status);
+
+long long
+parse_ull(const char *sval, int *out_status);
+
+int
+parse_byte_stream_delim(const char *sval, const char *delims, int max_len,
+ uint8_t *dst, int *out_len);
+
+int
+parse_byte_stream(const char *sval, int max_len, uint8_t *dst, int *out_len);
+
+int
+parse_byte_stream_exact_length(const char *sval, uint8_t *dst, int len);
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/46d08164/util/parse/pkg.yml
----------------------------------------------------------------------
diff --git a/util/parse/pkg.yml b/util/parse/pkg.yml
new file mode 100644
index 0000000..69389f7
--- /dev/null
+++ b/util/parse/pkg.yml
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+
+pkg.name: util/parse
+pkg.description: Library containing miscellaneous utilities.
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+ - parse
+
+pkg.cflags:
+ # Required for [U]LLONG_{MIN,MAX}
+ - "-std=c99"
+
+pkg.deps:
+ - "@apache-mynewt-core/sys/defs"
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/46d08164/util/parse/src/parse.c
----------------------------------------------------------------------
diff --git a/util/parse/src/parse.c b/util/parse/src/parse.c
new file mode 100644
index 0000000..c278592
--- /dev/null
+++ b/util/parse/src/parse.c
@@ -0,0 +1,263 @@
+/*
+ * 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 <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <assert.h>
+#include "defs/error.h"
+
+/**
+ * Determines which numeric base the specified string should be parsed with.
+ * Strings with leading zeroes are not parsed as octal.
+ */
+static int
+parse_num_base(const char *sval)
+{
+ /* Skip optional sign. */
+ if (sval[0] == '+' || sval[0] == '-') {
+ sval++;
+ }
+
+ if (sval[0] == '0' && sval[1] == 'x') {
+ return 0;
+ } else {
+ return 10;
+ }
+}
+
+/**
+ * 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)
+{
+ char *endptr;
+ long long llval;
+
+ llval = strtoll(sval, &endptr, parse_num_base(sval));
+ if (sval[0] != '\0' && *endptr == '\0' &&
+ llval >= min && llval <= max) {
+
+ *out_status = 0;
+ return llval;
+ }
+
+ *out_status = SYS_EINVAL;
+ 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,
+ int *out_status)
+{
+ char *endptr;
+ unsigned long long ullval;
+
+ ullval = strtoull(sval, &endptr, parse_num_base(sval));
+ if (sval[0] != '\0' && *endptr == '\0' &&
+ ullval >= min && ullval <= max) {
+
+ *out_status = 0;
+ return ullval;
+ }
+
+ *out_status = SYS_EINVAL;
+ 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.
+ */
+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)
+{
+ unsigned long ul;
+ const char *cur;
+ char *endptr;
+ int i;
+
+ i = 0;
+ cur = sval;
+ while (*cur != '\0') {
+ if (i >= max_len) {
+ return SYS_ERANGE;
+ }
+
+ ul = strtoul(cur, &endptr, parse_num_base(cur));
+ if (endptr == cur) {
+ return SYS_EINVAL;
+ }
+ cur = endptr;
+
+ if (*cur != '\0') {
+ if (strspn(cur, delims) != 1) {
+ return SYS_EINVAL;
+ }
+ cur++;
+ if (*cur == '\0') {
+ /* Ended with a delimiter. */
+ return SYS_EINVAL;
+ }
+ }
+
+ if (ul > UINT8_MAX) {
+ return SYS_EINVAL;
+ }
+
+ dst[i] = ul;
+ i++;
+ }
+
+ *out_len = i;
+
+ 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(const char *sval, int max_len, uint8_t *dst, int *out_len)
+{
+ return parse_byte_stream_delim(sval, ":-", 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)
+{
+ int actual_len;
+ int rc;
+
+ rc = parse_byte_stream(sval, len, dst, &actual_len);
+ if (rc != 0) {
+ return rc;
+ }
+
+ if (actual_len != len) {
+ return SYS_EINVAL;
+ }
+
+ return 0;
+}