reworked regex directory structure to match boost requirements.

[SVN r9752]
This commit is contained in:
John Maddock
2001-04-10 11:44:47 +00:00
parent dcb64d5db7
commit ed21a5183b
69 changed files with 155 additions and 111 deletions

50
example/jgrep/bc55.mak Normal file
View File

@ -0,0 +1,50 @@
# very basic makefile for jgrep.exe
#
# Borland C++ tools
#
# BCROOT defines the root directory of your bc builder install
#
!ifndef BCROOT
BCROOT=$(MAKEDIR)\..
!endif
BCC32 = $(BCROOT)\bin\Bcc32.exe
LIBPATH=..\..\build\bcb5
IDE_LinkFLAGS32 = -L$(BCROOT)\LIB
LINKOPTS= -ap -Tpe -x
COMPOPTS= -O2 -tWM- -DSTRICT; -I$(BCROOT)\include;../../../../; -D_NO_VCL
jgrep.exe : jgrep.obj main.obj
$(BCC32) $(COMPOPTS) -e$@ -L$(LIBPATH) main.obj jgrep.obj
jgrep.obj : jgrep.cpp
$(BCC32) -c @&&|
$(COMPOPTS) -o$@ jgrep.cpp
|
main.obj : main.cpp
$(BCC32) -c @&&|
$(COMPOPTS) -o$@ main.cpp
|

50
example/jgrep/bcb4.mak Normal file
View File

@ -0,0 +1,50 @@
# very basic makefile for jgrep.exe
#
# Borland C++ tools
#
# BCROOT defines the root directory of your bc builder install
#
!ifndef BCROOT
BCROOT=$(MAKEDIR)\..
!endif
BCC32 = $(BCROOT)\bin\Bcc32.exe
LIBPATH="..\..\build\bcb4"
IDE_LinkFLAGS32 = -L$(BCROOT)\LIB
LINKOPTS= -ap -Tpe -x
COMPOPTS= -O2 -tWM- -DSTRICT; -I$(BCROOT)\include;../../../../; -D_NO_VCL
jgrep.exe : jgrep.obj main.obj
$(BCC32) @&&|
$(COMPOPTS) -e$@ -L$(LIBPATH) main.obj jgrep.obj
|
jgrep.obj : jgrep.cpp
$(BCC32) -c @&&|
$(COMPOPTS) -o$@ jgrep.cpp
|
main.obj : main.cpp
$(BCC32) -c @&&|
$(COMPOPTS) -o$@ main.cpp
|

49
example/jgrep/bcb5.mak Normal file
View File

@ -0,0 +1,49 @@
# very basic makefile for jgrep.exe
#
# Borland C++ tools
#
# BCROOT defines the root directory of your bc builder install
#
!ifndef BCROOT
BCROOT=$(MAKEDIR)\..
!endif
BCC32 = $(BCROOT)\bin\Bcc32.exe
LIBPATH=../../build/bcb5
IDE_LinkFLAGS32 = -L$(BCROOT)\LIB
LINKOPTS= -ap -Tpe -x
COMPOPTS= -O2 -tWM- -DSTRICT; -I$(BCROOT)\include;../../../../; -D_NO_VCL
jgrep.exe : jgrep.obj main.obj
$(BCC32) $(COMPOPTS) -e$@ -L..\..\build\bcb5 main.obj jgrep.obj
jgrep.obj : jgrep.cpp
$(BCC32) -c @&&|
$(COMPOPTS) -o$@ jgrep.cpp
|
main.obj : main.cpp
$(BCC32) -c @&&|
$(COMPOPTS) -o$@ main.cpp
|

32
example/jgrep/gcc.mak Normal file
View File

@ -0,0 +1,32 @@
# very basic makefile for jgrep
#
# GNU compiler g++
#
CXX= $(INCLUDES) -O2 -I../../../../ -I./ $(CXXFLAGS) $(LDFLAGS)
jgrep : jgrep.cpp main.cpp
g++ -ojgrep $(CXX) jgrep.cpp main.cpp -L../../build/gcc -lboost_regex $(LIBS)
debug : jgrep.cpp main.cpp
g++ -ojgrep -I../../../../ -I./ -g jgrep.cpp main.cpp -L../../build/gcc -lboost_regex_debug $(LIBS)

126
example/jgrep/jgrep.cpp Normal file
View File

@ -0,0 +1,126 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* FILE jgrep.cpp
* VERSION 3.04
*/
#include <stdio.h>
#include <boost/regex.hpp>
#ifdef JM_OLD_IOSTREAM
#include <iostream.h>
#else
#include <iostream>
using std::cout;
using std::cin;
using std::cerr;
using std::endl;
#endif
#pragma hrdstop
#include <boost/re_detail/fileiter.hpp>
#include "jgrep.h"
//
// class ogrep_predicate
// outputs the results of regex_grep to screen:
template <class iterator, class Allocator >
class ogrep_predicate
{
unsigned int& lines;
const char* filename;
unsigned int last_line;
iterator end_of_storage;
public:
ogrep_predicate(unsigned int& i, const char* p, iterator e) : lines(i), filename(p), last_line(-1), end_of_storage(e) {}
ogrep_predicate(const ogrep_predicate& o) : lines(o.lines), filename(o.filename), last_line(o.last_line), end_of_storage(o.end_of_storage) {}
bool operator () (const boost::match_results<iterator, Allocator>& i);
};
// ideally we'd ignor the allocator type and use a template member function
// to deel with the allocator type passed to regex_grep, unfortunately most
// compilers don't support this feature yet, so we'll have to be sure that
// the allocator passed to instances of this class match that used in our
// regular expression classes.
template <class iterator, class Allocator>
bool ogrep_predicate<iterator, Allocator>::operator()(const boost::match_results<iterator, Allocator>& i)
{
if(last_line == (unsigned int)-1)
cout << "File " << filename << ":" << endl;
if(last_line != i.line())
{
++lines;
last_line = i.line();
if(count_only == 0)
{
if(show_lines)
cout << i.line() << "\t";
iterator ptr = i.line_start();
while((ptr != end_of_storage) && (*ptr != '\n'))++ptr;
iterator pos = i.line_start();
while(pos != ptr)
{
cout.put(*pos);
++pos;
}
cout << endl;
}
}
return true;
}
void process_grep(const char* file)
{
using namespace boost;
mapfile f(file);
unsigned int count = 0;
ogrep_predicate<mapfile::iterator, allocator_type> oi(count, file, f.end());
if(files_only)
{
bool ok;
boost::match_results<mapfile::iterator, allocator_type> m;
ok = regex_search(f.begin(), f.end(), m, e, match_not_dot_newline | match_not_dot_null);
if(ok)
cout << "File " << file << endl;
}
else
{
regex_grep(oi, f.begin(), f.end(), e, match_not_dot_newline | match_not_dot_null);
if(count)
{
if(verbose || count_only)
{
cout << count << " lines match" << endl;
return;
}
}
else if(verbose)
{
cout << "File " << file << "(" << f.size() << "bytes):" << endl << "0 lines match" << endl;
}
}
}

