Rewritten grep example program.

"touched" some of the sources to force regression tests to rebuild.
Split test code up some more to help msvc-stlport.


[SVN r26705]
This commit is contained in:
John Maddock
2005-01-15 12:29:59 +00:00
parent 1e48609cfd
commit 30acb7d2f8
17 changed files with 231 additions and 716 deletions

View File

@ -53,13 +53,10 @@
<P>Directory: <A href="../test/captures">libs/test/captures</A>.</P> <P>Directory: <A href="../test/captures">libs/test/captures</A>.</P>
<P>Files: <A href="../test/captures/captures_test.cpp">captures_test.cpp</A>.</P> <P>Files: <A href="../test/captures/captures_test.cpp">captures_test.cpp</A>.</P>
<H3>Example programs</H3> <H3>Example programs</H3>
<H4>jgrep.exe</H4> <H4>grep</H4>
<P>A simple grep implementation, run with no command line options to find out its <P>A simple grep implementation, run with the -h command line option to find out
usage. Look at <A href="../src/fileiter.cpp">fileiter.cpp</A>/fileiter.hpp and its usage.</P>
the mapfile class to see an example of a "smart" bidirectional iterator that <P>Files: <A href="../example/grep/grep.cpp">grep.cpp</A></P>
can be used with boost.regex or any other STL algorithm.</P>
<P>Files: <A href="../example/jgrep/jgrep.cpp">jgrep.cpp</A>, <A href="../example/jgrep/main.cpp">
main.cpp</A>.</P>
<H4>timer.exe</H4> <H4>timer.exe</H4>
<P>A simple interactive expression matching application, the results of all <P>A simple interactive expression matching application, the results of all
matches are timed, allowing the programmer to optimize their regular matches are timed, allowing the programmer to optimize their regular

View File

@ -53,13 +53,10 @@
<P>Directory: <A href="../test/captures">libs/test/captures</A>.</P> <P>Directory: <A href="../test/captures">libs/test/captures</A>.</P>
<P>Files: <A href="../test/captures/captures_test.cpp">captures_test.cpp</A>.</P> <P>Files: <A href="../test/captures/captures_test.cpp">captures_test.cpp</A>.</P>
<H3>Example programs</H3> <H3>Example programs</H3>
<H4>jgrep.exe</H4> <H4>grep</H4>
<P>A simple grep implementation, run with no command line options to find out its <P>A simple grep implementation, run with the -h command line option to find out
usage. Look at <A href="../src/fileiter.cpp">fileiter.cpp</A>/fileiter.hpp and its usage.</P>
the mapfile class to see an example of a "smart" bidirectional iterator that <P>Files: <A href="../example/grep/grep.cpp">grep.cpp</A></P>
can be used with boost.regex or any other STL algorithm.</P>
<P>Files: <A href="../example/jgrep/jgrep.cpp">jgrep.cpp</A>, <A href="../example/jgrep/main.cpp">
main.cpp</A>.</P>
<H4>timer.exe</H4> <H4>timer.exe</H4>
<P>A simple interactive expression matching application, the results of all <P>A simple interactive expression matching application, the results of all
matches are timed, allowing the programmer to optimize their regular matches are timed, allowing the programmer to optimize their regular

View File

@ -63,7 +63,7 @@ rule regex-test-run ( sources + : input * )
test-suite regex-examples : test-suite regex-examples :
[ regex-test-run timer/regex_timer.cpp <template>../build/msvc-stlport-tricky : $(BOOST_ROOT)/libs/regex/example/timer/input_script.txt ] [ regex-test-run timer/regex_timer.cpp <template>../build/msvc-stlport-tricky : $(BOOST_ROOT)/libs/regex/example/timer/input_script.txt ]
[ regex-test-run jgrep/jgrep.cpp jgrep/main.cpp : -n boost/ $(BOOST_ROOT)/boost/regex.hpp ] [ regex-test-run grep/grep.cpp <lib>../../program_options/build/boost_program_options : -n -b $(BOOST_ROOT)/boost/regex.hpp $(BOOST_ROOT)/boost/type_traits.hpp ]
[ regex-test-run snippets/credit_card_example.cpp ] [ regex-test-run snippets/credit_card_example.cpp ]
[ regex-test-run snippets/mfc_example.cpp ] [ regex-test-run snippets/mfc_example.cpp ]
[ regex-test-run snippets/icu_example.cpp ] [ regex-test-run snippets/icu_example.cpp ]

