Lars, I'd value some help.
Attached is a small test code for the boost regex code.
Whilst the first test, taken from the boost documentation, works:
// using this RE, regex_match will return true if the tested string
// has the form "1234 2345 3456 4567"
boost::regex const e("(\\d{4}[- ]){3}\\d{4}");
// A valid credit card entry
string const credit_card = "1234 5626 3956 2655";
// An invalid one
string const not_credit_card = "12345626 3956 2655";
boost::regex_match(credit_card, e) -> true
boost::regex_match(not_credit_card, e) -> false
I'm unable to devise any RE that makes sense to me for the second test,
however, where I enter an RE from the command line. Eg
$ gdb ./trial
(gdb) r
...
The grand old duke of York
He had ten thousand men
He marched them up to the top of the hill
And he marched them down again
And when they were up they were up
And when they were down they were down
And when they were only half way up
They were neither up nor down
Regex search pattern: ^And
Searching for "^And"
Not found!
Program exited normally.
(gdb)
Looks like a perfectly valid RE to me that should find "And he marched...".
I'm also unhappy about the fact that the documentation says that invalid REs
always throw an exception when they are created, yet I cannot find a function
to test whether the pattern is valid or not. Ie, I'm forced to use a try
block if the user is inputting the RE from the command line.
Moreover, the test does not seem to work. Eg
$ gdb ./trial
(gdb) r
...
Regex search pattern: {p[p
Searching for "{p[p"
Program received signal SIGFPE, Arithmetic exception.
0x3ff80197610 in _OtsRemainder64Unsigned () from /usr/shlib/libc.so
(gdb) where
#0 0x3ff80197610 in _OtsRemainder64Unsigned () from /usr/shlib/libc.so
Ie, the try block is superfluos. There's no problem creating the
boost::regex. although it doesn't look very valid to me...
It would appear therefore that boost::regex isn't "Angus-friendly". If we use
it in the citation dialog then we can definitely crash lyx without any
problems at all.
Any ideas on how to proceed?
Angus
#include <boost/regex.hpp>
#include <algorithm>
#include <ostream>
#include <string>
using std::string;
// A functor for use with std::find_if, used to ascertain whether a
// data entry contains the required word_
struct SimpleMatch
{
SimpleMatch(string const & word) : word_(word) {}
bool operator()(string const & data) {
return data.find(word_) != string::npos;
}
private:
string const word_;
};
// A functor for use with std::find_if, used to ascertain whether a
// data entry matches the required regex_
struct RegexMatch
{
RegexMatch(boost::regex const & regex) : regex_(regex) {}
bool operator()(string const & data) {
return boost::regex_match(data, regex_);
}
private:
boost::regex const regex_;
};
void simpleSearch(char const * const * data, size_t size)
{
string pattern;
std::cout << "\nSimple search pattern: ";
std::cin >> pattern;
std::cout << "Searching for \"" << pattern << "\"" << std::endl;
char const * const * it = data;
char const * const * const end = data + size;
it = std::find_if(it, end, SimpleMatch(pattern));
if (it == end)
std::cout << "Not found!" << std::endl;
else
std::cout << "Found it\n" << *it << std::endl;
}
void regexSearch(char const * const * data, size_t size)
{
string pattern;
std::cout << "\nRegex search pattern: ";
std::cin >> pattern;
std::cout << "Searching for \"" << pattern << "\"" << std::endl;
char const * const * it = data;
char const * const * const end = data + size;
try {
it = std::find_if(it, end, RegexMatch(boost::regex(pattern)));
if (it == end)
std::cout << "Not found!" << std::endl;
else
std::cout << "Found it\n" << *it << std::endl;
}
catch (boost::bad_expression * e) {
std::cerr << "\"" << e->what() << "\" is an invalid R.E."
<< std::endl;
}
catch(...) {
std::cerr << "Caught unknown exception" << std::endl;
}
}
int main()
{
// An example from the boost documentaion --- works fine
// using this RE, regex_match will return true if the tested string
// has the form "1234 2345 3456 4567"
boost::regex const e("(\\d{4}[- ]){3}\\d{4}");
// A valid credit card entry
string const credit_card = "1234 5626 3956 2655";
// An invalid one
string const not_credit_card = "12345626 3956 2655";
std::cout << "Is \"" << credit_card << "\" a credit card number? "
<< (regex_match(credit_card, e) ? "yes" : "no")
<< "\nWhat about \"" << not_credit_card << "\"? "
<< (regex_match(not_credit_card, e) ? "yes" : "no")
<< "\n\n" << std::endl;
char const * const c_data[] = {
"The grand old duke of York",
"He had ten thousand men",
"He marched them up to the top of the hill",
"And he marched them down again",
"And when they were up they were up",
"And when they were down they were down",
"And when they were only half way up",
"They were neither up nor down"
};
size_t const c_size = sizeof(c_data) / sizeof(char *);
std::copy(c_data, c_data + c_size,
std::ostream_iterator<char const *>(std::cout, "\n"));
std::cout << std::endl;
// this one works fine
simpleSearch(c_data, c_size);
regexSearch(c_data, c_size);
return 0;
}