summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-07-16 01:40:58 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-07-16 01:40:58 +0000
commit6ab0b94dceb7d7f0bfca39976e745f22c7ba8939 (patch)
tree976b955c1349a464c0a58748f286f7e7b792c60c /src
parent5454b47bd5d5ce5fb08aed83bac0148eabab620e (diff)
irc::tokenstream is a token parser which using std::string and std::vector builds a list of tokens using irc parsing rules.
e.g.: :arse PRIVMSG #chan :foo bar baz becomes a[0] = ":arse", a[1] = "PRIVMSG", a[2] = "#chan", a[3] = "foo bar baz". *** SOMEONE *** needs to optimize this or at least verify its neatness (without making it total craq and unreadable). Feel free to mess with my code. Any optimizations you make, run them against the COMMENTED OUT TEST SUITE at the top of main() in src/inspircd.cpp and ensure ALL output is the same with no crashes. (note: if you comment out and build with the test suite, all inspircd will do is output test data and exit!) git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4396 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src')
-rw-r--r--src/hashcomp.cpp44
-rw-r--r--src/inspircd.cpp60
2 files changed, 104 insertions, 0 deletions
diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp
index 3271e599c..08fbc8e2f 100644
--- a/src/hashcomp.cpp
+++ b/src/hashcomp.cpp
@@ -177,3 +177,47 @@ std::istream& operator>>(std::istream &is, irc::string &str)
str = tmp.c_str();
return is;
}
+
+irc::tokenstream::tokenstream(std::string &source)
+{
+ std::string::iterator last_starting_position = source.begin();
+ bool last_pushed = false;
+
+ for (std::string::iterator n = source.begin(); n != source.end(); n++)
+ {
+ if ((last_pushed) && (*n == ':'))
+ {
+ /* If we find a token thats not the first and starts with :,
+ * this is the last token on the line
+ */
+ tokens.push_back(std::string(n+1, source.end()));
+ break;
+ }
+
+ last_pushed = false;
+
+ if ((*n == ' ') || (n+1 == source.end()))
+ {
+ /* If we find a space, or end of string, this is the end of a token.
+ */
+ tokens.push_back(std::string(last_starting_position, n+1 == source.end() ? n+1 : n));
+ last_starting_position = n+1;
+ last_pushed = true;
+ }
+ }
+}
+
+irc::tokenstream::~tokenstream()
+{
+}
+
+unsigned int irc::tokenstream::GetNumTokens()
+{
+ return tokens.size();
+}
+
+const std::string& irc::tokenstream::GetToken(unsigned int index)
+{
+ return tokens[index];
+}
+
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 23a232c46..9635f707a 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -944,6 +944,66 @@ int InspIRCd::Run()
int main(int argc, char** argv)
{
+ /* TEST SUITE FOR TOKENSTREAM
+ *
+ * Expected output:
+ *
+ * String: 'PRIVMSG #test FOO BAR'
+ * NumItems = 4
+ * Token 0 = 'PRIVMSG'
+ * Token 1 = '#test'
+ * Token 2 = 'FOO'
+ * Token 3 = 'BAR'
+ * String: 'PRIVMSG #test :FOO BAR BAZ'
+ * NumItems = 3
+ * Token 0 = 'PRIVMSG'
+ * Token 1 = '#test'
+ * Token 2 = 'FOO BAR BAZ'
+ * String: ':PRIVMSG #test :FOO BAR BAZ'
+ * NumItems = 3
+ * Token 0 = ':PRIVMSG'
+ * String: 'AAAAAAA'
+ * NumItems = 1
+ * Token 0 = 'AAAAAAA'
+ * String: ''
+ * NumItems = 0
+ *
+ std::string a = "PRIVMSG #test FOO BAR";
+ printf("String: '%s'\n",a.c_str());
+ irc::tokenstream test(a);
+ printf("NumItems = %d\n",test.GetNumTokens());
+ printf("Token 0 = '%s'\n",test.GetToken(0).c_str());
+ printf("Token 1 = '%s'\n",test.GetToken(1).c_str());
+ printf("Token 2 = '%s'\n",test.GetToken(2).c_str());
+ printf("Token 3 = '%s'\n",test.GetToken(3).c_str());
+
+ std::string b = "PRIVMSG #test :FOO BAR BAZ";
+ printf("String: '%s'\n",b.c_str());
+ irc::tokenstream test2(b);
+ printf("NumItems = %d\n",test2.GetNumTokens());
+ printf("Token 0 = '%s'\n",test2.GetToken(0).c_str());
+ printf("Token 1 = '%s'\n",test2.GetToken(1).c_str());
+ printf("Token 2 = '%s'\n",test2.GetToken(2).c_str());
+
+ std::string c = ":PRIVMSG #test :FOO BAR BAZ";
+ printf("String: '%s'\n",c.c_str());
+ irc::tokenstream test3(c);
+ printf("NumItems = %d\n",test3.GetNumTokens());
+ printf("Token 0 = '%s'\n",test3.GetToken(0).c_str());
+
+ c = "AAAAAAA";
+ printf("String: '%s'\n",c.c_str());
+ irc::tokenstream test4(c);
+ printf("NumItems = %d\n",test4.GetNumTokens());
+ printf("Token 0 = '%s'\n",test4.GetToken(0).c_str());
+
+ c = "";
+ printf("String: '%s'\n",c.c_str());
+ irc::tokenstream test5(c);
+ printf("NumItems = %d\n",test5.GetNumTokens());
+
+ exit(0); */
+
try
{
ServerInstance = new InspIRCd(argc, argv);