annotate common/util.cpp @ 15:8d74eeb81184

Docs: update documentation in the irccd JavaScript events
author David Demelier <markand@malikania.fr>
date Thu, 11 Feb 2016 13:48:53 +0100
parents 1158cffe5a5e
children 03068f5ed79d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * util.cpp -- some utilities
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <algorithm>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #include <cctype>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include <cstdlib>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 #include <ctime>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #include <iomanip>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 #include <sstream>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 #include <stdexcept>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
26
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 #include <irccd-config.h>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
28
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 #include "util.h"
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 #include "unicode.h"
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
31
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 using namespace std::string_literals;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
33
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 namespace irccd {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
35
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 namespace util {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
37
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 namespace {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
39
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 const std::unordered_map<std::string, int> colorTable{
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 { "white", 0 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 { "black", 1 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 { "blue", 2 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 { "green", 3 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 { "red", 4 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 { "brown", 5 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 { "purple", 6 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 { "orange", 7 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 { "yellow", 8 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 { "lightgreen", 9 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 { "cyan", 10 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 { "lightcyan", 11 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 { "lightblue", 12 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 { "pink", 13 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 { "grey", 14 },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 { "lightgrey", 15 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 };
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
58
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 const std::unordered_map<std::string, char> attributesTable{
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 { "bold", '\x02' },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 { "italic", '\x09' },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 { "strike", '\x13' },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 { "reset", '\x0f' },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 { "underline", '\x15' },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 { "underline2", '\x1f' },
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 { "reverse", '\x16' }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 };
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
68
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 std::string substituteDate(const std::string &text, const Substitution &params)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 std::ostringstream oss;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
72
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 #if defined(HAVE_STD_PUT_TIME)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 oss << std::put_time(std::localtime(&params.time), text.c_str());
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 #else
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 /*
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 * Quick and dirty hack because GCC does not have this function.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 char buffer[4096];
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
80
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 std::strftime(buffer, sizeof (buffer) - 1, text.c_str(), std::localtime(&params.time));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
82
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 oss << buffer;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 #endif
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
85
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 return oss.str();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
88
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 std::string substituteKeywords(const std::string &content, const Substitution &params)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 auto value = params.keywords.find(content);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
92
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 if (value != params.keywords.end())
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
94 return value->second;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
95
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 return "";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
98
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 std::string substituteEnv(const std::string &content)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 auto value = std::getenv(content.c_str());
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
102
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 if (value != nullptr)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 return value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
105
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 return "";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
108
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 std::string substituteAttributes(const std::string &content)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 std::stringstream oss;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 std::vector<std::string> list = split(content, ",");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
113
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 /* @{} means reset */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 if (list.empty()) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 oss << attributesTable.at("reset");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 } else {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 /* Remove useless spaces */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
119 for (auto &a : list)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 a = strip(a);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
121
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 /*
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
123 * 0: foreground
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 * 1: background
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 * 2-n: attributes
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 auto foreground = list[0];
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
128 if (!foreground.empty() || list.size() >= 2) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 /* Color sequence */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
130 oss << '\x03';
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
131
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
132 /* Foreground */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 auto it = colorTable.find(foreground);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 if (it != colorTable.end())
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
135 oss << it->second;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
136
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 /* Background */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 if (list.size() >= 2 && (it = colorTable.find(list[1])) != colorTable.end())
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 oss << "," << it->second;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
140
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 /* Attributes */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 for (std::size_t i = 2; i < list.size(); ++i) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 auto attribute = attributesTable.find(list[i]);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
144
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 if (attribute != attributesTable.end())
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 oss << attribute->second;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
150
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 return oss.str();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
153
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 std::string substitute(std::string::const_iterator &it, std::string::const_iterator &end, char token, const Substitution &params)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 std::string content, value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
157
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 if (it == end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 return "";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
160
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 while (it != end && *it != '}')
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 content += *it++;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
163
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 if (*it != '}' || it == end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 throw std::invalid_argument("unclosed "s + token + " construct"s);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
166
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 it++;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
168
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 switch (token) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 case '#':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 value = substituteKeywords(content, params);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 case '$':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 value = substituteEnv(content);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
175 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 case '@':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 value = substituteAttributes(content);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 default:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 throw std::invalid_argument("unknown "s + token + " construct");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
182
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 return value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
185
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 } // !namespace
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
187
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 std::string format(std::string text, const Substitution &params)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 std::ostringstream oss;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
191
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 /*
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 * Change the date format before anything else to avoid interpolation with keywords and
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 * user input.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 text = substituteDate(text, params);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
197
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 std::string::const_iterator it = text.begin();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 std::string::const_iterator end = text.end();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
200
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 while (it != end) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 auto token = *it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
203
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 if (token == '#' || token == '@' || token == '$') {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
206
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 if (it == end) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 oss << token;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 continue;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
210 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
211
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 if (*it == '{') {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 /* Do we have a variable? */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 oss << substitute(++it, end, token, params);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 } else if (*it == token) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 /* Need one for sure */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 oss << token;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
218
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 /* Do we have a double token followed by a { for escaping? */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
220 if (++it == end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 continue;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
222
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 if (*it != '{')
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
224 oss << token;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
225 } else {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 oss << *it++;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 } else {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 oss << *it++;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
230 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
231 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
232
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 return oss.str();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
235
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 std::string strip(std::string str)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
237 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
238 auto test = [] (char c) { return !std::isspace(c); };
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
239
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 str.erase(str.begin(), std::find_if(str.begin(), str.end(), test));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 str.erase(std::find_if(str.rbegin(), str.rend(), test).base(), str.end());
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
242
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
243 return str;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
244 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
245
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
246 std::vector<std::string> split(const std::string &list, const std::string &delimiters, int max)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
247 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
248 std::vector<std::string> result;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 size_t next = -1, current;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 int count = 1;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 bool finished = false;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
252
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
253 if (list.empty())
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
254 return result;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
255
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 do {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
257 std::string val;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
258
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 current = next + 1;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
260 next = list.find_first_of(delimiters, current);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
261
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 // split max, get until the end
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 if (max >= 0 && count++ >= max) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 val = list.substr(current, std::string::npos);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
265 finished = true;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 } else {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 val = list.substr(current, next - current);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 finished = next == std::string::npos;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
269 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
270
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 result.push_back(val);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
272 } while (!finished);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
273
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 return result;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
276
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 MessagePair parseMessage(std::string message, const std::string &cc, const std::string &name)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
278 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
279 std::string result = message;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
280 bool iscommand = false;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
281
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
282 // handle special commands "!<plugin> command"
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 if (cc.length() > 0) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
284 auto pos = result.find_first_of(" \t");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
285 auto fullcommand = cc + name;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
286
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
287 /*
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
288 * If the message that comes is "!foo" without spaces we
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
289 * compare the command char + the plugin name. If there
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
290 * is a space, we check until we find a space, if not
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
291 * typing "!foo123123" will trigger foo plugin.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
292 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
293 if (pos == std::string::npos)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
294 iscommand = result == fullcommand;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
295 else
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
296 iscommand = result.length() >= fullcommand.length() && result.compare(0, pos, fullcommand) == 0;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
297
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
298 if (iscommand) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
299 /*
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 * If no space is found we just set the message to "" otherwise
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
301 * the plugin name will be passed through onCommand
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
302 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
303 if (pos == std::string::npos)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
304 result = "";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
305 else
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
306 result = message.substr(pos + 1);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
307 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
308 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
309
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
310 return MessagePair{result, ((iscommand) ? MessageType::Command : MessageType::Message)};
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
311 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
312
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
313 bool isBoolean(std::string value) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
314 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
315 return (value = unicode::toupper(value)) == "1" || value == "YES" || value == "TRUE" || value == "ON";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
316 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
317
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
318 bool isInt(const std::string &str, int base) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
319 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 if (str.empty())
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
321 return false;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
322
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
323 char *ptr;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
324
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
325 std::strtol(str.c_str(), &ptr, base);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
326
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
327 return *ptr == 0;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
328 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
329
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
330 bool isReal(const std::string &str) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
331 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
332 if (str.empty())
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
333 return false;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
334
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
335 char *ptr;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
336
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
337 std::strtod(str.c_str(), &ptr);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
338
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
339 return *ptr == 0;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
340 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
341
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
342 std::string nextNetwork(std::string &input)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
343 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
344 std::string result;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
345 std::string::size_type pos = input.find("\r\n\r\n");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
346
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
347 if ((pos = input.find("\r\n\r\n")) != std::string::npos) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
348 result = input.substr(0, pos);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
349 input.erase(input.begin(), input.begin() + pos + 4);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
350 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
351
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
352 return result;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
353 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
354
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
355 } // util
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
356
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
357 } // !irccd