View File

@ -24,7 +24,7 @@ rule regex-test-run ( sources + : input * )
test-suite regex-examples : test-suite regex-examples :
[ regex-test-run timer/regex_timer.cpp : $(BOOST_ROOT)/libs/regex/example/timer/input_script.txt ] [ regex-test-run timer/regex_timer.cpp : $(BOOST_ROOT)/libs/regex/example/timer/input_script.txt ]
[ regex-test-run jgrep/jgrep.cpp jgrep/main.cpp : -n boost/ $(BOOST_ROOT)/boost/regex.hpp ] [ regex-test-run grep/grep.cpp ../../program_options/build//program_options : -n -b $(BOOST_ROOT)/boost/regex.hpp $(BOOST_ROOT)/boost/type_traits.hpp ]
[ regex-test-run snippets/credit_card_example.cpp ] [ regex-test-run snippets/credit_card_example.cpp ]
[ regex-test-run snippets/mfc_example.cpp ] [ regex-test-run snippets/mfc_example.cpp ]
[ regex-test-run snippets/icu_example.cpp ] [ regex-test-run snippets/icu_example.cpp ]

212
example/grep/grep.cpp Normal file
View File

@ -0,0 +1,212 @@
/*
*
* Copyright (c) 2004
* Dr John Maddock
*
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/program_options.hpp>
#include <boost/regex.hpp>
namespace po = boost::program_options;
int after_context;
int before_context;
bool print_byte_offset;
bool count_only;
std::string pattern;
bool print_non_matching_files;
bool files_only;
bool print_line_numbers;
boost::regex_constants::syntax_option_type flags = boost::regex_constants::basic;
boost::regex re;
boost::smatch what;
std::string current_file;
int file_count;
void process_stream(std::istream& is)
{
std::string line;
int match_found = 0;
int linenum = 1;
while(std::getline(is, line))
{
bool result = boost::regex_search(line, what, re);
if(result)
{
if(print_non_matching_files)
return;
if(files_only)
{
std::cout << current_file << std::endl;
return;
}
if(!match_found && !count_only && (file_count > 1))
{
std::cout << current_file << ":\n";
}
++match_found;
if(!count_only)
{
if(print_line_numbers)
{
std::cout << linenum << ":";
}
if(print_byte_offset)
{
std::cout << what.position() << ":";
}
std::cout << what[0] << std::endl;
}
}
++linenum;
}
if(count_only && match_found)
{
std::cout << match_found << " matches found in file " << current_file << std::endl;
}
else if(print_non_matching_files && !match_found)
{
std::cout << current_file << std::endl;
}
}
void process_file(const std::string& name)
{
current_file = name;
std::ifstream is(name.c_str());
if(is.bad())
{
std::cerr << "Unable to open file " << name << std::endl;
}
process_stream(is);
}
int main(int argc, char * argv[])
{
try{
po::options_description opts("Options");
opts.add_options()
("help,h", "produce help message")
//("after-context,A", po::value<int>(&after_context)->default_value(0), "Print arg lines of trailing context after matching lines. Places a line containing -- between contiguous groups of matches.")
//("before-context,B", po::value<int>(&before_context)->default_value(0), "Print arg lines of leading context before matching lines. Places a line containing -- between contiguous groups of matches.")
//("context,C", po::value<int>(), "Print arg lines of output context. Places a line containing -- between contiguous groups of matches.")
("byte-offset,b", "Print the byte offset within the input file before each line of output.")
("count,c", "Suppress normal output; instead print a count of matching lines for each input file. With the -v, --invert-match option (see below), count non-matching lines.")
("extended-regexp,E", "Interpret PATTERN as an POSIX-extended regular expression.")
("perl-regexp,P", "Interpret PATTERN as a Perl regular expression.")
//("regexp,e", po::value<std::string>(&pattern), "Use PATTERN as the pattern; useful to protect patterns beginning with -.")
("basic-regexp,G", "Interpret arg as a POSIX-basic regular expression (see below). This is the default.")
("ignore-case,i", "Ignore case distinctions in both the PATTERN and the input files.")
("files-without-match,L", "Suppress normal output; instead print the name of each input file from which no output would normally have been printed. The scanning will stop on the first match.")
("files-with-matches,l", "Suppress normal output; instead print the name of each input file from which output would normally have been printed. The scanning will stop on the first match.")
("line-number,n", "Prefix each line of output with the line number within its input file.")
;
// Hidden options, will be allowed both on command line and
// in config file, but will not be shown to the user.
po::options_description hidden("Hidden options");
hidden.add_options()
("input-file", po::value< std::vector<std::string> >(), "input file")
("input-pattern", po::value< std::string >(), "input file")
;
po::options_description cmdline_options;
cmdline_options.add(opts).add(hidden);
po::positional_options_description p;
p.add("input-pattern", 1);
p.add("input-file", -1);
po::variables_map vm;
store(po::command_line_parser(argc, argv).options(cmdline_options)/*.options(hidden)*/.positional(p).run(), vm);
notify(vm);
if (vm.count("help"))
{
std::cout << opts << "\n";
return 0;
}
if (vm.count("context"))
{
after_context = vm["context"].as< int >();
before_context = after_context;
}
if(vm.count("extended-regexp"))
{
flags = boost::regex_constants::extended;
}
if(vm.count("basic-regexp"))
{
flags = boost::regex_constants::basic;
}
if(vm.count("perl-regexp"))
{
flags = boost::regex_constants::perl;
}
if(vm.count("ignore-case"))
{
flags |= boost::regex_constants::icase;
}
if(vm.count("byte-offset"))
{
print_byte_offset = true;
}
if(vm.count("count"))
{
count_only = true;
}
if(vm.count("files-without-match"))
{
print_non_matching_files = true;
}
if(vm.count("files-with-matches"))
{
files_only = true;
}
if(vm.count("line-number"))
{
print_line_numbers = true;
}
if(vm.count("input-pattern"))
{
pattern = vm["input-pattern"].as< std::string >();
re.assign(pattern, flags);
}
else
{
std::cerr << "No pattern specified" << std::endl;
return 1;
}
if (vm.count("input-file"))
{
const std::vector<std::string>& files = vm["input-file"].as< std::vector<std::string> >();
file_count = files.size();
for(std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i)
{
process_file(*i);
}
}
else
{
// no input files, scan stdin instead:
process_stream(std::cin);
}
}
catch(const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}

