diff --git a/src/.gitignore b/src/.gitignore index 1e4ffeb31..e0ef118ca 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,2 +1,3 @@ *.o Makefile.in +*_test diff --git a/src/Makefile.am b/src/Makefile.am index d014105ab..4ad43461f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,11 +6,11 @@ task_SOURCES = API.cpp Att.cpp Cmd.cpp Color.cpp Config.cpp Context.cpp \ Path.cpp Permission.cpp Record.cpp Sequence.cpp \ StringTable.cpp Subst.cpp TDB.cpp Table.cpp Task.cpp Timer.cpp \ command.cpp custom.cpp edit.cpp export.cpp import.cpp \ - interactive.cpp main.cpp recur.cpp report.cpp rules.cpp \ + interactive.cpp main.cpp recur.cpp report.cpp rules.cpp rx.cpp \ text.cpp util.cpp API.h Att.h Cmd.h Color.h Config.h Context.h \ Date.h Directory.h Duration.h File.h Filter.h Grid.h Hooks.h \ Keymap.h Location.h Nibbler.h Path.h Permission.h Record.h \ Sequence.h StringTable.h Subst.h TDB.h Table.h Task.h Timer.h \ - i18n.h main.h text.h util.h + i18n.h main.h text.h util.h rx.h task_CPPFLAGS=$(LUA_CFLAGS) task_LDFLAGS=$(LUA_LFLAGS) diff --git a/src/rx.cpp b/src/rx.cpp new file mode 100644 index 000000000..f7dc13e3c --- /dev/null +++ b/src/rx.cpp @@ -0,0 +1,135 @@ +//////////////////////////////////////////////////////////////////////////////// +// task - a command line task list manager. +// +// Copyright 2010, 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 "regex.h" +#include "rx.h" + +//#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& 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 & start, + std::vector & 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; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/rx.h b/src/rx.h new file mode 100644 index 000000000..a0a271f36 --- /dev/null +++ b/src/rx.h @@ -0,0 +1,39 @@ +//////////////////////////////////////////////////////////////////////////////// +// task - a command line task list manager. +// +// Copyright 2010, 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 +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_RX +#define INCLuDED_RX + +#include +#include + +bool regexMatch (const std::string&, const std::string&, bool caseSensitive = true); +bool regexMatch (std::vector&, const std::string&, const std::string&, bool caseSensitive = true); +bool regexMatch (std::vector&, std::vector&, const std::string&, const std::string&, bool caseSensitive = true); + +#endif + diff --git a/src/tests/.gitignore b/src/tests/.gitignore index 6eb059732..95b8b0660 100644 --- a/src/tests/.gitignore +++ b/src/tests/.gitignore @@ -21,4 +21,5 @@ path.t file.t directory.t grid.t +rx.t *.log diff --git a/src/tests/Makefile b/src/tests/Makefile index f93191ec4..3a3b801c6 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -1,6 +1,6 @@ PROJECT = t.t tdb.t date.t duration.t t.benchmark.t text.t autocomplete.t \ config.t seq.t att.t stringtable.t record.t nibbler.t subst.t filt.t \ - cmd.t util.t color.t list.t path.t file.t directory.t grid.t + cmd.t util.t color.t list.t path.t file.t directory.t grid.t rx.t CFLAGS = -I. -I.. -I../.. -Wall -pedantic -ggdb3 -fno-rtti LFLAGS = -L/usr/local/lib -lncurses -llua OBJECTS = ../t-TDB.o ../t-Task.o ../t-text.o ../t-Date.o ../t-Table.o \ @@ -11,7 +11,7 @@ OBJECTS = ../t-TDB.o ../t-Task.o ../t-text.o ../t-Date.o ../t-Table.o \ ../t-Grid.o ../t-Color.o ../t-rules.o ../t-recur.o ../t-custom.o \ ../t-export.o ../t-import.o ../t-edit.o ../t-Timer.o \ ../t-Permission.o ../t-Path.o ../t-File.o ../t-Directory.o \ - ../t-Hooks.o ../t-API.o + ../t-Hooks.o ../t-API.o ../t-rx.o all: $(PROJECT) @@ -96,3 +96,6 @@ directory.t: directory.t.o $(OBJECTS) test.o grid.t: grid.t.o $(OBJECTS) test.o g++ grid.t.o $(OBJECTS) test.o $(LFLAGS) -o grid.t +rx.t: rx.t.o $(OBJECTS) test.o + g++ rx.t.o $(OBJECTS) test.o $(LFLAGS) -o rx.t + diff --git a/src/tests/rx.t.cpp b/src/tests/rx.t.cpp new file mode 100644 index 000000000..7b17ddfa8 --- /dev/null +++ b/src/tests/rx.t.cpp @@ -0,0 +1,72 @@ +//////////////////////////////////////////////////////////////////////////////// +// Tegelsten - building blocks for UI +// +// Copyright 2010, 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 +#include +#include + +Context context; + +int main (int argc, char** argv) +{ + UnitTest ut (15); + + std::string text = "This is a test."; + + ut.ok (regexMatch (text, "i. ", true), text + " =~ /i. /"); + + std::vector matches; + ut.ok (regexMatch (matches, text, "(i.) ", false), text + " =~ /(i.) /"); + ut.ok (matches.size () == 1, "1 match"); + ut.is (matches[0], "is", "$1 == is"); + + text = "abcdefghijklmnopqrstuvwxyz"; + + ut.ok (regexMatch (text, "t..", true), "t.."); + ut.ok (regexMatch (text, "T..", false), "T.."); + ut.ok (!regexMatch (text, "T..", true), "! T.."); + + text = "this is a test of the regex engine."; + // |...:....|....:....|....:....|....: + + ut.ok (regexMatch (text, "^this"), "^this matches"); + ut.ok (regexMatch (text, "engine\\.$"), "engine\\.$ matches"); + + std::vector results; + std::vector start; + std::vector end; + ut.ok (regexMatch (results, text, "(e..)", true), "(e..) there are matches"); + ut.ok (regexMatch (start, end, text, "(e..)", true), "(e..) there are matches"); + ut.is (results.size (), (size_t) 1, "(e..) == 1 match"); + ut.is (results[0], "est", "(e..)[0] == 'est'"); + ut.is (start[0], 11, "(e..)[0] == 11->"); + ut.is (end[0], 14, "(e..)[0] == ->14"); + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +