mirror of
https://gitee.com/openharmony/third_party_rust_regex
synced 2025-04-12 07:34:07 +00:00
Reorganize CI testing.
Writing all of the testing scripts inside the .travis.yml file was becoming painful, and parts of it were wrong by allowing for some commands to fail without failing the entire build. This also fixes the Github token (again).
This commit is contained in:
parent
0788aad4b7
commit
c7bc06f8d4
45
.travis.yml
45
.travis.yml
@ -1,32 +1,12 @@
|
||||
dist: trusty
|
||||
sudo: false
|
||||
language: rust
|
||||
rust:
|
||||
- 1.12.0
|
||||
- stable
|
||||
- beta
|
||||
- nightly
|
||||
sudo: false
|
||||
script:
|
||||
- cargo build --verbose
|
||||
- if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then
|
||||
cargo build --verbose --manifest-path=regex-debug/Cargo.toml;
|
||||
RUSTFLAGS="-C target-feature=+ssse3" cargo test --verbose --features 'simd-accel pattern' --jobs 2;
|
||||
else
|
||||
travis_wait cargo test --verbose --jobs 2;
|
||||
fi
|
||||
- ./run-shootout-test
|
||||
- cargo doc --verbose
|
||||
- cargo test --verbose --manifest-path=regex-syntax/Cargo.toml
|
||||
- cargo doc --verbose --manifest-path=regex-syntax/Cargo.toml
|
||||
- if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then
|
||||
(cd regex-capi && cargo build --verbose);
|
||||
(cd regex-capi/ctest && ./compile && LD_LIBRARY_PATH=../target/debug ./test);
|
||||
(cd regex-capi/examples && ./compile && LD_LIBRARY_PATH=../target/release ./iter);
|
||||
(cd bench && travis_wait ./run rust);
|
||||
(cd bench && travis_wait ./run rust-bytes --no-run);
|
||||
(cd bench && travis_wait ./run pcre1 --no-run);
|
||||
(cd bench && travis_wait ./run onig --no-run);
|
||||
travis_wait cargo test --verbose --manifest-path=regex_macros/Cargo.toml;
|
||||
fi
|
||||
script: ci/script.sh
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
@ -34,20 +14,15 @@ addons:
|
||||
- libelf-dev
|
||||
- libdw-dev
|
||||
- binutils-dev
|
||||
after_success: |
|
||||
[ $TRAVIS_BRANCH = master ] &&
|
||||
[ $TRAVIS_PULL_REQUEST = false ] &&
|
||||
[ $TRAVIS_RUST_VERSION = nightly ] &&
|
||||
echo '<meta http-equiv=refresh content=0;url=regex/index.html>' > target/doc/index.html &&
|
||||
pip install ghp-import --user $USER &&
|
||||
$HOME/.local/bin/ghp-import -n target/doc &&
|
||||
git push -qf https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages &&
|
||||
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
|
||||
tar xzf master.tar.gz && mkdir kcov-master/build && cd kcov-master/build && cmake .. && make && make install DESTDIR=../tmp && cd ../.. &&
|
||||
PATH="./kcov-master/tmp/usr/local/bin:$PATH" ./run-kcov --coveralls-id $TRAVIS_JOB_ID
|
||||
- wget
|
||||
- clang-3.6
|
||||
- cmake
|
||||
- python
|
||||
- python-virtualenv
|
||||
after_success: ci/after_success.sh
|
||||
env:
|
||||
global:
|
||||
secure: "ii5NwZiArNTxFuVnjXDHrYutkp82116hqBbzsCv/v53O5gCn1GKbCRyusFYHjr+ytymEPKH171cAQ7doGt3QPyFs2jdzK6+xz4obwCBfAPwgbtuFu9P/lIasG1ja2i/2T61g12DSlzAVTCkLnHNTLad4FWsyDyqJLpY4I4JFvcE="
|
||||
secure: "GdGE0kFYiJGccVZligur7JlWRCy49eH6uWPl71mrnaaW8jLHmkva0jVb0LB9e5ol3YMaMCgrwM2pcj3Uk2C08YcGIoEKOLlDVho351KaD6XfclZ29CQTAPMz4Xut2IcB4YeuZlDrOnM26guTIOtn2NAjeQgOhpM/ErzVBgkB+wQ="
|
||||
notifications:
|
||||
email:
|
||||
on_success: never
|
||||
|
@ -30,7 +30,7 @@ utf8-ranges = "1"
|
||||
# For examples.
|
||||
lazy_static = "0.2.2"
|
||||
# For property based tests.
|
||||
quickcheck = "0.4.1"
|
||||
quickcheck = { version = "0.4.1", default-features = false }
|
||||
# For generating random test data.
|
||||
rand = "0.3.15"
|
||||
|
||||
|
@ -14,4 +14,4 @@ install:
|
||||
build: false
|
||||
|
||||
test_script:
|
||||
- cargo test --verbose
|
||||
- cargo test --verbose --jobs 4
|
||||
|
@ -14,7 +14,7 @@ build = "build.rs"
|
||||
docopt = "0.6"
|
||||
lazy_static = "0.1"
|
||||
libc = "0.2"
|
||||
onig = { version = "0.4", optional = true }
|
||||
onig = { version = "1.2", optional = true }
|
||||
libpcre-sys = { version = "0.2", optional = true }
|
||||
memmap = "0.2"
|
||||
regex = { version = "0.2.0", path = "..", features = ["simd-accel"] }
|
||||
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef RE2_RE2_H
|
||||
#define RE2_RE2_H
|
||||
#ifndef RE2_RE2_H_
|
||||
#define RE2_RE2_H_
|
||||
|
||||
// C++ interface to the re2 regular-expression library.
|
||||
// RE2 supports Perl-style regular expressions (with extensions like
|
||||
@ -179,23 +179,25 @@
|
||||
// RE2::Octal(&a), RE2::Hex(&b), RE2::CRadix(&c), RE2::CRadix(&d));
|
||||
// will leave 64 in a, b, c, and d.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include "re2/stringpiece.h"
|
||||
#include "re2/variadic_function.h"
|
||||
|
||||
#ifndef RE2_HAVE_LONGLONG
|
||||
#define RE2_HAVE_LONGLONG 1
|
||||
#endif
|
||||
#include "re2/stringpiece.h"
|
||||
|
||||
namespace re2 {
|
||||
class Prog;
|
||||
class Regexp;
|
||||
} // namespace re2
|
||||
|
||||
namespace re2 {
|
||||
|
||||
// TODO(junyer): Get rid of this.
|
||||
using std::string;
|
||||
using std::map;
|
||||
class Prog;
|
||||
class Regexp;
|
||||
|
||||
// Interface for regular expression matching. Also corresponds to a
|
||||
// pre-compiled regular expression. An "RE2" object is safe for
|
||||
@ -251,7 +253,7 @@ class RE2 {
|
||||
RE2(const string& pattern);
|
||||
#endif
|
||||
RE2(const StringPiece& pattern);
|
||||
RE2(const StringPiece& pattern, const Options& option);
|
||||
RE2(const StringPiece& pattern, const Options& options);
|
||||
~RE2();
|
||||
|
||||
// Returns whether RE2 was created properly.
|
||||
@ -281,7 +283,7 @@ class RE2 {
|
||||
// EXPERIMENTAL! SUBJECT TO CHANGE!
|
||||
// Outputs the program fanout as a histogram bucketed by powers of 2.
|
||||
// Returns the number of the largest non-empty bucket.
|
||||
int ProgramFanout(map<int, int>* histogram) const;
|
||||
int ProgramFanout(std::map<int, int>* histogram) const;
|
||||
|
||||
// Returns the underlying Regexp; not for general use.
|
||||
// Returns entire_regexp_ so that callers don't need
|
||||
@ -290,21 +292,21 @@ class RE2 {
|
||||
|
||||
/***** The useful part: the matching interface *****/
|
||||
|
||||
// Matches "text" against "pattern". If pointer arguments are
|
||||
// Matches "text" against "re". If pointer arguments are
|
||||
// supplied, copies matched sub-patterns into them.
|
||||
//
|
||||
// You can pass in a "const char*" or a "string" for "text".
|
||||
// You can pass in a "const char*" or a "string" or a "RE2" for "pattern".
|
||||
// You can pass in a "const char*" or a "string" or a "RE2" for "re".
|
||||
//
|
||||
// The provided pointer arguments can be pointers to any scalar numeric
|
||||
// type, or one of:
|
||||
// string (matched piece is copied to string)
|
||||
// StringPiece (StringPiece is mutated to point to matched piece)
|
||||
// T (where "bool T::ParseFrom(const char*, int)" exists)
|
||||
// T (where "bool T::ParseFrom(const char*, size_t)" exists)
|
||||
// (void*)NULL (the corresponding matched sub-pattern is not copied)
|
||||
//
|
||||
// Returns true iff all of the following conditions are satisfied:
|
||||
// a. "text" matches "pattern" exactly
|
||||
// a. "text" matches "re" exactly
|
||||
// b. The number of matched sub-patterns is >= number of supplied pointers
|
||||
// c. The "i"th argument has a suitable type for holding the
|
||||
// string captured as the "i"th sub-pattern. If you pass in
|
||||
@ -320,32 +322,65 @@ class RE2 {
|
||||
// RE2::FullMatch("abc", "[a-z]+(\\d+)?", &number);
|
||||
static bool FullMatchN(const StringPiece& text, const RE2& re,
|
||||
const Arg* const args[], int argc);
|
||||
static const VariadicFunction2<
|
||||
bool, const StringPiece&, const RE2&, Arg, RE2::FullMatchN> FullMatch;
|
||||
|
||||
// Exactly like FullMatch(), except that "pattern" is allowed to match
|
||||
// Exactly like FullMatch(), except that "re" is allowed to match
|
||||
// a substring of "text".
|
||||
static bool PartialMatchN(const StringPiece& text, const RE2& re, // 3..16 args
|
||||
static bool PartialMatchN(const StringPiece& text, const RE2& re,
|
||||
const Arg* const args[], int argc);
|
||||
static const VariadicFunction2<
|
||||
bool, const StringPiece&, const RE2&, Arg, RE2::PartialMatchN> PartialMatch;
|
||||
|
||||
// Like FullMatch() and PartialMatch(), except that pattern has to
|
||||
// match a prefix of "text", and "input" is advanced past the matched
|
||||
// Like FullMatch() and PartialMatch(), except that "re" has to match
|
||||
// a prefix of the text, and "input" is advanced past the matched
|
||||
// text. Note: "input" is modified iff this routine returns true.
|
||||
static bool ConsumeN(StringPiece* input, const RE2& pattern, // 3..16 args
|
||||
static bool ConsumeN(StringPiece* input, const RE2& re,
|
||||
const Arg* const args[], int argc);
|
||||
static const VariadicFunction2<
|
||||
bool, StringPiece*, const RE2&, Arg, RE2::ConsumeN> Consume;
|
||||
|
||||
// Like Consume(..), but does not anchor the match at the beginning of the
|
||||
// string. That is, "pattern" need not start its match at the beginning of
|
||||
// "input". For example, "FindAndConsume(s, "(\\w+)", &word)" finds the next
|
||||
// word in "s" and stores it in "word".
|
||||
static bool FindAndConsumeN(StringPiece* input, const RE2& pattern,
|
||||
const Arg* const args[], int argc);
|
||||
static const VariadicFunction2<
|
||||
bool, StringPiece*, const RE2&, Arg, RE2::FindAndConsumeN> FindAndConsume;
|
||||
// Like Consume(), but does not anchor the match at the beginning of
|
||||
// the text. That is, "re" need not start its match at the beginning
|
||||
// of "input". For example, "FindAndConsume(s, "(\\w+)", &word)" finds
|
||||
// the next word in "s" and stores it in "word".
|
||||
static bool FindAndConsumeN(StringPiece* input, const RE2& re,
|
||||
const Arg* const args[], int argc);
|
||||
|
||||
#ifndef SWIG
|
||||
private:
|
||||
template <typename F, typename SP>
|
||||
static inline bool Apply(F f, SP sp, const RE2& re) {
|
||||
return f(sp, re, NULL, 0);
|
||||
}
|
||||
|
||||
template <typename F, typename SP, typename... A>
|
||||
static inline bool Apply(F f, SP sp, const RE2& re, const A&... a) {
|
||||
const Arg* const args[] = {&a...};
|
||||
const int argc = sizeof...(a);
|
||||
return f(sp, re, args, argc);
|
||||
}
|
||||
|
||||
public:
|
||||
// In order to allow FullMatch() et al. to be called with a varying number
|
||||
// of arguments of varying types, we use two layers of variadic templates.
|
||||
// The first layer constructs the temporary Arg objects. The second layer
|
||||
// (above) constructs the array of pointers to the temporary Arg objects.
|
||||
|
||||
template <typename... A>
|
||||
static bool FullMatch(const StringPiece& text, const RE2& re, A&&... a) {
|
||||
return Apply(FullMatchN, text, re, Arg(std::forward<A>(a))...);
|
||||
}
|
||||
|
||||
template <typename... A>
|
||||
static bool PartialMatch(const StringPiece& text, const RE2& re, A&&... a) {
|
||||
return Apply(PartialMatchN, text, re, Arg(std::forward<A>(a))...);
|
||||
}
|
||||
|
||||
template <typename... A>
|
||||
static bool Consume(StringPiece* input, const RE2& re, A&&... a) {
|
||||
return Apply(ConsumeN, input, re, Arg(std::forward<A>(a))...);
|
||||
}
|
||||
|
||||
template <typename... A>
|
||||
static bool FindAndConsume(StringPiece* input, const RE2& re, A&&... a) {
|
||||
return Apply(FindAndConsumeN, input, re, Arg(std::forward<A>(a))...);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Replace the first match of "pattern" in "str" with "rewrite".
|
||||
// Within "rewrite", backslash-escaped digits (\1 to \9) can be
|
||||
@ -436,12 +471,12 @@ class RE2 {
|
||||
// The map records the index of the leftmost group
|
||||
// with the given name.
|
||||
// Only valid until the re is deleted.
|
||||
const map<string, int>& NamedCapturingGroups() const;
|
||||
const std::map<string, int>& NamedCapturingGroups() const;
|
||||
|
||||
// Return a map from capturing indices to names.
|
||||
// The map has no entries for unnamed groups.
|
||||
// Only valid until the re is deleted.
|
||||
const map<int, string>& CapturingGroupNames() const;
|
||||
const std::map<int, string>& CapturingGroupNames() const;
|
||||
|
||||
// General matching routine.
|
||||
// Match against text starting at offset startpos
|
||||
@ -464,8 +499,8 @@ class RE2 {
|
||||
// whether submatch i matched the empty string or did not match:
|
||||
// either way, match[i].data() == NULL.
|
||||
bool Match(const StringPiece& text,
|
||||
int startpos,
|
||||
int endpos,
|
||||
size_t startpos,
|
||||
size_t endpos,
|
||||
Anchor anchor,
|
||||
StringPiece *match,
|
||||
int nmatch) const;
|
||||
@ -623,19 +658,7 @@ class RE2 {
|
||||
void set_one_line(bool b) { one_line_ = b; }
|
||||
|
||||
void Copy(const Options& src) {
|
||||
encoding_ = src.encoding_;
|
||||
posix_syntax_ = src.posix_syntax_;
|
||||
longest_match_ = src.longest_match_;
|
||||
log_errors_ = src.log_errors_;
|
||||
max_mem_ = src.max_mem_;
|
||||
literal_ = src.literal_;
|
||||
never_nl_ = src.never_nl_;
|
||||
dot_nl_ = src.dot_nl_;
|
||||
never_capture_ = src.never_capture_;
|
||||
case_sensitive_ = src.case_sensitive_;
|
||||
perl_classes_ = src.perl_classes_;
|
||||
word_boundary_ = src.word_boundary_;
|
||||
one_line_ = src.one_line_;
|
||||
*this = src;
|
||||
}
|
||||
|
||||
int ParseFlags() const;
|
||||
@ -654,10 +677,6 @@ class RE2 {
|
||||
bool perl_classes_;
|
||||
bool word_boundary_;
|
||||
bool one_line_;
|
||||
|
||||
//DISALLOW_COPY_AND_ASSIGN(Options);
|
||||
Options(const Options&);
|
||||
void operator=(const Options&);
|
||||
};
|
||||
|
||||
// Returns the options set in the constructor.
|
||||
@ -670,10 +689,8 @@ class RE2 {
|
||||
static inline Arg CRadix(unsigned int* x);
|
||||
static inline Arg CRadix(long* x);
|
||||
static inline Arg CRadix(unsigned long* x);
|
||||
#if RE2_HAVE_LONGLONG
|
||||
static inline Arg CRadix(long long* x);
|
||||
static inline Arg CRadix(unsigned long long* x);
|
||||
#endif
|
||||
|
||||
static inline Arg Hex(short* x);
|
||||
static inline Arg Hex(unsigned short* x);
|
||||
@ -681,10 +698,8 @@ class RE2 {
|
||||
static inline Arg Hex(unsigned int* x);
|
||||
static inline Arg Hex(long* x);
|
||||
static inline Arg Hex(unsigned long* x);
|
||||
#if RE2_HAVE_LONGLONG
|
||||
static inline Arg Hex(long long* x);
|
||||
static inline Arg Hex(unsigned long long* x);
|
||||
#endif
|
||||
|
||||
static inline Arg Octal(short* x);
|
||||
static inline Arg Octal(unsigned short* x);
|
||||
@ -692,19 +707,17 @@ class RE2 {
|
||||
static inline Arg Octal(unsigned int* x);
|
||||
static inline Arg Octal(long* x);
|
||||
static inline Arg Octal(unsigned long* x);
|
||||
#if RE2_HAVE_LONGLONG
|
||||
static inline Arg Octal(long long* x);
|
||||
static inline Arg Octal(unsigned long long* x);
|
||||
#endif
|
||||
|
||||
private:
|
||||
void Init(const StringPiece& pattern, const Options& options);
|
||||
|
||||
bool DoMatch(const StringPiece& text,
|
||||
Anchor anchor,
|
||||
int* consumed,
|
||||
const Arg* const args[],
|
||||
int n) const;
|
||||
Anchor anchor,
|
||||
size_t* consumed,
|
||||
const Arg* const args[],
|
||||
int n) const;
|
||||
|
||||
re2::Prog* ReverseProg() const;
|
||||
|
||||
@ -725,10 +738,10 @@ class RE2 {
|
||||
mutable int num_captures_; // Number of capturing groups
|
||||
|
||||
// Map from capture names to indices
|
||||
mutable const map<string, int>* named_groups_;
|
||||
mutable const std::map<string, int>* named_groups_;
|
||||
|
||||
// Map from capture indices to names
|
||||
mutable const map<int, string>* group_names_;
|
||||
mutable const std::map<int, string>* group_names_;
|
||||
|
||||
// Onces for lazy computations.
|
||||
mutable std::once_flag rprog_once_;
|
||||
@ -736,9 +749,8 @@ class RE2 {
|
||||
mutable std::once_flag named_groups_once_;
|
||||
mutable std::once_flag group_names_once_;
|
||||
|
||||
//DISALLOW_COPY_AND_ASSIGN(RE2);
|
||||
RE2(const RE2&);
|
||||
void operator=(const RE2&);
|
||||
RE2(const RE2&) = delete;
|
||||
RE2& operator=(const RE2&) = delete;
|
||||
};
|
||||
|
||||
/***** Implementation details *****/
|
||||
@ -749,7 +761,7 @@ class RE2 {
|
||||
template <class T>
|
||||
class _RE2_MatchObject {
|
||||
public:
|
||||
static inline bool Parse(const char* str, int n, void* dest) {
|
||||
static inline bool Parse(const char* str, size_t n, void* dest) {
|
||||
if (dest == NULL) return true;
|
||||
T* object = reinterpret_cast<T*>(dest);
|
||||
return object->ParseFrom(str, n);
|
||||
@ -764,31 +776,29 @@ class RE2::Arg {
|
||||
// Constructor specially designed for NULL arguments
|
||||
Arg(void*);
|
||||
|
||||
typedef bool (*Parser)(const char* str, int n, void* dest);
|
||||
typedef bool (*Parser)(const char* str, size_t n, void* dest);
|
||||
|
||||
// Type-specific parsers
|
||||
#define MAKE_PARSER(type,name) \
|
||||
Arg(type* p) : arg_(p), parser_(name) { } \
|
||||
Arg(type* p, Parser parser) : arg_(p), parser_(parser) { } \
|
||||
|
||||
#define MAKE_PARSER(type, name) \
|
||||
Arg(type* p) : arg_(p), parser_(name) {} \
|
||||
Arg(type* p, Parser parser) : arg_(p), parser_(parser) {}
|
||||
|
||||
MAKE_PARSER(char, parse_char);
|
||||
MAKE_PARSER(signed char, parse_char);
|
||||
MAKE_PARSER(signed char, parse_schar);
|
||||
MAKE_PARSER(unsigned char, parse_uchar);
|
||||
MAKE_PARSER(float, parse_float);
|
||||
MAKE_PARSER(double, parse_double);
|
||||
MAKE_PARSER(string, parse_string);
|
||||
MAKE_PARSER(StringPiece, parse_stringpiece);
|
||||
|
||||
MAKE_PARSER(short, parse_short);
|
||||
MAKE_PARSER(unsigned short, parse_ushort);
|
||||
MAKE_PARSER(int, parse_int);
|
||||
MAKE_PARSER(unsigned int, parse_uint);
|
||||
MAKE_PARSER(long, parse_long);
|
||||
MAKE_PARSER(unsigned long, parse_ulong);
|
||||
#if RE2_HAVE_LONGLONG
|
||||
MAKE_PARSER(long long, parse_longlong);
|
||||
MAKE_PARSER(unsigned long long, parse_ulonglong);
|
||||
#endif
|
||||
MAKE_PARSER(float, parse_float);
|
||||
MAKE_PARSER(double, parse_double);
|
||||
MAKE_PARSER(string, parse_string);
|
||||
MAKE_PARSER(StringPiece, parse_stringpiece);
|
||||
|
||||
#undef MAKE_PARSER
|
||||
|
||||
@ -799,29 +809,31 @@ class RE2::Arg {
|
||||
: arg_(p), parser_(parser) { }
|
||||
|
||||
// Parse the data
|
||||
bool Parse(const char* str, int n) const;
|
||||
bool Parse(const char* str, size_t n) const;
|
||||
|
||||
private:
|
||||
void* arg_;
|
||||
Parser parser_;
|
||||
|
||||
static bool parse_null (const char* str, int n, void* dest);
|
||||
static bool parse_char (const char* str, int n, void* dest);
|
||||
static bool parse_uchar (const char* str, int n, void* dest);
|
||||
static bool parse_float (const char* str, int n, void* dest);
|
||||
static bool parse_double (const char* str, int n, void* dest);
|
||||
static bool parse_string (const char* str, int n, void* dest);
|
||||
static bool parse_stringpiece (const char* str, int n, void* dest);
|
||||
static bool parse_null (const char* str, size_t n, void* dest);
|
||||
static bool parse_char (const char* str, size_t n, void* dest);
|
||||
static bool parse_schar (const char* str, size_t n, void* dest);
|
||||
static bool parse_uchar (const char* str, size_t n, void* dest);
|
||||
static bool parse_float (const char* str, size_t n, void* dest);
|
||||
static bool parse_double (const char* str, size_t n, void* dest);
|
||||
static bool parse_string (const char* str, size_t n, void* dest);
|
||||
static bool parse_stringpiece (const char* str, size_t n, void* dest);
|
||||
|
||||
#define DECLARE_INTEGER_PARSER(name) \
|
||||
private: \
|
||||
static bool parse_ ## name(const char* str, int n, void* dest); \
|
||||
static bool parse_ ## name ## _radix( \
|
||||
const char* str, int n, void* dest, int radix); \
|
||||
public: \
|
||||
static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \
|
||||
static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \
|
||||
static bool parse_ ## name ## _cradix(const char* str, int n, void* dest)
|
||||
#define DECLARE_INTEGER_PARSER(name) \
|
||||
private: \
|
||||
static bool parse_##name(const char* str, size_t n, void* dest); \
|
||||
static bool parse_##name##_radix(const char* str, size_t n, void* dest, \
|
||||
int radix); \
|
||||
\
|
||||
public: \
|
||||
static bool parse_##name##_hex(const char* str, size_t n, void* dest); \
|
||||
static bool parse_##name##_octal(const char* str, size_t n, void* dest); \
|
||||
static bool parse_##name##_cradix(const char* str, size_t n, void* dest)
|
||||
|
||||
DECLARE_INTEGER_PARSER(short);
|
||||
DECLARE_INTEGER_PARSER(ushort);
|
||||
@ -829,29 +841,31 @@ class RE2::Arg {
|
||||
DECLARE_INTEGER_PARSER(uint);
|
||||
DECLARE_INTEGER_PARSER(long);
|
||||
DECLARE_INTEGER_PARSER(ulong);
|
||||
#if RE2_HAVE_LONGLONG
|
||||
DECLARE_INTEGER_PARSER(longlong);
|
||||
DECLARE_INTEGER_PARSER(ulonglong);
|
||||
#endif
|
||||
|
||||
#undef DECLARE_INTEGER_PARSER
|
||||
|
||||
};
|
||||
|
||||
inline RE2::Arg::Arg() : arg_(NULL), parser_(parse_null) { }
|
||||
inline RE2::Arg::Arg(void* p) : arg_(p), parser_(parse_null) { }
|
||||
|
||||
inline bool RE2::Arg::Parse(const char* str, int n) const {
|
||||
inline bool RE2::Arg::Parse(const char* str, size_t n) const {
|
||||
return (*parser_)(str, n, arg_);
|
||||
}
|
||||
|
||||
// This part of the parser, appropriate only for ints, deals with bases
|
||||
#define MAKE_INTEGER_PARSER(type, name) \
|
||||
inline RE2::Arg RE2::Hex(type* ptr) { \
|
||||
return RE2::Arg(ptr, RE2::Arg::parse_ ## name ## _hex); } \
|
||||
inline RE2::Arg RE2::Octal(type* ptr) { \
|
||||
return RE2::Arg(ptr, RE2::Arg::parse_ ## name ## _octal); } \
|
||||
inline RE2::Arg RE2::CRadix(type* ptr) { \
|
||||
return RE2::Arg(ptr, RE2::Arg::parse_ ## name ## _cradix); }
|
||||
#define MAKE_INTEGER_PARSER(type, name) \
|
||||
inline RE2::Arg RE2::Hex(type* ptr) { \
|
||||
return RE2::Arg(ptr, RE2::Arg::parse_##name##_hex); \
|
||||
} \
|
||||
inline RE2::Arg RE2::Octal(type* ptr) { \
|
||||
return RE2::Arg(ptr, RE2::Arg::parse_##name##_octal); \
|
||||
} \
|
||||
inline RE2::Arg RE2::CRadix(type* ptr) { \
|
||||
return RE2::Arg(ptr, RE2::Arg::parse_##name##_cradix); \
|
||||
}
|
||||
|
||||
MAKE_INTEGER_PARSER(short, short)
|
||||
MAKE_INTEGER_PARSER(unsigned short, ushort)
|
||||
@ -859,15 +873,62 @@ MAKE_INTEGER_PARSER(int, int)
|
||||
MAKE_INTEGER_PARSER(unsigned int, uint)
|
||||
MAKE_INTEGER_PARSER(long, long)
|
||||
MAKE_INTEGER_PARSER(unsigned long, ulong)
|
||||
#if RE2_HAVE_LONGLONG
|
||||
MAKE_INTEGER_PARSER(long long, longlong)
|
||||
MAKE_INTEGER_PARSER(unsigned long long, ulonglong)
|
||||
#endif
|
||||
|
||||
#undef MAKE_INTEGER_PARSER
|
||||
|
||||
#ifndef SWIG
|
||||
// Helper for writing global or static RE2s safely.
|
||||
// Write
|
||||
// static LazyRE2 re = {".*"};
|
||||
// and then use *re instead of writing
|
||||
// static RE2 re(".*");
|
||||
// The former is more careful about multithreaded
|
||||
// situations than the latter.
|
||||
//
|
||||
// N.B. This class never deletes the RE2 object that
|
||||
// it constructs: that's a feature, so that it can be used
|
||||
// for global and function static variables.
|
||||
class LazyRE2 {
|
||||
private:
|
||||
struct NoArg {};
|
||||
|
||||
public:
|
||||
typedef RE2 element_type; // support std::pointer_traits
|
||||
|
||||
// Constructor omitted to preserve braced initialization in C++98.
|
||||
|
||||
// Pretend to be a pointer to Type (never NULL due to on-demand creation):
|
||||
RE2& operator*() const { return *get(); }
|
||||
RE2* operator->() const { return get(); }
|
||||
|
||||
// Named accessor/initializer:
|
||||
RE2* get() const {
|
||||
std::call_once(once_, [this]() { LazyRE2::Init(this); });
|
||||
return ptr_;
|
||||
}
|
||||
|
||||
// All data fields must be public to support {"foo"} initialization.
|
||||
const char* pattern_;
|
||||
RE2::CannedOptions options_;
|
||||
NoArg barrier_against_excess_initializers_;
|
||||
|
||||
mutable RE2* ptr_;
|
||||
mutable std::once_flag once_;
|
||||
|
||||
private:
|
||||
static void Init(const LazyRE2* lazy_re2) {
|
||||
lazy_re2->ptr_ = new RE2(lazy_re2->pattern_, lazy_re2->options_);
|
||||
}
|
||||
|
||||
void operator=(const LazyRE2&); // disallowed
|
||||
};
|
||||
#endif // SWIG
|
||||
|
||||
} // namespace re2
|
||||
|
||||
using re2::RE2;
|
||||
using re2::LazyRE2;
|
||||
|
||||
#endif /* RE2_RE2_H */
|
||||
#endif // RE2_RE2_H_
|
||||
|
34
ci/after_success.sh
Executable file
34
ci/after_success.sh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This runs only when a commit is pushed to master. It is responsible for
|
||||
# updating docs and computing coverage statistics.
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$TRAVIS_RUST_VERSION" != "nightly" ] || [ "$TRAVIS_PULL_REQUEST" != "false" ] || [ "$TRAVIS_BRANCH" != "master" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
env
|
||||
|
||||
# Build and upload docs.
|
||||
echo '<meta http-equiv=refresh content=0;url=regex/index.html>' > target/doc/index.html
|
||||
ve=$(mktemp -d)
|
||||
virtualenv "$ve"
|
||||
"$ve"/bin/pip install --upgrade pip
|
||||
"$ve"/bin/pip install ghp-import
|
||||
"$ve"/bin/ghp-import -n target/doc
|
||||
git push -qf https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
|
||||
|
||||
# Install kcov.
|
||||
tmp=$(mktemp -d)
|
||||
pushd "$tmp"
|
||||
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz
|
||||
tar zxf master.tar.gz
|
||||
mkdir kcov-master/build
|
||||
cd kcov-master/build
|
||||
cmake ..
|
||||
make
|
||||
make install DESTDIR="$tmp"
|
||||
popd
|
||||
PATH="$tmp/usr/local/bin:$PATH" ./ci/run-kcov --coveralls-id $TRAVIS_JOB_ID
|
@ -12,7 +12,6 @@ tests=(
|
||||
nfa_utf8bytes
|
||||
nfa_bytes
|
||||
regex
|
||||
regex_inline
|
||||
)
|
||||
tmpdir=$(mktemp -d)
|
||||
with_plugin=
|
||||
@ -43,7 +42,7 @@ if [ -n "$with_plugin" ]; then
|
||||
$(ls -t ./regex_macros/target/debug/plugin-* | head -n1)
|
||||
fi
|
||||
|
||||
cargo test --no-run --verbose
|
||||
cargo test --no-run --verbose --jobs 4
|
||||
for t in ${tests[@]}; do
|
||||
kcov \
|
||||
--verify \
|
35
ci/script.sh
Executable file
35
ci/script.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This is the main CI script for testing the regex crate and its sub-crates.
|
||||
|
||||
set -e
|
||||
|
||||
# Builds the regex crate and runs tests.
|
||||
cargo build --verbose
|
||||
cargo doc --verbose
|
||||
if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then
|
||||
cargo build --verbose --manifest-path regex-debug/Cargo.toml
|
||||
RUSTFLAGS="-C target-feature=+ssse3" cargo test --verbose --features 'simd-accel pattern' --jobs 4
|
||||
else
|
||||
cargo test --verbose --jobs 4
|
||||
fi
|
||||
|
||||
# Run a test that confirms the shootout benchmarks are correct.
|
||||
ci/run-shootout-test
|
||||
|
||||
# Run tests on regex-syntax crate.
|
||||
cargo test --verbose --manifest-path regex-syntax/Cargo.toml
|
||||
cargo doc --verbose --manifest-path regex-syntax/Cargo.toml
|
||||
|
||||
# Run tests on regex-capi crate.
|
||||
cargo build --verbose --manifest-path regex-capi/Cargo.toml
|
||||
(cd regex-capi/ctest && ./compile && LD_LIBRARY_PATH=../target/debug ./test)
|
||||
(cd regex-capi/examples && ./compile && LD_LIBRARY_PATH=../target/release ./iter)
|
||||
|
||||
# Make sure benchmarks compile. Don't run them though because they take a
|
||||
# very long time.
|
||||
if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then
|
||||
for x in rust rust-bytes pcre1 onig; do
|
||||
(cd bench && ./run $x --no-run)
|
||||
done
|
||||
fi
|
@ -9,5 +9,5 @@ homepage = "https://github.com/rust-lang/regex"
|
||||
description = "A regular expression parser."
|
||||
|
||||
[dev-dependencies]
|
||||
quickcheck = "0.4.1"
|
||||
quickcheck = { version = "0.4.1", default-features = false }
|
||||
rand = "0.3.15"
|
||||
|
Loading…
x
Reference in New Issue
Block a user