53
example/jgrep/jgrep.h Normal file
View File

@ -0,0 +1,53 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* FILE jgrep.h
* VERSION 3.04
*/
#ifndef _JGREP_H
#define _JGREP_H
#include <boost/regex.hpp>
// case sensitive reg_expression determines our allocator type:
typedef boost::reg_expression<char> re_type;
typedef re_type::allocator_type allocator_type;
// now declare static (global) data, including an allocator
// instance which we'll pass to all instances that require an allocator.
extern allocator_type a;
extern re_type e;
// flags for output:
extern bool use_case;
extern bool show_lines;
extern bool count_only;
extern bool files_only;
extern bool recurse;
extern bool regularexs;
extern bool words_only;
extern bool verbose;
void process_grep(const char* file);
#endif

284
example/jgrep/main.cpp Normal file
View File

@ -0,0 +1,284 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* FILE main.cpp
* VERSION 3.04
*/
#include <stdio.h>
#include <boost/regex.hpp>
#ifdef JM_OLD_IOSTREAM
#include <iostream.h>
#else
#include <iostream>
using std::cout;
using std::cin;
using std::cerr;
using std::endl;
#endif
#pragma hrdstop
#include <boost/re_detail/fileiter.hpp>
#include "jgrep.h"
#ifndef JM_ALGO_INCLUDED
// HP and SGI STL's use <algo.h> instead
// this will have been pulled in by <jm_cfg.h>
// for std::distance
#include <algorithm>
#endif
allocator_type a;
re_type e(a);
//rei_type ei(a);
// flags for output:
bool use_case = true;
bool show_lines = false;
bool count_only = false;
bool files_only = false;
bool recurse = false;
bool regularexs = true;
bool words_only = false;
bool verbose = false;
void usage()
{
cout <<
"jgrep version 0.95\n"
"usage: jgrep [-options] expression file [files...]\n"
"\n"
"options can be one of the following:\n"
"\n"
"-c prints a count of the number of matching lines only\n"
"-d recurses through subdirectories for matching files\n"
"-i causes case to be ignored when matching\n"
"-l lists the files which contain a match only\n"
"-n displays the line numbers of matches\n"
"-r- causes the expression to be interpreted as a literal string and not\n"
" as a regular expression\n"
"-w searches for matches that are whole words only\n"
"-z verbose mode\n"
"\n"
"expression: a regular expression, or a literal string if -r- is specified\n"
"\n"
"files: one or more files to search, the names can contain the wildcard\n"
" characters ? and *\n" << endl;
}
void parse_switch(const char* flag)
{
++flag;
while(*flag)
{
switch(*flag)
{
case '-':
switch(*(flag-1))
{
case 'c':
count_only = false;
break;
case 'd':
recurse = false;
break;
case 'i':
use_case = false;
break;
case 'l':
files_only = false;
break;
case 'n':
show_lines = false;
break;
case 'r':
regularexs = false;
break;
case 'w':
words_only = false;
break;
case 'z':
verbose = false;
break;
default:
cout << "Undefined option -";
cout.put(*flag);
cout << endl;
}
// turn off prev character:
break;
case 'c':
count_only = true;
break;
case 'd':
recurse = true;
break;
case 'i':
use_case = false;
break;
case 'l':
files_only = true;
break;
case 'n':
show_lines = true;
break;
case 'r':
regularexs = true;
break;
case 'w':
words_only = true;
break;
case 'z':
verbose = true;
break;
case '?':
usage();
exit(0);
case '+':
break;
default:
cout << "Undefined option -";
cout.put(*flag);
cout << endl;
}
++flag;
}
}
void HandleFile(const char* wild)
{
using namespace boost;
jm_trace("Handling file " << wild);
file_iterator end;
file_iterator start(wild);
if(recurse)
{
// go through sub directories:
char buf[MAX_PATH];
std::strcpy(buf, start.root());
int rootlen = strlen(buf);
if(*buf == 0)
{
std::strcpy(buf, ".");
std::strcat(buf, directory_iterator::separator());
std::strcat(buf, "*");
}
else
{
std::strcat(buf, directory_iterator::separator());
std::strcat(buf, "*");
}
jm_trace("Enumerating directories: " << buf);
directory_iterator dstart(buf);
directory_iterator dend;
// now get the file mask bit of "wild":
const char* ptr = wild + rootlen;
if(*ptr) ++ptr;
jm_trace("File mask part is: " << ptr);
while(dstart != dend)
{
std::sprintf(buf, "%s%s%s", dstart.path(), directory_iterator::separator(), ptr);
HandleFile(buf);
++dstart;
}
}
std::for_each(start, end, process_grep);
}
int done = 0;
void HandleArg(const char* arg)
{
using namespace boost;
jm_trace("Handling argument: " << arg);
if(*arg == '-')
{
parse_switch(arg);
return;
}
if(done == 0)
{
// parse regular expression
if(regularexs)
{
if(words_only == 0)
{
e.set_expression(arg, use_case ? regbase::normal : regbase::normal | regbase::icase);
//ei.set_expression(arg);
}
else
{
char* buf = new char[std::strlen(arg) + 8];
std::sprintf(buf, "\\<%s\\>", arg);
e.set_expression(buf, use_case ? regbase::normal : regbase::normal | regbase::icase);
//ei.set_expression(buf);
delete[] buf;
}
}
else
{
// we need to convert text to literal:
int len2 = std::strlen(arg);
int len = len2 * 5 + 6;
char buf[8];
char* buf2 = new char[len];
*buf2 = 0;
if(words_only)
std::strcpy(buf2, "\\<");
for(int j = 0; j < len2; ++j)
{
std::sprintf(buf, "\\0%o", int(arg[j]));
std::strcat(buf2, buf);
}
if(words_only)
std::strcat(buf2, "\\>");
e.set_expression(buf2, use_case ? regbase::normal : regbase::normal | regbase::icase);
//ei.set_expression(buf2);
delete[] buf2;
}
done = 1;
return;
}
// if we get to here we have one or more file names to process:
++done;
HandleFile(arg);
}
int main(int argc, char * argv[])
{
for(int i = 1; i < argc; ++i)
HandleArg(argv[i]);
if(done < 2)
usage();
return 0;
}

42
example/jgrep/makefile.in Normal file
View File

