Mercurial > irccd
comparison irccd-test/main.cpp @ 689:c0c2926a35df
Irccdctl: cleanup main.cpp
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 17 Apr 2018 12:21:37 +0200 |
parents | c09aee75fde4 |
children | 2007a37d7e1a |
comparison
equal
deleted
inserted
replaced
688:a18dd69afdd0 | 689:c0c2926a35df |
---|---|
23 #include <iostream> | 23 #include <iostream> |
24 #include <string> | 24 #include <string> |
25 #include <unordered_map> | 25 #include <unordered_map> |
26 | 26 |
27 #include <boost/algorithm/string/trim.hpp> | 27 #include <boost/algorithm/string/trim.hpp> |
28 #include <boost/filesystem/path.hpp> | 28 #include <boost/filesystem.hpp> |
29 | 29 |
30 #if defined(HAVE_LIBEDIT) | 30 #if defined(HAVE_LIBEDIT) |
31 # include <histedit.h> | 31 # include <histedit.h> |
32 #endif | 32 #endif |
33 | 33 |
55 boost::asio::io_service io; | 55 boost::asio::io_service io; |
56 | 56 |
57 std::unique_ptr<irccd> daemon; | 57 std::unique_ptr<irccd> daemon; |
58 std::shared_ptr<plugin> plugin; | 58 std::shared_ptr<plugin> plugin; |
59 | 59 |
60 void usage() | 60 // {{{ function table |
61 { | 61 |
62 std::cerr << "usage: irccd-test [-c config] plugin-name" << std::endl; | 62 /* |
63 std::exit(1); | 63 * Forward declarations of handlers. |
64 } | 64 */ |
65 | 65 void on_command(const std::string&); |
66 std::shared_ptr<server> get_server(std::string name) | 66 void on_connect(const std::string&); |
67 { | 67 void on_invite(const std::string&); |
68 name = boost::algorithm::trim_copy(name); | 68 void on_join(const std::string&); |
69 | 69 void on_kick(const std::string&); |
70 if (name.empty()) | 70 void on_load(const std::string&); |
71 name = "test"; | 71 void on_me(const std::string&); |
72 | 72 void on_message(const std::string&); |
73 auto s = daemon->servers().get(name); | 73 void on_mode(const std::string&); |
74 | 74 void on_names(const std::string&); |
75 if (!s) { | 75 void on_nick(const std::string&); |
76 s = std::make_shared<debug_server>(io, std::move(name), "localhost"); | 76 void on_notice(const std::string&); |
77 daemon->servers().add(s); | 77 void on_part(const std::string&); |
78 } | 78 void on_reload(const std::string&); |
79 | 79 void on_topic(const std::string&); |
80 return s; | 80 void on_unload(const std::string&); |
81 } | 81 void on_whois(const std::string&); |
82 | |
83 std::string get_arg(const std::vector<std::string>& args, unsigned index) | |
84 { | |
85 if (index >= args.size()) | |
86 return ""; | |
87 | |
88 return args[index]; | |
89 } | |
90 | |
91 /* | |
92 * onCommand server origin channel message | |
93 */ | |
94 void on_command(const std::string& data) | |
95 { | |
96 const auto args = su::split(data, " ", 4); | |
97 | |
98 plugin->handle_command(*daemon, { | |
99 get_server(get_arg(args, 0)), | |
100 get_arg(args, 1), | |
101 get_arg(args, 2), | |
102 get_arg(args, 3) | |
103 }); | |
104 } | |
105 | |
106 /* | |
107 * onConnect server | |
108 */ | |
109 void on_connect(const std::string& data) | |
110 { | |
111 const auto args = su::split(data, " "); | |
112 | |
113 plugin->handle_connect(*daemon, {get_server(get_arg(args, 0))}); | |
114 } | |
115 | |
116 /* | |
117 * onInvite server origin channel target | |
118 */ | |
119 void on_invite(const std::string& data) | |
120 { | |
121 auto args = su::split(data, " "); | |
122 | |
123 plugin->handle_invite(*daemon, { | |
124 get_server(get_arg(args, 0)), | |
125 get_arg(args, 1), | |
126 get_arg(args, 2), | |
127 get_arg(args, 3), | |
128 }); | |
129 } | |
130 | |
131 /* | |
132 * onJoin server origin channel | |
133 */ | |
134 void on_join(const std::string& data) | |
135 { | |
136 const auto args = su::split(data, " "); | |
137 | |
138 plugin->handle_join(*daemon, { | |
139 get_server(get_arg(args, 0)), | |
140 get_arg(args, 1), | |
141 get_arg(args, 2) | |
142 }); | |
143 } | |
144 | |
145 /* | |
146 * onKick server origin channel reason | |
147 */ | |
148 void on_kick(const std::string& data) | |
149 { | |
150 const auto args = su::split(data, " ", 5); | |
151 | |
152 plugin->handle_kick(*daemon, { | |
153 get_server(get_arg(args, 0)), | |
154 get_arg(args, 1), | |
155 get_arg(args, 2), | |
156 get_arg(args, 3), | |
157 get_arg(args, 4), | |
158 }); | |
159 } | |
160 | |
161 /* | |
162 * onLoad | |
163 */ | |
164 void on_load(const std::string&) | |
165 { | |
166 plugin->handle_load(*daemon); | |
167 } | |
168 | |
169 /* | |
170 * onMe server origin channel message | |
171 */ | |
172 void on_me(const std::string& data) | |
173 { | |
174 const auto args = su::split(data, " ", 4); | |
175 | |
176 plugin->handle_me(*daemon, { | |
177 get_server(get_arg(args, 0)), | |
178 get_arg(args, 1), | |
179 get_arg(args, 2), | |
180 get_arg(args, 3) | |
181 }); | |
182 } | |
183 | |
184 /* | |
185 * onMessage server origin channel message | |
186 */ | |
187 void on_message(const std::string& data) | |
188 { | |
189 const auto args = su::split(data, " ", 4); | |
190 | |
191 plugin->handle_message(*daemon, { | |
192 get_server(get_arg(args, 0)), | |
193 get_arg(args, 1), | |
194 get_arg(args, 2), | |
195 get_arg(args, 3) | |
196 }); | |
197 } | |
198 | |
199 /* | |
200 * onMode server origin channel mode limit user mask | |
201 */ | |
202 void on_mode(const std::string& data) | |
203 { | |
204 const auto args = su::split(data, " ", 7); | |
205 | |
206 plugin->handle_mode(*daemon, { | |
207 get_server(get_arg(args, 0)), | |
208 get_arg(args, 1), | |
209 get_arg(args, 2), | |
210 get_arg(args, 3), | |
211 get_arg(args, 4), | |
212 get_arg(args, 5), | |
213 get_arg(args, 6), | |
214 }); | |
215 } | |
216 | |
217 /* | |
218 * onNames server channel nick1 nick2 nickN | |
219 */ | |
220 void on_names(const std::string& data) | |
221 { | |
222 const auto args = su::split(data, " "); | |
223 | |
224 names_event ev; | |
225 | |
226 ev.server = get_server(get_arg(args, 0)); | |
227 ev.channel = get_arg(args, 1); | |
228 | |
229 if (args.size() >= 3U) | |
230 ev.names.insert(ev.names.begin(), args.begin() + 2, args.end()); | |
231 | |
232 plugin->handle_names(*daemon, ev); | |
233 } | |
234 | |
235 /* | |
236 * onNick server origin nickname | |
237 */ | |
238 void on_nick(const std::string& data) | |
239 { | |
240 const auto args = su::split(data, " "); | |
241 | |
242 plugin->handle_nick(*daemon, { | |
243 get_server(get_arg(args, 0)), | |
244 get_arg(args, 1), | |
245 get_arg(args, 2) | |
246 }); | |
247 } | |
248 | |
249 /* | |
250 * onNotice server origin channel nickname | |
251 */ | |
252 void on_notice(const std::string& data) | |
253 { | |
254 const auto args = su::split(data, " ", 4); | |
255 | |
256 plugin->handle_notice(*daemon, { | |
257 get_server(get_arg(args, 0)), | |
258 get_arg(args, 1), | |
259 get_arg(args, 2), | |
260 get_arg(args, 3) | |
261 }); | |
262 } | |
263 | |
264 /* | |
265 * onPart server origin channel reason | |
266 */ | |
267 void on_part(const std::string& data) | |
268 { | |
269 const auto args = su::split(data, " ", 4); | |
270 | |
271 plugin->handle_part(*daemon, { | |
272 get_server(get_arg(args, 0)), | |
273 get_arg(args, 1), | |
274 get_arg(args, 2), | |
275 get_arg(args, 3), | |
276 }); | |
277 } | |
278 | |
279 /* | |
280 * onReload | |
281 */ | |
282 void on_reload(const std::string&) | |
283 { | |
284 plugin->handle_reload(*daemon); | |
285 } | |
286 | |
287 /* | |
288 * onTopic server origin channel topic | |
289 */ | |
290 void on_topic(const std::string& data) | |
291 { | |
292 const auto args = su::split(data, " ", 4); | |
293 | |
294 plugin->handle_topic(*daemon, { | |
295 get_server(get_arg(args, 0)), | |
296 get_arg(args, 1), | |
297 get_arg(args, 2), | |
298 get_arg(args, 3) | |
299 }); | |
300 } | |
301 | |
302 /* | |
303 * onUnload | |
304 */ | |
305 void on_unload(const std::string&) | |
306 { | |
307 plugin->handle_unload(*daemon); | |
308 } | |
309 | |
310 /* | |
311 * onWhois server nick user host realname chan1 chan2 chanN | |
312 */ | |
313 void on_whois(const std::string& data) | |
314 { | |
315 const auto args = su::split(data, " "); | |
316 | |
317 whois_event ev; | |
318 | |
319 ev.server = get_server(get_arg(args, 0)); | |
320 ev.whois.nick = get_arg(args, 1); | |
321 ev.whois.user = get_arg(args, 2); | |
322 ev.whois.host = get_arg(args, 3); | |
323 ev.whois.realname = get_arg(args, 4); | |
324 | |
325 if (args.size() >= 5) | |
326 ev.whois.channels.insert(ev.whois.channels.begin(), args.begin() + 5, args.end()); | |
327 | |
328 plugin->handle_whois(*daemon, ev); | |
329 } | |
330 | 82 |
331 /* | 83 /* |
332 * Table of user functions. | 84 * Table of user functions. |
333 */ | 85 */ |
334 using function = std::function<void (const std::string&)>; | 86 using function = std::function<void (const std::string&)>; |
352 { "onTopic", &(on_topic) }, | 104 { "onTopic", &(on_topic) }, |
353 { "onUnload", &(on_unload) }, | 105 { "onUnload", &(on_unload) }, |
354 { "onWhois", &(on_whois) } | 106 { "onWhois", &(on_whois) } |
355 }; | 107 }; |
356 | 108 |
109 // }}} | |
110 | |
111 // {{{ usage | |
112 | |
113 void usage() | |
114 { | |
115 std::cerr << "usage: irccd-test [-c config] plugin-name" << std::endl; | |
116 std::exit(1); | |
117 } | |
118 | |
119 // }}} | |
120 | |
121 // {{{ get_server | |
122 | |
123 std::shared_ptr<server> get_server(std::string name) | |
124 { | |
125 name = boost::algorithm::trim_copy(name); | |
126 | |
127 if (name.empty()) | |
128 name = "test"; | |
129 | |
130 auto s = daemon->servers().get(name); | |
131 | |
132 if (!s) { | |
133 s = std::make_shared<debug_server>(io, std::move(name), "localhost"); | |
134 daemon->servers().add(s); | |
135 } | |
136 | |
137 return s; | |
138 } | |
139 | |
140 // }}} | |
141 | |
142 // {{{ get_arg | |
143 | |
144 std::string get_arg(const std::vector<std::string>& args, unsigned index) | |
145 { | |
146 if (index >= args.size()) | |
147 return ""; | |
148 | |
149 return args[index]; | |
150 } | |
151 | |
152 // }}} | |
153 | |
154 // {{{ on_command | |
155 | |
156 /* | |
157 * onCommand server origin channel message | |
158 */ | |
159 void on_command(const std::string& data) | |
160 { | |
161 const auto args = su::split(data, " ", 4); | |
162 | |
163 plugin->handle_command(*daemon, { | |
164 get_server(get_arg(args, 0)), | |
165 get_arg(args, 1), | |
166 get_arg(args, 2), | |
167 get_arg(args, 3) | |
168 }); | |
169 } | |
170 | |
171 // }}} | |
172 | |
173 // {{{ on_connect | |
174 | |
175 /* | |
176 * onConnect server | |
177 */ | |
178 void on_connect(const std::string& data) | |
179 { | |
180 const auto args = su::split(data, " "); | |
181 | |
182 plugin->handle_connect(*daemon, {get_server(get_arg(args, 0))}); | |
183 } | |
184 | |
185 // }}} | |
186 | |
187 // {{{ on_invite | |
188 | |
189 /* | |
190 * onInvite server origin channel target | |
191 */ | |
192 void on_invite(const std::string& data) | |
193 { | |
194 const auto args = su::split(data, " "); | |
195 | |
196 plugin->handle_invite(*daemon, { | |
197 get_server(get_arg(args, 0)), | |
198 get_arg(args, 1), | |
199 get_arg(args, 2), | |
200 get_arg(args, 3), | |
201 }); | |
202 } | |
203 | |
204 // }}} | |
205 | |
206 // {{{ on_join | |
207 | |
208 /* | |
209 * onJoin server origin channel | |
210 */ | |
211 void on_join(const std::string& data) | |
212 { | |
213 const auto args = su::split(data, " "); | |
214 | |
215 plugin->handle_join(*daemon, { | |
216 get_server(get_arg(args, 0)), | |
217 get_arg(args, 1), | |
218 get_arg(args, 2) | |
219 }); | |
220 } | |
221 | |
222 // }}} | |
223 | |
224 // {{{ on_kick | |
225 | |
226 /* | |
227 * onKick server origin channel reason | |
228 */ | |
229 void on_kick(const std::string& data) | |
230 { | |
231 const auto args = su::split(data, " ", 5); | |
232 | |
233 plugin->handle_kick(*daemon, { | |
234 get_server(get_arg(args, 0)), | |
235 get_arg(args, 1), | |
236 get_arg(args, 2), | |
237 get_arg(args, 3), | |
238 get_arg(args, 4), | |
239 }); | |
240 } | |
241 | |
242 // }}} | |
243 | |
244 // {{{ on_load | |
245 | |
246 /* | |
247 * onLoad | |
248 */ | |
249 void on_load(const std::string&) | |
250 { | |
251 plugin->handle_load(*daemon); | |
252 } | |
253 | |
254 // }}} | |
255 | |
256 // {{{ on_me | |
257 | |
258 /* | |
259 * onMe server origin channel message | |
260 */ | |
261 void on_me(const std::string& data) | |
262 { | |
263 const auto args = su::split(data, " ", 4); | |
264 | |
265 plugin->handle_me(*daemon, { | |
266 get_server(get_arg(args, 0)), | |
267 get_arg(args, 1), | |
268 get_arg(args, 2), | |
269 get_arg(args, 3) | |
270 }); | |
271 } | |
272 | |
273 // }}} | |
274 | |
275 // {{{ on_message | |
276 | |
277 /* | |
278 * onMessage server origin channel message | |
279 */ | |
280 void on_message(const std::string& data) | |
281 { | |
282 const auto args = su::split(data, " ", 4); | |
283 | |
284 plugin->handle_message(*daemon, { | |
285 get_server(get_arg(args, 0)), | |
286 get_arg(args, 1), | |
287 get_arg(args, 2), | |
288 get_arg(args, 3) | |
289 }); | |
290 } | |
291 | |
292 // }}} | |
293 | |
294 // {{{ on_mode | |
295 | |
296 /* | |
297 * onMode server origin channel mode limit user mask | |
298 */ | |
299 void on_mode(const std::string& data) | |
300 { | |
301 const auto args = su::split(data, " ", 7); | |
302 | |
303 plugin->handle_mode(*daemon, { | |
304 get_server(get_arg(args, 0)), | |
305 get_arg(args, 1), | |
306 get_arg(args, 2), | |
307 get_arg(args, 3), | |
308 get_arg(args, 4), | |
309 get_arg(args, 5), | |
310 get_arg(args, 6), | |
311 }); | |
312 } | |
313 | |
314 // }}} | |
315 | |
316 // {{{ on_names | |
317 | |
318 /* | |
319 * onNames server channel nick1 nick2 nickN | |
320 */ | |
321 void on_names(const std::string& data) | |
322 { | |
323 const auto args = su::split(data, " "); | |
324 | |
325 names_event ev; | |
326 | |
327 ev.server = get_server(get_arg(args, 0)); | |
328 ev.channel = get_arg(args, 1); | |
329 | |
330 if (args.size() >= 3U) | |
331 ev.names.insert(ev.names.begin(), args.begin() + 2, args.end()); | |
332 | |
333 plugin->handle_names(*daemon, ev); | |
334 } | |
335 | |
336 // }}} | |
337 | |
338 // {{{ on_nick | |
339 | |
340 /* | |
341 * onNick server origin nickname | |
342 */ | |
343 void on_nick(const std::string& data) | |
344 { | |
345 const auto args = su::split(data, " "); | |
346 | |
347 plugin->handle_nick(*daemon, { | |
348 get_server(get_arg(args, 0)), | |
349 get_arg(args, 1), | |
350 get_arg(args, 2) | |
351 }); | |
352 } | |
353 | |
354 // }}} | |
355 | |
356 // {{{ on_notice | |
357 | |
358 /* | |
359 * onNotice server origin channel nickname | |
360 */ | |
361 void on_notice(const std::string& data) | |
362 { | |
363 const auto args = su::split(data, " ", 4); | |
364 | |
365 plugin->handle_notice(*daemon, { | |
366 get_server(get_arg(args, 0)), | |
367 get_arg(args, 1), | |
368 get_arg(args, 2), | |
369 get_arg(args, 3) | |
370 }); | |
371 } | |
372 | |
373 // }}} | |
374 | |
375 // {{{ on_part | |
376 | |
377 /* | |
378 * onPart server origin channel reason | |
379 */ | |
380 void on_part(const std::string& data) | |
381 { | |
382 const auto args = su::split(data, " ", 4); | |
383 | |
384 plugin->handle_part(*daemon, { | |
385 get_server(get_arg(args, 0)), | |
386 get_arg(args, 1), | |
387 get_arg(args, 2), | |
388 get_arg(args, 3), | |
389 }); | |
390 } | |
391 | |
392 // }}} | |
393 | |
394 // {{{ on_reload | |
395 | |
396 /* | |
397 * onReload | |
398 */ | |
399 void on_reload(const std::string&) | |
400 { | |
401 plugin->handle_reload(*daemon); | |
402 } | |
403 | |
404 // }}} | |
405 | |
406 // {{{ on_topic | |
407 | |
408 /* | |
409 * onTopic server origin channel topic | |
410 */ | |
411 void on_topic(const std::string& data) | |
412 { | |
413 const auto args = su::split(data, " ", 4); | |
414 | |
415 plugin->handle_topic(*daemon, { | |
416 get_server(get_arg(args, 0)), | |
417 get_arg(args, 1), | |
418 get_arg(args, 2), | |
419 get_arg(args, 3) | |
420 }); | |
421 } | |
422 | |
423 // }}} | |
424 | |
425 // {{{ on_unload | |
426 | |
427 /* | |
428 * onUnload | |
429 */ | |
430 void on_unload(const std::string&) | |
431 { | |
432 plugin->handle_unload(*daemon); | |
433 } | |
434 | |
435 // }}} | |
436 | |
437 // {{{ on_whois | |
438 | |
439 /* | |
440 * onWhois server nick user host realname chan1 chan2 chanN | |
441 */ | |
442 void on_whois(const std::string& data) | |
443 { | |
444 const auto args = su::split(data, " "); | |
445 | |
446 whois_event ev; | |
447 | |
448 ev.server = get_server(get_arg(args, 0)); | |
449 ev.whois.nick = get_arg(args, 1); | |
450 ev.whois.user = get_arg(args, 2); | |
451 ev.whois.host = get_arg(args, 3); | |
452 ev.whois.realname = get_arg(args, 4); | |
453 | |
454 if (args.size() >= 5) | |
455 ev.whois.channels.insert(ev.whois.channels.begin(), args.begin() + 5, args.end()); | |
456 | |
457 plugin->handle_whois(*daemon, ev); | |
458 } | |
459 | |
460 // }}} | |
461 | |
462 // {{{ exec | |
463 | |
357 void exec(const std::string& line) | 464 void exec(const std::string& line) |
358 { | 465 { |
359 const auto pos = line.find(' '); | 466 const auto pos = line.find(' '); |
360 const auto it = list.find(line.substr(0, pos)); | 467 const auto it = list.find(line.substr(0, pos)); |
361 | 468 |
362 if (it != list.end()) | 469 if (it != list.end()) |
363 it->second(pos == std::string::npos ? "" : line.substr(pos + 1)); | 470 it->second(pos == std::string::npos ? "" : line.substr(pos + 1)); |
364 } | 471 } |
365 | 472 |
473 // }}} | |
474 | |
366 #if defined(HAVE_LIBEDIT) | 475 #if defined(HAVE_LIBEDIT) |
476 | |
477 // {{{ prompt (libedit version) | |
367 | 478 |
368 const char* prompt(EditLine*) | 479 const char* prompt(EditLine*) |
369 { | 480 { |
370 static const char* text = "> "; | 481 static const char* text = "> "; |
371 | 482 |
439 | 550 |
440 exec(clean(s)); | 551 exec(clean(s)); |
441 } | 552 } |
442 } | 553 } |
443 | 554 |
555 // }}} | |
556 | |
444 #else | 557 #else |
558 | |
559 // {{{ run (standard version) | |
445 | 560 |
446 void run() | 561 void run() |
447 { | 562 { |
448 std::string line; | 563 std::string line; |
449 | 564 |
455 | 570 |
456 exec(line); | 571 exec(line); |
457 } | 572 } |
458 } | 573 } |
459 | 574 |
575 // }}} | |
576 | |
460 #endif | 577 #endif |
578 | |
579 // {{{ load_plugins | |
461 | 580 |
462 void load_plugins(int argc, char** argv) | 581 void load_plugins(int argc, char** argv) |
463 { | 582 { |
464 if (argc <= 0) | 583 if (argc <= 0) |
465 usage(); | 584 usage(); |
466 | 585 |
467 daemon->plugins().load("test", boost::filesystem::exists(argv[0]) ? argv[0] : ""); | 586 daemon->plugins().load("test", boost::filesystem::exists(argv[0]) ? argv[0] : ""); |
468 plugin = daemon->plugins().get("test"); | 587 plugin = daemon->plugins().get("test"); |
469 } | 588 } |
589 | |
590 // }}} | |
591 | |
592 // {{{ load_options | |
470 | 593 |
471 void load_options(int& argc, char**& argv) | 594 void load_options(int& argc, char**& argv) |
472 { | 595 { |
473 const option::options def{ | 596 const option::options def{ |
474 { "-c", true }, | 597 { "-c", true }, |
487 throw std::runtime_error(su::sprintf("%s: %s", it->second, ex.what())); | 610 throw std::runtime_error(su::sprintf("%s: %s", it->second, ex.what())); |
488 } | 611 } |
489 } | 612 } |
490 } | 613 } |
491 | 614 |
615 // }}} | |
616 | |
617 // {{{ load | |
618 | |
492 void load(int argc, char** argv) | 619 void load(int argc, char** argv) |
493 { | 620 { |
494 daemon = std::make_unique<irccd>(io); | 621 daemon = std::make_unique<irccd>(io); |
495 | 622 |
496 #if defined(HAVE_JS) | 623 #if defined(HAVE_JS) |
498 #endif | 625 #endif |
499 | 626 |
500 load_options(argc, argv); | 627 load_options(argc, argv); |
501 load_plugins(argc, argv); | 628 load_plugins(argc, argv); |
502 } | 629 } |
630 | |
631 // }}} | |
503 | 632 |
504 } // !namespace | 633 } // !namespace |
505 | 634 |
506 } // !irccd | 635 } // !irccd |
507 | 636 |