mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Regex
- Implemented RegX class to maintain a separate compile, and match method, thereby allowing efficient re-use of the regex. This is critical to Expression::eval, where an identical regex might be applied to every task. - Obsoleted rx.{h,cpp}, which combined the compile and match steps into a single call, and is therefore not efficient when used in the context of filtering. - Fixed some unit tests that weren't building. Now they do. They don't work of course (don't be silly) but that's a problem for another day. - Modified all code that relies on rx.h to use RegX.h.
This commit is contained in:
parent
aa8d872466
commit
b49523c06d
14 changed files with 249 additions and 490 deletions
31
src/Att.cpp
31
src/Att.cpp
|
@ -30,7 +30,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <rx.h>
|
#include <RegX.h>
|
||||||
#include <Color.h>
|
#include <Color.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <Date.h>
|
#include <Date.h>
|
||||||
|
@ -634,7 +634,8 @@ bool Att::match (const Att& other) const
|
||||||
if (regex)
|
if (regex)
|
||||||
{
|
{
|
||||||
std::string pattern = "^" + mValue + "$";
|
std::string pattern = "^" + mValue + "$";
|
||||||
if (!regexMatch (other.mValue, pattern, case_sensitive))
|
RegX r (pattern, case_sensitive);
|
||||||
|
if (!r.match (other.mValue))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (!compare (mValue, other.mValue, (bool) case_sensitive))
|
else if (!compare (mValue, other.mValue, (bool) case_sensitive))
|
||||||
|
@ -652,7 +653,8 @@ bool Att::match (const Att& other) const
|
||||||
#ifdef FEATURE_REGEX
|
#ifdef FEATURE_REGEX
|
||||||
if (regex)
|
if (regex)
|
||||||
{
|
{
|
||||||
if (!regexMatch (other.mValue, mValue, case_sensitive))
|
RegX r (mValue, case_sensitive);
|
||||||
|
if (!r.match (other.mValue))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (find (other.mValue, mValue, (bool) case_sensitive) == std::string::npos)
|
else if (find (other.mValue, mValue, (bool) case_sensitive) == std::string::npos)
|
||||||
|
@ -670,7 +672,8 @@ bool Att::match (const Att& other) const
|
||||||
if (regex)
|
if (regex)
|
||||||
{
|
{
|
||||||
std::string pattern = "^" + mValue + "$";
|
std::string pattern = "^" + mValue + "$";
|
||||||
if (!regexMatch (other.mValue, pattern, case_sensitive))
|
RegX r (pattern, case_sensitive);
|
||||||
|
if (!r.match (other.mValue))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (!compare (mValue, other.mValue, (bool) case_sensitive))
|
else if (!compare (mValue, other.mValue, (bool) case_sensitive))
|
||||||
|
@ -688,7 +691,8 @@ bool Att::match (const Att& other) const
|
||||||
if (regex)
|
if (regex)
|
||||||
{
|
{
|
||||||
std::string pattern = "^" + mValue + "$";
|
std::string pattern = "^" + mValue + "$";
|
||||||
if (regexMatch (other.mValue, pattern, case_sensitive))
|
RegX r (pattern, case_sensitive);
|
||||||
|
if (r.match (other.mValue))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (compare (mValue, other.mValue, (bool) case_sensitive))
|
else if (compare (mValue, other.mValue, (bool) case_sensitive))
|
||||||
|
@ -720,7 +724,8 @@ bool Att::match (const Att& other) const
|
||||||
if (regex)
|
if (regex)
|
||||||
{
|
{
|
||||||
std::string pattern = "^" + mValue;
|
std::string pattern = "^" + mValue;
|
||||||
if (!regexMatch (other.mValue, pattern, case_sensitive))
|
RegX r (pattern, case_sensitive);
|
||||||
|
if (!r.match (other.mValue))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -743,7 +748,8 @@ bool Att::match (const Att& other) const
|
||||||
if (regex)
|
if (regex)
|
||||||
{
|
{
|
||||||
std::string pattern = mValue + "$";
|
std::string pattern = mValue + "$";
|
||||||
if (!regexMatch (other.mValue, pattern, case_sensitive))
|
RegX r (pattern, case_sensitive);
|
||||||
|
if (!r.match (other.mValue))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -767,7 +773,8 @@ bool Att::match (const Att& other) const
|
||||||
#ifdef FEATURE_REGEX
|
#ifdef FEATURE_REGEX
|
||||||
if (regex)
|
if (regex)
|
||||||
{
|
{
|
||||||
if (regexMatch (other.mValue, mValue, case_sensitive))
|
RegX r (mValue, case_sensitive);
|
||||||
|
if (r.match (other.mValue))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (find (other.mValue, mValue, (bool) case_sensitive) != std::string::npos)
|
else if (find (other.mValue, mValue, (bool) case_sensitive) != std::string::npos)
|
||||||
|
@ -862,7 +869,8 @@ bool Att::match (const Att& other) const
|
||||||
{
|
{
|
||||||
std::vector <int> start;
|
std::vector <int> start;
|
||||||
std::vector <int> end;
|
std::vector <int> end;
|
||||||
if (!regexMatch (start, end, other.mValue, mValue, case_sensitive))
|
RegX r (mValue, case_sensitive);
|
||||||
|
if (!r.match (start, end, other.mValue))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!isWordStart (other.mValue, start[0]))
|
if (!isWordStart (other.mValue, start[0]))
|
||||||
|
@ -898,8 +906,9 @@ bool Att::match (const Att& other) const
|
||||||
{
|
{
|
||||||
std::vector <int> start;
|
std::vector <int> start;
|
||||||
std::vector <int> end;
|
std::vector <int> end;
|
||||||
if (regexMatch (start, end, other.mValue, mValue, case_sensitive) &&
|
RegX r (mValue, case_sensitive);
|
||||||
isWordStart (other.mValue, start[0]) &&
|
if (r.match (start, end, other.mValue) &&
|
||||||
|
isWordStart (other.mValue, start[0]) &&
|
||||||
isWordEnd (other.mValue, end[0]))
|
isWordEnd (other.mValue, end[0]))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ set (task_SRCS API.cpp API.h
|
||||||
Path.cpp Path.h
|
Path.cpp Path.h
|
||||||
Permission.cpp Permission.h
|
Permission.cpp Permission.h
|
||||||
Record.cpp Record.h
|
Record.cpp Record.h
|
||||||
|
RegX.cpp RegX.h
|
||||||
TDB.cpp TDB.h
|
TDB.cpp TDB.h
|
||||||
TDB2.cpp TDB2.h
|
TDB2.cpp TDB2.h
|
||||||
Task.cpp Task.h
|
Task.cpp Task.h
|
||||||
|
@ -45,7 +46,6 @@ set (task_SRCS API.cpp API.h
|
||||||
interactive.cpp
|
interactive.cpp
|
||||||
recur.cpp
|
recur.cpp
|
||||||
rules.cpp
|
rules.cpp
|
||||||
rx.cpp rx.h
|
|
||||||
sort.cpp
|
sort.cpp
|
||||||
text.cpp text.h
|
text.cpp text.h
|
||||||
utf8.cpp utf8.h
|
utf8.cpp utf8.h
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <Nibbler.h>
|
#include <Nibbler.h>
|
||||||
#include <Date.h>
|
#include <Date.h>
|
||||||
#include <rx.h>
|
#include <RegX.h>
|
||||||
|
|
||||||
const char* c_digits = "0123456789";
|
const char* c_digits = "0123456789";
|
||||||
|
|
||||||
|
@ -146,9 +146,10 @@ bool Nibbler::getUntilRx (const std::string& regex, std::string& result)
|
||||||
else
|
else
|
||||||
modified_regex = regex;
|
modified_regex = regex;
|
||||||
|
|
||||||
|
RegX r (modified_regex, true);
|
||||||
std::vector <int> start;
|
std::vector <int> start;
|
||||||
std::vector <int> end;
|
std::vector <int> end;
|
||||||
if (regexMatch (start, end, mInput.substr (mCursor), modified_regex, true))
|
if (r.match (start, end, mInput.substr (mCursor)))
|
||||||
{
|
{
|
||||||
result = mInput.substr (mCursor, start[0]);
|
result = mInput.substr (mCursor, start[0]);
|
||||||
mCursor += start[0];
|
mCursor += start[0];
|
||||||
|
@ -450,8 +451,9 @@ bool Nibbler::getRx (const std::string& regex, std::string& result)
|
||||||
else
|
else
|
||||||
modified_regex = regex;
|
modified_regex = regex;
|
||||||
|
|
||||||
|
RegX r (modified_regex, true);
|
||||||
std::vector <std::string> results;
|
std::vector <std::string> results;
|
||||||
if (regexMatch (results, mInput.substr (mCursor), modified_regex, true))
|
if (r.match (results, mInput.substr (mCursor)))
|
||||||
{
|
{
|
||||||
result = results[0];
|
result = results[0];
|
||||||
mCursor += result.length ();
|
mCursor += result.length ();
|
||||||
|
@ -1010,8 +1012,9 @@ bool Nibbler::skipRx (const std::string& regex)
|
||||||
else
|
else
|
||||||
modified_regex = regex;
|
modified_regex = regex;
|
||||||
|
|
||||||
|
RegX r (modified_regex, true);
|
||||||
std::vector <std::string> results;
|
std::vector <std::string> results;
|
||||||
if (regexMatch (results, mInput.substr (mCursor), modified_regex, true))
|
if (r.match (results, mInput.substr (mCursor)))
|
||||||
{
|
{
|
||||||
mCursor += results[0].length ();
|
mCursor += results[0].length ();
|
||||||
return true;
|
return true;
|
||||||
|
|
157
src/RegX.cpp
Normal file
157
src/RegX.cpp
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// taskwarrior - a command line task list manager.
|
||||||
|
//
|
||||||
|
// Copyright 2010 - 2011, Paul Beckingham, Federico Hernandez.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU General Public License as published by the Free Software
|
||||||
|
// Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
// version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
// details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along with
|
||||||
|
// this program; if not, write to the
|
||||||
|
//
|
||||||
|
// Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor,
|
||||||
|
// Boston, MA
|
||||||
|
// 02110-1301
|
||||||
|
// USA
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <RegX.h>
|
||||||
|
|
||||||
|
#define L10N // Localization complete.
|
||||||
|
|
||||||
|
//#define _POSIX_C_SOURCE 1
|
||||||
|
#define MAX_MATCHES 64
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
RegX::RegX (
|
||||||
|
const std::string& pattern,
|
||||||
|
bool case_sensitive /* = true */)
|
||||||
|
: _compiled (false)
|
||||||
|
, _pattern (pattern)
|
||||||
|
, _case_sensitive (case_sensitive)
|
||||||
|
{
|
||||||
|
compile ();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
RegX::RegX (const RegX& other)
|
||||||
|
: _compiled (false)
|
||||||
|
, _pattern (other._pattern)
|
||||||
|
, _case_sensitive (other._case_sensitive)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
RegX& RegX::operator= (const RegX& other)
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
_compiled = false;
|
||||||
|
_pattern = other._pattern;
|
||||||
|
_case_sensitive = other._case_sensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool RegX::operator== (const RegX& other) const
|
||||||
|
{
|
||||||
|
return _pattern == other._pattern &&
|
||||||
|
_case_sensitive == other._case_sensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
RegX::~RegX ()
|
||||||
|
{
|
||||||
|
if (_compiled)
|
||||||
|
regfree (&_regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void RegX::compile ()
|
||||||
|
{
|
||||||
|
if (!_compiled)
|
||||||
|
{
|
||||||
|
memset (&_regex, 0, sizeof (regex_t));
|
||||||
|
|
||||||
|
int result;
|
||||||
|
if ((result = regcomp (&_regex, _pattern.c_str (),
|
||||||
|
REG_EXTENDED | /*REG_NOSUB |*/ REG_NEWLINE |
|
||||||
|
(_case_sensitive ? 0 : REG_ICASE))) != 0)
|
||||||
|
{
|
||||||
|
char message[256];
|
||||||
|
regerror (result, &_regex, message, 256);
|
||||||
|
throw std::string (message);
|
||||||
|
}
|
||||||
|
|
||||||
|
_compiled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool RegX::match (const std::string& in)
|
||||||
|
{
|
||||||
|
if (!_compiled)
|
||||||
|
compile ();
|
||||||
|
|
||||||
|
return regexec (&_regex, in.c_str (), 0, NULL, 0) == 0 ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool RegX::match (
|
||||||
|
std::vector<std::string>& matches,
|
||||||
|
const std::string& in)
|
||||||
|
{
|
||||||
|
if (!_compiled)
|
||||||
|
compile ();
|
||||||
|
|
||||||
|
regmatch_t rm[MAX_MATCHES];
|
||||||
|
if (regexec (&_regex, in.c_str (), MAX_MATCHES, rm, 0) == 0)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 1; i < 1 + _regex.re_nsub; ++i)
|
||||||
|
matches.push_back (in.substr (rm[i].rm_so, rm[i].rm_eo - rm[i].rm_so));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool RegX::match (
|
||||||
|
std::vector <int>& start,
|
||||||
|
std::vector <int>& end,
|
||||||
|
const std::string& in)
|
||||||
|
{
|
||||||
|
if (!_compiled)
|
||||||
|
compile ();
|
||||||
|
|
||||||
|
regmatch_t rm[MAX_MATCHES];
|
||||||
|
if (regexec (&_regex, in.c_str (), MAX_MATCHES, rm, 0) == 0)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 1; i < 1 + _regex.re_nsub; ++i)
|
||||||
|
{
|
||||||
|
start.push_back (rm[i].rm_so);
|
||||||
|
end.push_back (rm[i].rm_eo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
|
@ -25,16 +25,36 @@
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef INCLUDED_RX
|
#ifndef INCLUDED_REGX
|
||||||
#define INCLuDED_RX
|
#define INCLUDED_REGX
|
||||||
#define L10N // Localization complete.
|
#define L10N // Localization complete.
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <regex.h>
|
||||||
|
|
||||||
bool regexMatch (const std::string&, const std::string&, bool caseSensitive = true);
|
class RegX
|
||||||
bool regexMatch (std::vector<std::string>&, const std::string&, const std::string&, bool caseSensitive = true);
|
{
|
||||||
bool regexMatch (std::vector<int>&, std::vector<int>&, const std::string&, const std::string&, bool caseSensitive = true);
|
public:
|
||||||
|
RegX (const std::string&, bool caseSensitive = true);
|
||||||
|
RegX (const RegX&);
|
||||||
|
RegX& operator= (const RegX&);
|
||||||
|
bool operator== (const RegX&) const;
|
||||||
|
~RegX ();
|
||||||
|
|
||||||
|
bool match (const std::string&);
|
||||||
|
bool match (std::vector<std::string>&, const std::string&);
|
||||||
|
bool match (std::vector <int>&, std::vector <int>&, const std::string&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void compile ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _compiled;
|
||||||
|
std::string _pattern;
|
||||||
|
bool _case_sensitive;
|
||||||
|
regex_t _regex;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <rx.h>
|
#include <RegX.h>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <cmake.h>
|
#include <cmake.h>
|
||||||
|
@ -223,9 +223,10 @@ int CmdDiagnostics::execute (std::string& output)
|
||||||
char* p = fgets (buffer, 1023, fp);
|
char* p = fgets (buffer, 1023, fp);
|
||||||
pclose (fp);
|
pclose (fp);
|
||||||
|
|
||||||
|
RegX r ("usage", false);
|
||||||
if (p)
|
if (p)
|
||||||
out << " scp: "
|
out << " scp: "
|
||||||
<< (regexMatch (buffer, "usage") ? "found" : "n/a")
|
<< (r.match (buffer) ? "found" : "n/a")
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,8 +238,9 @@ int CmdDiagnostics::execute (std::string& output)
|
||||||
// rsync version 2.6.9 protocol version 29
|
// rsync version 2.6.9 protocol version 29
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
|
RegX r ("version ([0-9]+\\.[0-9]+\\.[0-9]+)", false);
|
||||||
matches.clear ();
|
matches.clear ();
|
||||||
regexMatch (matches, buffer, "version ([0-9]+\\.[0-9]+\\.[0-9]+)");
|
r.match (matches, buffer);
|
||||||
out << " rsync: "
|
out << " rsync: "
|
||||||
<< (matches.size () ? matches[0] : "n/a")
|
<< (matches.size () ? matches[0] : "n/a")
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
@ -253,8 +255,9 @@ int CmdDiagnostics::execute (std::string& output)
|
||||||
// curl 7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3
|
// curl 7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
|
RegX r ("curl ([0-9]+\\.[0-9]+\\.[0-9]+)", false);
|
||||||
matches.clear ();
|
matches.clear ();
|
||||||
regexMatch (matches, buffer, "curl ([0-9]+\\.[0-9]+\\.[0-9]+)");
|
r.match (matches, buffer);
|
||||||
out << " curl: "
|
out << " curl: "
|
||||||
<< (matches.size () ? matches[0] : "n/a")
|
<< (matches.size () ? matches[0] : "n/a")
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
138
src/rx.cpp
138
src/rx.cpp
|
@ -1,138 +0,0 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// taskwarrior - a command line task list manager.
|
|
||||||
//
|
|
||||||
// Copyright 2010 - 2011, Paul Beckingham, Federico Hernandez.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or modify it under
|
|
||||||
// the terms of the GNU General Public License as published by the Free Software
|
|
||||||
// Foundation; either version 2 of the License, or (at your option) any later
|
|
||||||
// version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
// details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License along with
|
|
||||||
// this program; if not, write to the
|
|
||||||
//
|
|
||||||
// Free Software Foundation, Inc.,
|
|
||||||
// 51 Franklin Street, Fifth Floor,
|
|
||||||
// Boston, MA
|
|
||||||
// 02110-1301
|
|
||||||
// USA
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <regex.h>
|
|
||||||
#include <rx.h>
|
|
||||||
|
|
||||||
#define L10N // Localization complete.
|
|
||||||
|
|
||||||
//#define _POSIX_C_SOURCE 1
|
|
||||||
#define MAX_MATCHES 8
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool regexMatch (
|
|
||||||
const std::string& in,
|
|
||||||
const std::string& pattern,
|
|
||||||
bool caseSensitive /* = true */)
|
|
||||||
{
|
|
||||||
regex_t r = {0};
|
|
||||||
int result;
|
|
||||||
if ((result = regcomp (&r, pattern.c_str (),
|
|
||||||
REG_EXTENDED | REG_NOSUB | REG_NEWLINE |
|
|
||||||
(caseSensitive ? 0 : REG_ICASE))) == 0)
|
|
||||||
{
|
|
||||||
if ((result = regexec (&r, in.c_str (), 0, NULL, 0)) == 0)
|
|
||||||
{
|
|
||||||
regfree (&r);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == REG_NOMATCH)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char message[256];
|
|
||||||
regerror (result, &r, message, 256);
|
|
||||||
throw std::string (message);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool regexMatch (
|
|
||||||
std::vector<std::string>& out,
|
|
||||||
const std::string& in,
|
|
||||||
const std::string& pattern,
|
|
||||||
bool caseSensitive /* = true */)
|
|
||||||
{
|
|
||||||
regex_t r = {0};
|
|
||||||
int result;
|
|
||||||
if ((result = regcomp (&r, pattern.c_str (),
|
|
||||||
REG_EXTENDED | REG_NEWLINE |
|
|
||||||
(caseSensitive ? 0 : REG_ICASE))) == 0)
|
|
||||||
{
|
|
||||||
regmatch_t rm[MAX_MATCHES];
|
|
||||||
if ((result = regexec (&r, in.c_str (), MAX_MATCHES, rm, 0)) == 0)
|
|
||||||
{
|
|
||||||
for (unsigned int i = 1; i < 1 + r.re_nsub; ++i)
|
|
||||||
out.push_back (in.substr (rm[i].rm_so, rm[i].rm_eo - rm[i].rm_so));
|
|
||||||
|
|
||||||
regfree (&r);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == REG_NOMATCH)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char message[256];
|
|
||||||
regerror (result, &r, message, 256);
|
|
||||||
throw std::string (message);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool regexMatch (
|
|
||||||
std::vector <int>& start,
|
|
||||||
std::vector <int>& end,
|
|
||||||
const std::string& in,
|
|
||||||
const std::string& pattern,
|
|
||||||
bool caseSensitive /* = true */)
|
|
||||||
{
|
|
||||||
regex_t r = {0};
|
|
||||||
int result;
|
|
||||||
if ((result = regcomp (&r, pattern.c_str (),
|
|
||||||
REG_EXTENDED | REG_NEWLINE |
|
|
||||||
(caseSensitive ? 0 : REG_ICASE))) == 0)
|
|
||||||
{
|
|
||||||
regmatch_t rm[MAX_MATCHES];
|
|
||||||
if ((result = regexec (&r, in.c_str (), MAX_MATCHES, rm, 0)) == 0)
|
|
||||||
{
|
|
||||||
for (unsigned int i = 1; i < 1 + r.re_nsub; ++i)
|
|
||||||
{
|
|
||||||
start.push_back (rm[i].rm_so);
|
|
||||||
end.push_back (rm[i].rm_eo);
|
|
||||||
}
|
|
||||||
|
|
||||||
regfree (&r);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == REG_NOMATCH)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char message[256];
|
|
||||||
regerror (result, &r, message, 256);
|
|
||||||
throw std::string (message);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
|
@ -7,9 +7,9 @@ include_directories (${CMAKE_SOURCE_DIR}
|
||||||
${TASK_INCLUDE_DIRS})
|
${TASK_INCLUDE_DIRS})
|
||||||
|
|
||||||
set (test_SRCS arguments.t att.t autocomplete.t color.t config.t date.t
|
set (test_SRCS arguments.t att.t autocomplete.t color.t config.t date.t
|
||||||
directory.t dom.t duration.t file.t filt.t i18n.t json.t lexer.t
|
directory.t dom.t duration.t file.t i18n.t json.t lexer.t list.t
|
||||||
list.t nibbler.t path.t record.t rx.t seq.t t.benchmark.t t.t
|
nibbler.t path.t record.t rx.t t.benchmark.t t.t taskmod.t tdb.t
|
||||||
taskmod.t tdb.t tdb2.t text.t uri.t util.t variant.t view.t
|
tdb2.t text.t uri.t util.t variant.t view.t
|
||||||
json_test)
|
json_test)
|
||||||
|
|
||||||
add_custom_target (test ./run_all DEPENDS ${test_SRCS}
|
add_custom_target (test ./run_all DEPENDS ${test_SRCS}
|
||||||
|
|
168
test/filt.t.cpp
168
test/filt.t.cpp
|
@ -1,168 +0,0 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// taskwarrior - a command line task list manager.
|
|
||||||
//
|
|
||||||
// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or modify it under
|
|
||||||
// the terms of the GNU General Public License as published by the Free Software
|
|
||||||
// Foundation; either version 2 of the License, or (at your option) any later
|
|
||||||
// version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
// details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License along with
|
|
||||||
// this program; if not, write to the
|
|
||||||
//
|
|
||||||
// Free Software Foundation, Inc.,
|
|
||||||
// 51 Franklin Street, Fifth Floor,
|
|
||||||
// Boston, MA
|
|
||||||
// 02110-1301
|
|
||||||
// USA
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <main.h>
|
|
||||||
#include <test.h>
|
|
||||||
#include <Filter.h>
|
|
||||||
#include <Task.h>
|
|
||||||
|
|
||||||
Context context;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int main (int argc, char** argv)
|
|
||||||
{
|
|
||||||
UnitTest test (20);
|
|
||||||
|
|
||||||
// Create a filter consisting of two Att criteria.
|
|
||||||
Filter f;
|
|
||||||
f.push_back (Att ("name1", "value1"));
|
|
||||||
f.push_back (Att ("name2", "value2"));
|
|
||||||
test.is (f.size (), (size_t)2, "Filter created");
|
|
||||||
|
|
||||||
// Create a Task to match against.
|
|
||||||
Task yes;
|
|
||||||
yes.set ("name1", "value1");
|
|
||||||
yes.set ("name2", "value2");
|
|
||||||
test.ok (f.pass (yes), "full match");
|
|
||||||
|
|
||||||
yes.set ("name3", "value3");
|
|
||||||
test.ok (f.pass (yes), "over match");
|
|
||||||
|
|
||||||
// Negative tests.
|
|
||||||
Task no0;
|
|
||||||
test.notok (f.pass (no0), "no match against default Task");
|
|
||||||
|
|
||||||
Task no1;
|
|
||||||
no1.set ("name3", "value3");
|
|
||||||
test.notok (f.pass (no1), "no match against mismatch Task");
|
|
||||||
|
|
||||||
Task partial;
|
|
||||||
partial.set ("name1", "value1");
|
|
||||||
test.notok (f.pass (partial), "no match against partial Task");
|
|
||||||
|
|
||||||
// Modifiers.
|
|
||||||
Task mods;
|
|
||||||
mods.set ("name", "value");
|
|
||||||
mods.set ("description", "hello, world.");
|
|
||||||
|
|
||||||
Att a ("name", "is", "value");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.ok (f.pass (mods), "name:value -> name.is:value = match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("name", "isnt", "value");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.notok (f.pass (mods), "name:value -> name.isnt:value = no match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("name", "startswith", "val");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.ok (f.pass (mods), "name:value -> name.startswith:val = match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("name", "endswith", "lue");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.ok (f.pass (mods), "name:value -> name.endswith:lue = match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("name", "has", "alu");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.ok (f.pass (mods), "name:value -> name.has:alu = match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("name", "hasnt", "alu");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.notok (f.pass (mods), "name:value -> name.hasnt:alu = no match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("name", "any", "");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.ok (f.pass (mods), "name:value -> name.any: = match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("name", "none", "");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.notok (f.pass (mods), "name:value -> name.none: = no match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
/*
|
|
||||||
"before"
|
|
||||||
"after"
|
|
||||||
"under"
|
|
||||||
"over"
|
|
||||||
"above"
|
|
||||||
"below"
|
|
||||||
*/
|
|
||||||
|
|
||||||
a = Att ("description", "word", "hello");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.ok (f.pass (mods), "description:hello, world. -> description.word:hello = match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("description", "word", "world");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.ok (f.pass (mods), "description:hello, world. -> description.word:world = match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("description", "word", "pig");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.notok (f.pass (mods), "description:hello, world. -> description.word:pig = no match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("description", "noword", "hello");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.notok (f.pass (mods), "description:hello, world. -> description.noword:hello = no match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("description", "noword", "world");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.notok (f.pass (mods), "description:hello, world. -> description.noword:world = no match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
a = Att ("description", "noword", "pig");
|
|
||||||
f.clear ();
|
|
||||||
f.push_back (a);
|
|
||||||
test.ok (f.pass (mods), "description:hello, world. -> description.noword:pig = match");
|
|
||||||
// TODO test inverse.
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <rx.h>
|
#include <RegX.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
Context context;
|
Context context;
|
||||||
|
@ -36,30 +36,41 @@ int main (int argc, char** argv)
|
||||||
|
|
||||||
std::string text = "This is a test.";
|
std::string text = "This is a test.";
|
||||||
|
|
||||||
ut.ok (regexMatch (text, "i. ", true), text + " =~ /i. /");
|
RegX r1 ("i. ", true);
|
||||||
|
ut.ok (r1.match (text), text + " =~ /i. /");
|
||||||
|
|
||||||
std::vector <std::string> matches;
|
std::vector <std::string> matches;
|
||||||
ut.ok (regexMatch (matches, text, "(i.) ", false), text + " =~ /(i.) /");
|
RegX r2 ("(i.) ", false);
|
||||||
|
ut.ok (r2.match (matches, text), text + " =~ /(i.) /");
|
||||||
ut.ok (matches.size () == 1, "1 match");
|
ut.ok (matches.size () == 1, "1 match");
|
||||||
ut.is (matches[0], "is", "$1 == is");
|
ut.is (matches[0], "is", "$1 == is");
|
||||||
|
|
||||||
text = "abcdefghijklmnopqrstuvwxyz";
|
text = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
ut.ok (regexMatch (text, "t..", true), "t..");
|
RegX r3 ("t..", true);
|
||||||
ut.ok (regexMatch (text, "T..", false), "T..");
|
ut.ok (r3.match (text), "t..");
|
||||||
ut.ok (!regexMatch (text, "T..", true), "! T..");
|
|
||||||
|
RegX r4 ("T..", false);
|
||||||
|
ut.ok (r4.match (text), "T..");
|
||||||
|
|
||||||
|
RegX r5 ("T..", true);
|
||||||
|
ut.ok (!r5.match (text), "! T..");
|
||||||
|
|
||||||
text = "this is a test of the regex engine.";
|
text = "this is a test of the regex engine.";
|
||||||
// |...:....|....:....|....:....|....:
|
// |...:....|....:....|....:....|....:
|
||||||
|
|
||||||
ut.ok (regexMatch (text, "^this"), "^this matches");
|
RegX r6 ("^this");
|
||||||
ut.ok (regexMatch (text, "engine\\.$"), "engine\\.$ matches");
|
ut.ok (r6.match (text), "^this matches");
|
||||||
|
|
||||||
|
RegX r7 ("engine\\.$");
|
||||||
|
ut.ok (r7.match (text), "engine\\.$ matches");
|
||||||
|
|
||||||
std::vector <std::string> results;
|
std::vector <std::string> results;
|
||||||
std::vector <int> start;
|
std::vector <int> start;
|
||||||
std::vector <int> end;
|
std::vector <int> end;
|
||||||
ut.ok (regexMatch (results, text, "(e..)", true), "(e..) there are matches");
|
RegX r8 ("(e..)", true);
|
||||||
ut.ok (regexMatch (start, end, text, "(e..)", true), "(e..) there are matches");
|
ut.ok (r8.match (results, text), "(e..) there are matches");
|
||||||
|
ut.ok (r8.match (start, end, text), "(e..) there are matches");
|
||||||
ut.is (results.size (), (size_t) 1, "(e..) == 1 match");
|
ut.is (results.size (), (size_t) 1, "(e..) == 1 match");
|
||||||
ut.is (results[0], "est", "(e..)[0] == 'est'");
|
ut.is (results[0], "est", "(e..)[0] == 'est'");
|
||||||
ut.is (start[0], 11, "(e..)[0] == 11->");
|
ut.is (start[0], 11, "(e..)[0] == 11->");
|
||||||
|
|
137
test/seq.t.cpp
137
test/seq.t.cpp
|
@ -1,137 +0,0 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// taskwarrior - a command line task list manager.
|
|
||||||
//
|
|
||||||
// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or modify it under
|
|
||||||
// the terms of the GNU General Public License as published by the Free Software
|
|
||||||
// Foundation; either version 2 of the License, or (at your option) any later
|
|
||||||
// version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
// details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License along with
|
|
||||||
// this program; if not, write to the
|
|
||||||
//
|
|
||||||
// Free Software Foundation, Inc.,
|
|
||||||
// 51 Franklin Street, Fifth Floor,
|
|
||||||
// Boston, MA
|
|
||||||
// 02110-1301
|
|
||||||
// USA
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <iostream>
|
|
||||||
#include <Context.h>
|
|
||||||
#include <Sequence.h>
|
|
||||||
#include <test.h>
|
|
||||||
|
|
||||||
Context context;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Sequence parseSequence (const std::string& input)
|
|
||||||
{
|
|
||||||
try { Sequence s (input); return s; }
|
|
||||||
catch (...) {}
|
|
||||||
return Sequence ();
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char** argv)
|
|
||||||
{
|
|
||||||
UnitTest t (30);
|
|
||||||
|
|
||||||
// Test for validity.
|
|
||||||
Sequence seq;
|
|
||||||
t.notok (seq.valid ("1--2"), "not valid 1--2");
|
|
||||||
t.notok (seq.valid ("1-2-3"), "not valid 1-2-3");
|
|
||||||
t.notok (seq.valid ("-1-2"), "not valid -1-2");
|
|
||||||
t.notok (seq.valid ("1-two"), "not valid 1-two");
|
|
||||||
t.notok (seq.valid ("one-2"), "not valid one-2");
|
|
||||||
|
|
||||||
t.ok (seq.valid ("1"), "valid 1");
|
|
||||||
t.ok (seq.valid ("1,3"), "valid 1,3");
|
|
||||||
t.ok (seq.valid ("3,1"), "valid 3,1");
|
|
||||||
t.ok (seq.valid ("1,3-5,7"), "valid 1,3-5,7");
|
|
||||||
t.ok (seq.valid ("1-1000"), "valid 1-1000");
|
|
||||||
t.ok (seq.valid ("1-1001"), "valid 1-1001");
|
|
||||||
t.ok (seq.valid ("1-5,3-7"), "valid 1-5,3-7");
|
|
||||||
|
|
||||||
// 1
|
|
||||||
seq = parseSequence ("1");
|
|
||||||
t.is (seq.size (), (size_t)1, "seq '1' -> 1 item");
|
|
||||||
if (seq.size () == 1)
|
|
||||||
{
|
|
||||||
t.is (seq[0], 1, "seq '1' -> [0] == 1");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
t.fail ("seq '1' -> [0] == 1");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1,3
|
|
||||||
seq = parseSequence ("1,3");
|
|
||||||
t.is (seq.size (), (size_t)2, "seq '1,3' -> 2 items");
|
|
||||||
if (seq.size () == 2)
|
|
||||||
{
|
|
||||||
t.is (seq[0], 1, "seq '1,3' -> [0] == 1");
|
|
||||||
t.is (seq[1], 3, "seq '1,3' -> [1] == 3");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
t.fail ("seq '1,3' -> [0] == 1");
|
|
||||||
t.fail ("seq '1,3' -> [1] == 3");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1,3-5,7
|
|
||||||
seq = parseSequence ("1,3-5,7");
|
|
||||||
t.is (seq.size (), (size_t)5, "seq '1,3-5,7' -> 5 items");
|
|
||||||
if (seq.size () == 5)
|
|
||||||
{
|
|
||||||
t.is (seq[0], 1, "seq '1,3-5,7' -> [0] == 1");
|
|
||||||
t.is (seq[1], 3, "seq '1,3-5,7' -> [1] == 3");
|
|
||||||
t.is (seq[2], 4, "seq '1,3-5,7' -> [2] == 4");
|
|
||||||
t.is (seq[3], 5, "seq '1,3-5,7' -> [3] == 5");
|
|
||||||
t.is (seq[4], 7, "seq '1,3-5,7' -> [4] == 7");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
t.fail ("seq '1,3-5,7' -> [0] == 1");
|
|
||||||
t.fail ("seq '1,3-5,7' -> [1] == 3");
|
|
||||||
t.fail ("seq '1,3-5,7' -> [2] == 4");
|
|
||||||
t.fail ("seq '1,3-5,7' -> [3] == 5");
|
|
||||||
t.fail ("seq '1,3-5,7' -> [4] == 7");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1--2
|
|
||||||
seq = parseSequence ("1--2");
|
|
||||||
t.is (seq.size (), (size_t)0, "seq '1--2' -> 0 items (error)");
|
|
||||||
|
|
||||||
// 1-1000 (SEQUENCE_MAX);
|
|
||||||
seq = parseSequence ("1-1000");
|
|
||||||
t.is (seq.size (), (size_t)1000, "seq '1-1000' -> 1000 items");
|
|
||||||
if (seq.size () == 1000)
|
|
||||||
{
|
|
||||||
t.is (seq[0], 1, "seq '1-1000' -> [0] == 1");
|
|
||||||
t.is (seq[1], 2, "seq '1-1000' -> [1] == 3");
|
|
||||||
t.is (seq[998], 999, "seq '1-1000' -> [998] == 999");
|
|
||||||
t.is (seq[999], 1000, "seq '1-1000' -> [999] == 1000");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
t.fail ("seq '1-1000' -> [0] == 1");
|
|
||||||
t.fail ("seq '1-1000' -> [1] == 2");
|
|
||||||
t.fail ("seq '1-1000' -> [998] == 999");
|
|
||||||
t.fail ("seq '1-1000' -> [999] == 1000");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1-1001
|
|
||||||
seq = parseSequence ("1-1001");
|
|
||||||
t.is (seq.size (), (size_t)0, "seq '1-1001' -> 0 items (error)");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
|
@ -38,9 +38,8 @@ void get (std::vector <Task>& pending, std::vector <Task>& completed)
|
||||||
TDB tdb;
|
TDB tdb;
|
||||||
tdb.location (".");
|
tdb.location (".");
|
||||||
tdb.lock ();
|
tdb.lock ();
|
||||||
Filter filter;
|
tdb.loadPending (pending);
|
||||||
tdb.loadPending (pending, filter);
|
tdb.loadCompleted (completed);
|
||||||
tdb.loadCompleted (completed, filter);
|
|
||||||
tdb.unlock ();
|
tdb.unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +59,6 @@ int main (int argc, char** argv)
|
||||||
context.config.set ("gc", "on");
|
context.config.set ("gc", "on");
|
||||||
|
|
||||||
// Try reading an empty database.
|
// Try reading an empty database.
|
||||||
Filter filter;
|
|
||||||
std::vector <Task> all;
|
std::vector <Task> all;
|
||||||
std::vector <Task> pending;
|
std::vector <Task> pending;
|
||||||
std::vector <Task> completed;
|
std::vector <Task> completed;
|
||||||
|
@ -100,7 +98,7 @@ int main (int argc, char** argv)
|
||||||
completed.clear ();
|
completed.clear ();
|
||||||
|
|
||||||
tdb.lock ();
|
tdb.lock ();
|
||||||
tdb.load (all, filter);
|
tdb.load (all);
|
||||||
all[0].set ("name", "value2");
|
all[0].set ("name", "value2");
|
||||||
tdb.update (all[0]); // P1 C0 N0 M1
|
tdb.update (all[0]); // P1 C0 N0 M1
|
||||||
tdb.commit (); // P1 C0 N0 M0
|
tdb.commit (); // P1 C0 N0 M0
|
||||||
|
@ -118,7 +116,7 @@ int main (int argc, char** argv)
|
||||||
all.clear ();
|
all.clear ();
|
||||||
|
|
||||||
tdb.lock ();
|
tdb.lock ();
|
||||||
tdb.loadPending (all, filter);
|
tdb.loadPending (all);
|
||||||
all[0].setStatus (Task::completed);
|
all[0].setStatus (Task::completed);
|
||||||
tdb.update (all[0]); // P1 C0 N0 M1
|
tdb.update (all[0]); // P1 C0 N0 M1
|
||||||
Task t2 ("[foo:\"bar\" status:\"pending\"]");
|
Task t2 ("[foo:\"bar\" status:\"pending\"]");
|
||||||
|
|
|
@ -38,9 +38,8 @@ void get (std::vector <Task>& pending, std::vector <Task>& completed)
|
||||||
TDB tdb;
|
TDB tdb;
|
||||||
tdb.location (".");
|
tdb.location (".");
|
||||||
tdb.lock ();
|
tdb.lock ();
|
||||||
Filter filter;
|
tdb.loadPending (pending);
|
||||||
tdb.loadPending (pending, filter);
|
tdb.loadCompleted (completed);
|
||||||
tdb.loadCompleted (completed, filter);
|
|
||||||
tdb.unlock ();
|
tdb.unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ int main (int argc, char** argv)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
Variant v = Variant (1) + Variant (2);
|
Variant v = Variant (1) + Variant (2);
|
||||||
t.ok (v.type () == Variant::v_integer, "1 + 2 --> integer");
|
t.ok (v.type () == Variant::v_integer, "1 + 2 --> integer");
|
||||||
t.ok (v.format () == "3", "1 + 2 --> 3");
|
t.ok (v.format () == "3", "1 + 2 --> 3");
|
||||||
|
@ -49,6 +50,7 @@ int main (int argc, char** argv)
|
||||||
v = Variant (1.2) + Variant (2);
|
v = Variant (1.2) + Variant (2);
|
||||||
t.ok (v.type () == Variant::v_double, "1.2 + 2 --> double");
|
t.ok (v.type () == Variant::v_double, "1.2 + 2 --> double");
|
||||||
t.ok (v.format () == "3.2", "1.2 + 2 --> 3.2");
|
t.ok (v.format () == "3.2", "1.2 + 2 --> 3.2");
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (std::string& e)
|
catch (std::string& e)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue