1 #include <set>
2 #include <string>
3 #include <iostream>
4 
5 #include "common.h"
6 
7 #include <rtosc/ports.h>
8 #include <rtosc/port-sugar.h>
9 
null_fn(const char *,rtosc::RtData)10 void null_fn(const char*,rtosc::RtData){}
11 
12 static const rtosc::Ports d_ports = {
13     {"e", 0, 0, null_fn},
14 };
15 
16 static const rtosc::Ports c_ports = {
17     {"d/", 0, &d_ports, null_fn},
18 };
19 
20 static const rtosc::Ports a_ports = {
21     {"b/c/", 0, &c_ports, null_fn},
22     {"b/x/", 0,        0, null_fn}
23 };
24 
25 #define rObject walk_ports_tester
26 static const rtosc::Ports ports = {
27     {"a/", 0, &a_ports, null_fn},
28 //  {"a/b/c/", 0, &c_ports, null_fn},
29 };
30 #undef rObject
31 
32 static const rtosc::Ports multiple_ports = {
33     {"c/d/e:", 0, 0, null_fn},
34     {"a/x:", 0, 0, null_fn},
35     {"a/y:", 0, 0, null_fn},
36     {"c/d/", 0, 0, null_fn},
37     {"a/", 0, 0, null_fn},
38     {"b", 0, 0, null_fn},
39     {"b2", 0, 0, null_fn},
40 };
41 
42 static const rtosc::Ports masterTestPorts =
43 {
44     {"HDDRecorder/preparefile:s", rDoc("Init WAV file"), 0, null_fn},
45     {"HDDRecorder/start:", rDoc("Start recording"), 0, null_fn},
46     {"HDDRecorder/stop:", rDoc("Stop recording"), 0, null_fn},
47     {"HDDRecorder/pause:", rDoc("Pause recording"), 0, null_fn}
48 };
49 
50 static const rtosc::Ports samePortsSubSub =
51 {
52     {"y", 0, 0, null_fn},
53 };
54 
55 static const rtosc::Ports samePortsSub =
56 {
57     {"x/", 0, &samePortsSubSub, null_fn},
58 };
59 
60 static const rtosc::Ports samePorts =
61 {
62     {"x/", 0, &samePortsSub, null_fn},
63 };
64 
65 static const rtosc::Ports samePortsNoSubports =
66 {
67     {"x/", 0, 0, null_fn},
68 };
69 
70 static const rtosc::Ports samePorts2Sub =
71 {
72     {"x", 0, 0, null_fn},
73 };
74 
75 static const rtosc::Ports samePorts2 =
76 {
77     {"x/", 0, &samePorts2Sub, null_fn},
78 };
79 
80 static const rtosc::Ports samePorts2NoSlash =
81 {
82     {"x", 0, &samePorts2Sub, null_fn},
83 };
84 
main()85 int main()
86 {
87     char buffer[1024];
88     memset(buffer, 0, sizeof(buffer));
89 
90     std::size_t max_ports = 255;
91     size_t max_args    = max_ports << 1;
92     size_t max_types   = max_args + 1;
93     std::vector<char> types(max_types);
94     std::vector<rtosc_arg_t> args(max_types);
95 
96     assert_ptr_eq(ports.apropos("/a/b/c/d/e"),
97                   &ports.ports[0].ports->ports[0].ports->ports[0].ports->ports[0],
98                   "apropos(\"/a/b/c/d/e\")", __LINE__);
99 
100     assert_ptr_eq(ports.apropos("/a/b/c/d"),
101                   &ports.ports[0].ports->ports[0].ports->ports[0],
102                   "apropos(\"/a/b/c/d\")", __LINE__);
103 
104     assert_ptr_eq(ports.apropos("/a/b/c"),
105                   &ports.ports[0].ports->ports[0],
106                   "apropos(\"/a/b/c\")", __LINE__);
107 
108     assert_ptr_eq(ports.apropos("/a/b"),
109                   &ports.ports[0].ports->ports[0], // ???
110                   "apropos(\"/a/b\")", __LINE__);
111 
112     assert_ptr_eq(ports.apropos("/a"),
113                   &ports.ports[0],
114                   "apropos(\"/a\")", __LINE__);
115 
116     assert_ptr_eq(ports.apropos("/a"),
117                   &ports.ports[0],
118                   "apropos(\"/a\")", __LINE__);
119 
120     assert_ptr_eq(ports.apropos(""),
121                   nullptr,
122                   "apropos(\"\")", __LINE__);
123 
124     assert_ptr_eq(ports.apropos("doesnt-exist"),
125                   nullptr,
126                   "apropos(\"doesnt-exist\")", __LINE__);
127 
128     // all children at "/a/b/c/d/e"? no children - return e directly
129     path_search(ports, "/a/b/c/d/e", "", types.data(), max_types, args.data(), max_args);
130     assert_str_eq("sb", types.data(), "/a/b/c/d/e - types", __LINE__);
131     assert_str_eq("e", args[0].s, "/a/b/c/d/e - ports", __LINE__);
132 
133     // all children at "/a/b/c/d"? return e
134     path_search(ports, "/a/b/c/d", "", types.data(), max_types, args.data(), max_args);
135     assert_str_eq("sb", types.data(), "/a/b/c/d - types", __LINE__);
136     assert_str_eq("e", args[0].s, "/a/b/c/d - ports", __LINE__);
137 
138     path_search(ports, "/a/b/c", "", types.data(), max_types, args.data(), max_args);
139     assert_str_eq("sb", types.data(), "/a/b/c - types", __LINE__);
140     assert_str_eq("d/", args[0].s, "/a/b/c - ports", __LINE__);
141 
142     path_search(ports, "/a/b", "", types.data(), max_types, args.data(), max_args);
143     assert_str_eq("sb", types.data(), "/a/b - types", __LINE__);
144     assert_str_eq("d/", args[0].s, "/a/b - ports", __LINE__); // ???
145 
146     path_search(ports, "/a", "", types.data(), max_types, args.data(), max_args);
147     assert_str_eq("sbsb", types.data(), "/a - types", __LINE__);
148     assert_str_eq("b/c/", args[0].s, "/a - ports 1", __LINE__);
149     assert_str_eq("b/x/", args[2].s, "/a - ports 2", __LINE__);
150 
151     path_search(ports, "", "", types.data(), max_types, args.data(), max_args);
152     assert_str_eq("sb", types.data(), "\"\" - types", __LINE__);
153     assert_str_eq("a/", args[0].s, "\"\" - ports", __LINE__);
154 
155     // the same as before
156     path_search(ports, "/", "", types.data(), max_types, args.data(), max_args);
157     assert_str_eq("sb", types.data(), "\"/\" - types", __LINE__);
158     assert_str_eq("a/", args[0].s, "\"/\" - ports", __LINE__);
159 
160     path_search(ports, "/doesnt-exist", "", types.data(), max_types, args.data(), max_args);
161     assert_str_eq("", types.data(), "\"/doesnt-exist\" - types", __LINE__);
162 
163     // multiple ports
164 
165     path_search(multiple_ports, "", "", types.data(), max_types, args.data(), max_args,
166                 rtosc::path_search_opts::unmodified);
167     assert_str_eq("sbsbsbsbsbsbsb", types.data(), "multiple ports, unmodified - types", __LINE__);
168     assert_str_eq("c/d/e:", args[0].s, "multiple ports, sorted - ports 1", __LINE__);
169 
170     path_search(multiple_ports, "", "", types.data(), max_types, args.data(), max_args,
171                 rtosc::path_search_opts::sorted);
172     assert_str_eq("sbsbsbsbsbsbsb", types.data(), "multiple ports, sorted - types", __LINE__);
173     assert_str_eq("a/", args[0].s, "multiple ports, sorted - ports 1", __LINE__);
174     assert_str_eq("a/x:", args[2].s, "multiple ports, sorted - ports 2", __LINE__);
175     assert_str_eq("a/y:", args[4].s, "multiple ports, sorted - ports 3", __LINE__);
176     assert_str_eq("b", args[6].s, "multiple ports, sorted - ports 4", __LINE__);
177     assert_str_eq("b2", args[8].s, "multiple ports, sorted - ports 5", __LINE__);
178     assert_str_eq("c/d/", args[10].s, "multiple ports, sorted - ports 6", __LINE__);
179     assert_str_eq("c/d/e:", args[12].s, "multiple ports, sorted - ports 7", __LINE__);
180 
181     path_search(multiple_ports, "", "", types.data(), max_types, args.data(), max_args);
182     assert_str_eq("sbsbsbsb", types.data(), "multiple ports, unique prefix - types", __LINE__);
183     assert_str_eq("a/", args[0].s, "multiple ports, unique prefix - ports 1", __LINE__);
184     assert_str_eq("b", args[2].s, "multiple ports, unique prefix - ports 2", __LINE__);
185     assert_str_eq("b2", args[4].s, "multiple ports, unique prefix - ports 3", __LINE__);
186     assert_str_eq("c/d/", args[6].s, "multiple ports, unique prefix - ports 4", __LINE__);
187 
188     path_search(masterTestPorts, "HDDRecorder/preparefile", "",
189                 types.data(), max_types, args.data(), max_args);
190     assert_str_eq("sb", types.data(), "master test ports - types", __LINE__);
191     assert_str_eq("HDDRecorder/preparefile:s", args[0].s, "master test ports - ports 1", __LINE__);
192 
193 #ifdef KNOWN_ISSUES
194     path_search(masterTestPorts, "HDDRecorder/", "",
195                 types.data(), max_types, args.data(), max_args);
196     assert_str_eq("sbsbsbsb", types.data(), "master test ports 2 - types", __LINE__);
197 
198     path_search(masterTestPorts, "HDDRecorder/", "s",
199                 types.data(), max_types, args.data(), max_args);
200     assert_str_eq("sbsb", types.data(), "master test ports 3 - types", __LINE__);
201 #endif
202 
203     // sub-ports with same name as current port: /x/x/y
204     path_search(samePorts, "/x/", "",
205                 types.data(), max_types, args.data(), max_args);
206     assert_str_eq("sb", types.data(), "same ports - types", __LINE__);
207     assert_str_eq("x/", args[0].s, "same ports - ports 1", __LINE__);
208 
209     // the same, but the Ports coder forgot to add the sub port
210     // => same result
211     path_search(samePortsNoSubports, "/x/", "",
212                 types.data(), max_types, args.data(), max_args);
213     assert_str_eq("sb", types.data(), "same ports - types", __LINE__);
214     assert_str_eq("x/", args[0].s, "same ports - ports 1", __LINE__);
215 
216     // sub-ports with same name as current port: /x/x
217     path_search(samePorts2, "/x", "",
218                 types.data(), max_types, args.data(), max_args);
219     assert_str_eq("sb", types.data(), "same ports - types", __LINE__);
220     assert_str_eq("x", args[0].s, "same ports - ports 1", __LINE__);
221 
222     // the same, but the Ports coder forgot to add a slash
223     // => same result
224     path_search(samePorts2NoSlash, "/x", "",
225                 types.data(), max_types, args.data(), max_args);
226     assert_str_eq("sb", types.data(), "same ports - types", __LINE__);
227     assert_str_eq("x", args[0].s, "same ports - ports 1", __LINE__);
228 
229     return test_summary();
230 }
231 
232