KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_bus_parsing.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
21
23#include <sch_connection.h>
24
25
26BOOST_AUTO_TEST_SUITE( BusParsing )
27
28
29BOOST_AUTO_TEST_CASE( ParsesFormattedVectorBus )
30{
31 wxString name;
32 std::vector<wxString> members;
33
34 BOOST_CHECK( NET_SETTINGS::ParseBusVector( wxS( "D_{[1..2]}" ), &name, &members ) );
35 BOOST_CHECK_EQUAL( name, wxS( "D" ) );
36
37 std::vector<wxString> expected = { wxS( "D1" ), wxS( "D2" ) };
38
39 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
40}
41
42
43BOOST_AUTO_TEST_CASE( ParsesFormattedGroupWithVectorMember )
44{
45 wxString name;
46 std::vector<wxString> members;
47
48 BOOST_CHECK( NET_SETTINGS::ParseBusGroup( wxS( "MEM{D_{[1..2]} ~{LATCH}}" ), &name, &members ) );
49 BOOST_CHECK_EQUAL( name, wxS( "MEM" ) );
50
51 std::vector<wxString> expected = { wxS( "D[1..2]" ), wxS( "LATCH" ) };
52
53 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
54}
55
56
57BOOST_AUTO_TEST_CASE( RejectsUnescapedSpacesInBusVector )
58{
59 wxString name;
60 std::vector<wxString> members;
61
62 // Unescaped space in bus vector prefix should fail
63 BOOST_CHECK( !NET_SETTINGS::ParseBusVector( wxS( "Data Bus[1..4]" ), &name, &members ) );
64}
65
66
67BOOST_AUTO_TEST_CASE( ParsesBackslashEscapedSpacesInBusVector )
68{
69 wxString name;
70 std::vector<wxString> members;
71
72 // Backslash-escaped space in bus vector prefix should work
73 BOOST_CHECK( NET_SETTINGS::ParseBusVector( wxS( "Data\\ Bus[1..2]" ), &name, &members ) );
74 BOOST_CHECK_EQUAL( name, wxS( "Data Bus" ) );
75
76 std::vector<wxString> expected = { wxS( "Data Bus1" ), wxS( "Data Bus2" ) };
77
78 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
79}
80
81
82BOOST_AUTO_TEST_CASE( ParsesQuotedSpacesInBusVector )
83{
84 wxString name;
85 std::vector<wxString> members;
86
87 // Quoted string with space in bus vector prefix should work
88 BOOST_CHECK( NET_SETTINGS::ParseBusVector( wxS( "\"Data Bus\"[1..2]" ), &name, &members ) );
89 BOOST_CHECK_EQUAL( name, wxS( "Data Bus" ) );
90
91 std::vector<wxString> expected = { wxS( "Data Bus1" ), wxS( "Data Bus2" ) };
92
93 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
94}
95
96
97BOOST_AUTO_TEST_CASE( RejectsUnescapedSpacesInBusGroupPrefix )
98{
99 wxString name;
100 std::vector<wxString> members;
101
102 // Unescaped space in bus group prefix should fail
103 BOOST_CHECK( !NET_SETTINGS::ParseBusGroup( wxS( "My Bus{NET1 NET2}" ), &name, &members ) );
104}
105
106
107BOOST_AUTO_TEST_CASE( ParsesBackslashEscapedSpacesInBusGroupPrefix )
108{
109 wxString name;
110 std::vector<wxString> members;
111
112 // Backslash-escaped space in bus group prefix should work
113 BOOST_CHECK( NET_SETTINGS::ParseBusGroup( wxS( "My\\ Bus{NET1 NET2}" ), &name, &members ) );
114 BOOST_CHECK_EQUAL( name, wxS( "My Bus" ) );
115
116 std::vector<wxString> expected = { wxS( "NET1" ), wxS( "NET2" ) };
117
118 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
119}
120
121
122BOOST_AUTO_TEST_CASE( ParsesQuotedSpacesInBusGroupPrefix )
123{
124 wxString name;
125 std::vector<wxString> members;
126
127 // Quoted string with space in bus group prefix should work
128 BOOST_CHECK( NET_SETTINGS::ParseBusGroup( wxS( "\"My Bus\"{NET1 NET2}" ), &name, &members ) );
129 BOOST_CHECK_EQUAL( name, wxS( "My Bus" ) );
130
131 std::vector<wxString> expected = { wxS( "NET1" ), wxS( "NET2" ) };
132
133 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
134}
135
136
137BOOST_AUTO_TEST_CASE( ParsesBackslashEscapedSpacesInBusGroupMembers )
138{
139 wxString name;
140 std::vector<wxString> members;
141
142 // Backslash-escaped space in bus group member name should work.
143 // Members are stored with escaped spaces so ForEachBusMember recursion works correctly.
144 BOOST_CHECK( NET_SETTINGS::ParseBusGroup( wxS( "BUS{Net\\ One Net\\ Two}" ), &name, &members ) );
145 BOOST_CHECK_EQUAL( name, wxS( "BUS" ) );
146
147 std::vector<wxString> expected = { wxS( "Net\\ One" ), wxS( "Net\\ Two" ) };
148
149 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
150}
151
152
153BOOST_AUTO_TEST_CASE( ParsesQuotedSpacesInBusGroupMembers )
154{
155 wxString name;
156 std::vector<wxString> members;
157
158 // Quoted member names with spaces should work.
159 // Members are stored with escaped spaces so ForEachBusMember recursion works correctly.
160 BOOST_CHECK( NET_SETTINGS::ParseBusGroup( wxS( "BUS{\"Net One\" \"Net Two\"}" ), &name, &members ) );
161 BOOST_CHECK_EQUAL( name, wxS( "BUS" ) );
162
163 std::vector<wxString> expected = { wxS( "Net\\ One" ), wxS( "Net\\ Two" ) };
164
165 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
166}
167
168
169BOOST_AUTO_TEST_CASE( ParsesMixedEscapingInBusGroup )
170{
171 wxString name;
172 std::vector<wxString> members;
173
174 // Mix of quoted and backslash-escaped names should work.
175 // Members are stored with escaped spaces so ForEachBusMember recursion works correctly.
176 BOOST_CHECK( NET_SETTINGS::ParseBusGroup( wxS( "BUS{\"Net One\" Net\\ Two PLAIN}" ), &name, &members ) );
177 BOOST_CHECK_EQUAL( name, wxS( "BUS" ) );
178
179 std::vector<wxString> expected = { wxS( "Net\\ One" ), wxS( "Net\\ Two" ), wxS( "PLAIN" ) };
180
181 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
182}
183
184
185BOOST_AUTO_TEST_CASE( ForEachBusMemberExpandsVectorWithSpacesInGroup )
186{
187 // Test that vector members with spaces inside bus groups are correctly expanded.
188 // This tests the fix for the bug where quoted vector members like "Data Bus"[1..2]
189 // would fail recursive parsing because the quotes were stripped without preserving
190 // space escaping.
191 std::vector<wxString> expandedMembers;
192 auto collector = [&expandedMembers]( const wxString& member )
193 {
194 expandedMembers.push_back( member );
195 };
196
197 // Quoted vector member inside a bus group
198 NET_SETTINGS::ForEachBusMember( wxS( "BUS{\"Data Bus\"[1..2] PLAIN}" ), collector );
199
200 std::vector<wxString> expected = { wxS( "Data Bus1" ), wxS( "Data Bus2" ), wxS( "PLAIN" ) };
201
202 BOOST_CHECK_EQUAL_COLLECTIONS( expandedMembers.begin(), expandedMembers.end(),
203 expected.begin(), expected.end() );
204}
205
206
207BOOST_AUTO_TEST_CASE( ForEachBusMemberExpandsEscapedVectorInGroup )
208{
209 // Test backslash-escaped vector member inside a bus group
210 std::vector<wxString> expandedMembers;
211 auto collector = [&expandedMembers]( const wxString& member )
212 {
213 expandedMembers.push_back( member );
214 };
215
216 NET_SETTINGS::ForEachBusMember( wxS( "BUS{Data\\ Bus[1..2] PLAIN}" ), collector );
217
218 std::vector<wxString> expected = { wxS( "Data Bus1" ), wxS( "Data Bus2" ), wxS( "PLAIN" ) };
219
220 BOOST_CHECK_EQUAL_COLLECTIONS( expandedMembers.begin(), expandedMembers.end(),
221 expected.begin(), expected.end() );
222}
223
224
225BOOST_AUTO_TEST_CASE( ParsesOverbarInVectorBusPrefix )
226{
227 // Test overbar formatting in bus vector prefix (issue #22873)
228 wxString name;
229 std::vector<wxString> members;
230
231 BOOST_CHECK( NET_SETTINGS::ParseBusVector( wxS( "bus_~{label}[0..2]" ), &name, &members ) );
232 BOOST_CHECK_EQUAL( name, wxS( "bus_label" ) );
233
234 std::vector<wxString> expected = { wxS( "bus_label0" ), wxS( "bus_label1" ), wxS( "bus_label2" ) };
235
236 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
237}
238
239
240BOOST_AUTO_TEST_CASE( ParsesSuperscriptInVectorBusPrefix )
241{
242 // Test superscript formatting in bus vector prefix (issue #22873)
243 wxString name;
244 std::vector<wxString> members;
245
246 BOOST_CHECK( NET_SETTINGS::ParseBusVector( wxS( "bus_^{label}[0..2]" ), &name, &members ) );
247 BOOST_CHECK_EQUAL( name, wxS( "bus_label" ) );
248
249 std::vector<wxString> expected = { wxS( "bus_label0" ), wxS( "bus_label1" ), wxS( "bus_label2" ) };
250
251 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
252}
253
254
255BOOST_AUTO_TEST_CASE( ParsesSubscriptInVectorBusPrefix )
256{
257 // Test subscript formatting in bus vector prefix (issue #22873)
258 wxString name;
259 std::vector<wxString> members;
260
261 BOOST_CHECK( NET_SETTINGS::ParseBusVector( wxS( "bus__{label}[0..2]" ), &name, &members ) );
262 BOOST_CHECK_EQUAL( name, wxS( "bus_label" ) );
263
264 std::vector<wxString> expected = { wxS( "bus_label0" ), wxS( "bus_label1" ), wxS( "bus_label2" ) };
265
266 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
267}
268
269
270BOOST_AUTO_TEST_CASE( ParsesOverbarInGroupBusPrefix )
271{
272 // Test overbar formatting in bus group prefix (issue #22873)
273 wxString name;
274 std::vector<wxString> members;
275
276 BOOST_CHECK( NET_SETTINGS::ParseBusGroup( wxS( "bus_~{label}{net1 net2}" ), &name, &members ) );
277 BOOST_CHECK_EQUAL( name, wxS( "bus_label" ) );
278
279 std::vector<wxString> expected = { wxS( "net1" ), wxS( "net2" ) };
280
281 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
282}
283
284
285BOOST_AUTO_TEST_CASE( ParsesSuperscriptInGroupBusPrefix )
286{
287 // Test superscript formatting in bus group prefix (issue #22873)
288 wxString name;
289 std::vector<wxString> members;
290
291 BOOST_CHECK( NET_SETTINGS::ParseBusGroup( wxS( "bus_^{label}{net1 net2}" ), &name, &members ) );
292 BOOST_CHECK_EQUAL( name, wxS( "bus_label" ) );
293
294 std::vector<wxString> expected = { wxS( "net1" ), wxS( "net2" ) };
295
296 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
297}
298
299
300BOOST_AUTO_TEST_CASE( ParsesSubscriptInGroupBusPrefix )
301{
302 // Test subscript formatting in bus group prefix (issue #22873)
303 wxString name;
304 std::vector<wxString> members;
305
306 BOOST_CHECK( NET_SETTINGS::ParseBusGroup( wxS( "bus__{label}{net1 net2}" ), &name, &members ) );
307 BOOST_CHECK_EQUAL( name, wxS( "bus_label" ) );
308
309 std::vector<wxString> expected = { wxS( "net1" ), wxS( "net2" ) };
310
311 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
312}
313
314
315BOOST_AUTO_TEST_CASE( PrintBusForUIUnescapesBackslashSpaces )
316{
317 // Test that PrintBusForUI converts backslash-escaped spaces to regular spaces (issue #22872)
318
319 // Simple case with backslash-escaped space
320 BOOST_CHECK_EQUAL( SCH_CONNECTION::PrintBusForUI( wxS( "net\\ name" ) ),
321 wxS( "net name" ) );
322
323 // Bus group member with escaped space in prefix
324 BOOST_CHECK_EQUAL( SCH_CONNECTION::PrintBusForUI( wxS( "bus\\ name.net\\ 1" ) ),
325 wxS( "bus name.net 1" ) );
326
327 // Multiple escaped spaces
328 BOOST_CHECK_EQUAL( SCH_CONNECTION::PrintBusForUI( wxS( "my\\ net\\ name" ) ),
329 wxS( "my net name" ) );
330
331 // No escaped spaces (should pass through unchanged)
332 BOOST_CHECK_EQUAL( SCH_CONNECTION::PrintBusForUI( wxS( "simple_net" ) ),
333 wxS( "simple_net" ) );
334}
335
336
337BOOST_AUTO_TEST_CASE( PrintBusForUIHandlesMixedFormatting )
338{
339 // Test that PrintBusForUI handles both super/sub/overbar formatting and escaped spaces
340
341 // Overbar formatting only
343 wxS( "reset" ) );
344
345 // Both overbar and escaped space
346 BOOST_CHECK_EQUAL( SCH_CONNECTION::PrintBusForUI( wxS( "my\\ ~{signal}" ) ),
347 wxS( "my signal" ) );
348}
349
350
const char * name
static bool ParseBusGroup(const wxString &aGroup, wxString *name, std::vector< wxString > *aMemberList)
Parse a bus group label into the name and a list of components.
static bool ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parse a bus vector (e.g.
static void ForEachBusMember(const wxString &aBusPattern, const std::function< void(const wxString &)> &aFunction)
Call a function for each member of an expanded bus pattern.
static wxString PrintBusForUI(const wxString &aString)
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_CASE(ParsesFormattedVectorBus)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
BOOST_CHECK_EQUAL(result, "25.4")