@ -0,0 +1,42 @@
# very basic makefile for jgrep
#
CXX=@CXX@
CXXFLAGS=@CXXFLAGS@
LIBS=@LIBS@
EXE=@ac_exe_ext@
OBJ=@ac_obj_ext@
LIBDEP=../../build/libboost_regex.a ../../../../boost/re_detail/regex_options.hpp ../../../../boost/re_detail/regex_config.hpp
jgrep$(EXE) : jgrep$(OBJ) main$(OBJ)
$(CXX) -o jgrep$(EXE) jgrep$(OBJ) main$(OBJ) -L../../build -lboost_regex $(LIBS)
jgrep$(OBJ) : jgrep.cpp jgrep.h $(LIBDEP)
$(CXX) -c $(CXXFLAGS) -I../../../../ -I./ jgrep.cpp
main$(OBJ) : main.cpp jgrep.h $(LIBDEP)
$(CXX) -c $(CXXFLAGS) -I../../../../ -I./ main.cpp

View File

@ -0,0 +1,18 @@
#
# very simple makefile for Visual C++ 6 + STLPort 4
#
jgrep.exe: main.cpp jgrep.cpp jgrep.h
cl -GX -GR /Oityb1 /GF /Gy -MT -I..\..\..\..\ jgrep.cpp main.cpp /link /LIBPATH:..\..\build\vc6-stlport user32.lib

17
example/jgrep/vc6.mak Normal file
View File

@ -0,0 +1,17 @@
#
# very simple makefile for Visual C++ 6
#
jgrep.exe: main.cpp jgrep.cpp jgrep.h
cl -GX -GR /Oityb1 /GF /Gy -I..\..\..\..\ jgrep.cpp main.cpp /link /LIBPATH:..\..\build\vc6 user32.lib

View File

@ -0,0 +1,69 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE credit_card_example.cpp
* VERSION 3.00
* DESCRIPTION: Credit card number formatting code.
*/
#include <string>
#include <boost/regex.hpp>
bool validate_card_format(const std::string& s)
{
static const boost::regex e("(\\d{4}[- ]){3}\\d{4}");
return boost::regex_match(s, e);
}
const boost::regex e("\\A(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})\\z");
const std::string machine_format("\\1\\2\\3\\4");
const std::string human_format("\\1-\\2-\\3-\\4");
std::string machine_readable_card_number(const std::string& s)
{
return boost::regex_merge(s, e, machine_format, boost::match_default | boost::format_sed);
}
std::string human_readable_card_number(const std::string& s)
{
return boost::regex_merge(s, e, human_format, boost::match_default | boost::format_sed);
}
#include <iostream>
using namespace std;
int main()
{
string s[4] = { "0000111122223333", "0000 1111 2222 3333",
"0000-1111-2222-3333", "000-1111-2222-3333", };
int i;
for(i = 0; i < 4; ++i)
{
cout << "validate_card_format(\"" << s[i] << "\") returned " << validate_card_format(s[i]) << endl;
}
for(i = 0; i < 4; ++i)
{
cout << "machine_readable_card_number(\"" << s[i] << "\") returned " << machine_readable_card_number(s[i]) << endl;
}
for(i = 0; i < 4; ++i)
{
cout << "human_readable_card_number(\"" << s[i] << "\") returned " << human_readable_card_number(s[i]) << endl;
}
return 0;
}

View File

@ -0,0 +1,82 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <boost/regex.hpp>
// match some kind of html tag:
boost::regex e("<[^>]*>");
// count how many:
unsigned int tags = 0;
// saved position of partial match:
char* next_pos = 0;
bool grep_callback(const boost::match_results<char*>& m)
{
if(m[0].matched == false)
{
// save position and return:
next_pos = m[0].first;
}
else
++tags;
return true;
}
void search(std::istream& is)
{
char buf[4096];
next_pos = buf + sizeof(buf);
bool have_more = true;
while(have_more)
{
// how much do we copy forward from last try:
unsigned leftover = (buf + sizeof(buf)) - next_pos;
// and how much is left to fill:
unsigned size = next_pos - buf;
// copy forward whatever we have left:
memcpy(buf, next_pos, leftover);
// fill the rest from the stream:
unsigned read = is.readsome(buf + leftover, size);
// check to see if we've run out of text:
have_more = read == size;
// reset next_pos:
next_pos = buf + sizeof(buf);
// and then grep:
boost::regex_grep(grep_callback,
buf,
buf + read + leftover,
e,
boost::match_default | boost::match_partial);
}
}
int main(int argc, char* argv[])
{
if(argc > 1)
{
for(unsigned int i = 1; i < argc; ++i)
{
std::ifstream fs(argv[i]);
if(fs.bad()) continue;
search(fs);
}
}
else
{
std::string one("<META NAME=\"keywords\" CONTENT=\"regex++, regular expressions, regular expression library, C++\">");
std::string what;
while(what.size() < 10000)
{
what.append(one);
what.append(13, ' ');
}
std::stringstream ss;
ss.str(what);
search(ss);
}
std::cout << "total tag count was " << tags << std::endl;
return 0;
}

View File