View File

@ -1,51 +0,0 @@
# 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- -Vx -Ve -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
|

View File

@ -1,51 +0,0 @@
# 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- -Vx -Ve -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
|

View File

@ -1,50 +0,0 @@
# 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- -Vx -Ve -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
|

View File

@ -1,32 +0,0 @@
# 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)

View File

@ -1,148 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* Dr John Maddock
*
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
/*
* FILE jgrep.cpp
* VERSION see <boost/version.hpp>
*/
#include <stdio.h>
#include <algorithm>
#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
#ifdef __BORLANDC__
# pragma hrdstop
#endif
#ifdef BOOST_REGEX_V3
#include <boost/regex/v3/fileiter.hpp>
#else
#include <boost/regex/v4/fileiter.hpp>
#endif
#include "jgrep.h"
#ifndef BOOST_REGEX_NO_FILEITER
//
// 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, last_line_start;
public:
ogrep_predicate(unsigned int& i, const char* p, iterator start, iterator end) : lines(i), filename(p), last_line(-1), end_of_storage(end), last_line_start(start) {}
ogrep_predicate(const ogrep_predicate& o) : lines(o.lines), filename(o.filename), last_line(o.last_line), end_of_storage(o.end_of_storage), last_line_start(o.last_line_start) {}
bool operator () (const boost::match_results<iterator, Allocator>& i);
private:
void operator=(const ogrep_predicate&);
};
// 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 we haven't printed the filename yet, then do it now:
if(last_line == (unsigned int)-1)
{
cout << "File " << filename << ":" << endl;
last_line = 0;
}
// calculate which line we are on, by adding the number of newlines
// we've skipped in the last search:
unsigned int current_line = last_line + std::count(last_line_start, end_of_storage, '\n');
// if we haven't already printed this line out, then do it now:
if(last_line != current_line)
{
++lines;
last_line = current_line;
if(count_only == 0)
{
if(show_lines)
cout << current_line << "\t";
const char* nls = "\n";
iterator ptr = std::find_end(last_line_start, i[0].first, nls, nls+1);
++ptr;
iterator ptr2 = ptr;
while((ptr2 != end_of_storage) && (*ptr2 != '\n'))++ptr2;
while(ptr != ptr2)
{
cout.put(*ptr);
++ptr;
}
cout << endl;
}
}
// set the last line seen to the start of the current match:
last_line_start = i[0].first;
return true;
}
using namespace boost;
void process_grep(const char* file)
{
try{
mapfile f(file);
unsigned int count = 0;
ogrep_predicate<mapfile::iterator, boost::match_results<mapfile::iterator>::allocator_type> oi(count, file, f.begin(), f.end());
if(files_only)
{
bool ok;
boost::match_results<mapfile::iterator> 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;
}
}
}
catch(const std::exception& e)
{
std::cerr << std::endl << e.what() << std::endl;
}
catch(...)
{
}
}
#endif

