summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdemangle/common/strview.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libdemangle/common/strview.h')
-rw-r--r--usr/src/lib/libdemangle/common/strview.h140
1 files changed, 140 insertions, 0 deletions
diff --git a/usr/src/lib/libdemangle/common/strview.h b/usr/src/lib/libdemangle/common/strview.h
new file mode 100644
index 0000000000..ac94c67c6c
--- /dev/null
+++ b/usr/src/lib/libdemangle/common/strview.h
@@ -0,0 +1,140 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2019, Joyent, Inc.
+ */
+
+#ifndef _STRVIEW_H
+#define _STRVIEW_H
+
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * strview_t's represent a read-only subset of a string. It is somewhat
+ * similar to the concept of ranges found in other languages in that one can
+ * create a strview_t, and then create a smaller range for iteration.
+ *
+ * sv_first is the address of the first location (and is advanced as values
+ * are consumed) in the string.
+ *
+ * sv_last is the address one byte after the last valid value of the subset.
+ * Basically, the length of the range is equal to 'sv_last - sv_first'. For
+ * example, in the string 'abcdef' to create a view 'bcd', *sv_first would
+ * equal 'b' and *sv_last would equal 'e'.
+ *
+ * sv_rem is the number of bytes remaining in the range.
+ *
+ * A strview_t maintains references to the underlying string, so the lifetime
+ * of a strview_t should be equal to or less than the underlying string (i.e.
+ * it doesn't copy the data from the underlying string, but maintains pointers
+ * to the original data).
+ *
+ * While the underlying string does not need to be NUL-terminated, NUL is still
+ * used as a sentinel value in some instances (e.g. sv_peek()), and should not
+ * be contained within the defined range.
+ *
+ * As hinted above, the functions currently do not deal with multi-byte
+ * characters, i.e. each character is assumed to be a single byte. The
+ * current consumers do not need to handle multi-byte characters (UTF-8
+ * or otherwise), so this is sufficient at the current time.
+ */
+typedef struct strview {
+ const char *sv_first;
+ const char *sv_last;
+ size_t sv_rem;
+} strview_t;
+
+/*
+ * SV_PRINT() is used for printing strview_t values during debugging, e.g.
+ * `DEMDEBUG("%*.s", SV_PRINT(sv));`
+ */
+#define SV_PRINT(_sv) (int)(_sv)->sv_rem, (_sv)->sv_first
+
+/*
+ * Initialize a strview_t from an already initialized strview_t -- the state of
+ * the source strview_t is duplicated in the newly initialized strview_t.
+ */
+void sv_init_sv(strview_t *, const strview_t *);
+
+/*
+ * Initialize a strview_t as a subset of an already initialized strview_t.
+ * The size of the subset (size_t) must be <= sv_remaining(src).
+ */
+void sv_init_sv_range(strview_t *, const strview_t *, size_t);
+
+/*
+ * Initialize a strview_t from a string. The two const char * pointers are the
+ * sv_first and sv_last values to use (see above). If the source string is
+ * NUL-terminated, one can optionally pass NULL for the second parameter in
+ * which case, the entire NUL-terminated string (starting at sv_first) is
+ * treated as a strview_t.
+ */
+void sv_init_str(strview_t *, const char *, const char *);
+
+/*
+ * Return the number of bytes remaining to consume in the strview_t
+ */
+size_t sv_remaining(const strview_t *);
+
+/*
+ * Return the char at the given position in the strview_t (without advancing
+ * the position). Position values >=0 are relative to the current position
+ * of the strview_t (e.g. '0' will return the next character, '1' will return
+ * the character after that), while negative position values are relative to
+ * the end of the strview_t (e.g. '-1' will return the last character, '-2'
+ * will return the second to last character).
+ *
+ * If the position value is out of range, '\0' is returned.
+ */
+char sv_peek(const strview_t *, ssize_t);
+
+/*
+ * Return the next character and advance the strview_t position. If no more
+ * characters are available, '\0' is returned.
+ */
+char sv_consume_c(strview_t *);
+
+/*
+ * Advance the position of the strview_t by the given number of bytes. The
+ * amount must be <= the number of bytes remaining in the strview_t.
+ */
+void sv_consume_n(strview_t *, size_t);
+
+/*
+ * Advance the strview_t position if the bytes of the strview starting at the
+ * current position match the given NUL-terminated string. The length of the
+ * NUL-terminated string must be <= the number of bytes remaining in the
+ * strview_t.
+ *
+ * If there is a match, the position of the strview_t is advanced by the
+ * length of the NUL-terminated comparison string, and B_TRUE is returned. If
+ * there is no match, the position is not advanced and B_FALSE is returned.
+ */
+boolean_t sv_consume_if(strview_t *, const char *);
+
+/*
+ * Advance the position of the strview_t if the next char in the strview_t
+ * is equal to the given char. If there is a match, the strview_t position
+ * is advanced one byte and B_TRUE is returned. If they do not match, B_FALSE
+ * is returned and the position is not advanced.
+ */
+boolean_t sv_consume_if_c(strview_t *, char);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STRVIEW_H */