@ -0,0 +1,46 @@
#include <string>
#include <iostream>
#include <boost/regex.hpp>
boost::regex e("(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})");
bool is_possible_card_number(const std::string& input)
{
//
// return false for partial match, true for full match, or throw for
// impossible match based on what we have so far...
boost::match_results<std::string::const_iterator> what;
if(0 == boost::regex_match(input, what, e, boost::match_default | boost::match_partial))
{
// the input so far could not possibly be valid so reject it:
throw std::runtime_error("Invalid data entered - this could not possibly be a valid card number");
}
// OK so far so good, but have we finished?
if(what[0].matched)
{
// excellent, we have a result:
return true;
}
// what we have so far is only a partial match...
return false;
}
int main(int argc, char* argv[])
{
try{
std::string input;
std::cin >> input;
if(is_possible_card_number(input))
{
std::cout << "Matched OK..." << std::endl;
}
else
std::cout << "Got a partial match..." << std::endl;
}
catch(const std::exception& e)
{
std::cout << e.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,107 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_grep_example_1.cpp
* VERSION 3.00
* DESCRIPTION: regex_grep example 1: searches a cpp file for class definitions.
*/
#include <string>
#include <map>
#include <boost/regex.hpp>
// purpose:
// takes the contents of a file in the form of a string
// and searches for all the C++ class definitions, storing
// their locations in a map of strings/int's
typedef std::map<std::string, int, std::less<std::string> > map_type;
boost::regex expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>)?[[:space:]]*(\\{|:[^;\\{()]*\\{)");
class IndexClassesPred
{
map_type& m;
std::string::const_iterator base;
public:
IndexClassesPred(map_type& a, std::string::const_iterator b) : m(a), base(b) {}
bool operator()(const boost::match_results<std::string::const_iterator, boost::regex::allocator_type>& what)
{
// what[0] contains the whole string
// what[5] contains the class name.
// what[6] contains the template specialisation if any.
// add class name and position to map:
m[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
what[5].first - base;
return true;
}
};
void IndexClasses(map_type& m, const std::string& file)
{
std::string::const_iterator start, end;
start = file.begin();
end = file.end();
boost::regex_grep(IndexClassesPred(m, start), start, end, expression);
}
#include <fstream>
#include <iostream>
using namespace std;
void load_file(std::string& s, std::istream& is)
{
s.erase();
s.reserve(is.rdbuf()->in_avail());
char c;
while(is.get(c))
{
if(s.capacity() == s.size())
s.reserve(s.capacity() * 3);
s.append(1, c);
}
}
int main(int argc, const char** argv)
{
std::string text;
for(int i = 1; i < argc; ++i)
{
cout << "Processing file " << argv[i] << endl;
map_type m;
std::ifstream fs(argv[i]);
load_file(text, fs);
IndexClasses(m, text);
cout << m.size() << " matches found" << endl;
map_type::iterator c, d;
c = m.begin();
d = m.end();
while(c != d)
{
cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl;
++c;
}
}
return 0;
}

View File

@ -0,0 +1,99 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_grep_example_2.cpp
* VERSION 3.00
* DESCRIPTION: regex_grep example 2: searches a cpp file for class definitions,
* using a global callback function.
*/
#include <string>
#include <map>
#include <boost/regex.hpp>
// purpose:
// takes the contents of a file in the form of a string
// and searches for all the C++ class definitions, storing
// their locations in a map of strings/int's
typedef std::map<std::string, int, std::less<std::string> > map_type;
boost::regex expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>)?[[:space:]]*(\\{|:[^;\\{()]*\\{)");
map_type class_index;
std::string::const_iterator base;
bool grep_callback(const boost::match_results<std::string::const_iterator, boost::regex::allocator_type>& what)
{
// what[0] contains the whole string
// what[5] contains the class name.
// what[6] contains the template specialisation if any.
// add class name and position to map:
class_index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
what[5].first - base;
return true;
}
void IndexClasses(const std::string& file)
{
std::string::const_iterator start, end;
start = file.begin();
end = file.end();
base = start;
boost::regex_grep(grep_callback, start, end, expression);
}
#include <fstream>
#include <iostream>
using namespace std;
void load_file(std::string& s, std::istream& is)
{
s.erase();
s.reserve(is.rdbuf()->in_avail());
char c;
while(is.get(c))
{
if(s.capacity() == s.size())
s.reserve(s.capacity() * 3);
s.append(1, c);
}
}
int main(int argc, const char** argv)
{
std::string text;
for(int i = 1; i < argc; ++i)
{
cout << "Processing file " << argv[i] << endl;
std::ifstream fs(argv[i]);
load_file(text, fs);
IndexClasses(text);
cout << class_index.size() << " matches found" << endl;
map_type::iterator c, d;
c = class_index.begin();
d = class_index.end();
while(c != d)
{
cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl;
++c;
}
class_index.erase(class_index.begin(), class_index.end());
}
return 0;
}

View File

@ -0,0 +1,118 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_grep_example_3.cpp
* VERSION 3.00
* DESCRIPTION: regex_grep example 3: searches a cpp file for class definitions,
* using a bound member function callback.
*/
#include <string>
#include <map>
#include <boost/regex.hpp>
#include <functional>
// purpose:
// takes the contents of a file in the form of a string
// and searches for all the C++ class definitions, storing
// their locations in a map of strings/int's
typedef std::map<std::string, int, std::less<std::string> > map_type;
class class_index
{
boost::regex expression;
map_type index;
std::string::const_iterator base;
bool grep_callback(boost::match_results<std::string::const_iterator, boost::regex::allocator_type> what);
public:
map_type& get_map() { return index; }
void IndexClasses(const std::string& file);
class_index()
: index(),
expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>)?[[:space:]]*(\\{|:[^;\\{()]*\\{)")
{}
};
bool class_index::grep_callback(boost::match_results<std::string::const_iterator, boost::regex::allocator_type> what)
{
// what[0] contains the whole string
// what[5] contains the class name.
// what[6] contains the template specialisation if any.
// add class name and position to map:
index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
what[5].first - base;
return true;
}
void class_index::IndexClasses(const std::string& file)
{
std::string::const_iterator start, end;
start = file.begin();
end = file.end();
base = start;
boost::regex_grep(std::bind1st(std::mem_fun(&class_index::grep_callback), this),
start,
end,
expression);
}
#include <fstream>
#include <iostream>
using namespace std;
void load_file(std::string& s, std::istream& is)
{
s.erase();
s.reserve(is.rdbuf()->in_avail());
char c;
while(is.get(c))
{
if(s.capacity() == s.size())
s.reserve(s.capacity() * 3);
s.append(1, c);
}
}
int main(int argc, const char** argv)
{
std::string text;
for(int i = 1; i < argc; ++i)
{
cout << "Processing file " << argv[i] << endl;
std::ifstream fs(argv[i]);
load_file(text, fs);
class_index i;
i.IndexClasses(text);
cout << i.get_map().size() << " matches found" << endl;
map_type::iterator c, d;
c = i.get_map().begin();
d = i.get_map().end();
while(c != d)
{
cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl;
++c;
}
}
return 0;
}

View File

@ -0,0 +1,121 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_grep_example_4.cpp
* VERSION 3.00
* DESCRIPTION: regex_grep example 4: searches a cpp file for class definitions,
* using a C++ Builder closure as a callback.
*/
#include <string>
#include <map>
#include <boost/regex.hpp>
#include <functional>
// purpose:
// takes the contents of a file in the form of a string
// and searches for all the C++ class definitions, storing
// their locations in a map of strings/int's
typedef std::map<std::string, int, std::less<std::string> > map_type;
class class_index
{
boost::regex expression;
map_type index;
std::string::const_iterator base;
typedef boost::match_results<std::string::const_iterator, boost::regex::allocator_type> arg_type;
bool grep_callback(const boost::match_results<std::string::const_iterator, boost::regex::allocator_type>& what);
public:
map_type& get_map() { return index; }
typedef bool (__closure* grep_callback_type)(const arg_type&);
void IndexClasses(const std::string& file);
class_index()
: index(),
expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>)?[[:space:]]*(\\{|:[^;\\{()]*\\{)")
{}
};
bool class_index::grep_callback(const boost::match_results<std::string::const_iterator, boost::regex::allocator_type>& what)
{
// what[0] contains the whole string
// what[5] contains the class name.
// what[6] contains the template specialisation if any.
// add class name and position to map:
index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
what[5].first - base;
return true;
}
void class_index::IndexClasses(const std::string& file)
{
std::string::const_iterator start, end;
start = file.begin();
end = file.end();
base = start;
class_index::grep_callback_type cl = &(this->grep_callback);
boost::regex_grep(cl,
start,
end,
expression);
}
#include <fstream>
#include <iostream>
using namespace std;
void load_file(std::string& s, std::istream& is)
{
s.erase();
s.reserve(is.rdbuf()->in_avail());
char c;
while(is.get(c))
{
if(s.capacity() == s.size())
s.reserve(s.capacity() * 3);
s.append(1, c);
}
}
int main(int argc, const char** argv)
{
std::string text;
for(int i = 1; i < argc; ++i)
{
cout << "Processing file " << argv[i] << endl;
std::ifstream fs(argv[i]);
load_file(text, fs);
class_index i;
i.IndexClasses(text);
cout << i.get_map().size() << " matches found" << endl;
map_type::iterator c, d;
c = i.get_map().begin();
d = i.get_map().end();
while(c != d)
{
cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl;
++c;
}
}
return 0;
}

View File

@ -0,0 +1,100 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_match_example.cpp
* VERSION 3.00
* DESCRIPTION: ftp based regex_match example.
*/
#include <cstdlib>
#include <boost/regex.hpp>
#include <string>
#include <iostream>
using namespace std;
using namespace boost;
regex expression("^([0-9]+)(\\-| |$)(.*)$");
// process_ftp:
// on success returns the ftp response code, and fills
// msg with the ftp response message.
int process_ftp(const char* response, std::string* msg)
{
cmatch what;
if(regex_match(response, what, expression))
{
// what[0] contains the whole string
// what[1] contains the response code
// what[2] contains the separator character
// what[3] contains the text message.
if(msg)
msg->assign(what[3].first, what[3].second);
return atoi(what[1].first);
}
// failure did not match
if(msg)
msg->erase();
return -1;
}
#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && (__BORLANDC__ == 0x550))
//
// problem with std::getline under MSVC6sp3
istream& getline(istream& is, std::string& s)
{
s.erase();
char c = is.get();
while(c != '\n')
{
s.append(1, c);
c = is.get();
}
return is;
}
#endif
int main()
{
std::string in, out;
while(true)
{
cout << "enter test string" << endl;
getline(cin, in);
if(in == "quit")
break;
int result;
result = process_ftp(in.c_str(), &out);
if(result != -1)
{
cout << "Match found:" << endl;
cout << "Response code: " << result << endl;
cout << "Message text: " << out << endl;
}
else
{
cout << "Match not found" << endl;
}
cout << endl;
}
return 0;
}

View File

@ -0,0 +1,131 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_merge_example.cpp
* VERSION 3.00
* DESCRIPTION: regex_merge example:
* converts a C++ file to syntax highlighted HTML.
*/
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iterator>
#include <boost/regex.hpp>
#include <fstream>
#include <iostream>
// purpose:
// takes the contents of a file and transform to
// syntax highlighted code in html format
boost::regex e1, e2;
extern const char* expression_text;
extern const char* format_string;
extern const char* pre_expression;
extern const char* pre_format;
extern const char* header_text;
extern const char* footer_text;
void load_file(std::string& s, std::istream& is)
{
s.erase();
s.reserve(is.rdbuf()->in_avail());
char c;
while(is.get(c))
{
if(s.capacity() == s.size())
s.reserve(s.capacity() * 3);
s.append(1, c);
}
}
int main(int argc, const char** argv)
{
e1.set_expression(expression_text);
e2.set_expression(pre_expression);
for(int i = 1; i < argc; ++i)
{
std::cout << "Processing file " << argv[i] << std::endl;
std::ifstream fs(argv[i]);
std::string in;
load_file(in, fs);
std::string out_name = std::string(argv[i]) + std::string(".htm");
std::ofstream os(out_name.c_str());
os << header_text;
// strip '<' and '>' first by outputting to a
// temporary string stream
std::ostringstream t(std::ios::out | std::ios::binary);
std::ostream_iterator<char, char> oi(t);
boost::regex_merge(oi, in.begin(), in.end(), e2, pre_format);
// then output to final output stream
// adding syntax highlighting:
std::string s(t.str());
std::ostream_iterator<char, char> out(os);
boost::regex_merge(out, s.begin(), s.end(), e1, format_string);
os << footer_text;
}
return 0;
}
extern const char* pre_expression = "(<)|(>)|\\r";
extern const char* pre_format = "(?1&lt;)(?2&gt;)";
const char* expression_text = // preprocessor directives: index 1
"(^[[:blank:]]*#(?:[^\\\\\\n]|\\\\[^\\n[:punct:][:word:]]*[\\n[:punct:][:word:]])*)|"
// comment: index 2
"(//[^\\n]*|/\\*.*?\\*/)|"
// literals: index 3
"\\<([+-]?(?:(?:0x[[:xdigit:]]+)|(?:(?:[[:digit:]]*\\.)?[[:digit:]]+(?:[eE][+-]?[[:digit:]]+)?))u?(?:(?:int(?:8|16|32|64))|L)?)\\>|"
// string literals: index 4
"('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|"
// keywords: index 5
"\\<(__asm|__cdecl|__declspec|__export|__far16|__fastcall|__fortran|__import"
"|__pascal|__rtti|__stdcall|_asm|_cdecl|__except|_export|_far16|_fastcall"
"|__finally|_fortran|_import|_pascal|_stdcall|__thread|__try|asm|auto|bool"
"|break|case|catch|cdecl|char|class|const|const_cast|continue|default|delete"
"|do|double|dynamic_cast|else|enum|explicit|extern|false|float|for|friend|goto"
"|if|inline|int|long|mutable|namespace|new|operator|pascal|private|protected"
"|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_cast"
"|struct|switch|template|this|throw|true|try|typedef|typeid|typename|union|unsigned"
"|using|virtual|void|volatile|wchar_t|while)\\>"
;
const char* format_string = "(?1<font color=\"#008040\">$&</font>)"
"(?2<I><font color=\"#000080\">$&</font></I>)"
"(?3<font color=\"#0000A0\">$&</font>)"
"(?4<font color=\"#0000FF\">$&</font>)"
"(?5<B>$&</B>)";
const char* header_text = "<HTML>\n<HEAD>\n"
"<TITLE>Auto-generated html formated source</TITLE>\n"
"<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=windows-1252\">\n"
"</HEAD>\n"
"<BODY LINK=\"#0000ff\" VLINK=\"#800080\" BGCOLOR=\"#ffffff\">\n"
"<P> </P>\n<PRE>";
const char* footer_text = "</PRE>\n</BODY>\n\n";

View File

@ -0,0 +1,106 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_search_example.cpp
* VERSION 3.00
* DESCRIPTION: regex_search example: searches a cpp file for class definitions.
*/
#include <string>
#include <map>
#include <boost/regex.hpp>
// purpose:
// takes the contents of a file in the form of a string
// and searches for all the C++ class definitions, storing
// their locations in a map of strings/int's
typedef std::map<std::string, int, std::less<std::string> > map_type;
boost::regex expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>)?[[:space:]]*(\\{|:[^;\\{()]*\\{)");
void IndexClasses(map_type& m, const std::string& file)
{
std::string::const_iterator start, end;
start = file.begin();
end = file.end();
boost::match_results<std::string::const_iterator> what;
unsigned int flags = boost::match_default;
while(boost::regex_search(start, end, what, expression, flags))
{
// what[0] contains the whole string
// what[5] contains the class name.
// what[6] contains the template specialisation if any.
// add class name and position to map:
m[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
what[5].first - file.begin();
// update search position:
start = what[0].second;
// update flags:
flags |= boost::match_prev_avail;
flags |= boost::match_not_bob;
}
}
#include <iostream>
#include <fstream>
using namespace std;
void load_file(std::string& s, std::istream& is)
{
s.erase();
s.reserve(is.rdbuf()->in_avail());
char c;
while(is.get(c))
{
if(s.capacity() == s.size())
s.reserve(s.capacity() * 3);
s.append(1, c);
}
}
int main(int argc, const char** argv)
{
std::string text;
for(int i = 1; i < argc; ++i)
{
cout << "Processing file " << argv[i] << endl;
map_type m;
std::ifstream fs(argv[i]);
load_file(text, fs);
IndexClasses(m, text);
cout << m.size() << " matches found" << endl;
map_type::iterator c, d;
c = m.begin();
d = m.end();
while(c != d)
{
cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl;
++c;
}
}
return 0;
}

View File

@ -0,0 +1,73 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_split_example_1.cpp
* VERSION 3.00
* DESCRIPTION: regex_split example: split a string into tokens.
*/
#include <list>
#include <boost/regex.hpp>
unsigned tokenise(std::list<std::string>& l, std::string& s)
{
return boost::regex_split(std::back_inserter(l), s);
}
#include <iostream>
using namespace std;
#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && (__BORLANDC__ == 0x550))
//
// problem with std::getline under MSVC6sp3
istream& getline(istream& is, std::string& s)
{
s.erase();
char c = is.get();
while(c != '\n')
{
s.append(1, c);
c = is.get();
}
return is;
}
#endif
int main()
{
string s;
list<string> l;
do{
cout << "Enter text to split (or \"quit\" to exit): ";
getline(cin, s);
if(s == "quit") break;
unsigned result = tokenise(l, s);
cout << result << " tokens found" << endl;
cout << "The remaining text is: \"" << s << "\"" << endl;
while(l.size())
{
s = *(l.begin());
l.pop_front();
cout << s << endl;
}
}while(true);
return 0;
}

View File

@ -0,0 +1,85 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_split_example_2.cpp
* VERSION 3.00
* DESCRIPTION: regex_split example: spit out linked URL's.
*/
#include <list>
#include <fstream>
#include <iostream>
#include <boost/regex.hpp>
boost::regex e("<\\s*A\\s+[^>]*href\\s*=\\s*\"([^\"]*)\"",
boost::regbase::normal | boost::regbase::icase);
void load_file(std::string& s, std::istream& is)
{
s.erase();
//
// attempt to grow string buffer to match file size,
// this doesn't always work...
s.reserve(is.rdbuf()->in_avail());
char c;
while(is.get(c))
{
// use logarithmic growth stategy, in case
// in_avail (above) returned zero:
if(s.capacity() == s.size())
s.reserve(s.capacity() * 3);
s.append(1, c);
}
}
int main(int argc, char** argv)
{
std::string s;
std::list<std::string> l;
int i;
for(i = 1; i < argc; ++i)
{
std::cout << "Findings URL's in " << argv[i] << ":" << std::endl;
s.erase();
std::ifstream is(argv[i]);
load_file(s, is);
boost::regex_split(std::back_inserter(l), s, e);
while(l.size())
{
s = *(l.begin());
l.pop_front();
std::cout << s << std::endl;
}
}
//
// alternative method:
// split one match at a time and output direct to
// cout via ostream_iterator<std::string>....
//
for(i = 1; i < argc; ++i)
{
std::cout << "Findings URL's in " << argv[i] << ":" << std::endl;
s.erase();
std::ifstream is(argv[i]);
load_file(s, is);
while(boost::regex_split(std::ostream_iterator<std::string>(std::cout), s, e, boost::match_default, 1)) std::cout << std::endl;
}
return 0;
}

45
example/timer/bc55.mak Normal file
View File

@ -0,0 +1,45 @@
# very basic makefile for timer.exe
#
# Borland C++ tools
#
# BCROOT defines the root directory of your bc builder install
#
!ifndef BCROOT
BCROOT=$(MAKEDIR)\..
!endif
BCC32 = $(BCROOT)\bin\Bcc32.exe
IDE_LinkFLAGS32 = -L$(BCROOT)\LIB
COMPOPTS= -O2 -tWC -tWM- -D_NO_VCL; -I../../../../; -L..\..\build\bcb5
timer.exe : regex_timer.cpp
$(BCC32) @&&|
$(COMPOPTS) -e$@ regex_timer.cpp
|

45
example/timer/bcb4.mak Normal file
View File

@ -0,0 +1,45 @@
# very basic makefile for timer.exe
#
# Borland C++ tools
#
# BCROOT defines the root directory of your bc builder install
#
!ifndef BCROOT
BCROOT=$(MAKEDIR)\..
!endif
BCC32 = $(BCROOT)\bin\Bcc32.exe
IDE_LinkFLAGS32 = -L$(BCROOT)\LIB
COMPOPTS= -O2 -tWC -tWM- -D_NO_VCL; -I../../../../; -L..\..\build\bcb4
timer.exe : regex_timer.cpp
$(BCC32) @&&|
$(COMPOPTS) -e$@ regex_timer.cpp
|

45
example/timer/bcb5.mak Normal file
View File

@ -0,0 +1,45 @@
# very basic makefile for timer.exe
#
# Borland C++ tools
#
# BCROOT defines the root directory of your bc builder install
#
!ifndef BCROOT
BCROOT=$(MAKEDIR)\..
!endif
BCC32 = $(BCROOT)\bin\Bcc32.exe
IDE_LinkFLAGS32 = -L$(BCROOT)\LIB
COMPOPTS= -O2 -tWC -tWM- -D_NO_VCL; -I../../../../; -L..\..\build\bcb5
timer.exe : regex_timer.cpp
$(BCC32) @&&|
$(COMPOPTS) -e$@ regex_timer.cpp
|

33
example/timer/gcc.mak Normal file
View File

@ -0,0 +1,33 @@
# very basic makefile for timer.exe
#
# GNU compiler GCC
#
CXX= $(INCLUDES) -I../../../../ -I./ $(CXXFLAGS)
timer : regex_timer.cpp
g++ $(CXX) -O2 -o timer regex_timer.cpp -L../../build/gcc $(LDFLAGS) -lboost_regex $(LIBS)
debug : regex_timer.cpp timer.cpp
g++ $(CXX) -g -o timer regex_timer.cpp -L../../build/gcc $(LDFLAGS) -lboost_regex_debug $(LIBS)

39
example/timer/makefile.in Normal file
View File

@ -0,0 +1,39 @@
# very basic makefile for timer
#
CXX=@CXX@
CXXFLAGS=@CXXFLAGS@
LIBS=@LIBS@
EXE=@ac_exe_ext@
OBJ=@ac_obj_ext@
LIBDEP=../../build/libboost_regex.a ../../../../boost/re_detail/regex_options.hpp ../../../../boost/re_detail/regex_config.hpp
regex_timer$(EXE) : regex_timer$(OBJ)
$(CXX) -o timer$(EXE) regex_timer$(OBJ) -L../../build -lboost_regex $(LIBS)
regex_timer$(OBJ) : regex_timer.cpp $(LIBDEP)
$(CXX) -c $(CXXFLAGS) -DSTRICT -I../../../../ -I./ regex_timer.cpp
timer$(OBJ) : ../../../timer/timer.cpp $(LIBDEP)
$(CXX) -c $(CXXFLAGS) -DSTRICT -I../../../../ -I./ ../../../timer/timer.cpp

View File

@ -0,0 +1,322 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
#ifdef BOOST_RE_OLD_IOSTREAM
#include <iostream.h>
#else
#include <iostream>
using std::cout;
using std::cin;
using std::cerr;
using std::istream;
using std::ostream;
using std::endl;
#endif
#include <algorithm>
#include <string>
#include <deque>
#include <boost/regex.hpp>
#include <boost/timer.hpp>
#include <boost/smart_ptr.hpp>
#ifdef BOOST_MSVC
// no Koenig lookup, use using declaration instead:
using namespace boost;
#endif
#ifndef BOOST_RE_NO_WCSTRING
ostream& operator << (ostream& os, const std::wstring& s)
{
std::wstring::const_iterator i, j;
i = s.begin();
j = s.end();
while(i != j)
{
os.put(*i);
++i;
}
return os;
}
#endif
template <class S>
class string_out_iterator
{
S* out;
public:
string_out_iterator(S& s) : out(&s) {}
string_out_iterator& operator++() { return *this; }
string_out_iterator& operator++(int) { return *this; }
string_out_iterator& operator*() { return *this; }
string_out_iterator& operator=(typename S::value_type v)
{
out->append(1, v);
return *this;
}
};
#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && (__BORLANDC__ == 0x550)) || defined(__SGI_STL_PORT)
//
// problem with std::getline under MSVC6sp3
// and C++ Builder 5.5, is this really that hard?
istream& getline(istream& is, std::string& s)
{
s.erase();
char c = is.get();
while(c != '\n')
{
s.append(1, c);
c = is.get();
}
return is;
}
#endif
int main()
{
boost::regex ex;
boost::match_results<std::string::const_iterator> sm;
#ifndef BOOST_RE_NO_WCSTRING
std::wstring ws1, ws2;
boost::wregex wex;
boost::match_results<std::wstring::const_iterator> wsm;
#endif
boost::match_results<std::deque<char>::iterator> dm;
std::string s1, s2, ts;
std::deque<char> ds;
boost::regex_t r;
boost::scoped_array<boost::regmatch_t> matches;
size_t nsubs;
boost::timer t;
double tim;
bool result;
int iters = 100;
while(true)
{
cout << "Enter expression (or \"quit\" to exit): ";
getline(cin, s1);
if(s1 == "quit")
break;
#ifndef BOOST_RE_NO_WCSTRING
ws1.erase();
std::copy(s1.begin(), s1.end(), string_out_iterator<std::wstring>(ws1));
#endif
try{
ex.assign(s1.begin(), s1.end());
#ifndef BOOST_RE_NO_WCSTRING
wex.assign(ws1.begin(), ws1.end());
#endif
}
catch(std::exception& e)
{
cout << "Error in expression: \"" << e.what() << "\"" << endl;
continue;
}
int code = regcomp(&r, s1.c_str(), boost::REG_PERL);
if(code != 0)
{
char buf[256];
regerror(code, &r, buf, 256);
cout << "regcomp error: \"" << buf << "\"" << endl;
continue;
}
nsubs = r.re_nsub + 1;
matches.reset(new boost::regmatch_t[nsubs]);
while(true)
{
cout << "Enter string to search (or \"quit\" to exit): ";
getline(cin, s2);
if(s2 == "quit")
break;
#ifndef BOOST_RE_NO_WCSTRING
ws2.erase();
std::copy(s2.begin(), s2.end(), string_out_iterator<std::wstring>(ws2));
#endif
ds.erase(ds.begin(), ds.end());
std::copy(s2.begin(), s2.end(), std::back_inserter(ds));
int i;
iters = 10;
tim = 1.1;
#if defined(_WIN32) && defined(BOOST_RE_LOCALE_W32)
MSG msg;
PeekMessage(&msg, 0, 0, 0, 0);
Sleep(0);
#endif
// cache load:
regex_search(s2, sm, ex);
// measure time interval for reg_expression<char>
do{
iters *= (tim > 0.001) ? (1.1/tim) : 100;
t.restart();
for(i =0; i < iters; ++i)
{
result = regex_search(s2, sm, ex);
}
tim = t.elapsed();
}while((tim < t.elapsed_min() * 1000) || (tim < 1));
cout << "regex time: " << (tim * 1000000 / iters) << "us" << endl;
if(result)
{
for(i = 0; i < sm.size(); ++i)
{
ts = sm[i];
cout << "\tmatch " << i << ": \"";
cout << ts;
cout << "\" (matched=" << sm[i].matched << ")" << endl;
}
cout << "\tmatch $`: \"";
cout << std::string(sm[-1]);
cout << "\" (matched=" << sm[-1].matched << ")" << endl;
cout << "\tmatch $': \"";
cout << std::string(sm[-2]);
cout << "\" (matched=" << sm[-2].matched << ")" << endl << endl;
}
#ifndef BOOST_RE_NO_WCSTRING
// measure time interval for boost::wregex
iters = 10;
tim = 1.1;
// cache load:
regex_search(ws2, wsm, wex);
do{
iters *= (tim > 0.001) ? (1.1/tim) : 100;
t.restart();
for(i = 0; i < iters; ++i)
{
result = regex_search(ws2, wsm, wex);
}
tim = t.elapsed();
}while((tim < t.elapsed_min() * 1000) || (tim < 1));
cout << "wregex time: " << (tim * 1000000 / iters) << "us" << endl;
if(result)
{
std::wstring tw;
for(i = 0; i < wsm.size(); ++i)
{
tw.erase();
std::copy(wsm[i].first, wsm[i].second, string_out_iterator<std::wstring>(tw));
cout << "\tmatch " << i << ": \"" << tw;
cout << "\" (matched=" << sm[i].matched << ")" << endl;
}
cout << "\tmatch $`: \"";
tw.erase();
std::copy(wsm[-1].first, wsm[-1].second, string_out_iterator<std::wstring>(tw));
cout << tw;
cout << "\" (matched=" << sm[-1].matched << ")" << endl;
cout << "\tmatch $': \"";
tw.erase();
std::copy(wsm[-2].first, wsm[-2].second, string_out_iterator<std::wstring>(tw));
cout << tw;
cout << "\" (matched=" << sm[-2].matched << ")" << endl << endl;
}
#endif
// measure time interval for reg_expression<char> using a deque
iters = 10;
tim = 1.1;
// cache load:
regex_search(ds.begin(), ds.end(), dm, ex);
do{
iters *= (tim > 0.001) ? (1.1/tim) : 100;
t.restart();
for(i = 0; i < iters; ++i)
{
result = regex_search(ds.begin(), ds.end(), dm, ex);
}
tim = t.elapsed();
}while((tim < t.elapsed_min() * 1000) || (tim < 1));
cout << "regex time (search over std::deque<char>): " << (tim * 1000000 / iters) << "us" << endl;
if(result)
{
for(i = 0; i < dm.size(); ++i)
{
ts.erase();
std::copy(dm[i].first, dm[i].second, string_out_iterator<std::string>(ts));
cout << "\tmatch " << i << ": \"" << ts;
cout << "\" (matched=" << sm[i].matched << ")" << endl;
}
cout << "\tmatch $`: \"";
ts.erase();
std::copy(dm[-1].first, dm[-1].second, string_out_iterator<std::string>(ts));
cout << ts;
cout << "\" (matched=" << sm[-1].matched << ")" << endl;
cout << "\tmatch $': \"";
ts.erase();
std::copy(dm[-2].first, dm[-2].second, string_out_iterator<std::string>(ts));
cout << ts;
cout << "\" (matched=" << sm[-2].matched << ")" << endl << endl;
}
// measure time interval for POSIX matcher:
iters = 10;
tim = 1.1;
// cache load:
regexec(&r, s2.c_str(), nsubs, matches.get(), 0);
do{
iters *= (tim > 0.001) ? (1.1/tim) : 100;
t.restart();
for(i = 0; i < iters; ++i)
{
result = regexec(&r, s2.c_str(), nsubs, matches.get(), 0);
}
tim = t.elapsed();
}while((tim < t.elapsed_min() * 1000) || (tim < 1));
cout << "POSIX regexec time: " << (tim * 1000000 / iters) << "us" << endl;
if(result == 0)
{
for(i = 0; i < nsubs; ++i)
{
if(matches[i].rm_so >= 0)
{
ts.assign(s2.begin() + matches[i].rm_so, s2.begin() + matches[i].rm_eo);
cout << "\tmatch " << i << ": \"" << ts << "\" (matched=" << (matches[i].rm_so != -1) << ")"<< endl;
}
else
cout << "\tmatch " << i << ": \"\" (matched=" << (matches[i].rm_so != -1) << ")" << endl; // no match
}
cout << "\tmatch $`: \"";
ts.erase();
ts.assign(s2.begin(), s2.begin() + matches[0].rm_so);
cout << ts;
cout << "\" (matched=" << (matches[0].rm_so != 0) << ")" << endl;
cout << "\tmatch $': \"";
ts.erase();
ts.assign(s2.begin() + matches[0].rm_eo, s2.end());
cout << ts;
cout << "\" (matched=" << (matches[0].rm_eo != s2.size()) << ")" << endl << endl;
}
}
regfree(&r);
}
return 0;
}

View File

@ -0,0 +1,33 @@
#
# very basic VC6 makefile for timer
#
CXX=cl
CXXFLAGS=/Oityb1 /GF /Gy -MT -GX -DSTRICT -I../../../../ -I./
LIBS=/link /LIBPATH:..\..\build\vc6-stlport kernel32.lib user32.lib
EXE=.exe
OBJ=.obj
LIBDEP= ../../../../boost/re_detail/regex_options.hpp ../../../../boost/re_detail/regex_config.hpp
regex_timer$(EXE) : regex_timer$(OBJ)
$(CXX) -o timer$(EXE) regex_timer$(OBJ) $(LIBS)
regex_timer$(OBJ) : regex_timer.cpp $(LIBDEP)
$(CXX) -c $(CXXFLAGS) regex_timer.cpp
timer$(OBJ) : ../../../timer/timer.cpp $(LIBDEP)
$(CXX) -c $(CXXFLAGS) ../../../timer/timer.cpp

32
example/timer/vc6.mak Normal file
View File

@ -0,0 +1,32 @@
#
# very basic VC6 makefile for timer
#
CXX=cl
CXXFLAGS=/Oityb1 /GF /Gy -GX -DSTRICT -I../../../../ -I./
LIBS=/link /LIBPATH:..\..\build\vc6 kernel32.lib user32.lib
EXE=.exe
OBJ=.obj
LIBDEP= ../../../../boost/re_detail/regex_options.hpp ../../../../boost/re_detail/regex_config.hpp
regex_timer$(EXE) : regex_timer$(OBJ)
$(CXX) -o timer$(EXE) regex_timer$(OBJ) $(LIBS)
regex_timer$(OBJ) : regex_timer.cpp $(LIBDEP)
$(CXX) -c $(CXXFLAGS) regex_timer.cpp
timer$(OBJ) : ../../../timer/timer.cpp $(LIBDEP)
$(CXX) -c $(CXXFLAGS) ../../../timer/timer.cpp