View File

@ -1,42 +0,0 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
/*
* FILE jgrep.h
* VERSION see <boost/version.hpp>
*/
#ifndef _JGREP_H
#define _JGREP_H
#include <boost/regex.hpp>
typedef boost::basic_regex<char> re_type;
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

View File

@ -1,289 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* Dr John Maddock
*
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
/*
* FILE main.cpp
* VERSION see <boost/version.hpp>
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <boost/regex.hpp>
#include <boost/regex/v4/fileiter.hpp>
#include "jgrep.h"
#ifndef BOOST_REGEX_NO_FILEITER
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{
using ::strcpy;
using ::strcat;
using ::sprintf;
}
#endif
re_type e;
//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()
{
std::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" << std::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:
std::cout << "Undefined option -";
std::cout.put(*flag);
std::cout << std::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:
std::cout << "Undefined option -";
std::cout.put(*flag);
std::cout << std::endl;
}
++flag;
}
}
using namespace boost;
void HandleFile(const char* wild)
{
using namespace boost;
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, "*");
}
directory_iterator dstart(buf);
directory_iterator dend;
// now get the file mask bit of "wild":
const char* ptr = wild + rootlen;
if(*ptr) ++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;
if(*arg == '-')
{
parse_switch(arg);
return;
}
if(done == 0)
{
// parse regular expression
if(regularexs)
{
if(words_only == 0)
{
e.set_expression(arg, use_case ? regex::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 ? regex::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 ? regex::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;
}
#else
#include <iostream>
int main(int argc, char * argv[])
{
std::std::cout <<
"\n<note>\n"
"This functionality is not available on with this compiler on this platform.\n"
"</note>\n";
return 0;
}
#endif

View File

@ -1,18 +0,0 @@
#
# 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

View File

@ -1,18 +0,0 @@
#
# 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

View File

@ -30,4 +30,3 @@
#include <boost/regex.hpp> #include <boost/regex.hpp>
#endif #endif

View File

@ -31,3 +31,5 @@
#endif #endif

View File

@ -138,6 +138,8 @@ void test_sets()
} }
void test_sets2b(); void test_sets2b();
void test_sets2c();
void test_sets2() void test_sets2()
{ {
using namespace boost::regex_constants; using namespace boost::regex_constants;
@ -245,7 +247,12 @@ void test_sets2()
TEST_REGEX_SEARCH("[\\s]+", perl, "AB AB", match_default, make_array(2, 5, -2, -2)); TEST_REGEX_SEARCH("[\\s]+", perl, "AB AB", match_default, make_array(2, 5, -2, -2));
TEST_INVALID_REGEX("[\\S]", perl); TEST_INVALID_REGEX("[\\S]", perl);
TEST_REGEX_SEARCH("\\S+", perl, " abc ", match_default, make_array(2, 5, -2, -2)); TEST_REGEX_SEARCH("\\S+", perl, " abc ", match_default, make_array(2, 5, -2, -2));
test_sets2c();
}
void test_sets2c()
{
using namespace boost::regex_constants;
// and some Perl style properties: // and some Perl style properties:
TEST_REGEX_SEARCH("\\pl+", perl, "ABabcAB", match_default, make_array(2, 5, -2, -2)); TEST_REGEX_SEARCH("\\pl+", perl, "ABabcAB", match_default, make_array(2, 5, -2, -2));
TEST_REGEX_SEARCH("\\Pl+", perl, "abABCab", match_default, make_array(2, 5, -2, -2)); TEST_REGEX_SEARCH("\\Pl+", perl, "abABCab", match_default, make_array(2, 5, -2, -2));