diff options
Diffstat (limited to 'usr/src/lib/libdemangle/common/strview.h')
-rw-r--r-- | usr/src/lib/libdemangle/common/strview.h | 140 |
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 */ |