Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
strview.h
Go to the documentation of this file.
1
8
9#pragma once
10
11#include <assert.h>
12#include <stdbool.h>
13#include <stddef.h>
14#include <string.h>
15#include <util/alloc.h>
16#include <util/startswith.h>
17#include <util/strcasecmp.h>
18
20typedef struct {
21 const char *data;
22 size_t size;
23} strview_t;
24
26static inline strview_t strview(const char *referent, char terminator) {
27
28 assert(referent != NULL);
29
30 // can we find the terminator before the end of the containing string?
31 const char *end = strchr(referent, terminator);
32 if (end != NULL) {
33 return (strview_t){.data = referent, .size = (size_t)(end - referent)};
34 }
35
36 // otherwise, span the entire string
37 return (strview_t){.data = referent, .size = strlen(referent)};
38}
39
41static inline char *strview_str(strview_t source) {
42
43 assert(source.data != NULL);
44
45 return gv_strndup(source.data, source.size);
46}
47
49static inline bool strview_case_eq(strview_t a, strview_t b) {
50
51 assert(a.data != NULL);
52 assert(b.data != NULL);
53
54 if (a.size != b.size) {
55 return false;
56 }
57
58 return strncasecmp(a.data, b.data, a.size) == 0;
59}
60
62static inline bool strview_case_str_eq(strview_t a, const char *b) {
63
64 assert(a.data != NULL);
65 assert(b != NULL);
66
67 return strview_case_eq(a, strview(b, '\0'));
68}
69
71static inline int strview_cmp(strview_t a, strview_t b) {
72
73 size_t min_size = a.size > b.size ? b.size : a.size;
74 int cmp = strncmp(a.data, b.data, min_size);
75 if (cmp != 0) {
76 return cmp;
77 }
78
79 if (a.size > b.size) {
80 return 1;
81 }
82 if (a.size < b.size) {
83 return -1;
84 }
85 return 0;
86}
87
89static inline bool strview_eq(strview_t a, strview_t b) {
90
91 assert(a.data != NULL);
92 assert(b.data != NULL);
93
94 return strview_cmp(a, b) == 0;
95}
96
98static inline bool strview_str_eq(strview_t a, const char *b) {
99
100 assert(a.data != NULL);
101 assert(b != NULL);
102
103 return strview_eq(a, strview(b, '\0'));
104}
105
107static inline bool strview_str_contains(strview_t haystack,
108 const char *needle) {
109
110 assert(haystack.data != NULL);
111 assert(needle != NULL);
112
113 // the empty string is a substring of everything
114 if (strcmp(needle, "") == 0) {
115 return true;
116 }
117
118 for (size_t offset = 0; offset < haystack.size;) {
119
120 // find the next possible starting point for the substring
121 const char *candidate = (const char *)memchr(
122 haystack.data + offset, needle[0], haystack.size - offset);
123 if (candidate == NULL) {
124 break;
125 }
126
127 // is it too close to the end of the containing string?
128 if ((size_t)(haystack.data + haystack.size - candidate) < strlen(needle)) {
129 return false;
130 }
131
132 // is it a match?
133 if (startswith(candidate, needle)) {
134 return true;
135 }
136
137 // advance to the position after this match for the next scan
138 offset = (size_t)(candidate - haystack.data) + 1;
139 }
140
141 return false;
142}
Memory allocation wrappers that exit on failure.
static char * gv_strndup(const char *original, size_t length)
Definition alloc.h:114
static int cmp(const void *key, const void *candidate)
node NULL
Definition grammar.y:163
swig_ptr_object_handlers offset
Definition gv_php.cpp:5907
static bool startswith(const char *s, const char *prefix)
does the string s begin with the string prefix?
Definition startswith.h:11
platform abstraction for case-insensitive string functions
a non-owning string reference
Definition strview.h:20
const char * data
start of the pointed to string
Definition strview.h:21
size_t size
extent of the string in bytes
Definition strview.h:22
static bool strview_str_eq(strview_t a, const char *b)
compare a string reference to a string for equality
Definition strview.h:98
static bool strview_str_contains(strview_t haystack, const char *needle)
does the given string appear as a substring of the string view?
Definition strview.h:107
static int strview_cmp(strview_t a, strview_t b)
compare two string references
Definition strview.h:71
static char * strview_str(strview_t source)
make a heap-allocated string from this string view
Definition strview.h:41
static bool strview_eq(strview_t a, strview_t b)
compare two string references for equality
Definition strview.h:89
static bool strview_case_eq(strview_t a, strview_t b)
compare two string references for case insensitive equality
Definition strview.h:49
static strview_t strview(const char *referent, char terminator)
create a string reference
Definition strview.h:26
static bool strview_case_str_eq(strview_t a, const char *b)
compare a string reference to a string for case insensitive equality
Definition strview.h:62