slang-netlist  0.10.0
Loading...
Searching...
No Matches
Wildcard.hpp
Go to the documentation of this file.
1#pragma once
2
3namespace slang::netlist {
4
26inline auto wildcardMatch(const char *text, const char *pattern) -> bool {
27 while (*pattern != '\0') {
28 // Detect a recursive wildcard token at the current pattern
29 // position, optionally preceded by a `.` we can absorb as part
30 // of a segment-boundary match.
31 bool hasLead = false;
32 const char *p = pattern;
33 if (*p == '.') {
34 const char *q = p + 1;
35 bool isRecur = (q[0] == '*' && q[1] == '*') ||
36 (q[0] == '.' && q[1] == '.' && q[2] == '.');
37 if (isRecur) {
38 hasLead = true;
39 p = q;
40 }
41 }
42
43 int recurLen = 0;
44 if (p[0] == '*' && p[1] == '*') {
45 recurLen = 2;
46 } else if (p[0] == '.' && p[1] == '.' && p[2] == '.') {
47 recurLen = 3;
48 }
49
50 if (recurLen != 0) {
51 const char *afterRecur = p + recurLen;
52 bool hasTrail = (*afterRecur == '.');
53 const char *rest = hasTrail ? afterRecur + 1 : afterRecur;
54
55 if (hasLead && hasTrail) {
56 // `.**.` — match a segment boundary `.` plus zero or more
57 // additional `<chars>.` segments before the boundary.
58 if (*text != '.') {
59 return false;
60 }
61 ++text;
62 if (wildcardMatch(text, rest)) {
63 return true;
64 }
65 while (*text != '\0') {
66 if (*text == '.' && wildcardMatch(text + 1, rest)) {
67 return true;
68 }
69 ++text;
70 }
71 return false;
72 }
73
74 if (hasLead) {
75 // `.**` with no trailing dot: match nothing, or `.` plus any
76 // suffix (including further `.`s).
77 if (wildcardMatch(text, rest)) {
78 return true;
79 }
80 if (*text != '.') {
81 return false;
82 }
83 ++text;
84 while (true) {
85 if (wildcardMatch(text, rest)) {
86 return true;
87 }
88 if (*text == '\0') {
89 return false;
90 }
91 ++text;
92 }
93 }
94
95 if (hasTrail) {
96 // `**.` with no leading dot: match nothing, or any prefix
97 // ending at a `.` (which the trailing `.` absorbs).
98 if (wildcardMatch(text, rest)) {
99 return true;
100 }
101 while (*text != '\0') {
102 if (*text == '.' && wildcardMatch(text + 1, rest)) {
103 return true;
104 }
105 ++text;
106 }
107 return false;
108 }
109
110 // Standalone `**` / `...`: match any (possibly empty) chars.
111 while (true) {
112 if (wildcardMatch(text, rest)) {
113 return true;
114 }
115 if (*text == '\0') {
116 return false;
117 }
118 ++text;
119 }
120 }
121
122 if (*pattern == '*') {
123 // Single-segment wildcard: matches zero or more non-`.` chars.
124 const char *rest = pattern + 1;
125 while (true) {
126 if (wildcardMatch(text, rest)) {
127 return true;
128 }
129 if (*text == '\0' || *text == '.') {
130 return false;
131 }
132 ++text;
133 }
134 }
135
136 if (*pattern == '?') {
137 // Single character within a segment; does not match `.` or end.
138 if (*text == '\0' || *text == '.') {
139 return false;
140 }
141 ++pattern;
142 ++text;
143 continue;
144 }
145
146 if (*pattern != *text) {
147 return false;
148 }
149 ++pattern;
150 ++text;
151 }
152 return *text == '\0';
153}
154
155} // namespace slang::netlist
Definition Utilities.hpp:16
auto wildcardMatch(const char *text, const char *pattern) -> bool
Definition Wildcard.hpp:26