forked from boostorg/regex
Add module support and tests. (#174)
This commit is contained in:
99
test/concepts/module_concept_check.cpp
Normal file
99
test/concepts/module_concept_check.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
//
|
||||
// For some reason, GCC chokes unless all std lib includes appear
|
||||
// before module imports:
|
||||
//
|
||||
#include <boost/concept_archetype.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <bitset>
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
#endif
|
||||
|
||||
import boost.regex;
|
||||
|
||||
#define BOOST_REGEX_TEST_MODULE
|
||||
|
||||
#include <boost/regex/concepts.hpp>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::function_requires<
|
||||
boost::RegexTraitsConcept<
|
||||
boost::regex_traits<char>
|
||||
>
|
||||
>();
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
boost::function_requires<
|
||||
boost::BoostRegexConcept<
|
||||
boost::basic_regex<char, boost::cpp_regex_traits<char> >
|
||||
>
|
||||
>();
|
||||
#ifndef BOOST_NO_WREGEX
|
||||
boost::function_requires<
|
||||
boost::BoostRegexConcept<
|
||||
boost::basic_regex<wchar_t, boost::cpp_regex_traits<wchar_t> >
|
||||
>
|
||||
>();
|
||||
#endif
|
||||
#endif
|
||||
boost::function_requires<
|
||||
boost::BoostRegexConcept<
|
||||
boost::basic_regex<char, boost::c_regex_traits<char> >
|
||||
>
|
||||
>();
|
||||
#ifndef BOOST_NO_WREGEX
|
||||
boost::function_requires<
|
||||
boost::BoostRegexConcept<
|
||||
boost::basic_regex<wchar_t, boost::c_regex_traits<wchar_t> >
|
||||
>
|
||||
>();
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
|
||||
boost::function_requires<
|
||||
boost::BoostRegexConcept<
|
||||
boost::basic_regex<char, boost::w32_regex_traits<char> >
|
||||
>
|
||||
>();
|
||||
#ifndef BOOST_NO_WREGEX
|
||||
boost::function_requires<
|
||||
boost::BoostRegexConcept<
|
||||
boost::basic_regex<wchar_t, boost::w32_regex_traits<wchar_t> >
|
||||
>
|
||||
>();
|
||||
#endif
|
||||
#endif
|
||||
//
|
||||
// now test the regex_traits concepts:
|
||||
//
|
||||
typedef boost::basic_regex<char, boost::regex_traits_architype<char> > regex_traits_tester_type1;
|
||||
boost::function_requires<
|
||||
boost::BoostRegexConcept<
|
||||
regex_traits_tester_type1
|
||||
>
|
||||
>();
|
||||
typedef boost::basic_regex<boost::char_architype, boost::regex_traits_architype<boost::char_architype> > regex_traits_tester_type2;
|
||||
boost::function_requires<
|
||||
boost::BaseRegexConcept<
|
||||
regex_traits_tester_type2
|
||||
>
|
||||
>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
33
test/module/Jamfile.v2
Normal file
33
test/module/Jamfile.v2
Normal file
@ -0,0 +1,33 @@
|
||||
# copyright John Maddock 2022
|
||||
# Distributed under 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.
|
||||
|
||||
project
|
||||
: requirements
|
||||
<threading>multi
|
||||
<toolset>msvc:<asynch-exceptions>on
|
||||
<toolset>msvc:<cxxstd>latest
|
||||
<toolset>gcc:<cxxflags>-fmodules-ts
|
||||
;
|
||||
|
||||
obj regex : ../../module/regex.cxx : <toolset>msvc:<cxxflags>-interface [ check-target-builds ./config//test_has_module_support : : <build>no ] ;
|
||||
|
||||
exe credit_card_example : credit_card_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe partial_regex_grep : partial_regex_grep.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe partial_regex_iterate : partial_regex_iterate.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe partial_regex_match : partial_regex_match.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_grep_example_1 : regex_grep_example_1.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_grep_example_2 : regex_grep_example_2.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_grep_example_3 : regex_grep_example_3.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_iterator_example : regex_iterator_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_match_example : regex_match_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_merge_example : regex_merge_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_replace_example : regex_replace_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_search_example : regex_search_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_split_example_1 : regex_split_example_1.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_split_example_2 : regex_split_example_2.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_token_iterator_eg_1 : regex_token_iterator_eg_1.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
exe regex_token_iterator_eg_2 : regex_token_iterator_eg_2.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
||||
|
||||
compile ../concepts/module_concept_check.cpp regex : [ check-target-builds ./config//test_has_module_support : : <build>no ] <dependency>regex ;
|
79
test/module/credit_card_example.cpp
Normal file
79
test/module/credit_card_example.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2002
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE credit_card_example.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: Credit card number formatting code.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
|
||||
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_replace(s, e, machine_format, boost::match_default | boost::format_sed);
|
||||
}
|
||||
|
||||
std::string human_readable_card_number(const std::string& s)
|
||||
{
|
||||
return boost::regex_replace(s, e, human_format, boost::match_default | boost::format_sed);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
27
test/module/msvc_test.bat
Normal file
27
test/module/msvc_test.bat
Normal file
@ -0,0 +1,27 @@
|
||||
REM Basic command line to build everything with msvc:
|
||||
|
||||
rem del *.obj
|
||||
rem del *.exe
|
||||
rem del *.lib
|
||||
|
||||
cl /std:c++latest /EHsc /nologo /W4 /c "%VCToolsInstallDir%\modules\std.ixx" || exit 1
|
||||
cl /std:c++latest /EHsc /nologo /W4 /c /interface /I ..\..\..\.. ..\..\module\regex.cxx || exit 1
|
||||
cl /std:c++latest /EHsc /nologo /W4 /c /I ..\..\..\.. ..\..\module\*.cpp || exit 1
|
||||
|
||||
lib *.obj /OUT:regex.lib || exit 1
|
||||
|
||||
rem time < nul
|
||||
|
||||
for %%f in (*.cpp) do (
|
||||
cl /std:c++latest /EHsc /nologo /W4 /I ..\..\..\.. %%f regex.lib || exit 1
|
||||
)
|
||||
|
||||
rem time < nul
|
||||
|
||||
rem uncomment this section to test/time non-module build:
|
||||
rem for %%f in (*.cpp) do (
|
||||
rem cl /DTEST_HEADERS /std:c++latest /EHsc /nologo /W4 /I ..\..\..\.. %%f || exit 1
|
||||
rem )
|
||||
|
||||
rem time < nul
|
||||
|
113
test/module/partial_regex_grep.cpp
Normal file
113
test/module/partial_regex_grep.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE partial_regex_grep.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: Search example using partial matches.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
// match some kind of html tag:
|
||||
boost::regex e("<[^>]*>");
|
||||
// count how many:
|
||||
unsigned int tags = 0;
|
||||
// saved position of partial match:
|
||||
const char* next_pos = 0;
|
||||
|
||||
bool grep_callback(const boost::match_results<const 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:
|
||||
std::ptrdiff_t leftover = (buf + sizeof(buf)) - next_pos;
|
||||
// and how much is left to fill:
|
||||
std::ptrdiff_t size = next_pos - buf;
|
||||
// copy forward whatever we have left:
|
||||
std::memmove(buf, next_pos, leftover);
|
||||
// fill the rest from the stream:
|
||||
is.read(buf + leftover, size);
|
||||
std::streamsize read = is.gcount();
|
||||
// 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<bool(*)(const boost::cmatch&), const char*>(grep_callback,
|
||||
static_cast<const char*>(buf),
|
||||
static_cast<const char*>(buf + read + leftover),
|
||||
e,
|
||||
boost::match_default | boost::match_partial);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if(argc > 1)
|
||||
{
|
||||
for(int i = 1; i < argc; ++i)
|
||||
{
|
||||
std::ifstream fs(argv[i]);
|
||||
if(fs.bad()) continue;
|
||||
search(fs);
|
||||
fs.close();
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
129
test/module/partial_regex_iterate.cpp
Normal file
129
test/module/partial_regex_iterate.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE partial_regex_iterate.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: Search example using partial matches.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std{ using ::memmove; }
|
||||
#endif
|
||||
|
||||
// match some kind of html tag:
|
||||
boost::regex e("<[^>]*>");
|
||||
// count how many:
|
||||
unsigned int tags = 0;
|
||||
|
||||
void search(std::istream& is)
|
||||
{
|
||||
// buffer we'll be searching in:
|
||||
char buf[4096];
|
||||
// saved position of end of partial match:
|
||||
const char* next_pos = buf + sizeof(buf);
|
||||
// flag to indicate whether there is more input to come:
|
||||
bool have_more = true;
|
||||
|
||||
while(have_more)
|
||||
{
|
||||
// how much do we copy forward from last try:
|
||||
std::ptrdiff_t leftover = (buf + sizeof(buf)) - next_pos;
|
||||
// and how much is left to fill:
|
||||
std::ptrdiff_t size = next_pos - buf;
|
||||
// copy forward whatever we have left:
|
||||
std::memmove(buf, next_pos, leftover);
|
||||
// fill the rest from the stream:
|
||||
is.read(buf + leftover, size);
|
||||
std::streamsize read = is.gcount();
|
||||
// check to see if we've run out of text:
|
||||
have_more = read == size;
|
||||
// reset next_pos:
|
||||
next_pos = buf + sizeof(buf);
|
||||
// and then iterate:
|
||||
boost::cregex_iterator a(
|
||||
buf,
|
||||
buf + read + leftover,
|
||||
e,
|
||||
boost::match_default | boost::match_partial);
|
||||
boost::cregex_iterator b;
|
||||
|
||||
while(a != b)
|
||||
{
|
||||
if((*a)[0].matched == false)
|
||||
{
|
||||
// Partial match, save position and break:
|
||||
next_pos = (*a)[0].first;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// full match:
|
||||
++tags;
|
||||
}
|
||||
|
||||
// move to next match:
|
||||
++a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if(argc > 1)
|
||||
{
|
||||
for(int i = 1; i < argc; ++i)
|
||||
{
|
||||
std::ifstream fs(argv[i]);
|
||||
if(fs.bad()) continue;
|
||||
search(fs);
|
||||
fs.close();
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
81
test/module/partial_regex_match.cpp
Normal file
81
test/module/partial_regex_match.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE partial_regex_match.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_match example using partial matches.
|
||||
*/
|
||||
|
||||
|
||||
//#include <version>
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
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;
|
||||
if(argc > 1)
|
||||
input = argv[1];
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
142
test/module/regex_grep_example_1.cpp
Normal file
142
test/module/regex_grep_example_1.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_grep_example_1.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_grep example 1: searches a cpp file for class definitions.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
// 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, std::string::difference_type, std::less<std::string> > map_type;
|
||||
|
||||
const char* re =
|
||||
// possibly leading whitespace:
|
||||
"^[[:space:]]*"
|
||||
// possible template declaration:
|
||||
"(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
|
||||
// class or struct:
|
||||
"(class|struct)[[:space:]]*"
|
||||
// leading declspec macros etc:
|
||||
"("
|
||||
"\\<\\w+\\>"
|
||||
"("
|
||||
"[[:blank:]]*\\([^)]*\\)"
|
||||
")?"
|
||||
"[[:space:]]*"
|
||||
")*"
|
||||
// the class name
|
||||
"(\\<\\w*\\>)[[:space:]]*"
|
||||
// template specialisation parameters
|
||||
"(<[^;:{]+>)?[[:space:]]*"
|
||||
// terminate in { or :
|
||||
"(\\{|:[^;\\{()]*\\{)";
|
||||
|
||||
boost::regex expression(re);
|
||||
|
||||
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>& 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;
|
||||
}
|
||||
private:
|
||||
IndexClassesPred& operator=(const IndexClassesPred&);
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
void load_file(std::string& s, std::istream& is)
|
||||
{
|
||||
s.erase();
|
||||
if(is.bad()) return;
|
||||
s.reserve(static_cast<std::string::size_type>(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);
|
||||
fs.close();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
132
test/module/regex_grep_example_2.cpp
Normal file
132
test/module/regex_grep_example_2.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_grep_example_2.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_grep example 2: searches a cpp file for class definitions,
|
||||
* using a global callback function.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
// 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, std::string::difference_type, std::less<std::string> > map_type;
|
||||
|
||||
const char* re =
|
||||
// possibly leading whitespace:
|
||||
"^[[:space:]]*"
|
||||
// possible template declaration:
|
||||
"(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
|
||||
// class or struct:
|
||||
"(class|struct)[[:space:]]*"
|
||||
// leading declspec macros etc:
|
||||
"("
|
||||
"\\<\\w+\\>"
|
||||
"("
|
||||
"[[:blank:]]*\\([^)]*\\)"
|
||||
")?"
|
||||
"[[:space:]]*"
|
||||
")*"
|
||||
// the class name
|
||||
"(\\<\\w*\\>)[[:space:]]*"
|
||||
// template specialisation parameters
|
||||
"(<[^;:{]+>)?[[:space:]]*"
|
||||
// terminate in { or :
|
||||
"(\\{|:[^;\\{()]*\\{)";
|
||||
|
||||
|
||||
boost::regex expression(re);
|
||||
map_type class_index;
|
||||
std::string::const_iterator base;
|
||||
|
||||
bool grep_callback(const boost::match_results<std::string::const_iterator>& 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);
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
void load_file(std::string& s, std::istream& is)
|
||||
{
|
||||
s.erase();
|
||||
if(is.bad()) return;
|
||||
s.reserve(static_cast<std::string::size_type>(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);
|
||||
fs.close();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
144
test/module/regex_grep_example_3.cpp
Normal file
144
test/module/regex_grep_example_3.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_grep_example_3.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_grep example 3: searches a cpp file for class definitions,
|
||||
* using a bound member function callback.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
// 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, std::string::difference_type, std::less<std::string> > map_type;
|
||||
|
||||
const char* re =
|
||||
// possibly leading whitespace:
|
||||
"^[[:space:]]*"
|
||||
// possible template declaration:
|
||||
"(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
|
||||
// class or struct:
|
||||
"(class|struct)[[:space:]]*"
|
||||
// leading declspec macros etc:
|
||||
"("
|
||||
"\\<\\w+\\>"
|
||||
"("
|
||||
"[[:blank:]]*\\([^)]*\\)"
|
||||
")?"
|
||||
"[[:space:]]*"
|
||||
")*"
|
||||
// the class name
|
||||
"(\\<\\w*\\>)[[:space:]]*"
|
||||
// template specialisation parameters
|
||||
"(<[^;:{]+>)?[[:space:]]*"
|
||||
// terminate in { or :
|
||||
"(\\{|:[^;\\{()]*\\{)";
|
||||
|
||||
|
||||
class class_index
|
||||
{
|
||||
boost::regex expression;
|
||||
map_type index;
|
||||
std::string::const_iterator base;
|
||||
|
||||
bool grep_callback(boost::match_results<std::string::const_iterator> what);
|
||||
public:
|
||||
map_type& get_map() { return index; }
|
||||
void IndexClasses(const std::string& file);
|
||||
class_index()
|
||||
: expression(re) {}
|
||||
};
|
||||
|
||||
bool class_index::grep_callback(boost::match_results<std::string::const_iterator> 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([&](boost::match_results<std::string::const_iterator>const & what)->bool { return this->grep_callback(what); },
|
||||
start,
|
||||
end,
|
||||
expression);
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
void load_file(std::string& s, std::istream& is)
|
||||
{
|
||||
s.erase();
|
||||
if(is.bad()) return;
|
||||
s.reserve(static_cast<std::string::size_type>(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);
|
||||
fs.close();
|
||||
class_index idx;
|
||||
idx.IndexClasses(text);
|
||||
cout << idx.get_map().size() << " matches found" << endl;
|
||||
map_type::iterator c, d;
|
||||
c = idx.get_map().begin();
|
||||
d = idx.get_map().end();
|
||||
while(c != d)
|
||||
{
|
||||
cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl;
|
||||
++c;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
126
test/module/regex_iterator_example.cpp
Normal file
126
test/module/regex_iterator_example.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2003-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_iterator_example_2.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_iterator example 2: searches a cpp file for class definitions,
|
||||
* using global data.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 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, std::string::difference_type, std::less<std::string> > map_type;
|
||||
|
||||
const char* re =
|
||||
// possibly leading whitespace:
|
||||
"^[[:space:]]*"
|
||||
// possible template declaration:
|
||||
"(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
|
||||
// class or struct:
|
||||
"(class|struct)[[:space:]]*"
|
||||
// leading declspec macros etc:
|
||||
"("
|
||||
"\\<\\w+\\>"
|
||||
"("
|
||||
"[[:blank:]]*\\([^)]*\\)"
|
||||
")?"
|
||||
"[[:space:]]*"
|
||||
")*"
|
||||
// the class name
|
||||
"(\\<\\w*\\>)[[:space:]]*"
|
||||
// template specialisation parameters
|
||||
"(<[^;:{]+>)?[[:space:]]*"
|
||||
// terminate in { or :
|
||||
"(\\{|:[^;\\{()]*\\{)";
|
||||
|
||||
|
||||
boost::regex expression(re);
|
||||
map_type class_index;
|
||||
|
||||
bool regex_callback(const boost::match_results<std::string::const_iterator>& 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[what[5].str() + what[6].str()] = what.position(5);
|
||||
return true;
|
||||
}
|
||||
|
||||
void load_file(std::string& s, std::istream& is)
|
||||
{
|
||||
s.erase();
|
||||
if(is.bad()) return;
|
||||
s.reserve(static_cast<std::string::size_type>(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);
|
||||
fs.close();
|
||||
// construct our iterators:
|
||||
boost::sregex_iterator m1(text.begin(), text.end(), expression);
|
||||
boost::sregex_iterator m2;
|
||||
std::for_each(m1, m2, ®ex_callback);
|
||||
// copy results:
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
93
test/module/regex_match_example.cpp
Normal file
93
test/module/regex_match_example.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_match_example.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: ftp based regex_match example.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <cstdlib>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
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 std::atoi(what[1].first);
|
||||
}
|
||||
// failure did not match
|
||||
if(msg)
|
||||
msg->erase();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(int argc, const char*[])
|
||||
{
|
||||
using namespace std;
|
||||
std::string in, out;
|
||||
do
|
||||
{
|
||||
if(argc == 1)
|
||||
{
|
||||
cout << "enter test string" << endl;
|
||||
getline(cin, in);
|
||||
if(in == "quit")
|
||||
break;
|
||||
}
|
||||
else
|
||||
in = "100 this is an ftp message text";
|
||||
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;
|
||||
} while(argc == 1);
|
||||
return 0;
|
||||
}
|
||||
|
138
test/module/regex_merge_example.cpp
Normal file
138
test/module/regex_merge_example.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_merge_example.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_merge example:
|
||||
* converts a C++ file to syntax highlighted HTML.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
// 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();
|
||||
if(is.bad()) return;
|
||||
s.reserve(static_cast<std::string::size_type>(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)
|
||||
{
|
||||
try{
|
||||
e1.assign(expression_text);
|
||||
e2.assign(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);
|
||||
fs.close();
|
||||
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> oi(t);
|
||||
boost::regex_merge(oi, in.begin(), in.end(), e2, pre_format, boost::match_default | boost::format_all);
|
||||
// then output to final output stream
|
||||
// adding syntax highlighting:
|
||||
std::string s(t.str());
|
||||
std::ostream_iterator<char> out(os);
|
||||
boost::regex_merge(out, s.begin(), s.end(), e1, format_string, boost::match_default | boost::format_all);
|
||||
os << footer_text;
|
||||
os.close();
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{ return -1; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* pre_expression = "(<)|(>)|\\r";
|
||||
const char* pre_format = "(?1<)(?2>)";
|
||||
|
||||
|
||||
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";
|
||||
|
149
test/module/regex_replace_example.cpp
Normal file
149
test/module/regex_replace_example.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_replace_example.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_replace example:
|
||||
* converts a C++ file to syntax highlighted HTML.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
// 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();
|
||||
if(is.bad()) return;
|
||||
s.reserve(static_cast<std::string::size_type>(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)
|
||||
{
|
||||
try{
|
||||
e1.assign(expression_text);
|
||||
e2.assign(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);
|
||||
fs.close();
|
||||
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> oi(t);
|
||||
boost::regex_replace(oi, in.begin(), in.end(), e2, pre_format, boost::match_default | boost::format_all);
|
||||
// then output to final output stream
|
||||
// adding syntax highlighting:
|
||||
std::string s(t.str());
|
||||
std::ostream_iterator<char> out(os);
|
||||
boost::regex_replace(out, s.begin(), s.end(), e1, format_string, boost::match_default | boost::format_all);
|
||||
os << footer_text;
|
||||
os.close();
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{ return -1; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* pre_expression = "(<)|(>)|(&)|\\r";
|
||||
const char* pre_format = "(?1<)(?2>)(?3&)";
|
||||
|
||||
|
||||
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";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
139
test/module/regex_search_example.cpp
Normal file
139
test/module/regex_search_example.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_search_example.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_search example: searches a cpp file for class definitions.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
// 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, std::string::difference_type, std::less<std::string> > map_type;
|
||||
|
||||
const char* re =
|
||||
// possibly leading whitespace:
|
||||
"^[[:space:]]*"
|
||||
// possible template declaration:
|
||||
"(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
|
||||
// class or struct:
|
||||
"(class|struct)[[:space:]]*"
|
||||
// leading declspec macros etc:
|
||||
"("
|
||||
"\\<\\w+\\>"
|
||||
"("
|
||||
"[[:blank:]]*\\([^)]*\\)"
|
||||
")?"
|
||||
"[[:space:]]*"
|
||||
")*"
|
||||
// the class name
|
||||
"(\\<\\w*\\>)[[:space:]]*"
|
||||
// template specialisation parameters
|
||||
"(<[^;:{]+>)?[[:space:]]*"
|
||||
// terminate in { or :
|
||||
"(\\{|:[^;\\{()]*\\{)";
|
||||
|
||||
|
||||
boost::regex expression(re);
|
||||
|
||||
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;
|
||||
boost::match_flag_type 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
void load_file(std::string& s, std::istream& is)
|
||||
{
|
||||
s.erase();
|
||||
if(is.bad()) return;
|
||||
s.reserve(static_cast<std::string::size_type>(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);
|
||||
fs.close();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
69
test/module/regex_split_example_1.cpp
Normal file
69
test/module/regex_split_example_1.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_split_example_1.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_split example: split a string into tokens.
|
||||
*/
|
||||
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
Simport std.core;
|
||||
#else
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
unsigned tokenise(std::list<std::string>& l, std::string& s)
|
||||
{
|
||||
return boost::regex_split(std::back_inserter(l), s);
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, const char*[])
|
||||
{
|
||||
string s;
|
||||
list<string> l;
|
||||
do{
|
||||
if(argc == 1)
|
||||
{
|
||||
cout << "Enter text to split (or \"quit\" to exit): ";
|
||||
getline(cin, s);
|
||||
if(s == "quit") break;
|
||||
}
|
||||
else
|
||||
s = "This is a string of tokens";
|
||||
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(argc == 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
97
test/module/regex_split_example_2.cpp
Normal file
97
test/module/regex_split_example_2.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_split_example_2.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_split example: spit out linked URL's.
|
||||
*/
|
||||
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <list>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
boost::regex e("<\\s*A\\s+[^>]*href\\s*=\\s*\"([^\"]*)\"",
|
||||
boost::regex::normal | boost::regex::icase);
|
||||
|
||||
void load_file(std::string& s, std::istream& is)
|
||||
{
|
||||
s.erase();
|
||||
if(is.bad()) return;
|
||||
//
|
||||
// attempt to grow string buffer to match file size,
|
||||
// this doesn't always work...
|
||||
s.reserve(static_cast<std::string::size_type>(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);
|
||||
is.close();
|
||||
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);
|
||||
is.close();
|
||||
while(boost::regex_split(std::ostream_iterator<std::string>(std::cout), s, e, boost::match_default, 1)) std::cout << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
66
test/module/regex_token_iterator_eg_1.cpp
Normal file
66
test/module/regex_token_iterator_eg_1.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2003-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_token_iterator_example_1.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_token_iterator example: split a string into tokens.
|
||||
*/
|
||||
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, const char*[])
|
||||
{
|
||||
string s;
|
||||
do{
|
||||
if(argc == 1)
|
||||
{
|
||||
cout << "Enter text to split (or \"quit\" to exit): ";
|
||||
getline(cin, s);
|
||||
if(s == "quit") break;
|
||||
}
|
||||
else
|
||||
s = "This is a string of tokens";
|
||||
|
||||
boost::regex re("\\s+");
|
||||
boost::sregex_token_iterator i(s.begin(), s.end(), re, -1);
|
||||
boost::sregex_token_iterator j;
|
||||
|
||||
unsigned count = 0;
|
||||
while(i != j)
|
||||
{
|
||||
cout << *i++ << endl;
|
||||
count++;
|
||||
}
|
||||
cout << "There were " << count << " tokens found." << endl;
|
||||
|
||||
}while(argc == 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
99
test/module/regex_token_iterator_eg_2.cpp
Normal file
99
test/module/regex_token_iterator_eg_2.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2003-2022
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_token_iterator_example_2.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: regex_token_iterator example: spit out linked URL's.
|
||||
*/
|
||||
|
||||
#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS)
|
||||
import std;
|
||||
#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS)
|
||||
import std.core;
|
||||
#else
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_HEADERS
|
||||
#include <boost/regex.hpp>
|
||||
#else
|
||||
import boost.regex;
|
||||
#endif
|
||||
|
||||
boost::regex e("<\\s*A\\s+[^>]*href\\s*=\\s*\"([^\"]*)\"",
|
||||
boost::regex::normal | boost::regex::icase);
|
||||
|
||||
void load_file(std::string& s, std::istream& is)
|
||||
{
|
||||
s.erase();
|
||||
if(is.bad()) return;
|
||||
//
|
||||
// attempt to grow string buffer to match file size,
|
||||
// this doesn't always work...
|
||||
s.reserve(static_cast<std::string::size_type>(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;
|
||||
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);
|
||||
is.close();
|
||||
boost::sregex_token_iterator i(s.begin(), s.end(), e, 1);
|
||||
boost::sregex_token_iterator j;
|
||||
while(i != j)
|
||||
{
|
||||
std::cout << *i++ << std::endl;
|
||||
}
|
||||
}
|
||||
//
|
||||
// alternative method:
|
||||
// test the array-literal constructor, and split out the whole
|
||||
// match as well as $1....
|
||||
//
|
||||
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);
|
||||
is.close();
|
||||
const int subs[] = {1, 0,};
|
||||
boost::sregex_token_iterator i(s.begin(), s.end(), e, subs);
|
||||
boost::sregex_token_iterator j;
|
||||
while(i != j)
|
||||
{
|
||||
std::cout << *i++ << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
28
test/module/test_clang.sh
Executable file
28
test/module/test_clang.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Builds all of the tests in this folder using clang modules
|
||||
#
|
||||
: ${CXX:="clang++"}
|
||||
: ${CXXFLAGS:="-std=c++20 -g -I../../../.."}
|
||||
|
||||
rm *.o *.pcm *.exe
|
||||
|
||||
cmd="$CXX $CXXFLAGS -x c++-module ../../module/regex.cxx --precompile -o boost.regex.pcm"
|
||||
echo $cmd
|
||||
$cmd || exit 1
|
||||
cmd="$CXX $CXXFLAGS boost.regex.pcm -c -o regex.o"
|
||||
echo $cmd
|
||||
$cmd || exit 1
|
||||
cmd="$CXX $CXXFLAGS -fprebuilt-module-path=. -c ../../module/*.cpp"
|
||||
echo $cmd
|
||||
$cmd || exit 1
|
||||
|
||||
|
||||
for file in *.cpp; do
|
||||
|
||||
cmd="$CXX $CXXFLAGS -fprebuilt-module-path=. $file *.o -o ${file%.*}.exe"
|
||||
echo $cmd
|
||||
$cmd || exit 1
|
||||
|
||||
done
|
Reference in New Issue
Block a user