summaryrefslogtreecommitdiff
path: root/utils/tfstats/regexp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/tfstats/regexp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/tfstats/regexp')
-rw-r--r--utils/tfstats/regexp/include/cregex5
-rw-r--r--utils/tfstats/regexp/include/cregex.h11
-rw-r--r--utils/tfstats/regexp/include/fileiter.h13
-rw-r--r--utils/tfstats/regexp/include/jm/cregex.h309
-rw-r--r--utils/tfstats/regexp/include/jm/fileiter.h368
-rw-r--r--utils/tfstats/regexp/include/jm/jm_cfg.h1057
-rw-r--r--utils/tfstats/regexp/include/jm/jm_opt.h414
-rw-r--r--utils/tfstats/regexp/include/jm/jstack.h209
-rw-r--r--utils/tfstats/regexp/include/jm/re_cls.h79
-rw-r--r--utils/tfstats/regexp/include/jm/re_coll.h61
-rw-r--r--utils/tfstats/regexp/include/jm/re_kmp.h112
-rw-r--r--utils/tfstats/regexp/include/jm/re_lib.h155
-rw-r--r--utils/tfstats/regexp/include/jm/re_lst.h184
-rw-r--r--utils/tfstats/regexp/include/jm/re_mss.h90
-rw-r--r--utils/tfstats/regexp/include/jm/re_nls.h371
-rw-r--r--utils/tfstats/regexp/include/jm/re_raw.h185
-rw-r--r--utils/tfstats/regexp/include/jm/re_str.h301
-rw-r--r--utils/tfstats/regexp/include/jm/re_thrd.h169
-rw-r--r--utils/tfstats/regexp/include/jm/regcomp.h1888
-rw-r--r--utils/tfstats/regexp/include/jm/regex.h1722
-rw-r--r--utils/tfstats/regexp/include/jm/regfac.h168
-rw-r--r--utils/tfstats/regexp/include/jm/regfmt.h565
-rw-r--r--utils/tfstats/regexp/include/jm/regmatch.h1707
-rw-r--r--utils/tfstats/regexp/include/regex3
-rw-r--r--utils/tfstats/regexp/include/regex.h16
-rw-r--r--utils/tfstats/regexp/lib/libregex++.abin0 -> 845616 bytes
-rw-r--r--utils/tfstats/regexp/lib/mre200.libbin0 -> 477874 bytes
-rw-r--r--utils/tfstats/regexp/lib/mre200d.libbin0 -> 1984456 bytes
28 files changed, 10162 insertions, 0 deletions
diff --git a/utils/tfstats/regexp/include/cregex b/utils/tfstats/regexp/include/cregex
new file mode 100644
index 0000000..d5d7541
--- /dev/null
+++ b/utils/tfstats/regexp/include/cregex
@@ -0,0 +1,5 @@
+#ifndef CREGEX_H
+#include <jm/cregex.h>
+#endif
+
+
diff --git a/utils/tfstats/regexp/include/cregex.h b/utils/tfstats/regexp/include/cregex.h
new file mode 100644
index 0000000..ae03b6b
--- /dev/null
+++ b/utils/tfstats/regexp/include/cregex.h
@@ -0,0 +1,11 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef CREGEX_H
+#include <jm/cregex.h>
+#endif
+
diff --git a/utils/tfstats/regexp/include/fileiter.h b/utils/tfstats/regexp/include/fileiter.h
new file mode 100644
index 0000000..3842cbb
--- /dev/null
+++ b/utils/tfstats/regexp/include/fileiter.h
@@ -0,0 +1,13 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef __FILEITER_H
+
+#include <jm/fileiter.h>
+
+#endif
+
diff --git a/utils/tfstats/regexp/include/jm/cregex.h b/utils/tfstats/regexp/include/jm/cregex.h
new file mode 100644
index 0000000..f628522
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/cregex.h
@@ -0,0 +1,309 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE cregex.h
+ * VERSION 2.12
+ */
+
+#ifndef CREGEX_H
+#define CREGEX_H
+
+#include <jm/jm_cfg.h>
+
+/* include these defs only for POSIX compatablity */
+
+typedef int regoff_t;
+
+typedef struct
+{
+ unsigned int re_magic;
+ unsigned int re_nsub; /* number of parenthesized subexpressions */
+ const char* re_endp; /* end pointer for REG_PEND */
+ void* guts; /* none of your business :-) */
+ unsigned int eflags; /* none of your business :-) */
+} regex_tA;
+
+#ifndef JM_NO_WCSTRING
+typedef struct
+{
+ unsigned int re_magic;
+ unsigned int re_nsub; /* number of parenthesized subexpressions */
+ const wchar_t* re_endp; /* end pointer for REG_PEND */
+ void* guts; /* none of your business :-) */
+ unsigned int eflags; /* none of your business :-) */
+} regex_tW;
+#endif
+
+typedef struct
+{
+ regoff_t rm_so; /* start of match */
+ regoff_t rm_eo; /* end of match */
+} regmatch_t;
+
+/* regcomp() flags */
+#define REG_BASIC 0000
+#define REG_EXTENDED 0001
+#define REG_ICASE 0002
+#define REG_NOSUB 0004
+#define REG_NEWLINE 0010
+#define REG_NOSPEC 0020
+#define REG_PEND 0040
+#define REG_DUMP 0200
+#define REG_NOCOLLATE 0400
+
+#define REG_ASSERT 15
+#define REG_INVARG 16
+#define REG_ATOI 255 /* convert name to number (!) */
+#define REG_ITOA 0400 /* convert number to name (!) */
+
+/* regexec() flags */
+#define REG_NOTBOL 00001
+#define REG_NOTEOL 00002
+#define REG_STARTEND 00004
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JM_IX_DECL int RE_CCALL regcompA(regex_tA*, const char*, int);
+JM_IX_DECL unsigned int RE_CCALL regerrorA(int, const regex_tA*, char*, unsigned int);
+JM_IX_DECL int RE_CCALL regexecA(const regex_tA*, const char*, unsigned int, regmatch_t*, int);
+JM_IX_DECL void RE_CCALL regfreeA(regex_tA*);
+
+#ifndef JM_NO_WCSTRING
+JM_IX_DECL int RE_CCALL regcompW(regex_tW*, const wchar_t*, int);
+JM_IX_DECL unsigned int RE_CCALL regerrorW(int, const regex_tW*, wchar_t*, unsigned int);
+JM_IX_DECL int RE_CCALL regexecW(const regex_tW*, const wchar_t*, unsigned int, regmatch_t*, int);
+JM_IX_DECL void RE_CCALL regfreeW(regex_tW*);
+#endif
+
+#ifdef UNICODE
+#define regcomp regcompW
+#define regerror regerrorW
+#define regexec regexecW
+#define regfree regfreeW
+#define regex_t regex_tW
+#else
+#define regcomp regcompA
+#define regerror regerrorA
+#define regexec regexecA
+#define regfree regfreeA
+#define regex_t regex_tA
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#ifdef __cplusplus
+JM_NAMESPACE(__JM)
+#endif
+
+/* regerror() flags */
+typedef enum
+{
+ REG_NOERROR = 0, /* Success. */
+ REG_NOMATCH = 1, /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+ REG_BADPAT = 2, /* Invalid pattern. */
+ REG_ECOLLATE = 3, /* Undefined collating element. */
+ REG_ECTYPE = 4, /* Invalid character class name. */
+ REG_EESCAPE = 5, /* Trailing backslash. */
+ REG_ESUBREG = 6, /* Invalid back reference. */
+ REG_EBRACK = 7, /* Unmatched left bracket. */
+ REG_EPAREN = 8, /* Parenthesis imbalance. */
+ REG_EBRACE = 9, /* Unmatched \{. */
+ REG_BADBR = 10, /* Invalid contents of \{\}. */
+ REG_ERANGE = 11, /* Invalid range end. */
+ REG_ESPACE = 12, /* Ran out of memory. */
+ REG_BADRPT = 13, /* No preceding re for repetition op. */
+ REG_EEND = 14, /* unexpected end of expression */
+ REG_ESIZE = 15, /* expression too big */
+ REG_ERPAREN = 16, /* unmatched right parenthesis */
+ REG_EMPTY = 17, /* empty expression */
+ REG_E_MEMORY = 18, /* out of memory */
+ REG_E_UNKNOWN = 19 /* unknown error */
+} reg_errcode_t;
+
+enum match_flags
+{
+ match_default = 0,
+ match_not_bol = 1, // first is not start of line
+ match_not_eol = match_not_bol << 1, // last is not end of line
+ match_not_bob = match_not_eol << 1, // first is not start of buffer
+ match_not_eob = match_not_bob << 1, // last is not end of buffer
+ match_not_bow = match_not_eob << 1, // first is not start of word
+ match_not_eow = match_not_bow << 1, // last is not end of word
+ match_not_dot_newline = match_not_eow << 1, // \n is not matched by '.'
+ match_not_dot_null = match_not_dot_newline << 1, // '\0' is not matched by '.'
+ match_prev_avail = match_not_dot_null << 1, // *--first is a valid expression
+ match_init = match_prev_avail << 1, // internal use
+ match_any = match_init << 1, // don't care what we match
+ match_not_null = match_any << 1, // string can't be null
+ match_continuous = match_not_null << 1, // each grep match must continue from
+ // uninterupted from the previous one
+ match_stop = match_continuous << 1 // stop after first match (grep)
+};
+
+
+
+#ifdef __cplusplus
+JM_END_NAMESPACE
+#endif
+
+//
+// C++ high level wrapper goes here:
+//
+#if defined(__cplusplus) && !defined(JM_NO_STRING_H)
+#include <string>
+#include <vector>
+JM_NAMESPACE(__JM)
+
+class RegExData;
+class RegEx;
+struct pred1;
+struct pred2;
+struct pred3;
+struct pred4;
+
+typedef bool (*GrepCallback)(const RegEx& expression);
+typedef bool (*GrepFileCallback)(const char* file, const RegEx& expression);
+typedef bool (*FindFilesCallback)(const char* file);
+
+class JM_IX_DECL RegEx
+{
+private:
+ RegExData* pdata;
+public:
+ RegEx();
+ RegEx(const RegEx& o);
+ ~RegEx();
+ RegEx(const char* c, bool icase = false);
+ RegEx(const __JM_STD::string& s, bool icase = false);
+ RegEx& operator=(const RegEx& o);
+ RegEx& operator=(const char* p);
+ RegEx& operator=(const __JM_STD::string& s){ return this->operator=(s.c_str()); }
+ unsigned int SetExpression(const char* p, bool icase = false);
+ unsigned int SetExpression(const __JM_STD::string& s, bool icase = false){ return SetExpression(s.c_str(), icase); }
+ __JM_STD::string Expression()const;
+ //
+ // now matching operators:
+ //
+ bool Match(const char* p, unsigned int flags = match_default);
+ bool Match(const __JM_STD::string& s, unsigned int flags = match_default) { return Match(s.c_str(), flags); }
+ bool Search(const char* p, unsigned int flags = match_default);
+ bool Search(const __JM_STD::string& s, unsigned int flags = match_default) { return Search(s.c_str(), flags); }
+ unsigned int Grep(GrepCallback cb, const char* p, unsigned int flags = match_default);
+ unsigned int Grep(GrepCallback cb, const __JM_STD::string& s, unsigned int flags = match_default) { return Grep(cb, s.c_str(), flags); }
+ unsigned int Grep(__JM_STD::vector<__JM_STD::string>& v, const char* p, unsigned int flags = match_default);
+ unsigned int Grep(__JM_STD::vector<__JM_STD::string>& v, const __JM_STD::string& s, unsigned int flags = match_default) { return Grep(v, s.c_str(), flags); }
+ unsigned int Grep(__JM_STD::vector<unsigned int>& v, const char* p, unsigned int flags = match_default);
+ unsigned int Grep(__JM_STD::vector<unsigned int>& v, const __JM_STD::string& s, unsigned int flags = match_default) { return Grep(v, s.c_str(), flags); }
+ unsigned int GrepFiles(GrepFileCallback cb, const char* files, bool recurse = false, unsigned int flags = match_default);
+ unsigned int GrepFiles(GrepFileCallback cb, const __JM_STD::string& files, bool recurse = false, unsigned int flags = match_default) { return GrepFiles(cb, files.c_str(), recurse, flags); }
+ unsigned int FindFiles(FindFilesCallback cb, const char* files, bool recurse = false, unsigned int flags = match_default);
+ unsigned int FindFiles(FindFilesCallback cb, const __JM_STD::string& files, bool recurse = false, unsigned int flags = match_default) { return FindFiles(cb, files.c_str(), recurse, flags); }
+ //
+ // now operators for returning what matched in more detail:
+ //
+ unsigned int Position(int i = 0)const;
+ unsigned int Length(int i = 0)const;
+ unsigned int Line()const;
+ unsigned int Marks()const;
+ __JM_STD::string What(int i = 0)const;
+ __JM_STD::string operator[](int i)const { return What(i); }
+
+ friend struct pred1;
+ friend struct pred2;
+ friend struct pred3;
+ friend struct pred4;
+};
+
+
+JM_END_NAMESPACE
+
+#if !defined(JM_NO_NAMESPACES) && !defined(JM_NO_USING) && defined(__cplusplus)
+
+using __JM::RegEx;
+using __JM::GrepCallback;
+using __JM::GrepFileCallback;
+using __JM::FindFilesCallback;
+
+#endif
+
+#endif // __cplusplus
+
+#if !defined(JM_NO_NAMESPACES) && !defined(JM_NO_USING) && defined(__cplusplus)
+
+using __JM::match_flags;
+using __JM::reg_errcode_t;
+
+using __JM::REG_NOERROR;
+using __JM::REG_NOMATCH;
+using __JM::REG_BADPAT;
+using __JM::REG_ECOLLATE;
+using __JM::REG_ECTYPE;
+using __JM::REG_EESCAPE;
+using __JM::REG_ESUBREG;
+using __JM::REG_EBRACK;
+using __JM::REG_EPAREN;
+using __JM::REG_EBRACE;
+using __JM::REG_BADBR;
+using __JM::REG_ERANGE;
+using __JM::REG_ESPACE;
+using __JM::REG_BADRPT;
+using __JM::REG_EEND;
+using __JM::REG_ESIZE;
+using __JM::REG_ERPAREN;
+using __JM::REG_EMPTY;
+using __JM::REG_E_MEMORY;
+using __JM::REG_E_UNKNOWN;
+using __JM::match_default;
+using __JM::match_not_bol;
+using __JM::match_not_eol;
+using __JM::match_not_bob;
+using __JM::match_not_eob;
+using __JM::match_not_bow;
+using __JM::match_not_eow;
+using __JM::match_not_dot_newline;
+using __JM::match_not_dot_null;
+using __JM::match_prev_avail;
+using __JM::match_init;
+using __JM::match_any;
+using __JM::match_not_null;
+using __JM::match_continuous;
+using __JM::match_stop;
+
+#endif
+
+
+#endif
+
+
+
+
+
diff --git a/utils/tfstats/regexp/include/jm/fileiter.h b/utils/tfstats/regexp/include/jm/fileiter.h
new file mode 100644
index 0000000..b886a1d
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/fileiter.h
@@ -0,0 +1,368 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ *
+ * FILE fileiter.h
+ * VERSION 2.12
+ *
+ * this file declares various platform independent file and directory
+ * iterators, plus binary file input in the form of class map_file.
+ *
+ */
+
+
+#ifndef __FILEITER_H
+#define __FILEITER_H
+
+#include <jm/jm_cfg.h>
+
+#if (defined(__WIN32__) || defined(_WIN32) || defined(WIN32)) && !defined(JM_NO_WIN32)
+
+#define FI_W32
+#include <windows.h>
+
+JM_NAMESPACE(__JM)
+
+typedef WIN32_FIND_DATA _fi_find_data;
+typedef HANDLE _fi_find_handle;
+
+JM_END_NAMESPACE
+
+#define _fi_invalid_handle INVALID_HANDLE_VALUE
+#define _fi_dir FILE_ATTRIBUTE_DIRECTORY
+
+#else
+
+#include <stdio.h>
+#include <ctype.h>
+#ifndef JM_NO_STL
+#include <iterator>
+#include <list>
+#if defined(__SUNPRO_CC) && !defined(JM_NO_NAMESPACES)
+using __JM_STD::list;
+#endif
+#endif
+#include <assert.h>
+#include <dirent.h>
+
+#ifndef MAX_PATH
+#define MAX_PATH 256
+#endif
+
+JM_NAMESPACE(__JM)
+
+struct _fi_find_data
+{
+ unsigned dwFileAttributes;
+ char cFileName[MAX_PATH];
+};
+
+struct _fi_priv_data;
+
+typedef _fi_priv_data* _fi_find_handle;
+#define _fi_invalid_handle NULL
+#define _fi_dir 1
+
+_fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindFileData);
+bool _fi_FindNextFile(_fi_find_handle hFindFile, _fi_find_data* lpFindFileData);
+bool _fi_FindClose(_fi_find_handle hFindFile);
+
+JM_END_NAMESPACE
+
+#ifdef FindFirstFile
+ #undef FindFirstFile
+#endif
+#ifdef FindNextFile
+ #undef FindNextFile
+#endif
+#ifdef FindClose
+ #undef FindClose
+#endif
+
+#define FindFirstFile _fi_FindFirstFile
+#define FindNextFile _fi_FindNextFile
+#define FindClose _fi_FindClose
+
+#endif
+
+JM_NAMESPACE(__JM)
+
+#ifdef FI_W32 // win32 mapfile
+
+class JM_IX_DECL mapfile
+{
+ HANDLE hfile;
+ HANDLE hmap;
+ const char* _first;
+ const char* _last;
+public:
+
+ typedef const char* iterator;
+
+ mapfile(){ hfile = hmap = 0; _first = _last = 0; }
+ mapfile(const char* file){ hfile = hmap = 0; _first = _last = 0; open(file); }
+ ~mapfile(){ close(); }
+ void open(const char* file);
+ void close();
+ const char* begin(){ return _first; }
+ const char* end(){ return _last; }
+ size_t size(){ return _last - _first; }
+ bool valid(){ return (hfile != 0) && (hfile != INVALID_HANDLE_VALUE); }
+};
+
+
+#elif !defined(JM_NO_STL) // use POSIX API to emulate the memory map:
+
+class JM_IX_DECL mapfile_iterator;
+
+class JM_IX_DECL mapfile
+{
+ typedef char* pointer;
+ FILE* hfile;
+ long int _size;
+ pointer* _first;
+ pointer* _last;
+ mutable __JM_STD::list<pointer*> condemed;
+ enum sizes
+ {
+ buf_size = 4096
+ };
+ void lock(pointer* node)const;
+ void unlock(pointer* node)const;
+public:
+
+ typedef mapfile_iterator iterator;
+
+ mapfile(){ hfile = 0; _size = 0; _first = _last = 0; }
+ mapfile(const char* file){ hfile = 0; _size = 0; _first = _last = 0; open(file); }
+ ~mapfile(){ close(); }
+ void open(const char* file);
+ void close();
+ iterator begin()const;
+ iterator end()const;
+ unsigned long size()const{ return _size; }
+ bool valid()const{ return hfile != 0; }
+ friend class mapfile_iterator;
+};
+
+class JM_IX_DECL mapfile_iterator : public JM_RA_ITERATOR(char, long)
+{
+ typedef mapfile::pointer pointer;
+ pointer* node;
+ const mapfile* file;
+ unsigned long offset;
+ long position()const
+ {
+ return file ? ((node - file->_first) * mapfile::buf_size + offset) : 0;
+ }
+ void position(long pos)
+ {
+ if(file)
+ {
+ node = file->_first + (pos / mapfile::buf_size);
+ offset = pos % mapfile::buf_size;
+ }
+ }
+public:
+ mapfile_iterator() { node = 0; file = 0; offset = 0; }
+ mapfile_iterator(const mapfile* f, long position)
+ {
+ file = f;
+ node = f->_first + position / mapfile::buf_size;
+ offset = position % mapfile::buf_size;
+ if(file)
+ file->lock(node);
+ }
+ mapfile_iterator(const mapfile_iterator& i)
+ {
+ file = i.file;
+ node = i.node;
+ offset = i.offset;
+ if(file)
+ file->lock(node);
+ }
+ ~mapfile_iterator()
+ {
+ if(file && node)
+ file->unlock(node);
+ }
+ mapfile_iterator& operator = (const mapfile_iterator& i);
+ char operator* ()const
+ {
+ assert(node >= file->_first);
+ assert(node < file->_last);
+ return file ? *(*node + sizeof(int) + offset) : char(0);
+ }
+ mapfile_iterator& operator++ ();
+ mapfile_iterator operator++ (int);
+ mapfile_iterator& operator-- ();
+ mapfile_iterator operator-- (int);
+
+ mapfile_iterator& operator += (long off)
+ {
+ position(position() + off);
+ return *this;
+ }
+ mapfile_iterator& operator -= (long off)
+ {
+ position(position() - off);
+ return *this;
+ }
+
+ friend inline bool operator==(const mapfile_iterator& i, const mapfile_iterator& j)
+ {
+ return (i.file == j.file) && (i.node == j.node) && (i.offset == j.offset);
+ }
+#ifndef JM_NO_NOT_EQUAL
+ friend inline bool operator!=(const mapfile_iterator& i, const mapfile_iterator& j)
+ {
+ return !(i == j);
+ }
+#endif
+ friend inline bool operator<(const mapfile_iterator& i, const mapfile_iterator& j)
+ {
+ return i.position() < j.position();
+ }
+
+ friend mapfile_iterator operator + (const mapfile_iterator& i, long off);
+ friend mapfile_iterator operator - (const mapfile_iterator& i, long off);
+ friend inline long operator - (const mapfile_iterator& i, const mapfile_iterator& j)
+ {
+ return i.position() - j.position();
+ }
+};
+
+#endif
+
+// _fi_sep determines the directory separator, either '\\' or '/'
+JM_IX_DECL extern const char* _fi_sep;
+
+struct file_iterator_ref
+{
+ _fi_find_handle hf;
+ _fi_find_data _data;
+ long count;
+};
+
+
+class JM_IX_DECL file_iterator : public JM_INPUT_ITERATOR(const char*, __JM_STDC::ptrdiff_t)
+{
+ char* _root;
+ char* _path;
+ char* ptr;
+ file_iterator_ref* ref;
+
+public:
+ file_iterator();
+ file_iterator(const char* wild);
+ ~file_iterator();
+ file_iterator(const file_iterator&);
+ file_iterator& operator=(const file_iterator&);
+ const char* root() { return _root; }
+ const char* path() { return _path; }
+ _fi_find_data* data() { return &(ref->_data); }
+ void next();
+ file_iterator& operator++() { next(); return *this; }
+ file_iterator operator++(int);
+ const char* operator*() { return path(); }
+
+ friend inline bool operator == (const file_iterator& f1, const file_iterator& f2)
+ {
+ return ((f1.ref->hf == _fi_invalid_handle) && (f1.ref->hf == _fi_invalid_handle));
+ }
+#ifndef JM_NO_NOT_EQUAL
+ friend inline bool operator != (const file_iterator& f1, const file_iterator& f2)
+ {
+ return !(f1 == f2);
+ }
+#endif
+};
+
+inline bool operator < (const file_iterator& f1, const file_iterator& f2)
+{
+ return false;
+}
+
+
+class JM_IX_DECL directory_iterator : public JM_INPUT_ITERATOR(const char*, __JM_STDC::ptrdiff_t)
+{
+ char* _root;
+ char* _path;
+ char* ptr;
+ file_iterator_ref* ref;
+
+public:
+ directory_iterator();
+ directory_iterator(const char* wild);
+ ~directory_iterator();
+ directory_iterator(const directory_iterator& other);
+ directory_iterator& operator=(const directory_iterator& other);
+
+ const char* root() { return _root; }
+ const char* path() { return _path; }
+ _fi_find_data* data() { return &(ref->_data); }
+ void next();
+ directory_iterator& operator++() { next(); return *this; }
+ directory_iterator operator++(int);
+ const char* operator*() { return path(); }
+
+ static const char* separator() { return _fi_sep; }
+
+ friend inline bool operator == (const directory_iterator& f1, const directory_iterator& f2)
+ {
+ return ((f1.ref->hf == _fi_invalid_handle) && (f1.ref->hf == _fi_invalid_handle));
+ }
+
+#ifndef JM_NO_NOT_EQUAL
+ friend inline bool operator != (const directory_iterator& f1, const directory_iterator& f2)
+ {
+ return !(f1 == f2);
+ }
+#endif
+};
+
+inline bool operator < (const directory_iterator& f1, const directory_iterator& f2)
+{
+ return false;
+}
+
+JM_END_NAMESPACE
+
+#if !defined(JM_NO_NAMESPACES) && !defined(JM_NO_USING)
+
+using __JM::directory_iterator;
+using __JM::file_iterator;
+using __JM::mapfile;
+
+#endif
+
+
+#endif // __WINITER_H
+
+
+
+
+
+
+
+
diff --git a/utils/tfstats/regexp/include/jm/jm_cfg.h b/utils/tfstats/regexp/include/jm/jm_cfg.h
new file mode 100644
index 0000000..49f150c
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/jm_cfg.h
@@ -0,0 +1,1057 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE jm_cfg.h
+ * VERSION 2.12
+ */
+
+#ifndef JM_CFG_H
+#define JM_CFG_H
+
+/************************************************************************
+
+The purpose of this header is to provide compiler and STL configuration
+options. Options fall into three categaries (namespaces, compiler and STL),
+throughout, the defaults assume that the compiler and STL are fully C++ standard
+compliant, features that are not supported on your system may be selectively
+turned off by defining the appropriate macros. Borland C++, Borland C++ Builder,
+and Microsoft Visual C++ should be auto-recognised and configured. The HP aCC and
+SunPro C++ compiler should also be supported - but run configure for best results.
+The SGI, HP, Microsoft and Rogue Wave STL's should be auto-recognised and configured.
+Do not change this file unless you really really have to, add options to
+<jm_opt.h> instead. See <jm_opt.h> for a full list of macros and their usage.
+
+************************************************************************/
+
+#include <jm/jm_opt.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+/* this will increase in future versions: */
+#define JM_VERSION 212
+
+#ifndef JM_AUTO_CONFIGURE
+#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
+ #define JM_PLATFORM_W32
+#endif
+
+#ifdef __BORLANDC__
+
+ #if __BORLANDC__ < 0x500
+ #define JM_NO_NAMESPACES
+ #define JM_NO_BOOL
+ #define JM_NO_MUTABLE
+ #endif
+
+ #if __BORLANDC__ < 0x520
+ #define JM_NO_WCSTRING
+ #define JM_NO_INT64
+ // Early versions of Borlands namespace code can't cope with iterators
+ // that are in different namespaces from STL code.
+ #define __JM std
+ #define JM_NO_NOT_EQUAL
+ #endif
+
+ #if __BORLANDC__ < 0x530
+ #define JM_NO_WCTYPE_H
+ #define JM_NO_WCHAR_H
+ #define JM_OLD_IOSTREAM
+ #define __JM_STDC
+ #define JM_NO_TRICKY_DEFAULT_PARAM
+ #define JM_NO_EXCEPTION_H
+ #ifndef __WIN32__
+ #define JM_NO_WCSTRING
+ #endif
+ #define JM_NO_LOCALE_H
+ #define JM_NO_TEMPLATE_RETURNS
+ #define JM_TEMPLATE_SPECIALISE
+ #endif
+
+ #if __BORLANDC__ < 0x540
+ #define JM_NO_MEMBER_TEMPLATES
+ // inline contructors exhibit strange behaviour
+ // under Builder 3 and C++ 5.x when throwing exceptions
+ #define INLINE_EXCEPTION_BUG
+ #define JM_NESTED_TEMPLATE_DECL
+ #define JM_NO_PARTIAL_FUNC_SPEC
+ #define JM_NO_STRING_DEF_ARGS
+ #define JM_NO_TYPEINFO // bad_cast etc not in namespace std.
+ #endif
+ //
+ // Builder 4 seems to have broken template friend support:
+ #define JM_NO_TEMPLATE_FRIEND
+
+ #ifndef _CPPUNWIND
+ #define JM_NO_EXCEPTIONS
+ #endif
+
+ #ifdef _Windows
+ #define JM_PLATFORM_WINDOWS
+ #else
+ #define JM_PLATFORM_DOS
+ #endif
+
+ #ifndef __WIN32__
+ #define RE_CALL
+ #define RE_CCALL
+ #else
+ #define RE_CALL __fastcall
+ #define RE_CCALL __stdcall
+ #endif
+
+ #define JM_INT64t __int64
+ #define JM_IMM64(val) val##i64
+ #define JM_NO_CAT
+
+ #ifdef __MT__
+ #define JM_THREADS
+ #endif
+
+ //
+ // import export options:
+ #ifdef _RTLDLL
+ #ifdef RE_BUILD_DLL
+ #define JM_IX_DECL __declspec( dllexport )
+ #else
+ #define JM_IX_DECL __declspec( dllimport )
+ #endif
+ #endif
+ #include <jm/re_lib.h>
+#endif
+
+#ifdef _MSC_VER
+ #define RE_CALL __fastcall
+ #define RE_CCALL __stdcall
+
+ #if _MSC_VER < 1100
+ #define JM_NO_NAMESPACES
+ #define JM_NO_DEFAULT_PARAM
+ #define JM_NO_BOOL
+ #define JM_NO_MUTABLE
+ #define JM_NO_WCSTRING
+ #define JM_NO_LOCALE_H
+ #define JM_NO_TEMPLATE_RETURNS
+ #define JM_NO_INT64
+ #endif
+
+ #if _MSC_VER < 1200
+ #define JM_TEMPLATE_SPECIALISE
+ #define JM_NESTED_TEMPLATE_DECL
+ #endif
+
+ #ifndef _CPPUNWIND
+ #define JM_NO_EXCEPTIONS
+ #endif
+
+ #define __JM_STDC
+ #define JM_PLATFORM_WINDOWS
+ //
+ // no support for nested template classes yet....
+ // although this part of VC6 is badly documented
+ #define JM_NO_MEMBER_TEMPLATES
+ #define JM_INT64t __int64
+ #define JM_IMM64(val) val##i64
+ #define JM_NO_CAT
+ #define JM_NO_PARTIAL_FUNC_SPEC
+ #define JM_NO_TEMPLATE_FRIEND
+
+ #ifdef _MT
+ #define JM_THREADS
+ #endif
+
+#pragma warning(disable: 4786)
+#pragma warning(disable: 4800)
+#pragma warning(disable: 4200)
+
+ //
+ // import export options:
+ #ifdef _DLL
+ #ifdef RE_BUILD_DLL
+ #define JM_IX_DECL __declspec( dllexport )
+ #else
+ #define JM_IX_DECL __declspec( dllimport )
+ #endif
+ #endif
+ #include <jm/re_lib.h>
+#endif
+
+#ifdef __GNUC__
+ #if (__GNUC__ < 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ < 91))
+ #define JM_NO_NAMESPACES
+ #define JM_NO_MUTABLE
+ #define JM_NO_MEMBER_TEMPLATES
+ #define JM_NO_PARTIAL_FUNC_SPEC
+ #define JM_NO_TEMPLATE_FRIEND
+ #endif
+ #ifndef __STL_USE_NAMESPACES
+ #define JM_NO_EXCEPTION_H
+ #endif
+ #define JM_INT64t long long
+ #define JM_IMM64(val) val##LL
+
+ #ifdef _WIN32
+ #define JM_PLATFORM_WINDOWS
+ #define JM_NO_WCTYPE_H
+ //#define JM_NO_TEMPLATE_SWITCH_MERGE
+ #endif
+ #define JM_NO_CAT
+ #define OLD_IOSTREAM
+ #define JM_NESTED_TEMPLATE_DECL
+ #define JM_NO_TEMPLATE_TYPENAME
+
+#endif
+
+#ifdef __SUNPRO_CC
+ #if (__SUNPRO_CC < 0x500)
+ #define JM_NO_NAMESPACES
+ #define JM_NO_MUTABLE
+ #define JM_NO_MEMBER_TEMPLATES
+ #define OLD_IOSTREAM
+ #endif
+ #ifndef __STL_USE_NAMESPACES
+ #define JM_NO_EXCEPTION_H
+ #endif
+ #define JM_INT64t long long
+ #define JM_IMM64(val) val##LL
+ #define JM_NESTED_TEMPLATE_DECL
+ #define JM_NO_TEMPLATE_TYPENAME
+ #define JM_NO_SWPRINTF
+ #define JM_NO_TEMPLATE_FRIEND
+#endif
+
+#ifdef __HP_aCC
+ // putative HP aCC support, run configure for
+ // support tailored to your system....
+ #define JM_NO_NAMESPACES
+ #define JM_NO_MUTABLE
+ #define JM_NO_MEMBER_TEMPLATES
+ #define OLD_IOSTREAM
+ #ifndef __STL_USE_NAMESPACES
+ #define JM_NO_EXCEPTION_H
+ #endif
+ #define JM_INT64t long long
+ #define JM_IMM64(val) val##LL
+ #define JM_NESTED_TEMPLATE_DECL
+ #define JM_NO_TEMPLATE_TYPENAME
+ #define JM_NO_TEMPLATE_FRIEND
+#endif
+
+
+
+#endif // JM_AUTO_CONFIGURE
+
+#ifndef JM_NO_WCSTRING
+#ifndef JM_NO_WCTYPE_H
+#include <wctype.h>
+#endif
+#ifndef JM_NO_WCHAR_H
+#include <wchar.h>
+#endif
+#endif
+
+#ifdef JM_NO_NAMESPACES
+#define JM_MAYBE_ACCESS_SPEC ::
+#else
+#define JM_MAYBE_ACCESS_SPEC __JM::
+#endif
+
+#if !defined(JM_INT64t) || !defined(JM_IMM64)
+#define JM_NO_INT64
+#endif
+
+#ifndef JM_INT32
+typedef unsigned int jm_uintfast32_t;
+#else
+typedef JM_INT32 jm_uintfast32_t;
+#endif
+
+#ifndef JM_TEMPLATE_SPECIALISE
+#define JM_TEMPLATE_SPECIALISE template <>
+#endif
+
+#ifndef JM_NESTED_TEMPLATE_DECL
+#define JM_NESTED_TEMPLATE_DECL template
+#endif
+
+#ifndef JM_IX_DECL
+#define JM_IX_DECL
+#endif
+
+#ifndef MB_CUR_MAX
+// yuk!
+// better make a conservative guess!
+#define MB_CUR_MAX 10
+#endif
+
+
+/* everything else is C++: */
+
+#ifdef __cplusplus
+
+/* define macro's to make default parameter declaration easier: */
+
+#ifdef JM_NO_DEFAULT_PARAM
+ #define JM_DEFAULT_PARAM(x)
+ #define JM_TRICKY_DEFAULT_PARAM(x)
+#elif defined(JM_NO_TRICKY_DEFAULT_PARAM)
+ #define JM_DEFAULT_PARAM(x) = x
+ #define JM_TRICKY_DEFAULT_PARAM(x)
+#else
+ #define JM_DEFAULT_PARAM(x) = x
+ #define JM_TRICKY_DEFAULT_PARAM(x) = x
+#endif
+
+/* STL configuration goes here: */
+
+#ifndef JM_AUTO_CONFIGURE
+#ifdef JM_NO_STL
+ #define JM_NO_EXCEPTION_H
+ #define JM_NO_ITERATOR_H
+ #define JM_NO_MEMORY_H
+ #define JM_NO_LOCALE_H
+ #define JM_NO_STRING_H
+#endif
+
+#ifndef JM_NO_EXCEPTION_H
+ #include <exception>
+#endif
+
+#ifndef JM_NO_ITERATOR_H
+ #include <iterator>
+
+ #if defined(__SGI_STL_INTERNAL_ITERATOR_H) || defined(__SGI_STL_ITERATOR_H)
+ #define JM_NO_LOCALE_H
+ #define OLD_IOSTREAM
+
+ /* we are using SGI's STL
+ some of these (__JM_STDC)
+ may be guesswork: */
+ #if !defined(__STL_MEMBER_TEMPLATE_CLASSES) || !defined(__STL_MEMBER_TEMPLATES)
+ #define JM_NO_MEMBER_TEMPLATES
+ #endif
+
+ #if !defined( __JM_STD)
+ #if defined (__STL_USE_NAMESPACES)
+ #define __JM_STD __STD
+ #else
+ #define __JM_STD
+ #endif
+ #endif
+ #ifndef __JM_STDC
+ #define __JM_STDC
+ #endif
+ #ifdef __STL_NO_BOOL
+ #define JM_NO_BOOL
+ #endif
+ #ifdef __STL_LIMITED_DEFAULT_TEMPLATES
+ #define JM_NO_TRICKY_DEFAULT_PARAM
+ #define JM_NO_STRING_DEF_ARGS
+ #endif
+ #ifndef __STL_USE_EXCEPTIONS
+ #define JM_NO_EXCEPTIONS
+ #endif
+
+ #include <algo.h>
+ #include <alloc.h>
+
+ #define JM_ALGO_INCLUDED
+
+ #define JM_DISTANCE(i, j, n) __JM_STD::distance(i, j, n)
+ #define JM_OUTPUT_ITERATOR(T, D) __JM_STD::output_iterator
+ #define JM_INPUT_ITERATOR(T, D) __JM_STD::input_iterator<T, D>
+ #define JM_FWD_ITERATOR(T, D) __JM_STD::forward_iterator<T, D>
+ #define JM_BIDI_ITERATOR(T, D) __JM_STD::bidirectional_iterator<T, D>
+ #define JM_RA_ITERATOR(T, D) __JM_STD::random_access_iterator<T, D>
+
+ #ifdef __STL_USE_STD_ALLOCATORS
+
+ /* new style allocator's with nested template classes */
+
+ #define REBIND_INSTANCE(x, y, inst) y::JM_NESTED_TEMPLATE_DECL rebind<x>::other(inst)
+ #define REBIND_TYPE(x, y) y::JM_NESTED_TEMPLATE_DECL rebind<x>::other
+ #define JM_DEF_ALLOC_PARAM(x) JM_TRICKY_DEFAULT_PARAM( __JM_STD::allocator<x> )
+ #define JM_DEF_ALLOC(x) __JM_STD::allocator<x>
+
+ #else /* __STL_USE_STD_ALLOCATORS */
+
+ /* old style byte allocator's, no nested templates */
+ #define JM_OLD_ALLOCATORS
+ #define REBIND_INSTANCE(x, y, inst) JM_MAYBE_ACCESS_SPEC re_alloc_binder<x, y>(inst)
+ #define REBIND_TYPE(x, y) JM_MAYBE_ACCESS_SPEC re_alloc_binder<x, y>
+ #define JM_DEF_ALLOC_PARAM(x) JM_DEFAULT_PARAM( __JM_STD::alloc )
+ #define JM_DEF_ALLOC(x) __JM_STD::alloc
+ #define JM_NEED_BINDER
+
+ #endif /* __STL_USE_STD_ALLOCATORS */
+
+ #define JM_STL_DONE
+ #define JM_NO_NOT_EQUAL
+
+ #elif defined(__STD_ITERATOR__)
+
+ /* Rogue Wave STL */
+
+ #if defined(RWSTD_NO_MEMBER_TEMPLATES) || defined(RWSTD_NO_MEM_CLASS_TEMPLATES)
+ #define JM_NO_MEMBER_TEMPLATES
+ #endif
+ #ifdef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
+ #define JM_NO_TEMPLATE_RETURNS
+ #endif
+
+ #ifdef _RWSTD_NO_NAMESPACE
+ #define __JM_STD
+ #define __JM_STDC
+ #else
+ #define __JM_STD std
+ #endif
+
+ #ifdef RWSTD_NO_EXCEPTIONS
+ #define JM_NO_EXCEPTIONS
+ #endif
+
+ #ifdef RWSTD_NO_MUTABLE
+ #define JM_NO_MUTABLE
+ #endif
+
+ #ifdef RWSTD_NO_DEFAULT_TEMPLATES
+ #define JM_NO_DEFAULT_PARAM
+ #define JM_NO_TRICKY_DEFAULT_PARAM
+ #define JM_NO_STRING_DEF_ARGS
+ #endif
+
+ #ifdef _RWSTD_NO_COMPLEX_DEFAULT_TEMPLATES
+ #define JM_NO_TRICKY_DEFAULT_PARAM
+ #define JM_NO_STRING_DEF_ARGS
+ #endif
+
+ #ifdef RWSTD_NO_BOOL
+ #define JM_NO_BOOL
+ #endif
+
+ #if _RWSTD_VER > 0x020000
+ #ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
+ #define JM_DISTANCE(i, j, n) __JM_STD::distance(i, j, n)
+ #else
+ #define JM_DISTANCE(i, j, n) (n = __JM_STD::distance(i, j))
+ #endif
+ #define JM_OUTPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::output_iterator_tag, T, D, T*, T&>
+ #define JM_INPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::input_iterator_tag, T, D, T*, T&>
+ #define JM_FWD_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::forward_iterator_tag, T, D, T*, T&>
+ #define JM_BIDI_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::bidirectional_iterator_tag, T, D, T*, T&>
+ #define JM_RA_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::random_access_iterator_tag, T, D, T*, T&>
+ #else
+ #define JM_DISTANCE(i, j, n) __JM_STD::distance(i, j, n)
+ #define JM_OUTPUT_ITERATOR(T, D) __JM_STD::output_iterator
+ #if _RWSTD_VER >= 0x0200
+ #define JM_INPUT_ITERATOR(T, D) __JM_STD::input_iterator<T>
+ #else
+ #define JM_INPUT_ITERATOR(T, D) __JM_STD::input_iterator<T, D>
+ #endif
+ #define JM_FWD_ITERATOR(T, D) __JM_STD::forward_iterator<T, D>
+ #define JM_BIDI_ITERATOR(T, D) __JM_STD::bidirectional_iterator<T, D>
+ #define JM_RA_ITERATOR(T, D) __JM_STD::random_access_iterator<T, D>
+ #endif
+
+ #include <memory>
+
+ #ifdef _RWSTD_ALLOCATOR
+
+ /* new style allocator */
+
+ #define REBIND_INSTANCE(x, y, inst) y::JM_NESTED_TEMPLATE_DECL rebind<x>::other(inst)
+ #define REBIND_TYPE(x, y) y::JM_NESTED_TEMPLATE_DECL rebind<x>::other
+ #define JM_DEF_ALLOC_PARAM(x) JM_TRICKY_DEFAULT_PARAM( __JM_STD::allocator<x> )
+ #define JM_DEF_ALLOC(x) __JM_STD::allocator<x>
+
+ #else
+ /*
+ // old style allocator
+ // this varies a great deal between versions, and there is no way
+ // that I can tell of differentiating between them, so use our
+ // own default allocator...
+ */
+ #define JM_OLD_ALLOCATORS
+ #define REBIND_INSTANCE(x, y, inst) JM_MAYBE_ACCESS_SPEC re_alloc_binder<x, y>(inst)
+ #define REBIND_TYPE(x, y) JM_MAYBE_ACCESS_SPEC re_alloc_binder<x, y>
+ #define JM_DEF_ALLOC_PARAM(x) JM_DEFAULT_PARAM( jm_def_alloc )
+ #define JM_DEF_ALLOC(x) jm_def_alloc
+
+ #define JM_NEED_BINDER
+ #define JM_NEED_ALLOC
+
+ #endif
+
+ #define JM_STL_DONE
+ #define JM_NO_OI_ASSIGN
+
+ #elif defined (ITERATOR_H)
+
+ /* HP STL */
+
+ #define __JM_STD
+ #define __JM_STDC
+ #define JM_NO_LOCALE_H
+
+ #include <algo.h>
+ #define JM_ALGO_INCLUDED
+
+ #define JM_DISTANCE(i, j, n) __JM_STD::distance(i, j, n)
+ #define JM_OUTPUT_ITERATOR(T, D) __JM_STD::output_iterator
+ #define JM_INPUT_ITERATOR(T, D) __JM_STD::input_iterator<T, D>
+ #define JM_FWD_ITERATOR(T, D) __JM_STD::forward_iterator<T, D>
+ #define JM_BIDI_ITERATOR(T, D) __JM_STD::bidirectional_iterator<T, D>
+ #define JM_RA_ITERATOR(T, D) __JM_STD::random_access_iterator<T, D>
+
+ /* old style allocator */
+ #define JM_OLD_ALLOCATORS
+ #define REBIND_INSTANCE(x, y, inst) JM_MAYBE_ACCESS_SPEC re_alloc_binder<x, y>(inst)
+ #define REBIND_TYPE(x, y) JM_MAYBE_ACCESS_SPEC re_alloc_binder<x, y>
+ #define JM_DEF_ALLOC_PARAM(x) JM_DEFAULT_PARAM( jm_def_alloc )
+ #define JM_DEF_ALLOC(x) jm_def_alloc
+
+ #define JM_NEED_BINDER
+ #define JM_NEED_ALLOC
+ #define JM_NO_NOT_EQUAL
+
+ #define JM_STL_DONE
+
+ #elif defined (_MSC_VER)
+
+ /* assume we're using MS's own STL (VC++ 5/6) */
+ #define __JM_STD std
+ #define __JM_STDC
+ #define JM_NO_OI_ASSIGN
+
+ #define JM_DISTANCE(i, j, n) n = __JM_STD::distance(i, j)
+ #define JM_OUTPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::output_iterator_tag, T, D>
+ #define JM_INPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::input_iterator_tag, T, D>
+ #define JM_FWD_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::forward_iterator_tag, T, D>
+ #define JM_BIDI_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::bidirectional_iterator_tag, T, D>
+ #define JM_RA_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::random_access_iterator_tag, T, D>
+
+ /* MS's allocators are rather ambiguous about their properties
+ at least as far as MSDN is concerned, so play safe: */
+ #define JM_OLD_ALLOCATORS
+ #define REBIND_INSTANCE(x, y, inst) JM_MAYBE_ACCESS_SPEC re_alloc_binder<x, y>(inst)
+ #define REBIND_TYPE(x, y) JM_MAYBE_ACCESS_SPEC re_alloc_binder<x, y>
+ #define JM_DEF_ALLOC_PARAM(x) JM_DEFAULT_PARAM( jm_def_alloc )
+ #define JM_DEF_ALLOC(x) jm_def_alloc
+
+ #define JM_NEED_BINDER
+ #define JM_NEED_ALLOC
+
+ #define JM_STL_DONE
+
+ #define JM_USE_FACET(l, type) __JM_STD::use_facet(l, (type*)0, true)
+ #define JM_HAS_FACET(l, type) __JM_STD::has_facet(l, (type*)0)
+
+
+
+ #else
+
+ /* unknown STL version
+ try the defaults: */
+
+ #define JM_DISTANCE(i, j, n) __JM_STD::distance(i, j, n)
+ /* these may be suspect for older libraries */
+ #define JM_OUTPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::output_iterator_tag, T, D, T*, T&>
+ #define JM_INPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::input_iterator_tag, T, D, T*, T&>
+ #define JM_FWD_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::forward_iterator_tag, T, D, T*, T&>
+ #define JM_BIDI_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::bidirectional_iterator_tag, T, D, T*, T&>
+ #define JM_RA_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::random_access_iterator_tag, T, D, T*, T&>
+
+ #endif /* <iterator> config */
+
+#else /* no <iterator> at all */
+
+ #define JM_DISTANCE(i, j, n) (n = j - i)
+ #define JM_OUTPUT_ITERATOR(T, D) dummy_iterator_base<T>
+ #define JM_INPUT_ITERATOR(T, D) dummy_iterator_base<T>
+ #define JM_FWD_ITERATOR(T, D) dummy_iterator_base<T>
+ #define JM_BIDI_ITERATOR(T, D) dummy_iterator_base<T>
+ #define JM_RA_ITERATOR(T, D) dummy_iterator_base<T>
+
+
+#endif
+
+/* now do allocator if not already done */
+
+#ifndef JM_STL_DONE
+
+ #ifdef JM_NO_MEMORY_H
+
+ /* old style allocator */
+
+ #define JM_OLD_ALLOCATORS
+
+ #define REBIND_INSTANCE(x, y, inst) JM_MAYBE_ACCESS_SPEC re_alloc_binder<x, y>(inst)
+ #define REBIND_TYPE(x, y) JM_MAYBE_ACCESS_SPEC re_alloc_binder<x, y>
+ #define JM_DEF_ALLOC_PARAM(x) JM_DEFAULT_PARAM( jm_def_alloc )
+ #define JM_DEF_ALLOC(x) jm_def_alloc
+
+ #define JM_NEED_BINDER
+ #define JM_NEED_ALLOC
+
+ #else
+
+ /* new style allocator's with nested template classes */
+
+ #define REBIND_INSTANCE(x, y, inst) y::JM_NESTED_TEMPLATE_DECL rebind<x>::other(inst)
+ #define REBIND_TYPE(x, y) y::JM_NESTED_TEMPLATE_DECL rebind<x>::other
+ #define JM_DEF_ALLOC_PARAM(x) JM_TRICKY_DEFAULT_PARAM( __JM_STD::allocator<x> )
+ #define JM_DEF_ALLOC(x) __JM_STD::allocator<x>
+
+ #endif
+
+#endif
+#endif // JM_AUTO_CONFIGURE
+
+
+
+/* namespace configuration goes here: */
+#ifdef JM_NO_NAMESPACES
+
+ #ifdef __JM_STD
+ #undef __JM_STD
+ #endif
+
+ #ifdef __JM_STDC
+ #undef __JM_STDC
+ #endif
+
+ #ifdef __JM
+ #undef __JM
+ #endif
+
+ #define __JM
+ #define __JM_STD
+ #define __JM_STDC
+ #define JM_NAMESPACE(x)
+ #define JM_END_NAMESPACE
+ #define JM_USING(x)
+
+#else
+
+ #ifndef __JM_STD
+ #define __JM_STD std
+ #endif
+
+ #ifndef __JM_STDC
+ #define __JM_STDC std
+ #endif
+
+ #ifndef __JM
+ #define __JM jm
+ #endif
+
+ #define JM_NAMESPACE(x) namespace x{
+ #define JM_END_NAMESPACE };
+ #define JM_USING(x) using namespace x;
+
+#endif
+
+/* locale configuration goes here */
+#if !defined(JM_NO_LOCALE_H) && defined(RE_LOCALE_CPP)
+ #include <locale>
+ #define LOCALE_INSTANCE(i) __JM_STD::locale i;
+ #define MAYBE_PASS_LOCALE(i) , i
+ #ifndef JM_NO_TEMPLATE_RETURNS
+ #ifndef JM_USE_FACET
+ #define JM_USE_FACET(l, type) __JM_STD::use_facet< type >(l)
+ #endif
+ #ifndef JM_HAS_FACET
+ #define JM_HAS_FACET(l, type) __JM_STD::has_facet< type >(l)
+ #endif
+ #else
+ #ifndef JM_USE_FACET
+ #define JM_USE_FACET(l, type) __JM_STD::use_facet(l, (type*)0)
+ #endif
+ #ifndef JM_HAS_FACET
+ #define JM_HAS_FACET(l, type) __JM_STD::has_facet(l, (type*)0)
+ #endif
+ #endif
+#else
+ #define LOCALE_INSTANCE(i)
+ #define MAYBE_PASS_LOCALE(i)
+#endif
+
+/* compiler configuration goes here: */
+
+#ifdef JM_NO_MUTABLE
+ #define JM_MUTABLE
+#else
+ #define JM_MUTABLE mutable
+#endif
+
+#if defined( JM_NO_BOOL) && !defined(bool)
+ #define bool int
+ #define true 1
+ #define false 0
+#endif
+
+#ifndef RE_CALL
+#define RE_CALL
+#endif
+
+#ifndef RE_CCALL
+#define RE_CCALL
+#endif
+
+#ifndef RE_DECL
+#define RE_DECL
+#endif
+
+#if defined(JM_NO_DEFAULT_PARAM) || defined(JM_NO_TRICKY_DEFAULT_PARAM)
+#define JM_NO_STRING_DEF_ARGS
+#endif
+
+
+
+/* add our class def's if they are needed: */
+
+JM_NAMESPACE(__JM)
+
+// add our destroy functions:
+
+template <class T>
+inline void RE_CALL jm_destroy(T* t)
+{
+ t->~T();
+}
+
+inline void RE_CALL jm_destroy(char* t){}
+inline void RE_CALL jm_destroy(short* t){}
+inline void RE_CALL jm_destroy(unsigned short* t){}
+inline void RE_CALL jm_destroy(int* t){}
+inline void RE_CALL jm_destroy(unsigned int* t){}
+inline void RE_CALL jm_destroy(long* t){}
+inline void RE_CALL jm_destroy(unsigned long* t){}
+
+
+template <class T>
+inline void RE_CALL jm_construct(void* p, const T& t)
+{
+ new (p) T(t);
+}
+
+
+template<class T, class Allocator>
+class re_alloc_binder : public Allocator
+{
+public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef size_t size_type;
+ typedef __JM_STDC::ptrdiff_t difference_type;
+
+ re_alloc_binder(const Allocator& i);
+ re_alloc_binder(const re_alloc_binder& o) : Allocator(o) {}
+
+ T* RE_CALL allocate(size_t n, size_t /* hint */ = 0)
+ { return 0 == n ? 0 : (T*) this->Allocator::allocate(n * sizeof(T)); }
+ void RE_CALL deallocate(T *p, size_t n)
+ { if (0 != n) this->Allocator::deallocate((char*)p, n * sizeof (T)); }
+
+ pointer RE_CALL address(reference x) const { return &x; }
+ const_pointer RE_CALL address(const_reference x) const { return &x; }
+ static size_type RE_CALL max_size() { return -1; }
+ static void RE_CALL construct(pointer p, const T& val) { jm_construct(p, val); }
+ void RE_CALL destroy(pointer p) { jm_destroy(p); }
+
+ const Allocator& RE_CALL instance()const { return *this; }
+
+#ifndef JM_NO_MEMBER_TEMPLATES
+
+ template <class U>
+ struct rebind
+ {
+ typedef re_alloc_binder<U, Allocator> other;
+ };
+
+ template <class U>
+ RE_CALL re_alloc_binder(const re_alloc_binder<U, Allocator>& o) throw()
+ : Allocator(o.instance())
+ {
+ }
+#endif
+};
+
+template<class T, class Allocator>
+inline re_alloc_binder<T, Allocator>::re_alloc_binder(const Allocator &i)
+ : Allocator(i)
+{}
+
+
+//
+// class jm_def_alloc
+// basically a standard allocator that only allocates bytes...
+// think of it as allocator<char>, with a non-standard
+// rebind::other typedef.
+//
+class jm_def_alloc
+{
+public:
+ typedef char value_type;
+ typedef char* pointer;
+ typedef const char* const_pointer;
+ typedef char& reference;
+ typedef const char& const_reference;
+ typedef size_t size_type;
+ typedef __JM_STDC::ptrdiff_t difference_type;
+
+ pointer RE_CALL address(reference x) const { return &x; }
+ const_pointer RE_CALL address(const_reference x) const { return &x; }
+ static size_type RE_CALL max_size() { return (size_type)-1; }
+ static void RE_CALL construct(pointer , const char& ) { }
+ void RE_CALL destroy(pointer ) { }
+ static void * RE_CALL allocate(size_t n, size_t /* hint */ = 0)
+ {
+ return ::operator new(n);
+ }
+ static void RE_CALL deallocate(void *p, size_t /*n*/ )
+ {
+ ::operator delete(p);
+ }
+
+#ifndef JM_NO_MEMBER_TEMPLATES
+ template <class U>
+ struct rebind
+ {
+ typedef re_alloc_binder<U, jm_def_alloc> other;
+ };
+
+ template <class U>
+ RE_CALL jm_def_alloc(const re_alloc_binder<U, jm_def_alloc>& ) throw() { }
+#endif
+ jm_def_alloc(const jm_def_alloc&) {}
+ jm_def_alloc() {}
+};
+
+template <class T>
+struct dummy_iterator_base
+{
+ typedef T value_type;
+ typedef __JM_STDC::ptrdiff_t difference_type;
+ typedef T* pointer;
+ typedef T& reference;
+ //typedef Category iterator_category;
+};
+
+// we need to absolutely sure that int values are correctly
+// translated to bool (true or false) values...
+// note that the original HP STL redefines the bool type regardless
+// of whether the compiler supports it.... yuk
+
+#if defined(JM_NO_BOOL) || defined(ITERATOR_H) || defined(bool)
+#define JM_MAKE_BOOL(x) boolify(x)
+
+template <class I>
+inline bool RE_CALL boolify(I val)
+{
+ return val ? true : false;
+}
+
+#else
+#define JM_MAKE_BOOL(x) x
+#endif
+
+// class auto_array:
+//
+// encapsulates objects allocated with ::operator new[]()
+// interface the same as auto_ptr, but no stream operators
+// since we don't know how big the array is.
+//
+// Usage: auto_array<char> buf = new char[256];
+//
+
+template<class X>
+class auto_array
+{
+public: // construct/copy/destroy:
+
+ auto_array(X* p =0)
+ { ptr = p; }
+
+ auto_array(const auto_array& ap)
+ { ptr = const_cast<auto_array&>(ap).release(); }
+
+ void RE_CALL operator=(const auto_array&);
+
+ ~auto_array();
+
+ // members:
+
+ X& RE_CALL operator*() const;
+ X* RE_CALL operator->() const;
+ X* RE_CALL get() const;
+ X& RE_CALL operator[](int i);
+ X* RE_CALL release();
+
+ // operator not part of the spec:
+ RE_CALL operator X*()const
+ { return ptr; }
+
+private: // data:
+
+ X* ptr;
+};
+
+template <class X>
+inline void RE_CALL auto_array<X>::operator=(const auto_array<X>& ap)
+{
+ delete[] ptr;
+ ptr = const_cast<auto_array<X>&>(ap).release();
+}
+
+template <class X>
+inline auto_array<X>::~auto_array()
+{
+ delete[] ptr;
+}
+
+template <class X>
+inline X& RE_CALL auto_array<X>::operator*() const
+{
+ return *ptr;
+}
+
+template <class X>
+inline X* RE_CALL auto_array<X>::operator->() const
+{
+ return ptr;
+}
+
+template <class X>
+inline X* RE_CALL auto_array<X>::get() const
+{
+ return ptr;
+}
+
+template <class X>
+inline X& RE_CALL auto_array<X>::operator[](int i)
+{
+ return ptr[i];
+}
+
+template <class X>
+inline X* RE_CALL auto_array<X>::release()
+{
+ X* tmp = ptr;
+ ptr = NULL;
+ return tmp;
+}
+
+
+JM_END_NAMESPACE
+
+#if !defined(INLINE_EXCEPTION_BUG) || defined(JM_NO_TEMPLATE_MERGE)
+ #define CONSTRUCTOR_INLINE inline
+#else
+ #define CONSTRUCTOR_INLINE
+#endif
+
+#if defined(JM_PLATFORM_W32) && !defined(RE_LOCALE_W32) && !defined(RE_LOCALE_C) && !defined(RE_LOCALE_CPP) && !defined(JM_NO_W32)
+#define RE_LOCALE_W32
+#endif
+
+#if !defined(RE_LOCALE_W32) && !defined(RE_LOCALE_C) && !defined(RE_LOCALE_CPP)
+#define RE_LOCALE_C
+#endif
+
+#if defined(JM_OLD_ALLOCATORS) && defined(JM_NO_TEMPLATE_TYPENAME)
+#define JM_MAYBE_TYPENAME
+#else
+#define JM_MAYBE_TYPENAME typename
+#endif
+
+#ifdef RE_LOCALE_W32
+#include <windows.h>
+#endif
+
+
+/* now do debugging stuff: */
+
+#ifdef JM_DEBUG
+
+#ifdef OLD_IOSTREAM
+#include <iostream.h>
+#else
+#include <iostream>
+using std::cout;
+using std::cin;
+using std::cerr;
+#endif
+
+ #ifndef jm_assert
+ #define jm_assert(x) if((x) == 0){ cerr << "Assertion failed: " << #x << " in file " << __FILE__ << "and line " << __LINE__ << endl; exit(-1); }
+ #endif
+ #ifndef jm_trace
+ #define jm_trace(x) cerr << x;
+ #endif
+
+ #ifdef __BORLANDC__
+ #pragma message "macro __jm_std: " __JM_STD
+ #pragma message "macro __jm_stdc: " __JM_STDC
+ #pragma message "macro namespace: " JM_NAMESPACE(__JM_STD)
+ #pragma message "macro allocator: " JM_DEF_ALLOC_PARAM(wchar_t)
+ #pragma message "macro jm_input_iterator: " JM_INPUT_ITERATOR(char, __JM_STDC::ptrdiff_t)
+ #pragma message "macro jm_output_iterator: " JM_OUTPUT_ITERATOR(char, __JM_STDC::ptrdiff_t)
+ #pragma message "macro jm_fwd_iterator: " JM_FWD_ITERATOR(char, __JM_STDC::ptrdiff_t)
+ #pragma message "macro jm_bidi_iterator: " JM_BIDI_ITERATOR(char, __JM_STDC::ptrdiff_t)
+ #pragma message "macro jm_ra_iterator: " JM_RA_ITERATOR(char, __JM_STDC::ptrdiff_t)
+ #ifdef RE_LOCALE_CPP
+ #pragma message "locale support enabled"
+ #endif
+ #endif
+
+#else
+
+ #define jm_assert(x)
+ #define jm_trace(x)
+
+#endif
+
+#endif /* __cplusplus */
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/utils/tfstats/regexp/include/jm/jm_opt.h b/utils/tfstats/regexp/include/jm/jm_opt.h
new file mode 100644
index 0000000..0c53a50
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/jm_opt.h
@@ -0,0 +1,414 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+
+#ifndef JM_OPT_H
+#define JM_OPT_H
+
+/* #define JM_AUTO_CONFIGURE */
+#ifdef JM_AUTO_CONFIGURE
+
+/* Namespace Options: */
+
+/* JM_NO_NAMESPACES Define if your compiler does not support namespaces */
+/* #define JM_NO_NAMESPACES */
+
+/* __JM Defines the namespace used for this library,
+ defaults to "jm", but can be changed by defining
+ __JM on the command line. */
+/* #define __JM */
+
+/* __JM_STD Defines the namespace used by the underlying STL
+ (if any), defaults to "std", can be changed by
+ defining __JM_STD on the command line. */
+/* #define __JM_STD */
+
+
+/* __JM_STDC Defines the namespace used by the C Library defs.
+ Defaults to "std" as recomended by the latest
+ draft standard, can be redefined by defining
+ __JM_STDC on the command line. */
+/* #define __JM_STDC */
+
+
+
+/* Compiler options: */
+
+/* JM_NO_EXCEPTIONS Disables exception handling support. */
+/* #define JM_NO_EXCEPTIONS */
+
+/* JM_NO_MUTABLE Disables use of mutable keyword. */
+/* #define JM_NO_MUTABLE */
+
+/* JM_INT32 The type for 32-bit integers - what C calls intfast32_t */
+/* #define JM_INT32 */
+
+/* JM_NO_DEFAULT_PARAM If templates can not have default parameters. */
+/* #define JM_NO_DEFAULT_PARAM */
+
+/* JM_NO_TRICKY_DEFAULT_PARAM If templates can not have derived default parameters. */
+/* #define JM_NO_TRICKY_DEFAULT_PARAM */
+
+/* JM_NO_TEMPLATE_TYPENAME If class scope typedefs of the form:
+ typedef typename X<T> Y;
+ where T is a template parameter to this,
+ do not compile unless the typename is omitted. */
+/* #define JM_NO_TEMPLATE_TYPENAME */
+
+/* JM_NO_TEMPLATE_FRIEND If template friend declarations are not supported */
+/* #define JM_NO_TEMPLATE_FRIEND */
+
+/* JM_PLATFORM_WINDOWS Platform is MS Windows. */
+/* #define JM_PLATFORM_WINDOWS */
+
+/* JM_PLATFORM_DOS Platform if MSDOS. */
+/* #define JM_PLATFORM_DOS */
+
+/* JM_PLATFORM_W32 Platform is MS Win32 */
+/* #define JM_PLATFORM_W32 */
+
+/* JM_NO_WIN32 Disable Win32 support even when present */
+/* #define JM_NO_WIN32 */
+
+/* JM_NO_BOOL If bool is not a distict type. */
+/* #define JM_NO_BOOL */
+
+/* JM_NO_WCHAR_H If there is no <wchar.h> */
+/* #define JM_NO_WCHAR_H */
+
+/* JM_NO_WCTYPE_H If there is no <wctype.h> */
+/* #define JM_NO_WCTYPE_H */
+
+/* JM_NO_WCSTRING If there are no wcslen and wcsncmp functions available. */
+/* #define JM_NO_WCSTRING */
+
+/* JM_NO_SWPRINTF If there is no swprintf available. */
+/* #define JM_NO_SWPRINTF */
+
+/* JM_NO_WSPRINTF If there is no wsprintf available. */
+/* #define JM_NO_WSPRINTF */
+
+/* JM_NO_MEMBER_TEMPLATES If member function templates or nested template classes are not allowed. */
+/* #define JM_NO_MEMBER_TEMPLATES */
+
+/* JM_NO_TEMPLATE_RETURNS If template functions based on return type are not supported. */
+/* #define JM_NO_TEMPLATE_RETURNS */
+
+/* JM_NO_PARTIAL_FUNC_SPEC If partial template function specialisation is not supported */
+/* #define JM_NO_PARTIAL_FUNC_SPEC */
+
+/* JM_NO_INT64 If 64bit integers are not supported. */
+/* JM_INT64t The type of a 64-bit signed integer if available. */
+/* JM_IMM64(val) Declares a 64-bit immediate value by appending any
+ necessary suffix to val. */
+/* JM_INT64_T 0 = NA
+ 1 = short
+ 2 = int
+ 3 = long
+ 4 = int64_t
+ 5 = long long
+ 6 = __int64 */
+/* #define JM_INT64_T */
+
+/* JM_NO_CAT Define if the compiler does not support POSIX style
+ message categories (catopen catgets catclose). */
+/* #define JM_NO_CAT */
+
+/* JM_THREADS Define if the compiler supports multiple threads in
+ the current translation mode. */
+/* #define JM_THREADS */
+
+/* JM_TEMPLATE_SPECIALISE Defaults to template<> , ie the template specialisation
+ prefix, can be redefined to nothing for older compilers. */
+/* #define JM_TEMPLATE_SPECIALISE */
+
+/* JM_NESTED_TEMPLATE_DECL Defaults to template, the standard prefix when accessing
+ nested template classes, can be redefined to nothing if
+ the compiler does not support this. */
+/* #define JM_NESTED_TEMPLATE_DECL */
+
+/* JM_NO_TEMPLATE_INST If explicit template instantiation with the "template class X<T>"
+ syntax is not supported */
+/* #define JM_NO_TEMPLATE_INST */
+
+/* JM_NO_TEMPLATE_MERGE If template in separate translation units don't merge at link time */
+/* #define JM_NO_TEMPLATE_MERGE */
+
+/* JM_NO_TEMPLATE_MERGE_A If template merging from library archives is not supported */
+/* #define JM_NO_TEMPLATE_MERGE_A */
+
+/* JM_NO_TEMPLATE_SWITCH_MERGE If merging of templates containing switch statements is not supported */
+/* #define JM_NO_TEMPLATE_SWITCH_MERGE */
+
+/* RE_CALL Optionally define a calling convention for C++ functions */
+/* #define RE_CALL */
+
+/* RE_CCALL Optionally define a calling convention for C functions */
+/* #define RE_CCALL */
+
+/* JM_SIZEOF_SHORT sizeof(short) */
+/* #define JM_SIZEOF_SHORT */
+
+/* JM_SIZEOF_INT sizeof(int) */
+/* #define JM_SIZEOF_INT */
+
+/* JM_SIZEOF_LONG sizeof(long) */
+/* #define JM_SIZEOF_LONG */
+
+/* JM_SIZEOF_WCHAR_T sizeof(wchar_t) */
+/* #define JM_SIZEOF_WCHAR_T */
+
+
+/* STL options: */
+
+/* JM_NO_EXCEPTION_H Define if you do not a compliant <exception>
+ header file. */
+/* #define JM_NO_EXCEPTION_H */
+
+/* JM_NO_ITERATOR_H Define if you do not have a version of <iterator>. */
+/* #define JM_NO_ITERATOR_H */
+
+/* JM_NO_MEMORY_H Define if <memory> does not fully comply with the
+ latest standard, and is not auto-recognised,
+ that means nested template classes
+ which hardly any compilers support at present. */
+/* #define JM_NO_MEMORY_H */
+
+/* JM_NO_LOCALE_H Define if there is no verion of the standard
+ <locale> header available. */
+/* #define JM_NO_LOCALE_H */
+
+/* JM_NO_STL Disables the use of any supporting STL code. */
+/* #define JM_NO_STL */
+
+/* JM_NO_NOT_EQUAL Disables the generation of operator!= if this
+ clashes with the STL version. */
+
+/* JM_NO_STRING_H Define if <string> not available */
+/* #define JM_NO_STRING_H */
+
+/* JM_NO_STRING_DEF_ARGS Define if std::basic_string<charT> not allowed - in
+ other words if the template is missing its required
+ default arguments. */
+/* #define JM_NO_STRING_DEF_ARGS */
+
+/* JM_NO_TYPEINFO Define if <typeinfo> is absent or non-standard */
+/* #define JM_NO_TYPEINFO */
+
+/* JM_USE_ALGO If <algo.h> not <algorithm> is present */
+/* #define JM_USE_ALGO */
+
+/* JM_OLD_IOSTREAM If the new iostreamm classes are not available */
+/* #define JM_OLD_IOSTREAM */
+
+/* JM_DISTANCE_T For std::distance:
+ 0 = NA
+ 1 = std::distance(i, j, n)
+ 2 = n = std::distance(i, j) */
+/* #define JM_DISTANCE_T */
+
+/* JM_ITERATOR_T Defines generic standard iterator type if available, use this as
+ a shortcut to define all the other iterator types.
+ 1 = __JM_STD::iterator<__JM_STD::tag_type, T, D, T*, T&>
+ 2 = __JM_STD::iterator<__JM_STD::tag_type, T, D> */
+/* #define JM_ITERATOR_T */
+
+/* JM_OI_T For output iterators:
+ 0 = NA
+ 1 = __JM_STD::iterator<__JM_STD::output_iterator_tag, T, D, T*, T&>
+ 2 = __JM_STD::iterator<__JM_STD::output_iterator_tag, T, D>
+ 3 = __JM_STD::output_iterator */
+/* #define JM_OI_T */
+
+/* JM_II_T For input iterators:
+ 0 = NA
+ 1 = __JM_STD::iterator<__JM_STD::input_iterator_tag, T, D, T*, T&>
+ 2 = __JM_STD::iterator<__JM_STD::input_iterator_tag, T, D>
+ 3 = __JM_STD::input_iterator<T, D>
+ 4 = __JM_STD::input_iterator<T> */
+/* #define JM_II_T */
+
+/* JM_FI_T For forward iterators:
+ 0 = NA
+ 1 = __JM_STD::iterator<__JM_STD::forward_iterator_tag, T, D, T*, T&>
+ 2 = __JM_STD::iterator<__JM_STD::forward_iterator_tag, T, D>
+ 3 = __JM_STD::forward_iterator<T, D> */
+/* #define JM_FI_T */
+
+/* JM_BI_T For bidirectional iterators:
+ 0 = NA
+ 1 = __JM_STD::iterator<__JM_STD::bidirectional_iterator_tag, T, D, T*, T&>
+ 2 = __JM_STD::iterator<__JM_STD::bidirectional_iterator_tag, T, D>
+ 3 = __JM_STD::bidirectional_iterator<T, D> */
+/* #define JM_BI_T */
+
+/* JM_RI_T For random access iterators:
+ 0 = NA
+ 1 = __JM_STD::iterator<__JM_STD::random_access_iterator_tag, T, D, T*, T&>
+ 2 = __JM_STD::iterator<__JM_STD::random_access_iterator_tag, T, D>
+ 3 = __JM_STD::random_access_iterator<T, D> */
+/* #define JM_RI_T */
+
+/* JM_NO_OI_ASSIGN If output iterators ostream_iterator<>, back_insert_iterator<> and
+ front_insert_iterator<> do not have assignment operators */
+/* #define JM_NO_OI_ASSIGN */
+
+
+#if JM_INT64_T == 0
+#define JM_NO_INT64
+#elif JM_INT64_T == 1
+#define JM_INT64t short
+#define JM_IMM64(val) val
+#elif JM_INT64_T == 2
+#define JM_INT64t int
+#define JM_IMM64(val) val
+#elif JM_INT64_T == 3
+#define JM_INT64t long
+#define JM_IMM64(val) val##L
+#elif JM_INT64_T == 4
+#define JM_INT64t int64_t
+#define JM_IMM64(val) INT64_C(val)
+#elif JM_INT64_T == 5
+#define JM_INT64t long long
+#define JM_IMM64(val) val##LL
+#elif JM_INT64_T == 6
+#define JM_INT64t __int64
+#define JM_IMM64(val) val##i64
+#else
+syntax error: unknown value for JM_INT64_T
+#endif
+
+#if JM_DISTANCE_T == 0
+# define JM_DISTANCE(i, j, n) n = j - i
+#elif JM_DISTANCE_T == 1
+# define JM_DISTANCE(i, j, n) n = __JM_STD::distance(i, j)
+#elif JM_DISTANCE_T == 2
+# define JM_DISTANCE(i, j, n) (n = 0, __JM_STD::distance(i, j, n))
+#else
+syntax erorr
+#endif
+
+#ifdef JM_ITERATOR_T
+#ifndef JM_OI_T
+#define JM_OI_T JM_ITERATOR_T
+#endif
+#ifndef JM_II_T
+#define JM_II_T JM_ITERATOR_T
+#endif
+#ifndef JM_FI_T
+#define JM_FI_T JM_ITERATOR_T
+#endif
+#ifndef JM_BI_T
+#define JM_BI_T JM_ITERATOR_T
+#endif
+#ifndef JM_RI_T
+#define JM_RI_T JM_ITERATOR_T
+#endif
+#endif
+
+#if JM_OI_T == 0
+# define JM_OUTPUT_ITERATOR(T, D) dummy_iterator_base<T>
+#elif JM_OI_T == 1
+# define JM_OUTPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::output_iterator_tag, T, D, T*, T&>
+#elif JM_OI_T == 2
+# define JM_OUTPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::output_iterator_tag, T, D>
+#elif JM_OI_T == 3
+# define JM_OUTPUT_ITERATOR(T, D) __JM_STD::output_iterator
+#else
+syntax error
+#endif
+
+#if JM_II_T == 0
+# define JM_INPUT_ITERATOR(T, D) dummy_iterator_base<T>
+#elif JM_II_T == 1
+#define JM_INPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::input_iterator_tag, T, D, T*, T&>
+#elif JM_II_T == 2
+#define JM_INPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::input_iterator_tag, T, D>
+#elif JM_II_T == 3
+# define JM_INPUT_ITERATOR(T, D) __JM_STD::input_iterator<T, D>
+#elif JM_II_T == 4
+# define JM_INPUT_ITERATOR(T, D) __JM_STD::input_iterator<T>
+#else
+syntax error
+#endif
+
+#if JM_FI_T == 0
+# define JM_FWD_ITERATOR(T, D) dummy_iterator_base<T>
+#elif JM_FI_T == 1
+# define JM_FWD_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::forward_iterator_tag, T, D, T*, T&>
+#elif JM_FI_T == 2
+# define JM_FWD_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::forward_iterator_tag, T, D>
+#elif JM_FI_T == 3
+# define JM_FWD_ITERATOR(T, D) __JM_STD::forward_iterator<T, D>
+#else
+syntax error
+#endif
+
+#if JM_BI_T == 0
+# define JM_BIDI_ITERATOR(T, D) dummy_iterator_base<T>
+#elif JM_BI_T == 1
+# define JM_BIDI_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::bidirectional_iterator_tag, T, D, T*, T&>
+#elif JM_BI_T == 2
+# define JM_BIDI_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::bidirectional_iterator_tag, T, D>
+#elif JM_BI_T == 3
+# define JM_BIDI_ITERATOR(T, D) __JM_STD::bidirectional_iterator<T, D>
+#else
+syntax error
+#endif
+
+#if JM_RI_T == 0
+# define JM_RA_ITERATOR(T, D) dummy_iterator_base<T>
+#elif JM_RI_T == 1
+# define JM_RA_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::random_access_iterator_tag, T, D, T*, T&>
+#elif JM_RI_T == 2
+# define JM_RA_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::random_access_iterator_tag, T, D>
+#elif JM_RI_T == 3
+# define JM_RA_ITERATOR(T, D) __JM_STD::random_access_iterator<T, D>
+#else
+syntax error
+#endif
+
+
+#ifndef JM_NO_EXCEPTION_H
+#include <exception>
+#endif
+
+#ifndef JM_NO_ITERATOR_H
+#include <iterator>
+#ifdef JM_USE_ALGO
+#include <algo.h>
+#else
+#include <algorithm>
+#endif
+#endif
+
+#ifdef JM_NO_MEMORY_H
+ #define JM_OLD_ALLOCATORS
+ #define REBIND_INSTANCE(x, y, inst) re_alloc_binder<x, y>(inst)
+ #define REBIND_TYPE(x, y) re_alloc_binder<x, y>
+ #define JM_DEF_ALLOC_PARAM(x) JM_DEFAULT_PARAM( jm_def_alloc )
+ #define JM_DEF_ALLOC(x) jm_def_alloc
+
+ #define JM_NEED_BINDER
+ #define JM_NEED_ALLOC
+#else
+#include <memory>
+ #define REBIND_INSTANCE(x, y, inst) y::JM_NESTED_TEMPLATE_DECL rebind<x>::other(inst)
+ #define REBIND_TYPE(x, y) y::JM_NESTED_TEMPLATE_DECL rebind<x>::other
+ #define JM_DEF_ALLOC_PARAM(x) JM_TRICKY_DEFAULT_PARAM( __JM_STD::allocator<x> )
+ #define JM_DEF_ALLOC(x) __JM_STD::allocator<x>
+#endif
+
+
+#endif // JM_AUTO_CONFIGURE
+
+
+#endif /* JM_OPT_H */
+
+
+
+
diff --git a/utils/tfstats/regexp/include/jm/jstack.h b/utils/tfstats/regexp/include/jm/jstack.h
new file mode 100644
index 0000000..fca5058
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/jstack.h
@@ -0,0 +1,209 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE jstack.h
+ * VERSION 2.12
+ */
+
+#ifndef __JSTACH_H
+#define __JSTACK_H
+
+#ifndef JM_CFG_H
+#include <jm/jm_cfg.h>
+#endif
+
+JM_NAMESPACE(__JM)
+
+//
+// class jstack
+// simplified stack optimised for push/peek/pop
+// operations, we could use std::stack<std::vector<T>> instead...
+//
+template <class T, class Allocator JM_DEF_ALLOC_PARAM(T) >
+class jstack
+{
+private:
+ typedef JM_MAYBE_TYPENAME REBIND_TYPE(unsigned char, Allocator) alloc_type;
+ typedef typename REBIND_TYPE(T, Allocator)::size_type size_type;
+ struct node
+ {
+ node* next;
+ T* start; // first item
+ T* end; // last item
+ T* last; // end of storage
+ };
+
+ //
+ // empty base member optimisation:
+ struct data : public alloc_type
+ {
+ unsigned char buf[sizeof(T)*16];
+ data(const Allocator& a) : alloc_type(a){}
+ };
+
+ data alloc_inst;
+ mutable node* stack;
+ mutable node* unused;
+ node base;
+ size_type block_size;
+
+ void RE_CALL pop_aux()const;
+ void RE_CALL push_aux();
+
+public:
+ jstack(size_type n = 64, const Allocator& a = Allocator());
+
+ ~jstack();
+
+ node* RE_CALL get_node()
+ {
+ node* new_stack = (node*)alloc_inst.allocate(sizeof(node) + sizeof(T) * block_size);
+ new_stack->last = (T*)(new_stack+1);
+ new_stack->start = new_stack->end = new_stack->last + block_size;
+ new_stack->next = 0;
+ return new_stack;
+ }
+
+ bool RE_CALL empty()
+ {
+ return (stack->start == stack->end) && (stack->next == 0);
+ }
+
+ bool RE_CALL good()
+ {
+ return (stack->start != stack->end) || (stack->next != 0);
+ }
+
+ T& RE_CALL peek()
+ {
+ if(stack->start == stack->end)
+ pop_aux();
+ return *stack->end;
+ }
+
+ const T& RE_CALL peek()const
+ {
+ if(stack->start == stack->end)
+ pop_aux();
+ return *stack->end;
+ }
+
+ void RE_CALL pop()
+ {
+ if(stack->start == stack->end)
+ pop_aux();
+ jm_destroy(stack->end);
+ ++(stack->end);
+ }
+
+ void RE_CALL pop(T& t)
+ {
+ if(stack->start == stack->end)
+ pop_aux();
+ t = *stack->end;
+ jm_destroy(stack->end);
+ ++(stack->end);
+ }
+
+ void RE_CALL push(const T& t)
+ {
+ if(stack->end == stack->last)
+ push_aux();
+ --(stack->end);
+ jm_construct(stack->end, t);
+ }
+
+};
+
+template <class T, class Allocator>
+jstack<T, Allocator>::jstack(size_type n, const Allocator& a)
+ : alloc_inst(a)
+{
+ unused = 0;
+ block_size = n;
+ stack = &base;
+ base.last = (T*)alloc_inst.buf;
+ base.end = base.start = base.last + 16;
+ base.next = 0;
+}
+
+template <class T, class Allocator>
+void RE_CALL jstack<T, Allocator>::push_aux()
+{
+ // make sure we have spare space on TOS:
+ register node* new_node;
+ if(unused)
+ {
+ new_node = unused;
+ unused = new_node->next;
+ new_node->next = stack;
+ stack = new_node;
+ }
+ else
+ {
+ new_node = get_node();
+ new_node->next = stack;
+ stack = new_node;
+ }
+}
+
+template <class T, class Allocator>
+void RE_CALL jstack<T, Allocator>::pop_aux()const
+{
+ // make sure that we have a valid item
+ // on TOS:
+ jm_assert(stack->next);
+ register node* p = stack;
+ stack = p->next;
+ p->next = unused;
+ unused = p;
+}
+
+template <class T, class Allocator>
+jstack<T, Allocator>::~jstack()
+{
+ node* condemned;
+ while(good())
+ pop();
+ while(unused)
+ {
+ condemned = unused;
+ unused = unused->next;
+ alloc_inst.deallocate((unsigned char*)condemned, sizeof(node) + sizeof(T) * block_size);
+ }
+ while(stack != &base)
+ {
+ condemned = stack;
+ stack = stack->next;
+ alloc_inst.deallocate((unsigned char*)condemned, sizeof(node) + sizeof(T) * block_size);
+ }
+}
+
+JM_END_NAMESPACE
+
+#endif
+
+
+
+
+
diff --git a/utils/tfstats/regexp/include/jm/re_cls.h b/utils/tfstats/regexp/include/jm/re_cls.h
new file mode 100644
index 0000000..5dd8f8e
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/re_cls.h
@@ -0,0 +1,79 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE re_cls.h
+ * VERSION 2.12
+ * This is an internal header file, do not include directly.
+ * character class lookup, for regular
+ * expression library.
+ */
+
+#ifndef RE_CLS_H
+#define RE_CLS_H
+
+#ifndef JM_CFG_H
+#include <jm/jm_cfg.h>
+#endif
+
+#ifndef RE_STR_H
+#include <jm/re_str.h>
+#endif
+
+JM_NAMESPACE(__JM)
+
+#define re_classes_max 14
+
+void RE_CALL re_init_classes();
+void RE_CALL re_free_classes();
+void RE_CALL re_update_classes();
+JM_IX_DECL jm_uintfast32_t RE_CALL __re_lookup_class(const char* p);
+
+inline jm_uintfast32_t RE_CALL re_lookup_class(const char* first, const char* last)
+{
+ re_str<char> s(first, last);
+ return __re_lookup_class(s.c_str());
+}
+
+#ifndef JM_NO_WCSTRING
+inline jm_uintfast32_t RE_CALL re_lookup_class(const wchar_t* first, const wchar_t* last)
+{
+ re_str<wchar_t> s(first, last);
+ unsigned int len = re_strnarrow((char*)NULL, 0, s.c_str());
+ auto_array<char> buf(new char[len]);
+ re_strnarrow((char*)buf, len, s.c_str());
+ len = __re_lookup_class((char*)buf);
+ return len;
+}
+#endif
+
+#ifdef RE_LOCALE_CPP
+
+extern jm_uintfast32_t re_char_class_id[];
+extern const char* re_char_class_names[];
+
+#endif
+
+JM_END_NAMESPACE
+
+#endif
+
diff --git a/utils/tfstats/regexp/include/jm/re_coll.h b/utils/tfstats/regexp/include/jm/re_coll.h
new file mode 100644
index 0000000..d3fa3d0
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/re_coll.h
@@ -0,0 +1,61 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE re_coll.h
+ * VERSION 2.12
+ * This is an internal header file, do not include directly
+ */
+
+#ifndef RE_COLL_H
+#define RE_COLL_H
+
+#ifndef JM_CFG_H
+#include <jm/jm_cfg.h>
+#endif
+
+#ifndef RE_STR_H
+#include <re_str.h>
+#endif
+
+JM_NAMESPACE(__JM)
+
+JM_IX_DECL bool RE_CALL re_lookup_def_collate_name(re_str<char>& buf, const char* name);
+
+void RE_CALL re_init_collate();
+void RE_CALL re_free_collate();
+void RE_CALL re_update_collate();
+JM_IX_DECL bool RE_CALL __re_lookup_collate(re_str<char>& buf, const char* p);
+
+inline bool RE_CALL re_lookup_collate(re_str<char>& buf, const char* first, const char* last)
+{
+ re_str<char> s(first, last);
+ return __re_lookup_collate(buf, s.c_str());
+}
+
+#ifndef JM_NO_WCSTRING
+JM_IX_DECL bool RE_CALL re_lookup_collate(re_str<wchar_t>& out, const wchar_t* first, const wchar_t* last);
+#endif
+
+JM_END_NAMESPACE
+
+#endif
diff --git a/utils/tfstats/regexp/include/jm/re_kmp.h b/utils/tfstats/regexp/include/jm/re_kmp.h
new file mode 100644
index 0000000..65d1e90
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/re_kmp.h
@@ -0,0 +1,112 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE re_kmp.h
+ * VERSION 2.12
+ * Knuth-Morris-Pratt search.
+ */
+
+
+#ifndef __RE_KMP_H
+#define __RE_KMP_H
+
+#ifdef JM_CFG_H
+#include <jm/jm_cfg.h>
+#endif
+
+
+JM_NAMESPACE(__JM)
+
+template <class charT>
+struct kmp_info
+{
+ unsigned int size;
+ unsigned int len;
+ const charT* pstr;
+ int kmp_next[1];
+};
+
+template <class charT, class Allocator>
+void kmp_free(kmp_info<charT>* pinfo, Allocator a)
+{
+ typedef JM_MAYBE_TYPENAME REBIND_TYPE(char, Allocator) atype;
+ atype(a).deallocate((char*)pinfo, pinfo->size);
+}
+
+template <class iterator, class charT, class Trans, class Allocator>
+kmp_info<charT>* kmp_compile(iterator first, iterator last, charT, Trans translate, Allocator a
+#ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+#endif
+ )
+{
+ typedef JM_MAYBE_TYPENAME REBIND_TYPE(char, Allocator) atype;
+ int i, j, m;
+ i = 0;
+ m = 0;
+ JM_DISTANCE(first, last, m);
+ ++m;
+ unsigned int size = sizeof(kmp_info<charT>) + sizeof(int)*m + sizeof(charT)*m;
+ --m;
+ //
+ // allocate struct and fill it in:
+ //
+ kmp_info<charT>* pinfo = (kmp_info<charT>*)atype(a).allocate(size);
+ pinfo->size = size;
+ pinfo->len = m;
+ charT* p = (charT*)((char*)pinfo + sizeof(kmp_info<charT>) + sizeof(int)*(m+1));
+ pinfo->pstr = p;
+ while(first != last)
+ {
+ *p = translate(*first MAYBE_PASS_LOCALE(l));
+ ++first;
+ ++p;
+ }
+ *p = 0;
+ //
+ // finally do regular kmp compile:
+ //
+ j = pinfo->kmp_next[0] = -1;
+ while (i < m)
+ {
+ while ((j > -1) && (pinfo->pstr[i] != pinfo->pstr[j]))
+ j = pinfo->kmp_next[j];
+ ++i;
+ ++j;
+ if (pinfo->pstr[i] == pinfo->pstr[j])
+ pinfo->kmp_next[i] = pinfo->kmp_next[j];
+ else
+ pinfo->kmp_next[i] = j;
+ }
+
+ return pinfo;
+}
+
+
+JM_END_NAMESPACE // namespace regex
+
+#endif // __RE_KMP_H
+
+
+
+
diff --git a/utils/tfstats/regexp/include/jm/re_lib.h b/utils/tfstats/regexp/include/jm/re_lib.h
new file mode 100644
index 0000000..4e87eb9
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/re_lib.h
@@ -0,0 +1,155 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE re_lib.h
+ * VERSION 2.12
+ * Automatic library file inclusion.
+ */
+
+
+#ifndef RE_LIB_H
+#define RE_LIB_H
+
+#if defined(_MSC_VER) && !defined(RE_BUILD_DLL)
+ #ifdef _DLL
+ #ifdef _DEBUG
+ #pragma comment(lib, "mre200dl.lib")
+ #else // DEBUG
+ #pragma comment(lib, "mre200l.lib")
+ #endif // _DEBUG
+ #else // _DLL
+ #ifdef _MT
+ #ifdef _DEBUG
+ #pragma comment(lib, "mre200dm.lib")
+ #else //_DEBUG
+ #pragma comment(lib, "mre200m.lib")
+ #endif //_DEBUG
+ #else //_MT
+ #ifdef _DEBUG
+ #pragma comment(lib, "mre200d.lib")
+ #else //_DEBUG
+ #pragma comment(lib, "mre200.lib")
+ #endif //_DEBUG
+ #endif //_MT
+ #endif //_DLL
+#endif //_MSC_VER
+
+
+#if defined(__BORLANDC__) && !defined(RE_BUILD_DLL)
+ #if (__BORLANDC__ > 0x520) && !defined(_NO_VCL)
+ #define JM_USE_VCL
+ #endif
+
+ #if __BORLANDC__ <= 0x520
+
+ #ifdef JM_USE_VCL
+
+ #ifdef _RTLDLL
+ #pragma comment(lib, "b2re200lv.lib")
+ #else
+ #pragma comment(lib, "b2re200v.lib")
+ #endif
+
+ #else // VCL
+
+ #ifdef _RTLDLL
+ #ifdef __MT__
+ #pragma comment(lib, "b2re200lm.lib")
+ #else // __MT__
+ #pragma comment(lib, "b2re200l.lib")
+ #endif // __MT__
+ #else //_RTLDLL
+ #ifdef __MT__
+ #pragma comment(lib, "b2re200m.lib")
+ #else // __MT__
+ #pragma comment(lib, "b2re200.lib")
+ #endif // __MT__
+ #endif // _RTLDLL
+
+ #endif // VCL
+
+ #elif __BORLANDC__ <= 0x530
+
+ #ifdef JM_USE_VCL
+
+ #ifdef _RTLDLL
+ #pragma comment(lib, "b3re200lv.lib")
+ #else
+ #pragma comment(lib, "b3re200v.lib")
+ #endif
+
+ #else // VCL
+
+ #ifdef _RTLDLL
+ #ifdef __MT__
+ #pragma comment(lib, "b3re200lm.lib")
+ #else // __MT__
+ #pragma comment(lib, "b3re200l.lib")
+ #endif // __MT__
+ #else //_RTLDLL
+ #ifdef __MT__
+ #pragma comment(lib, "b3re200m.lib")
+ #else // __MT__
+ #pragma comment(lib, "b3re200.lib")
+ #endif // __MT__
+ #endif // _RTLDLL
+
+ #endif // VCL
+
+ #else // Version: 0x540
+
+ #ifdef JM_USE_VCL
+
+ #ifdef _RTLDLL
+ #pragma comment(lib, "b4re200lv.lib")
+ #else
+ #pragma comment(lib, "b4re200v.lib")
+ #endif
+
+ #else // VCL
+
+ #ifdef _RTLDLL
+ #ifdef __MT__
+ #pragma comment(lib, "b4re200lm.lib")
+ #else // __MT__
+ #pragma comment(lib, "b4re200l.lib")
+ #endif // __MT__
+ #else //_RTLDLL
+ #ifdef __MT__
+ #pragma comment(lib, "b4re200m.lib")
+ #else // __MT__
+ #pragma comment(lib, "b4re200.lib")
+ #endif // __MT__
+ #endif // _RTLDLL
+
+ #endif // VCL
+
+ #endif
+
+#endif //__BORLANDC__
+
+
+#endif // RE_LIB_H
+
+
+
diff --git a/utils/tfstats/regexp/include/jm/re_lst.h b/utils/tfstats/regexp/include/jm/re_lst.h
new file mode 100644
index 0000000..525d2dc
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/re_lst.h
@@ -0,0 +1,184 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE re_lst.h
+ * VERSION 2.12
+ * This is an internal header file, do not include directly.
+ * re_list support class, for regular
+ * expression library.
+ */
+
+#ifndef RE_LST_H
+#define RE_LST_H
+
+#ifndef JM_CFG_H
+#include <jm/jm_cfg.h>
+#endif
+
+#include <new.h>
+
+JM_NAMESPACE(__JM)
+
+template <class T, class Allocator>
+class re_list
+{
+public:
+ struct node
+ {
+ node* next;
+ T t;
+ node(const T& o) : t(o) {}
+ };
+public:
+ class iterator
+ {
+ node* pos;
+ public:
+ iterator() { pos = 0; }
+ ~iterator() {}
+ iterator(const iterator& i) { pos = i.pos; }
+ iterator(node* n) { pos = n; }
+ iterator& operator=(const iterator& i)
+ {
+ pos = i.pos;
+ return *this;
+ }
+ bool operator==(iterator& i)
+ {
+ return pos == i.pos;
+ }
+ bool operator!=(iterator& i)
+ {
+ return pos != i.pos;
+ }
+ T& operator*() { return pos->t; }
+ iterator& operator++()
+ {
+ pos = pos->next;
+ return *this;
+ }
+ iterator operator++(int)
+ {
+ iterator t(*this);
+ pos = pos->next;
+ return t;
+ }
+ const node* tell()const
+ {
+ return pos;
+ }
+ };
+
+ class const_iterator
+ {
+ const node* pos;
+ public:
+ const_iterator() { pos = 0; }
+ ~const_iterator() {}
+ const_iterator(const const_iterator& i) { pos = i.pos; }
+ const_iterator(const iterator& i) { pos = i.tell(); }
+ const_iterator(const node* n) { pos = n; }
+ const_iterator& operator=(const iterator& i)
+ {
+ pos = i.tell();
+ return *this;
+ }
+ const_iterator& operator=(const const_iterator& i)
+ {
+ pos = i.pos;
+ return *this;
+ }
+ bool operator==(const_iterator& i)
+ {
+ return pos == i.pos;
+ }
+ bool operator!=(const_iterator& i)
+ {
+ return pos != i.pos;
+ }
+ const T& operator*() { return pos->t; }
+ const_iterator& operator++()
+ {
+ pos = pos->next;
+ return *this;
+ }
+ const_iterator operator++(int)
+ {
+ const_iterator t(*this);
+ pos = pos->next;
+ return t;
+ }
+ };
+private:
+ typedef JM_MAYBE_TYPENAME REBIND_TYPE(node, Allocator) node_alloc;
+
+ struct data : public node_alloc
+ {
+ node* first;
+ data(const Allocator& a) : node_alloc(a), first(0) {}
+ };
+ data alloc_inst;
+
+public:
+ re_list(const Allocator& a = Allocator()) : alloc_inst(a) {}
+ ~re_list() { clear(); }
+ iterator RE_CALL begin() { return iterator(alloc_inst.first); }
+ iterator RE_CALL end() { return iterator(0); }
+ const_iterator RE_CALL begin()const { return const_iterator(alloc_inst.first); }
+ const_iterator RE_CALL end()const { return const_iterator(0); }
+ void RE_CALL add(const T& t)
+ {
+ node* temp;
+ temp = alloc_inst.allocate(1);
+#ifndef JM_NO_EXCEPTIONS
+ try{
+#endif
+ alloc_inst.construct(temp, t);
+#ifndef JM_NO_EXCEPTIONS
+ }catch(...){ alloc_inst.deallocate(temp, 1); throw; }
+#endif
+ temp->next = alloc_inst.first;
+ alloc_inst.first = temp;
+ }
+ void RE_CALL clear();
+};
+
+template <class T, class Allocator>
+void RE_CALL re_list<T, Allocator>::clear()
+{
+ node* temp;
+ while(alloc_inst.first)
+ {
+ temp = alloc_inst.first;
+ alloc_inst.first = alloc_inst.first->next;
+ alloc_inst.destroy(temp);
+ alloc_inst.deallocate(temp, 1);
+ }
+}
+
+
+JM_END_NAMESPACE
+
+#endif
+
+
diff --git a/utils/tfstats/regexp/include/jm/re_mss.h b/utils/tfstats/regexp/include/jm/re_mss.h
new file mode 100644
index 0000000..7ff4809
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/re_mss.h
@@ -0,0 +1,90 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE re_mss.h
+ * VERSION 2.12
+ * This is an internal header file, do not include directly.
+ * Message helper functions, for regular
+ * expression library.
+ */
+
+#ifndef RE_MSS_H
+#define RE_MSS_H
+
+#ifndef JM_CFG_H
+#include <jm/jm_cfg.h>
+#endif
+
+JM_NAMESPACE(__JM)
+
+//
+// re_get_message
+// returns required buffer size if len is zero
+// otherwise fills in buf.
+//
+
+JM_IX_DECL unsigned int RE_CALL re_get_default_message(char* buf, unsigned int len, unsigned int id);
+
+JM_IX_DECL unsigned int RE_CALL __re_get_message(char* buf, unsigned int len, unsigned int id);
+
+template <class charT>
+unsigned int RE_CALL re_get_message(charT* buf, unsigned int len, unsigned int id)
+{
+ unsigned int size = __re_get_message((char*)0, 0, id);
+ if(len < size)
+ return size;
+ auto_array<char> cb(new char[size]);
+ __re_get_message((char*)cb, size, id);
+ size = re_strwiden(buf, len, (char*)cb);
+ return size;
+}
+
+inline unsigned int RE_CALL re_get_message(char* buf, unsigned int len, unsigned int id)
+{
+ return __re_get_message(buf, len, id);
+}
+
+
+//
+// declare message initialisers:
+//
+void RE_CALL re_message_init();
+void RE_CALL re_message_update();
+void RE_CALL re_message_free();
+
+#ifdef RE_LOCALE_CPP
+
+__JM_STD::messages<char>::string_type RE_CALL re_get_def_message(unsigned int i);
+
+__JM_STD::messages<wchar_t>::string_type RE_CALL re_get_def_message_w(unsigned int i);
+
+extern const char *re_default_error_messages[];
+
+#endif
+
+
+JM_END_NAMESPACE
+
+
+#endif
+
diff --git a/utils/tfstats/regexp/include/jm/re_nls.h b/utils/tfstats/regexp/include/jm/re_nls.h
new file mode 100644
index 0000000..b6a293a
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/re_nls.h
@@ -0,0 +1,371 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE re_nls.h
+ * VERSION 2.12
+ * This is an internal header file, do not include directly
+ */
+
+#ifndef RE_NLS_H
+#define RE_NLS_H
+
+#ifndef JM_CFG_H
+#include <jm/jm_cfg.h>
+#endif
+
+#ifdef RE_LOCALE_CPP
+#include <jm/regfac.h>
+#endif
+
+#include <limits.h>
+
+JM_NAMESPACE(__JM)
+
+enum char_class_type
+{
+#ifdef RE_LOCALE_CPP
+ char_class_none = 0,
+ char_class_alnum = __JM_STD::ctype_base::alnum,
+ char_class_alpha = __JM_STD::ctype_base::alpha,
+ char_class_cntrl = __JM_STD::ctype_base::cntrl,
+ char_class_digit = __JM_STD::ctype_base::digit,
+ char_class_graph = __JM_STD::ctype_base::graph,
+ char_class_lower = __JM_STD::ctype_base::lower,
+ char_class_print = __JM_STD::ctype_base::print,
+ char_class_punct = __JM_STD::ctype_base::punct,
+ char_class_space = __JM_STD::ctype_base::space,
+ char_class_upper = __JM_STD::ctype_base::upper,
+ char_class_xdigit = __JM_STD::ctype_base::xdigit,
+ char_class_blank = 1<<12,
+ char_class_underscore = 1<<13,
+ char_class_word = __JM_STD::ctype_base::alnum | char_class_underscore,
+ char_class_unicode = 1<<14,
+ char_class_all_base = char_class_alnum | char_class_alpha | char_class_cntrl
+ | char_class_digit | char_class_graph | char_class_lower
+ | char_class_print | char_class_punct | char_class_space
+ | char_class_upper | char_class_xdigit
+
+#elif defined(RE_LOCALE_W32)
+ char_class_none = 0,
+ char_class_alnum = C1_ALPHA | C1_DIGIT,
+ char_class_alpha = C1_ALPHA,
+ char_class_cntrl = C1_CNTRL,
+ char_class_digit = C1_DIGIT,
+ char_class_graph = C1_UPPER | C1_LOWER | C1_DIGIT | C1_PUNCT | C1_ALPHA,
+ char_class_lower = C1_LOWER,
+ char_class_print = C1_UPPER | C1_LOWER | C1_DIGIT | C1_PUNCT | C1_BLANK | C1_ALPHA,
+ char_class_punct = C1_PUNCT,
+ char_class_space = C1_SPACE,
+ char_class_upper = C1_UPPER,
+ char_class_xdigit = C1_XDIGIT,
+ char_class_blank = C1_BLANK,
+ char_class_underscore = 0x0200,
+ char_class_word = C1_ALPHA | C1_DIGIT | char_class_underscore,
+ char_class_unicode = 0x0400
+#else
+ char_class_none = 0,
+ char_class_alpha = 1,
+ char_class_cntrl = char_class_alpha << 1,
+ char_class_digit = char_class_cntrl << 1,
+ char_class_lower = char_class_digit << 1,
+ char_class_punct = char_class_lower << 1,
+ char_class_space = char_class_punct << 1,
+ char_class_upper = char_class_space << 1,
+ char_class_xdigit = char_class_upper << 1,
+ char_class_blank = char_class_xdigit << 1,
+ char_class_unicode = char_class_blank << 1,
+ char_class_underscore = char_class_unicode << 1,
+
+ char_class_alnum = char_class_alpha | char_class_digit,
+ char_class_graph = char_class_alpha | char_class_digit | char_class_punct | char_class_underscore,
+ char_class_print = char_class_alpha | char_class_digit | char_class_punct | char_class_underscore | char_class_blank,
+ char_class_word = char_class_alpha | char_class_digit | char_class_underscore
+#endif
+};
+
+//
+// declare our initialise class and functions:
+//
+
+template <class charT>
+class re_initialiser
+{
+public:
+ void update();
+};
+
+JM_IX_DECL void RE_CALL re_init();
+JM_IX_DECL void RE_CALL re_update();
+JM_IX_DECL void RE_CALL re_free();
+JM_IX_DECL void RE_CALL re_init_w();
+JM_IX_DECL void RE_CALL re_update_w();
+JM_IX_DECL void RE_CALL re_free_w();
+
+JM_TEMPLATE_SPECIALISE
+class re_initialiser<char>
+{
+public:
+ re_initialiser() { re_init(); }
+ ~re_initialiser() { re_free(); }
+ void RE_CALL update() { re_update(); }
+};
+
+#ifndef JM_NO_WCSTRING
+JM_TEMPLATE_SPECIALISE
+class re_initialiser<wchar_t>
+{
+public:
+ re_initialiser() { re_init_w(); }
+ ~re_initialiser() { re_free_w(); }
+ void RE_CALL update() { re_update_w(); }
+};
+#endif
+
+//
+// start by declaring externals for RE_LOCALE_C
+// and RE_LOCALE_W32:
+//
+
+JM_IX_DECL extern unsigned char re_syntax_map[];
+JM_IX_DECL extern unsigned short re_class_map[];
+JM_IX_DECL extern char re_lower_case_map[];
+JM_IX_DECL extern char re_zero;
+JM_IX_DECL extern char re_ten;
+
+#ifndef JM_NO_WCSTRING
+JM_IX_DECL extern unsigned short re_unicode_classes[];
+JM_IX_DECL extern const wchar_t* re_lower_case_map_w;
+JM_IX_DECL extern wchar_t re_zero_w;
+JM_IX_DECL extern wchar_t re_ten_w;
+
+JM_IX_DECL wchar_t RE_CALL re_wtolower(wchar_t c);
+JM_IX_DECL bool RE_CALL re_iswclass(wchar_t c, jm_uintfast32_t f);
+#endif
+
+JM_IX_DECL const char* RE_CALL re_get_error_str(unsigned int id);
+JM_IX_DECL unsigned int RE_CALL re_get_syntax_type(wchar_t c);
+
+#ifdef RE_LOCALE_CPP
+__JM_STD::string RE_CALL re_get_error_str(unsigned int id, const __JM_STD::locale&);
+#endif
+
+//
+// add some API's for character manipulation:
+//
+inline char RE_CALL re_tolower(char c
+#ifdef RE_LOCALE_CPP
+, const __JM_STD::locale& l
+#endif
+)
+{
+#ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, __JM_STD::ctype<char>).tolower(c);
+#else
+ return re_lower_case_map[(unsigned char)c];
+#endif
+}
+
+#ifndef JM_NO_WCSTRING
+inline wchar_t RE_CALL re_tolower(wchar_t c
+#ifdef RE_LOCALE_CPP
+, const __JM_STD::locale& l
+#endif
+)
+{
+#ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, __JM_STD::ctype<wchar_t>).tolower(c);
+#else
+ return c < 256 ? re_lower_case_map_w[c] : re_wtolower(c);
+#endif
+}
+#endif
+
+inline bool RE_CALL re_istype(char c, jm_uintfast32_t f
+#ifdef RE_LOCALE_CPP
+, const __JM_STD::locale& l
+#endif
+)
+{
+#ifdef RE_LOCALE_CPP
+ if(JM_USE_FACET(l, __JM_STD::ctype<char>).is((__JM_STD::ctype<char>::mask)(f & char_class_all_base), c))
+ return true;
+ if((f & char_class_underscore) && (c == '_'))
+ return true;
+ if((f & char_class_blank) && ((c == ' ') || (c == '\t')))
+ return true;
+ return false;
+#else
+ return re_class_map[(unsigned char)c] & f;
+#endif
+}
+
+#ifndef JM_NO_WCSTRING
+inline bool RE_CALL re_istype(wchar_t c, jm_uintfast32_t f
+#ifdef RE_LOCALE_CPP
+, const __JM_STD::locale& l
+#endif
+)
+{
+#ifdef RE_LOCALE_CPP
+ if(JM_USE_FACET(l, __JM_STD::ctype<wchar_t>).is((__JM_STD::ctype<wchar_t>::mask)(f & char_class_all_base), c))
+ return true;
+ if((f & char_class_underscore) && (c == '_'))
+ return true;
+ if((f & char_class_blank) && ((c == ' ') || (c == '\t')))
+ return true;
+ return false;
+#else
+ return c < 256 ? re_unicode_classes[c] & f : re_iswclass(c, f);
+#endif
+}
+#endif
+
+inline char RE_CALL re_get_zero(char
+#ifdef RE_LOCALE_CPP
+, const __JM_STD::locale& l
+#endif
+)
+{
+#ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, regfacet<char>).zero();
+#else
+ return re_zero;
+#endif
+}
+
+#ifndef JM_NO_WCSTRING
+inline wchar_t RE_CALL re_get_zero(wchar_t
+#ifdef RE_LOCALE_CPP
+, const __JM_STD::locale& l
+#endif
+)
+{
+#ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, regfacet<wchar_t>).zero();
+#else
+ return re_zero_w;
+#endif
+}
+#endif
+
+inline char RE_CALL re_get_ten(char
+#ifdef RE_LOCALE_CPP
+, const __JM_STD::locale& l
+#endif
+)
+{
+#ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, regfacet<char>).ten();
+#else
+ return re_ten;
+#endif
+}
+
+#ifndef JM_NO_WCSTRING
+inline wchar_t RE_CALL re_get_ten(wchar_t
+#ifdef RE_LOCALE_CPP
+, const __JM_STD::locale& l
+#endif
+)
+{
+#ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, regfacet<wchar_t>).ten();
+#else
+ return re_ten_w;
+#endif
+}
+#endif
+
+//
+// re_toi:
+// convert a single character to the int it represents:
+//
+template <class charT>
+unsigned int RE_CALL re_toi(charT c
+#ifdef RE_LOCALE_CPP
+, const __JM_STD::locale& l
+#endif
+)
+{
+ if(re_istype(c, char_class_digit MAYBE_PASS_LOCALE(l)))
+ return c - re_get_zero(c MAYBE_PASS_LOCALE(l));
+ if(re_istype(c, char_class_xdigit MAYBE_PASS_LOCALE(l)))
+ return 10 + re_tolower(c MAYBE_PASS_LOCALE(l)) - re_tolower(re_get_ten(c MAYBE_PASS_LOCALE(l)) MAYBE_PASS_LOCALE(l));
+ return -1; // error!!
+}
+
+//
+// re_toi:
+// parse an int from the input string
+// update first to point to end of int
+// on exit.
+//
+template <class charT>
+unsigned int RE_CALL re_toi(const charT*& first, const charT*const last, int radix
+#ifdef RE_LOCALE_CPP
+, const __JM_STD::locale& l
+#endif
+)
+{
+ unsigned int maxval;
+ if(radix < 0)
+ {
+ // if radix is less than zero, then restrict
+ // return value to charT. NB assumes sizeof(charT) <= sizeof(int)
+ radix *= -1;
+ maxval = 1 << (sizeof(charT) * CHAR_BIT - 1);
+ maxval /= radix;
+ maxval *= 2;
+ maxval -= 1;
+ }
+ else
+ {
+ maxval = (unsigned int)-1;
+ maxval /= radix;
+ }
+
+ unsigned int result = 0;
+ unsigned int type = (radix > 10) ? char_class_xdigit : char_class_digit;
+ while((first != last) && re_istype(*first, type MAYBE_PASS_LOCALE(l)) && (result <= maxval))
+ {
+ result *= radix;
+ result += re_toi(*first MAYBE_PASS_LOCALE(l));
+ ++first;
+ }
+ return result;
+}
+
+
+#ifndef JM_NO_WCSTRING
+JM_IX_DECL bool RE_CALL re_is_combining(wchar_t c);
+#endif
+
+extern const char* regex_message_catalogue;
+
+JM_IX_DECL const char* RE_CALL get_global_locale_name(int);
+
+
+JM_END_NAMESPACE
+
+#endif
+
diff --git a/utils/tfstats/regexp/include/jm/re_raw.h b/utils/tfstats/regexp/include/jm/re_raw.h
new file mode 100644
index 0000000..e270097
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/re_raw.h
@@ -0,0 +1,185 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE re_raw.h
+ * VERSION 2.12
+ */
+
+#ifndef RE_RAW_H
+#define RE_RAW_H
+
+#ifndef JM_CFG_H
+#include <jm/jm_cfg.h>
+#endif
+
+JM_NAMESPACE(__JM)
+
+union padding
+{
+ void* p;
+ unsigned int i;
+};
+
+
+//
+// class raw_storage
+// basically this is a simplified vector<unsigned char>
+// this is used by reg_expression for expression storage
+//
+
+template <class Allocator>
+class raw_storage
+{
+public:
+ typedef Allocator alloc_type;
+ typedef typename REBIND_TYPE(unsigned char, alloc_type)::size_type size_type;
+ typedef JM_MAYBE_TYPENAME REBIND_TYPE(unsigned char, alloc_type) alloc_inst_type;
+ typedef typename REBIND_TYPE(unsigned char, alloc_type)::pointer pointer;
+private:
+ //
+ // empty member optimisation:
+ struct alloc_data : public alloc_inst_type
+ {
+ pointer last;
+ alloc_data(const Allocator& a) : alloc_inst_type(a){}
+ } alloc_inst;
+ pointer start, end;
+public:
+
+ raw_storage(const Allocator& a = Allocator());
+ raw_storage(size_type n, const Allocator& a = Allocator());
+
+ ~raw_storage()
+ {
+ alloc_inst.deallocate(start, (alloc_inst.last - start));
+ }
+
+ void RE_CALL resize(size_type n);
+
+ void* RE_CALL extend(size_type n)
+ {
+ if(size_type(alloc_inst.last - end) < n)
+ resize(n + (end - start));
+ register void* result = end;
+ end += n;
+ return result;
+ }
+
+ void* RE_CALL insert(size_type pos, size_type n);
+
+ size_type RE_CALL size()
+ {
+ return end - start;
+ }
+
+ size_type RE_CALL capacity()
+ {
+ return alloc_inst.last - start;
+ }
+
+ void* RE_CALL data()const
+ {
+ return start;
+ }
+
+ size_type RE_CALL index(void* ptr)
+ {
+ return (unsigned char*)ptr - start;
+ }
+
+ void RE_CALL clear()
+ {
+ end = start;
+ }
+
+ void RE_CALL align()
+ {
+ // move end up to a boundary:
+ end = (unsigned char*)((long)(end + sizeof(padding) - 1) & ~((long)sizeof(padding) - 1));
+ }
+
+ Allocator RE_CALL allocator()const;
+};
+
+template <class Allocator>
+CONSTRUCTOR_INLINE raw_storage<Allocator>::raw_storage(const Allocator& a)
+ : alloc_inst(a)
+{
+ start = end = alloc_inst.allocate(1024);
+ alloc_inst.last = start + 1024;
+}
+
+template <class Allocator>
+CONSTRUCTOR_INLINE raw_storage<Allocator>::raw_storage(size_type n, const Allocator& a)
+ : alloc_inst(a)
+{
+ start = end = alloc_inst.allocate(n);
+ alloc_inst.last = start + n;
+}
+
+template <class Allocator>
+Allocator RE_CALL raw_storage<Allocator>::allocator()const
+{
+ return alloc_inst;
+}
+
+template <class Allocator>
+void RE_CALL raw_storage<Allocator>::resize(size_type n)
+{
+ register size_type newsize = (alloc_inst.last - start) * 2;
+ register size_type datasize = end - start;
+ if(newsize < n)
+ newsize = n;
+ // extend newsize to WORD/DWORD boundary:
+ newsize = (newsize + (sizeof(padding) - 1)) & ~(sizeof(padding) - 1);
+
+ // allocate and copy data:
+ register unsigned char* ptr = alloc_inst.allocate(newsize);
+ memcpy(ptr, start, datasize);
+
+ // get rid of old buffer:
+ alloc_inst.deallocate(start, (alloc_inst.last - start));
+
+ // and set up pointers:
+ start = ptr;
+ end = ptr + datasize;
+ alloc_inst.last = ptr + newsize;
+}
+
+template <class Allocator>
+void* RE_CALL raw_storage<Allocator>::insert(size_type pos, size_type n)
+{
+ jm_assert(pos <= size_type(end - start));
+ if(size_type(alloc_inst.last - end) < n)
+ resize(n + (end - start));
+ register void* result = start + pos;
+ memmove(start + pos + n, start + pos, (end - start) - pos);
+ end += n;
+ return result;
+}
+
+JM_END_NAMESPACE
+
+#endif
+
+
diff --git a/utils/tfstats/regexp/include/jm/re_str.h b/utils/tfstats/regexp/include/jm/re_str.h
new file mode 100644
index 0000000..387342b
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/re_str.h
@@ -0,0 +1,301 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE re_str.h
+ * VERSION 2.12
+ * This is an internal header file, do not include directly.
+ * String support and helper functions, for regular
+ * expression library.
+ */
+
+#ifndef RE_STR_H
+#define RE_STR_H
+
+#ifndef JM_CFG_H
+#include <jm/jm_cfg.h>
+#endif
+
+#include <string.h>
+
+JM_NAMESPACE(__JM)
+
+//
+// start by defining some template function aliases for C API functions:
+//
+
+template <class charT>
+size_t RE_CALL re_strlen(const charT *s)
+{
+ size_t len = 0;
+ while(*s)
+ {
+ ++s;
+ ++len;
+ }
+ return len;
+}
+
+template <class charT>
+int RE_CALL re_strcmp(const charT *s1, const charT *s2)
+{
+ while(*s1 && *s2)
+ {
+ if(*s1 != *s2)
+ return *s1 - *s2;
+ ++s1;
+ ++s2;
+ }
+ return *s1 - *s2;
+}
+
+template <class charT>
+charT* RE_CALL re_strcpy(charT *s1, const charT *s2)
+{
+ charT* base = s1;
+ while(*s2)
+ {
+ *s1 = *s2;
+ ++s1;
+ ++s2;
+ }
+ *s1 = *s2;
+ return base;
+}
+
+template <class charT>
+unsigned int RE_CALL re_strwiden(charT *s1, unsigned int len, const char *s2)
+{
+ unsigned int result = 1 + re_strlen(s2);
+ if(result > len)
+ return result;
+ while(*s2)
+ {
+ *s1 = (unsigned char)*s2;
+ ++s2;
+ ++s1;
+ }
+ *s1 = (unsigned char)*s2;
+ return result;
+}
+
+template <class charT>
+unsigned int RE_CALL re_strnarrow(char *s1, unsigned int len, const charT *s2)
+{
+ unsigned int result = 1 + re_strlen(s2);
+ if(result > len)
+ return result;
+ while(*s2)
+ {
+ *s1 = (char)(unsigned char)*s2;
+ ++s2;
+ ++s1;
+ }
+ *s1 = (char)(unsigned char)*s2;
+ return result;
+}
+
+inline size_t RE_CALL re_strlen(const char *s)
+{
+ return strlen(s);
+}
+
+inline int RE_CALL re_strcmp(const char *s1, const char *s2)
+{
+ return strcmp(s1, s2);
+}
+
+inline char* RE_CALL re_strcpy(char *s1, const char *s2)
+{
+ return strcpy(s1, s2);
+}
+
+#ifndef JM_NO_WCSTRING
+
+inline size_t RE_CALL re_strlen(const wchar_t *s)
+{
+ return wcslen(s);
+}
+
+inline int RE_CALL re_strcmp(const wchar_t *s1, const wchar_t *s2)
+{
+ return wcscmp(s1, s2);
+}
+
+inline wchar_t* RE_CALL re_strcpy(wchar_t *s1, const wchar_t *s2)
+{
+ return wcscpy(s1, s2);
+}
+
+#endif
+
+#if !defined(JM_NO_WCSTRING) || defined(JM_PLATFORM_W32)
+
+JM_IX_DECL unsigned int RE_CALL _re_strnarrow(char *s1, unsigned int len, const wchar_t *s2);
+JM_IX_DECL unsigned int RE_CALL _re_strwiden(wchar_t *s1, unsigned int len, const char *s2);
+
+
+inline unsigned int RE_CALL re_strnarrow(char *s1, unsigned int len, const wchar_t *s2)
+{
+ return _re_strnarrow(s1, len, s2);
+}
+
+inline unsigned int RE_CALL re_strwiden(wchar_t *s1, unsigned int len, const char *s2)
+{
+ return _re_strwiden(s1, len, s2);
+}
+
+#endif
+
+template <class charT>
+charT* RE_CALL re_strdup(const charT* p)
+{
+ charT* buf = new charT[re_strlen(p) + 1];
+ re_strcpy(buf, p);
+ return buf;
+}
+
+template <class charT>
+charT* RE_CALL re_strdup(const charT* p1, const charT* p2)
+{
+ unsigned int len = p2 - p1 + 1;
+ charT* buf = new charT[len];
+ memcpy(buf, p1, (len - 1) * sizeof(charT));
+ *(buf + len - 1) = 0;
+ return buf;
+}
+
+template <class charT>
+inline void RE_CALL re_strfree(charT* p)
+{
+ delete[] p;
+}
+
+template <class charT>
+class re_str
+{
+ charT* buf;
+public:
+ re_str()
+ {
+ charT c = 0;
+ buf = re_strdup(&c);
+ }
+ ~re_str();
+ re_str(const re_str& other);
+ re_str(const charT* p1);
+ re_str(const charT* p1, const charT* p2);
+ re_str(charT c);
+
+ re_str& RE_CALL operator=(const re_str& other)
+ {
+ re_strfree(buf);
+ buf = re_strdup(other.buf);
+ return *this;
+ }
+ re_str& RE_CALL operator=(const charT* p)
+ {
+ re_strfree(buf);
+ buf = re_strdup(p);
+ return *this;
+ }
+ re_str& RE_CALL operator=(charT c)
+ {
+ re_strfree(buf);
+ buf = re_strdup(&c, &c+1);
+ return *this;
+ }
+ const charT* RE_CALL c_str()const { return buf; }
+ RE_CALL operator const charT*()const { return buf; }
+ unsigned int RE_CALL size()const { return re_strlen(buf); }
+ charT& RE_CALL operator[](unsigned int i) { return buf[i]; }
+ charT RE_CALL operator[](unsigned int i)const { return buf[i]; }
+
+ bool RE_CALL operator==(const re_str& other)const { return re_strcmp(buf, other.buf) == 0; }
+ bool RE_CALL operator==(const charT* p)const { return re_strcmp(buf, p) == 0; }
+ bool RE_CALL operator==(const charT c)const
+ {
+ if((*buf) && (*buf == c) && (*(buf+1) == 0))
+ return true;
+ return false;
+ }
+ bool RE_CALL operator!=(const re_str& other)const { return re_strcmp(buf, other.buf) != 0; }
+ bool RE_CALL operator!=(const charT* p)const { return re_strcmp(buf, p) != 0; }
+ bool RE_CALL operator!=(const charT c)const { return !(*this == c); }
+
+ bool RE_CALL operator<(const re_str& other)const { return re_strcmp(buf, other.buf) < 0; }
+ bool RE_CALL operator<=(const re_str& other)const { return re_strcmp(buf, other.buf) <= 0; }
+ bool RE_CALL operator>(const re_str& other)const { return re_strcmp(buf, other.buf) > 0; }
+ bool RE_CALL operator>=(const re_str& other)const { return re_strcmp(buf, other.buf) >= 0; }
+
+ bool RE_CALL operator<(const charT* p)const { return re_strcmp(buf, p) < 0; }
+ bool RE_CALL operator<=(const charT* p)const { return re_strcmp(buf, p) <= 0; }
+ bool RE_CALL operator>(const charT* p)const { return re_strcmp(buf, p) > 0; }
+ bool RE_CALL operator>=(const charT* p)const { return re_strcmp(buf, p) >= 0; }
+};
+
+template <class charT>
+CONSTRUCTOR_INLINE re_str<charT>::~re_str() { re_strfree(buf); }
+
+template <class charT>
+CONSTRUCTOR_INLINE re_str<charT>::re_str(const re_str<charT>& other) { buf = re_strdup(other.buf); }
+
+template <class charT>
+CONSTRUCTOR_INLINE re_str<charT>::re_str(const charT* p1) { buf = re_strdup(p1); }
+
+template <class charT>
+CONSTRUCTOR_INLINE re_str<charT>::re_str(const charT* p1, const charT* p2) { buf = re_strdup(p1, p2); }
+
+template <class charT>
+CONSTRUCTOR_INLINE re_str<charT>::re_str(charT c) { buf = re_strdup(&c, &c+1); }
+
+
+#ifndef JM_NO_WCSTRING
+JM_IX_DECL void RE_CALL re_transform(re_str<wchar_t>& out, const re_str<wchar_t>& in);
+#endif
+JM_IX_DECL void RE_CALL re_transform(re_str<char>& out, const re_str<char>& in);
+
+template <class charT>
+void RE_CALL re_trunc_primary(re_str<charT>& s)
+{
+ for(unsigned int i = 0; i < s.size(); ++i)
+ {
+ if(s[i] <= 1)
+ {
+ s[i] = 0;
+ break;
+ }
+ }
+}
+
+#ifdef RE_LOCALE_C
+#define TRANSFORM_ERROR (size_t)-1
+#else
+#define TRANSFORM_ERROR 0
+#endif
+
+
+JM_END_NAMESPACE
+
+#endif
+
+
diff --git a/utils/tfstats/regexp/include/jm/re_thrd.h b/utils/tfstats/regexp/include/jm/re_thrd.h
new file mode 100644
index 0000000..c0fc7b7
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/re_thrd.h
@@ -0,0 +1,169 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE re_thrd.h
+ * VERSION 2.12
+ * Thread synch helper functions, for regular
+ * expression library.
+ */
+
+#ifndef RE_THRD_H
+#define RE_THRD_H
+
+#ifndef JM_CFG_H
+#include <jm/jm_cfg.h>
+#endif
+
+#if defined(JM_PLATFORM_W32) && defined(JM_THREADS)
+//#include <windows.h>
+#endif
+
+#if !defined(JM_PLATFORM_W32) && defined(JM_THREADS)
+#include <pthread.h>
+#endif
+
+
+JM_NAMESPACE(__JM)
+
+void RE_CALL re_init_threads();
+void RE_CALL re_free_threads();
+
+#ifdef JM_THREADS
+
+#ifndef JM_PLATFORM_W32
+
+typedef pthread_mutex_t CRITICAL_SECTION;
+
+inline void RE_CALL InitializeCriticalSection(CRITICAL_SECTION* ps)
+{
+ pthread_mutex_init(ps, NULL);
+}
+
+inline void RE_CALL DeleteCriticalSection(CRITICAL_SECTION* ps)
+{
+ pthread_mutex_destroy(ps);
+}
+
+inline void RE_CALL EnterCriticalSection(CRITICAL_SECTION* ps)
+{
+ pthread_mutex_lock(ps);
+}
+
+inline void RE_CALL LeaveCriticalSection(CRITICAL_SECTION* ps)
+{
+ pthread_mutex_unlock(ps);
+}
+
+#endif
+
+template <class Lock>
+class lock_guard
+{
+ typedef Lock lock_type;
+public:
+ lock_guard(lock_type& m, bool aq = true)
+ : mut(m), owned(false){ acquire(aq); }
+
+ ~lock_guard()
+ { acquire(false); }
+
+ void RE_CALL acquire(bool aq = true, DWORD timeout = INFINITE)
+ {
+ if(aq && !owned)
+ {
+ mut.acquire(true, timeout);
+ owned = true;
+ }
+ else if(!aq && owned)
+ {
+ mut.acquire(false);
+ owned = false;
+ }
+ }
+private:
+ lock_type& mut;
+ bool owned;
+};
+
+
+class critical_section
+{
+public:
+ critical_section()
+ { InitializeCriticalSection(&hmutex);}
+
+ critical_section(const critical_section&)
+ { InitializeCriticalSection(&hmutex);}
+
+ const critical_section& RE_CALL operator=(const critical_section&)
+ {return *this;}
+
+ ~critical_section()
+ {DeleteCriticalSection(&hmutex);}
+
+private:
+
+ void RE_CALL acquire(bool aq, DWORD unused = INFINITE)
+ { if(aq) EnterCriticalSection(&hmutex);
+ else LeaveCriticalSection(&hmutex);
+ }
+
+ CRITICAL_SECTION hmutex;
+
+public:
+ typedef lock_guard<critical_section> ro_guard;
+ typedef lock_guard<critical_section> rw_guard;
+
+ friend lock_guard<critical_section>;
+};
+
+inline bool RE_CALL operator==(const critical_section&, const critical_section&)
+{
+ return false;
+}
+
+inline bool RE_CALL operator<(const critical_section&, const critical_section&)
+{
+ return true;
+}
+
+typedef lock_guard<critical_section> cs_guard;
+
+JM_IX_DECL extern critical_section* p_re_lock;
+JM_IX_DECL extern unsigned int re_lock_count;
+
+#define JM_GUARD(inst) __JM::critical_section::rw_guard g(inst);
+
+#else // JM_THREADS
+
+#define JM_GUARD(inst)
+
+#endif // JM_THREADS
+
+JM_END_NAMESPACE
+
+#endif // sentry
+
+
+
+
diff --git a/utils/tfstats/regexp/include/jm/regcomp.h b/utils/tfstats/regexp/include/jm/regcomp.h
new file mode 100644
index 0000000..0065bba
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/regcomp.h
@@ -0,0 +1,1888 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE regcomp.h
+ * VERSION 2.12
+ * This is an internal header file, do not include directly
+ */
+
+JM_NAMESPACE(__JM)
+
+template <class traits>
+struct kmp_translator
+{
+ typedef typename traits::char_type char_type;
+ bool icase;
+ kmp_translator(bool c) : icase(c) {}
+ char_type operator()(char_type c
+#ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+#endif
+ )
+ {
+ return traits::translate(c, icase MAYBE_PASS_LOCALE(l));
+ }
+};
+
+#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
+//
+// Ugly ugly hack,
+// template don't merge if they contain switch statements so declare these
+// templates in unnamed namespace (ie with internal linkage), each translation
+// unit then gets its own local copy, it works seemlessly but bloats the app.
+namespace{
+#endif
+
+template <class charT, class traits, class Allocator>
+inline bool RE_CALL reg_expression<charT, traits, Allocator>::can_start(charT c, const unsigned char* __map, unsigned char mask, const __wide_type&)
+{
+ if((traits_size_type)(traits_uchar_type)c >= 256)
+ return true;
+ return JM_MAKE_BOOL(__map[(traits_uchar_type)c] & mask);
+}
+
+template <class charT, class traits, class Allocator>
+inline bool RE_CALL reg_expression<charT, traits, Allocator>::can_start(charT c, const unsigned char* __map, unsigned char mask, const __narrow_type&)
+{
+ return JM_MAKE_BOOL(__map[(traits_uchar_type)c] & mask);
+}
+
+template <class charT, class traits, class Allocator>
+CONSTRUCTOR_INLINE reg_expression<charT, traits, Allocator>::reg_expression(const Allocator& a)
+ : regbase(), data(a), pkmp(0)
+{
+}
+
+template <class charT, class traits, class Allocator>
+CONSTRUCTOR_INLINE reg_expression<charT, traits, Allocator>::reg_expression(const charT* p, jm_uintfast32_t f, const Allocator& a)
+ : data(a), pkmp(0)
+{
+ set_expression(p, f);
+}
+
+template <class charT, class traits, class Allocator>
+CONSTRUCTOR_INLINE reg_expression<charT, traits, Allocator>::reg_expression(const charT* p1, const charT* p2, jm_uintfast32_t f, const Allocator& a)
+ : data(a), pkmp(0)
+{
+ set_expression(p1, p2, f);
+}
+
+template <class charT, class traits, class Allocator>
+CONSTRUCTOR_INLINE reg_expression<charT, traits, Allocator>::reg_expression(const charT* p, size_type len, jm_uintfast32_t f, const Allocator& a)
+ : data(a), pkmp(0)
+{
+ set_expression(p, p + len, f);
+}
+
+template <class charT, class traits, class Allocator>
+reg_expression<charT, traits, Allocator>::reg_expression(const reg_expression<charT, traits, Allocator>& e)
+ : regbase(e), data(e.allocator()), pkmp(0)
+{
+ //
+ // we do a deep copy only if e is a valid expression, otherwise fail.
+ //
+ //_flags = 0;
+ //fail(e.error_code());
+ if(error_code() == 0)
+ set_expression(e.expression(), e.flags());
+}
+
+template <class charT, class traits, class Allocator>
+reg_expression<charT, traits, Allocator>::~reg_expression()
+{
+ if(pkmp)
+ kmp_free(pkmp, data.allocator());
+}
+
+template <class charT, class traits, class Allocator>
+reg_expression<charT, traits, Allocator>& RE_CALL reg_expression<charT, traits, Allocator>::operator=(const reg_expression<charT, traits, Allocator>& e)
+{
+ //
+ // we do a deep copy only if e is a valid expression, otherwise fail.
+ //
+ if(this == &e) return *this;
+ _flags = 0;
+ fail(e.error_code());
+ if(error_code() == 0)
+ set_expression(e.expression(), e.flags());
+ return *this;
+}
+
+template <class charT, class traits, class Allocator>
+inline bool RE_CALL reg_expression<charT, traits, Allocator>::operator==(const reg_expression<charT, traits, Allocator>& e)
+{
+ return (_flags == e.flags()) && (re_strcmp(expression(), e.expression()) == 0);
+}
+
+template <class charT, class traits, class Allocator>
+bool RE_CALL reg_expression<charT, traits, Allocator>::operator<(const reg_expression<charT, traits, Allocator>& e)
+{
+ int i = re_strcmp(expression(), e.expression());
+ if(i == 0)
+ return _flags < e.flags();
+ return i < 0;
+}
+
+template <class charT, class traits, class Allocator>
+Allocator RE_CALL reg_expression<charT, traits, Allocator>::allocator()const
+{
+ return data.allocator();
+}
+
+template <class charT, class traits, class Allocator>
+unsigned int RE_CALL reg_expression<charT, traits, Allocator>::parse_inner_set(const charT*& first, const charT* last)
+{
+ //
+ // we have an inner [...] construct
+ //
+ jm_assert(traits_type::syntax_type((traits_size_type)(traits_uchar_type)*first MAYBE_PASS_LOCALE(locale_inst)) == syntax_open_set);
+ const charT* base = first;
+ while( (first != last)
+ && (traits_type::syntax_type((traits_size_type)(traits_uchar_type)*first MAYBE_PASS_LOCALE(locale_inst)) != syntax_close_set) )
+ ++first;
+ if(first == last)
+ return 0;
+ ++first;
+ if((first-base) < 5)
+ return 0;
+ if(*(base+1) != *(first-2))
+ return 0;
+ unsigned int result = traits_type::syntax_type((traits_size_type)(traits_uchar_type)*(base+1) MAYBE_PASS_LOCALE(locale_inst));
+ if((result == syntax_colon) && ((first-base) == 5))
+ {
+ return traits_type::syntax_type((traits_size_type)(traits_uchar_type)*(base+2) MAYBE_PASS_LOCALE(locale_inst));
+ }
+ return ((result == syntax_colon) || (result == syntax_dot) || (result == syntax_equal)) ? result : 0;
+}
+
+
+template <class charT, class traits, class Allocator>
+bool RE_CALL reg_expression<charT, traits, Allocator>::skip_space(const charT*& first, const charT* last)
+{
+ //
+ // returns true if we get to last:
+ //
+ while((first != last) && (traits_type::is_class(*first, char_class_space MAYBE_PASS_LOCALE(locale_inst)) == true))
+ {
+ ++first;
+ }
+ return first == last;
+}
+
+template <class charT, class traits, class Allocator>
+void RE_CALL reg_expression<charT, traits, Allocator>::parse_range(const charT*& ptr, const charT* end, unsigned& min, unsigned& max)
+{
+ //
+ // we have {x} or {x,} or {x,y} NB no spaces inside braces
+ // anything else is illegal
+ // On input ptr points to "{"
+ //
+ ++ptr;
+ if(skip_space(ptr, end))
+ {
+ fail(REG_EBRACE);
+ return;
+ }
+ if(traits_type::syntax_type((traits_size_type)(traits_uchar_type)*ptr MAYBE_PASS_LOCALE(locale_inst)) != syntax_digit)
+ {
+ fail(REG_BADBR);
+ return;
+ }
+ min = traits_type::toi(ptr, end, 10 MAYBE_PASS_LOCALE(locale_inst));
+ if(skip_space(ptr, end))
+ {
+ fail(REG_EBRACE);
+ return;
+ }
+ if(traits_type::syntax_type((traits_size_type)(traits_uchar_type)*ptr MAYBE_PASS_LOCALE(locale_inst)) == syntax_comma)
+ {
+ //we have a second interval:
+ ++ptr;
+ if(skip_space(ptr, end))
+ {
+ fail(REG_EBRACE);
+ return;
+ }
+ if(traits_type::syntax_type((traits_size_type)(traits_uchar_type)*ptr MAYBE_PASS_LOCALE(locale_inst)) == syntax_digit)
+ max = traits_type::toi(ptr, end, 10 MAYBE_PASS_LOCALE(locale_inst));
+ else
+ max = (unsigned)-1;
+ }
+ else
+ max = min;
+
+ // validate input:
+ if(skip_space(ptr, end))
+ {
+ fail(REG_EBRACE);
+ return;
+ }
+ if(max < min)
+ {
+ fail(REG_ERANGE);
+ return;
+ }
+ if(_flags & bk_braces)
+ {
+ if(traits_type::syntax_type((traits_size_type)(traits_uchar_type)*ptr MAYBE_PASS_LOCALE(locale_inst)) != syntax_slash)
+ {
+ fail(REG_BADBR);
+ return;
+ }
+ else
+ {
+ // back\ is OK now check the }
+ ++ptr;
+ if((ptr == end) || (traits_type::syntax_type((traits_size_type)(traits_uchar_type)*ptr MAYBE_PASS_LOCALE(locale_inst)) != syntax_close_brace))
+ {
+ fail(REG_BADBR);
+ return;
+ }
+ }
+ }
+ else if(traits_type::syntax_type((traits_size_type)(traits_uchar_type)*ptr MAYBE_PASS_LOCALE(locale_inst)) != syntax_close_brace)
+ {
+ fail(REG_BADBR);
+ return;
+ }
+}
+
+template <class charT, class traits, class Allocator>
+charT RE_CALL reg_expression<charT, traits, Allocator>::parse_escape(const charT*& first, const charT* last)
+{
+ charT c;
+ switch(traits_type::syntax_type(*first MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ case syntax_a:
+ c = '\a';
+ ++first;
+ break;
+ case syntax_f:
+ c = '\f';
+ ++first;
+ break;
+ case syntax_n:
+ c = '\n';
+ ++first;
+ break;
+ case syntax_r:
+ c = '\r';
+ ++first;
+ break;
+ case syntax_t:
+ c = '\t';
+ ++first;
+ break;
+ case syntax_v:
+ c = '\v';
+ ++first;
+ break;
+ case syntax_x:
+ ++first;
+ if(first == last)
+ {
+ fail(REG_EESCAPE);
+ break;
+ }
+ // maybe have \x{ddd}
+ if(traits_type::syntax_type(*first MAYBE_PASS_LOCALE(locale_inst)) == syntax_open_brace)
+ {
+ ++first;
+ if(first == last)
+ {
+ fail(REG_EESCAPE);
+ break;
+ }
+ if(traits_type::is_class(*first, char_class_xdigit MAYBE_PASS_LOCALE(locale_inst)) == false)
+ {
+ fail(REG_BADBR);
+ break;
+ }
+ c = (charT)traits_type::toi(first, last, -16 MAYBE_PASS_LOCALE(locale_inst));
+ if((first == last) || (traits_type::syntax_type(*first MAYBE_PASS_LOCALE(locale_inst)) != syntax_close_brace))
+ {
+ fail(REG_BADBR);
+ }
+ ++first;
+ break;
+ }
+ else
+ {
+ if(traits_type::is_class(*first, char_class_xdigit MAYBE_PASS_LOCALE(locale_inst)) == false)
+ {
+ fail(REG_BADBR);
+ break;
+ }
+ c = (charT)traits_type::toi(first, last, -16 MAYBE_PASS_LOCALE(locale_inst));
+ }
+ break;
+ case syntax_c:
+ ++first;
+ if(first == last)
+ {
+ fail(REG_EESCAPE);
+ break;
+ }
+ if(((traits_uchar_type)(*first) < (traits_uchar_type)'@')
+ || ((traits_uchar_type)(*first) > (traits_uchar_type)127) )
+ {
+ fail(REG_EESCAPE);
+ return (charT)0;
+ }
+ c = (charT)((traits_uchar_type)(*first) - (traits_uchar_type)'@');
+ ++first;
+ break;
+ case syntax_e:
+ c = (charT)27;
+ ++first;
+ break;
+ case syntax_digit:
+ c = (charT)traits_type::toi(first, last, -8 MAYBE_PASS_LOCALE(locale_inst));
+ break;
+ default:
+ c = *first;
+ ++first;
+ }
+ return c;
+}
+
+template <class charT, class traits, class Allocator>
+void RE_CALL reg_expression<charT, traits, Allocator>::compile_maps()
+{
+ re_syntax_base* record = (re_syntax_base*)data.data();
+ // always compile the first __map:
+ memset(startmap, 0, 256);
+ record->can_be_null = 0;
+ compile_map(record, startmap, NULL, mask_all);
+
+ while(record->type != syntax_element_match)
+ {
+ if((record->type == syntax_element_alt) || (record->type == syntax_element_rep))
+ {
+ memset(&(((re_jump*)record)->__map), 0, 256);
+ record->can_be_null = 0;
+ compile_map(record->next.p, ((re_jump*)record)->__map, &(record->can_be_null), mask_take, ((re_jump*)record)->alt.p);
+ compile_map(((re_jump*)record)->alt.p, ((re_jump*)record)->__map, &(record->can_be_null), mask_skip);
+ }
+ else
+ {
+ record->can_be_null = 0;
+ compile_map(record, NULL, &(record->can_be_null), mask_all);
+ }
+ record = record->next.p;
+ }
+ record->can_be_null = mask_all;
+}
+
+template <class charT, class traits_type, class Allocator>
+bool RE_CALL re_maybe_set_member(charT c,
+ re_set_long* set,
+ const reg_expression<charT, traits_type, Allocator>& e)
+{
+ const charT* p = (const charT*)(set+1);
+ bool icase = e.flags() & regbase::icase;
+ charT col = traits_type::translate(c, icase MAYBE_PASS_LOCALE(e.locale()));
+ for(unsigned int i = 0; i < set->csingles; ++i)
+ {
+ if(col == *p)
+ return set->isnot ? false : true;
+
+ while(*p)++p;
+ ++p; // skip null
+ }
+ return set->isnot ? true : false;
+}
+
+template <class charT, class traits, class Allocator>
+bool RE_CALL reg_expression<charT, traits, Allocator>::probe_start(
+ re_syntax_base* node, charT cc, re_syntax_base* terminal) const
+{
+ unsigned int c;
+
+ switch(node->type)
+ {
+ case syntax_element_startmark:
+ case syntax_element_endmark:
+ case syntax_element_start_line:
+ case syntax_element_word_boundary:
+ case syntax_element_buffer_start:
+ case syntax_element_restart_continue:
+ // doesn't tell us anything about the next character, so:
+ return probe_start(node->next.p, cc, terminal);
+ case syntax_element_literal:
+ // only the first character of the literal can match:
+ // note these have already been translated:
+ if(*(charT*)(((re_literal*)node)+1) == traits_type::translate(cc, (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst)))
+ return true;
+ return false;
+ case syntax_element_end_line:
+ // next character (if there is one!) must be a newline:
+ if(traits_type::is_separator(traits_type::translate(cc, (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst))))
+ return true;
+ return false;
+ case syntax_element_wild:
+ return true;
+ case syntax_element_match:
+ return true;
+ case syntax_element_within_word:
+ case syntax_element_word_start:
+ return traits_type::is_class(traits_type::translate(cc, (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst)), char_class_word MAYBE_PASS_LOCALE(locale_inst));
+ case syntax_element_word_end:
+ // what follows must not be a word character,
+ return traits_type::is_class(traits_type::translate(cc, (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst)), char_class_word MAYBE_PASS_LOCALE(locale_inst)) ? false : true;
+ case syntax_element_buffer_end:
+ // we can be null, nothing must follow,
+ // NB we assume that this is followed by
+ // syntax_element_match, if its not then we can
+ // never match anything anyway!!
+ return false;
+ case syntax_element_soft_buffer_end:
+ // we can be null, only newlines must follow,
+ // NB we assume that this is followed by
+ // syntax_element_match, if its not then we can
+ // never match anything anyway!!
+ return traits_type::is_separator(traits_type::translate(cc, (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst)));
+ case syntax_element_backref:
+ // there's no easy way to determine this
+ // which is not to say it can't be done!
+ // for now:
+ return true;
+ case syntax_element_long_set:
+ // we can not be null,
+ // we need to add already translated values in the set
+ // to values in the __map
+ return re_maybe_set_member(cc, (re_set_long*)node, *this) || re_is_set_member((const charT*)&cc, (const charT*)(&cc+1), (re_set_long*)node, *this) != &cc;
+ case syntax_element_set:
+ // set all the elements that are set in corresponding set:
+ c = (traits_size_type)(traits_uchar_type)traits_type::translate(cc, (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst));
+ return ((re_set*)node)->__map[c] != 0;
+ case syntax_element_jump:
+ if(((re_jump*)node)->alt.p < node)
+ {
+ // backwards jump,
+ // caused only by end of repeat section, we'll treat this
+ // the same as a match, because the sub-expression has matched.
+ // this is only caused by NULL repeats as in "(a*)*" or "(\<)*"
+ // these are really nonsensence and make the matching code much
+ // harder, it would be nice to get rid of them altogether.
+ if(node->next.p == terminal)
+ return true;
+ else
+ return probe_start(((re_jump*)node)->alt.p, cc, terminal);
+ }
+ else
+ // take the jump and compile:
+ return probe_start(((re_jump*)node)->alt.p, cc, terminal);
+ case syntax_element_alt:
+ // we need to take the OR of the two alternatives:
+ return probe_start(((re_jump*)node)->alt.p, cc, terminal) || probe_start(node->next.p, cc, terminal);
+ case syntax_element_rep:
+ // we need to take the OR of the two alternatives
+ if(((re_repeat*)node)->min == 0)
+ return probe_start(node->next.p, cc, ((re_jump*)node)->alt.p) || probe_start(((re_jump*)node)->alt.p, cc, terminal);
+ else
+ return probe_start(node->next.p, cc, ((re_jump*)node)->alt.p);
+ case syntax_element_combining:
+ return !traits_type::is_combining(traits_type::translate(cc, (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst)));
+ }
+ return false;
+}
+
+template <class charT, class traits, class Allocator>
+bool RE_CALL reg_expression<charT, traits, Allocator>::probe_start_null(re_syntax_base* node, re_syntax_base* terminal)const
+{
+ switch(node->type)
+ {
+ case syntax_element_startmark:
+ case syntax_element_endmark:
+ case syntax_element_start_line:
+ case syntax_element_word_boundary:
+ case syntax_element_buffer_start:
+ case syntax_element_restart_continue:
+ case syntax_element_end_line:
+ case syntax_element_word_end:
+ // doesn't tell us anything about the next character, so:
+ return probe_start_null(node->next.p, terminal);
+ case syntax_element_match:
+ case syntax_element_buffer_end:
+ case syntax_element_soft_buffer_end:
+ case syntax_element_backref:
+ return true;
+ case syntax_element_jump:
+ if(((re_jump*)node)->alt.p < node)
+ {
+ // backwards jump,
+ // caused only by end of repeat section, we'll treat this
+ // the same as a match, because the sub-expression has matched.
+ // this is only caused by NULL repeats as in "(a*)*" or "(\<)*"
+ // these are really nonsensence and make the matching code much
+ // harder, it would be nice to get rid of them altogether.
+ if(node->next.p == terminal)
+ return true;
+ else
+ return probe_start_null(((re_jump*)node)->alt.p, terminal);
+ }
+ else
+ // take the jump and compile:
+ return probe_start_null(((re_jump*)node)->alt.p, terminal);
+ case syntax_element_alt:
+ // we need to take the OR of the two alternatives:
+ return probe_start_null(((re_jump*)node)->alt.p, terminal) || probe_start_null(node->next.p, terminal);
+ case syntax_element_rep:
+ // only need to consider skipping the repeat:
+ return probe_start_null(((re_jump*)node)->alt.p, terminal);
+ }
+ return false;
+}
+
+template <class charT, class traits, class Allocator>
+void RE_CALL reg_expression<charT, traits, Allocator>::compile_map(
+ re_syntax_base* node, unsigned char* __map,
+ unsigned int* pnull, unsigned char mask, re_syntax_base* terminal)const
+{
+ if(__map)
+ {
+ for(unsigned int i = 0; i < 256; ++i)
+ {
+ if(probe_start(node, (charT)i, terminal))
+ __map[i] |= mask;
+ }
+ }
+ if(pnull && probe_start_null(node, terminal))
+ *pnull |= mask;
+}
+
+template <class charT, class traits, class Allocator>
+void RE_CALL reg_expression<charT, traits, Allocator>::move_offsets(re_syntax_base* j, unsigned size)
+{
+ // move all offsets starting with j->link forward by size
+ // called after an insert:
+ j = (re_syntax_base*)((const char*)data.data() + j->next.i);
+ while(true)
+ {
+ switch(j->type)
+ {
+ case syntax_element_rep:
+ ((re_jump*)j)->alt.i += size;
+ j->next.i += size;
+ break;
+ case syntax_element_jump:
+ case syntax_element_alt:
+ ((re_jump*)j)->alt.i += size;
+ j->next.i += size;
+ break;
+ default:
+ j->next.i += size;
+ break;
+ }
+ if(j->next.i == size)
+ break;
+ j = (re_syntax_base*)((const char*)data.data() + j->next.i);
+ }
+}
+
+template <class charT, class traits, class Allocator>
+re_syntax_base* RE_CALL reg_expression<charT, traits, Allocator>::compile_set_simple(re_syntax_base* dat, unsigned long cls, bool isnot)
+{
+ jstack<re_str<charT>, Allocator> singles(64, data.allocator());
+ jstack<re_str<charT>, Allocator> ranges(64, data.allocator());
+ jstack<jm_uintfast32_t, Allocator> classes(64, data.allocator());
+ jstack<re_str<charT>, Allocator> equivalents(64, data.allocator());
+ classes.push(cls);
+ if(dat)
+ {
+ data.align();
+ dat->next.i = data.size();
+ }
+ return compile_set_aux(singles, ranges, classes, equivalents, isnot, is_byte<charT>::width_type());
+}
+
+template <class charT, class traits, class Allocator>
+re_syntax_base* RE_CALL reg_expression<charT, traits, Allocator>::compile_set(const charT*& first, const charT* last)
+{
+ jstack<re_str<charT>, Allocator> singles(64, data.allocator());
+ jstack<re_str<charT>, Allocator> ranges(64, data.allocator());
+ jstack<jm_uintfast32_t, Allocator> classes(64, data.allocator());
+ jstack<re_str<charT>, Allocator> equivalents(64, data.allocator());
+ bool has_digraphs = false;
+ jm_assert(traits_type::syntax_type((traits_size_type)(traits_uchar_type)*first MAYBE_PASS_LOCALE(locale_inst)) == syntax_open_set);
+ ++first;
+ bool started = false;
+ bool done = false;
+ bool isnot = false;
+
+ enum last_type
+ {
+ last_single,
+ last_none,
+ last_dash
+ };
+
+ unsigned l = last_none;
+ re_str<charT> s;
+
+ while((first != last) && !done)
+ {
+ traits_size_type c = (traits_size_type)(traits_uchar_type)*first;
+ switch(traits_type::syntax_type(c MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ case syntax_caret:
+ if(!started && !isnot)
+ {
+ isnot = true;
+ }
+ else
+ {
+ s = (charT)c;
+ goto char_set_literal;
+ }
+ break;
+ case syntax_open_set:
+ {
+ if((_flags & char_classes) == 0)
+ {
+ s = (charT)c;
+ goto char_set_literal;
+ }
+ // check to see if we really have a class:
+ const charT* base = first;
+ switch(parse_inner_set(first, last))
+ {
+ case syntax_colon:
+ {
+ if(l == last_dash)
+ {
+ fail(REG_ERANGE);
+ return NULL;
+ }
+ jm_uintfast32_t id = traits_type::lookup_classname(base+2, first-2 MAYBE_PASS_LOCALE(locale_inst));
+ if(_flags & regbase::icase)
+ {
+ if((id == char_class_upper) || (id == char_class_lower))
+ {
+ id = char_class_alpha;
+ }
+ }
+ if(id == 0)
+ {
+ fail(REG_ECTYPE);
+ return NULL;
+ }
+ classes.push(id);
+ started = true;
+ l = last_none;
+ }
+ break;
+ case syntax_dot:
+ //
+ // we have a collating element [.collating-name.]
+ //
+ if(traits_type::lookup_collatename(s, base+2, first-2 MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ --first;
+ if(s.size() > 1)
+ has_digraphs = true;
+ goto char_set_literal;
+ }
+ fail(REG_ECOLLATE);
+ return NULL;
+ case syntax_equal:
+ //
+ // we have an equivalence class [=collating-name=]
+ //
+ if(traits_type::lookup_collatename(s, base+2, first-2 MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ unsigned i = 0;
+ while(s[i])
+ {
+ s[i] = traits_type::translate(s[i], (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst));
+ ++i;
+ }
+ re_str<charT> s2;
+ traits_type::transform_primary(s2, s MAYBE_PASS_LOCALE(locale_inst));
+ equivalents.push(s2);
+ started = true;
+ l = last_none;
+ break;
+ }
+ fail(REG_ECOLLATE);
+ return NULL;
+ case syntax_left_word:
+ if((started == false) && (traits_type::syntax_type((traits_size_type)(traits_uchar_type)*first MAYBE_PASS_LOCALE(locale_inst)) == syntax_close_set))
+ {
+ ++first;
+ return add_simple(0, syntax_element_word_start);
+ }
+ fail(REG_EBRACK);
+ return NULL;
+ case syntax_right_word:
+ if((started == false) && (traits_type::syntax_type((traits_size_type)(traits_uchar_type)*first MAYBE_PASS_LOCALE(locale_inst)) == syntax_close_set))
+ {
+ ++first;
+ return add_simple(0, syntax_element_word_end);
+ }
+ fail(REG_EBRACK);
+ return NULL;
+ default:
+ if(started == false)
+ {
+ unsigned int t = traits_type::syntax_type((traits_size_type)(traits_uchar_type)*(base+1) MAYBE_PASS_LOCALE(locale_inst));
+ if((t != syntax_colon) && (t != syntax_dot) && (t != syntax_equal))
+ {
+ first = base;
+ s = (charT)c;
+ goto char_set_literal;
+ }
+ }
+ fail(REG_EBRACK);
+ return NULL;
+ }
+ if(first == last)
+ {
+ fail(REG_EBRACK);
+ return NULL;
+ }
+ continue;
+ }
+ case syntax_close_set:
+ if(started == false)
+ {
+ s = (charT)c;
+ goto char_set_literal;
+ }
+ done = true;
+ break;
+ case syntax_dash:
+ if(!started)
+ {
+ s = (charT)c;
+ goto char_set_literal;
+ }
+ ++first;
+ if(traits_type::syntax_type((traits_size_type)(traits_uchar_type)*first MAYBE_PASS_LOCALE(locale_inst)) == syntax_close_set)
+ {
+ --first;
+ s = (charT)c;
+ goto char_set_literal;
+ }
+ if((singles.empty() == true) || (l != last_single))
+ {
+ fail(REG_ERANGE);
+ return NULL;
+ }
+ ranges.push(singles.peek());
+ if(singles.peek().size() <= 1) // leave digraphs and ligatures in place
+ singles.pop();
+ l = last_dash;
+ continue;
+ case syntax_slash:
+ if(_flags & regbase::escape_in_lists)
+ {
+ ++first;
+ if(first == last)
+ continue;
+ switch(traits_type::syntax_type(*first MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ case syntax_w:
+ if(l == last_dash)
+ {
+ fail(REG_ERANGE);
+ return NULL;
+ }
+ classes.push(char_class_word);
+ started = true;
+ l = last_none;
+ ++first;
+ continue;
+ case syntax_d:
+ if(l == last_dash)
+ {
+ fail(REG_ERANGE);
+ return NULL;
+ }
+ classes.push(char_class_digit);
+ started = true;
+ l = last_none;
+ ++first;
+ continue;
+ case syntax_s:
+ if(l == last_dash)
+ {
+ fail(REG_ERANGE);
+ return NULL;
+ }
+ classes.push(char_class_space);
+ started = true;
+ l = last_none;
+ ++first;
+ continue;
+ case syntax_l:
+ if(l == last_dash)
+ {
+ fail(REG_ERANGE);
+ return NULL;
+ }
+ classes.push(char_class_lower);
+ started = true;
+ l = last_none;
+ ++first;
+ continue;
+ case syntax_u:
+ if(l == last_dash)
+ {
+ fail(REG_ERANGE);
+ return NULL;
+ }
+ classes.push(char_class_upper);
+ started = true;
+ l = last_none;
+ ++first;
+ continue;
+ case syntax_W:
+ case syntax_D:
+ case syntax_S:
+ case syntax_U:
+ case syntax_L:
+ fail(REG_EESCAPE);
+ return NULL;
+ default:
+ c = parse_escape(first, last);
+ --first;
+ s = (charT)c;
+ goto char_set_literal;
+ }
+ }
+ else
+ {
+ s = (charT)c;
+ goto char_set_literal;
+ }
+ default:
+ s = (charT)c;
+ char_set_literal:
+ unsigned i = 0;
+ while(s[i])
+ {
+ s[i] = traits_type::translate(s[i], (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst));
+ ++i;
+ }
+ started = true;
+ if(l == last_dash)
+ {
+ ranges.push(s);
+ l = last_none;
+ if(s.size() > 1) // add ligatures to singles list as well
+ singles.push(s);
+ }
+ else
+ {
+ singles.push(s);
+ l = last_single;
+ }
+ }
+ ++first;
+ }
+ if(!done)
+ return NULL;
+
+ re_syntax_base* result;
+ if(has_digraphs)
+ result = compile_set_aux(singles, ranges, classes, equivalents, isnot, __wide_type());
+ else
+ result = compile_set_aux(singles, ranges, classes, equivalents, isnot, is_byte<charT>::width_type());
+ #ifdef __BORLANDC__
+ // delayed throw:
+ if((result == 0) && (_flags & regbase::use_except))
+ fail(code);
+ #endif
+ return result;
+}
+
+template <class charT, class traits, class Allocator>
+re_syntax_base* RE_CALL reg_expression<charT, traits, Allocator>::compile_set_aux(jstack<re_str<charT>, Allocator>& singles, jstack<re_str<charT>, Allocator>& ranges, jstack<jm_uintfast32_t, Allocator>& classes, jstack<re_str<charT>, Allocator>& equivalents, bool isnot, const __wide_type&)
+{
+ size_type base = data.size();
+ data.extend(sizeof(re_set_long));
+ unsigned int csingles = 0;
+ unsigned int cranges = 0;
+ jm_uintfast32_t cclasses = 0;
+ unsigned int cequivalents = 0;
+ bool nocollate_state = flags() & regbase::nocollate;
+
+ while(singles.empty() == false)
+ {
+ ++csingles;
+ const re_str<charT>& s = singles.peek();
+ unsigned len = (re_strlen(s.c_str()) + 1) * sizeof(charT);
+ memcpy((charT*)data.extend(len), s.c_str(), len);
+ //*(charT*)data.extend(sizeof(charT)) = charT(singles.peek());
+ singles.pop();
+ }
+ while(ranges.empty() == false)
+ {
+ re_str<charT> c1, c2;
+ if(nocollate_state)
+ c1 = ranges.peek();
+ else
+ traits_type::transform(c1, ranges.peek() MAYBE_PASS_LOCALE(locale_inst));
+ ranges.pop();
+ if(nocollate_state)
+ c2 = ranges.peek();
+ else
+ traits_type::transform(c2, ranges.peek() MAYBE_PASS_LOCALE(locale_inst));
+ ranges.pop();
+ if(c1 < c2)
+ {
+ // for some reason bc5 crashes when throwing exceptions
+ // from here - probably an EH-compiler bug, but hard to
+ // be sure...
+ // delay throw to later:
+ #ifdef __BORLANDC__
+ jm_uintfast32_t f = _flags;
+ _flags &= ~regbase::use_except;
+ #endif
+ fail(REG_ERANGE);
+ #ifdef __BORLANDC__
+ _flags = f;
+ #endif
+ return NULL;
+ }
+ ++cranges;
+ unsigned len = (re_strlen(c1.c_str()) + 1) * sizeof(charT);
+ memcpy(data.extend(len), c1.c_str(), len);
+ len = (re_strlen(c2.c_str()) + 1) * sizeof(charT);
+ memcpy(data.extend(len), c2.c_str(), len);
+ }
+ while(classes.empty() == false)
+ {
+ cclasses |= classes.peek();
+ classes.pop();
+ }
+ while(equivalents.empty() == false)
+ {
+ ++cequivalents;
+ const re_str<charT>& s = equivalents.peek();
+ unsigned len = (re_strlen(s.c_str()) + 1) * sizeof(charT);
+ memcpy((charT*)data.extend(len), s.c_str(), len);
+ equivalents.pop();
+ }
+
+ re_set_long* dat = (re_set_long*)((unsigned char*)data.data() + base);
+ dat->type = syntax_element_long_set;
+ dat->csingles = csingles;
+ dat->cranges = cranges;
+ dat->cclasses = cclasses;
+ dat->cequivalents = cequivalents;
+ dat->isnot = isnot;
+ dat->next.i = -1;
+ return dat;
+}
+
+template <class charT, class traits, class Allocator>
+re_syntax_base* RE_CALL reg_expression<charT, traits, Allocator>::compile_set_aux(jstack<re_str<charT>, Allocator>& singles, jstack<re_str<charT>, Allocator>& ranges, jstack<jm_uintfast32_t, Allocator>& classes, jstack<re_str<charT>, Allocator>& equivalents, bool isnot, const __narrow_type&)
+{
+ re_set* dat = (re_set*)data.extend(sizeof(re_set));
+ memset(dat, 0, sizeof(re_set));
+
+ while(singles.empty() == false)
+ {
+ dat->__map[(traits_size_type)(traits_uchar_type)*(singles.peek().c_str())] = mask_all;
+ singles.pop();
+ }
+ while(ranges.empty() == false)
+ {
+ re_str<charT> c1, c2, c3, c4;
+
+ if(flags() & regbase::nocollate)
+ c1 = ranges.peek();
+ else
+ traits_type::transform(c1, ranges.peek() MAYBE_PASS_LOCALE(locale_inst));
+ ranges.pop();
+ if(flags() & regbase::nocollate)
+ c2 = ranges.peek();
+ else
+ traits_type::transform(c2, ranges.peek() MAYBE_PASS_LOCALE(locale_inst));
+ ranges.pop();
+
+ if(c1 < c2)
+ {
+ // for some reason bc5 crashes when throwing exceptions
+ // from here - probably an EH-compiler bug, but hard to
+ // be sure...
+ // delay throw to later:
+ #ifdef __BORLANDC__
+ jm_uintfast32_t f = _flags;
+ _flags &= ~regbase::use_except;
+ #endif
+ fail(REG_ERANGE);
+ #ifdef __BORLANDC__
+ _flags = f;
+ #endif
+ return NULL;
+ }
+ for(unsigned int i = 0; i < 256; ++i)
+ {
+ c4 = (charT)i;
+ if(flags() & regbase::nocollate)
+ c3 = c4;
+ else
+ traits_type::transform(c3, c4 MAYBE_PASS_LOCALE(locale_inst));
+ if((c3 <= c1) && (c3 >= c2))
+ dat->__map[i] = mask_all;
+ }
+ }
+ while(equivalents.empty() == false)
+ {
+ re_str<charT> c1, c2;
+ for(unsigned int i = 0; i < 256; ++i)
+ {
+ c2 = (charT)i;
+ traits_type::transform_primary(c1, c2 MAYBE_PASS_LOCALE(locale_inst));
+ if(c1 == equivalents.peek())
+ dat->__map[i] = mask_all;
+ }
+ equivalents.pop();
+ }
+
+ jm_uintfast32_t flags = 0;
+ while(classes.empty() == false)
+ {
+ flags |= classes.peek();
+ classes.pop();
+ }
+ if(flags)
+ {
+ for(unsigned int i = 0; i < 256; ++i)
+ {
+ if(traits_type::is_class(charT(i), flags MAYBE_PASS_LOCALE(locale_inst)))
+ dat->__map[(traits_uchar_type)traits_type::translate((charT)i, (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst))] = mask_all;
+ }
+ }
+
+ if(isnot)
+ {
+ for(unsigned int i = 0; i < 256; ++i)
+ {
+ dat->__map[i] = !dat->__map[i];
+ }
+ }
+
+ dat->type = syntax_element_set;
+ dat->next.i = -1;
+ return dat;
+}
+
+
+template <class charT, class traits, class Allocator>
+void RE_CALL reg_expression<charT, traits, Allocator>::fixup_apply(re_syntax_base* b, unsigned cbraces)
+{
+ typedef JM_MAYBE_TYPENAME REBIND_TYPE(bool, Allocator) b_alloc;
+
+ register unsigned char* base = (unsigned char*)b;
+ register re_syntax_base* ptr = b;
+ bool* pb = 0;
+ b_alloc a(data.allocator());
+#ifndef JM_NO_EXCEPTIONS
+ try
+ {
+#endif
+ pb = a.allocate(cbraces);
+ for(unsigned i = 0; i < cbraces; ++i)
+ pb[i] = false;
+
+ repeats = 0;
+
+ while(ptr->next.i)
+ {
+ switch(ptr->type)
+ {
+ case syntax_element_rep:
+ ((re_jump*)ptr)->alt.p = (re_syntax_base*)(base + ((re_jump*)ptr)->alt.i);
+ ((re_repeat*)ptr)->id = repeats;
+ ++repeats;
+ goto rebase;
+ case syntax_element_jump:
+ case syntax_element_alt:
+ ((re_jump*)ptr)->alt.p = (re_syntax_base*)(base + ((re_jump*)ptr)->alt.i);
+ goto rebase;
+ case syntax_element_backref:
+ if((((re_brace*)ptr)->index >= cbraces) || (pb[((re_brace*)ptr)->index] == false) )
+ {
+ fail(REG_ESUBREG);
+ a.deallocate(pb, cbraces);
+ return;
+ }
+ goto rebase;
+ case syntax_element_endmark:
+ pb[((re_brace*)ptr)->index] = true;
+ goto rebase;
+ default:
+ rebase:
+ ptr->next.p = (re_syntax_base*)(base + ptr->next.i);
+ ptr = ptr->next.p;
+ }
+ }
+ a.deallocate(pb, cbraces);
+ pb = 0;
+#ifndef JM_NO_EXCEPTIONS
+ }
+ catch(...)
+ {
+ if(pb)
+ a.deallocate(pb, cbraces);
+ throw;
+ }
+#endif
+}
+
+
+template <class charT, class traits, class Allocator>
+unsigned int RE_CALL reg_expression<charT, traits, Allocator>::set_expression(const charT* p, const charT* end, jm_uintfast32_t f)
+{
+ if(p == expression())
+ {
+ re_str<charT> s(p, end);
+ return set_expression(s.c_str(), f);
+ }
+#if defined(RE_LOCALE_C) || defined(RE_LOCALE_W32)
+ locale_initialiser.update();
+#else
+ if(JM_HAS_FACET(locale_inst, regfacet<charT>) == false)
+ {
+#ifdef _MSC_VER
+ locale_inst = __JM_STD::_ADDFAC(locale_inst, new regfacet<charT>());
+#else
+ locale_inst = __JM_STD::locale(locale_inst, new regfacet<charT>());
+#endif
+ }
+ JM_USE_FACET(locale_inst, regfacet<charT>).update(locale_inst);
+#endif
+ const charT* base = p;
+ data.clear();
+ _flags = f;
+ fail(REG_NOERROR); // clear any error
+
+ if(p >= end)
+ {
+ fail(REG_EMPTY);
+ return code;
+ }
+
+ const charT* ptr = p;
+ marks = 0;
+ jstack<unsigned int, Allocator> mark(64, data.allocator());
+ jstack<unsigned int, Allocator> markid(64, data.allocator());
+ unsigned int last_mark_popped = 0;
+ register traits_size_type c;
+ register re_syntax_base* dat;
+
+ unsigned rep_min, rep_max;
+
+ //
+ // set up header:
+ //
+ ++marks;
+ dat = 0;
+
+ if(_flags & regbase::literal)
+ {
+ while(ptr != end)
+ {
+ dat = add_literal(dat, traits::translate(*ptr, (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst)));
+ ++ptr;
+ }
+ }
+
+ while (ptr < end)
+ {
+ c = (traits_size_type)(traits_uchar_type)*ptr;
+ switch(traits_type::syntax_type(c MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ case syntax_open_bracket:
+ if(_flags & bk_parens)
+ {
+ dat = add_literal(dat, (charT)c);
+ ++ptr;
+ continue;
+ }
+ open_bracked_jump:
+ // extend:
+ dat = add_simple(dat, syntax_element_startmark, sizeof(re_brace));
+ markid.push(marks);
+ ((re_brace*)dat)->index = marks++;
+ mark.push(data.index(dat));
+ ++ptr;
+ break;
+ case syntax_close_bracket:
+ if(_flags & bk_parens)
+ {
+ dat = add_literal(dat, (charT)c);
+ ++ptr;
+ continue;
+ }
+
+ close_bracked_jump:
+ if(dat)
+ {
+ data.align();
+ dat->next.i = data.size();
+ }
+
+ if(mark.empty())
+ {
+ fail(REG_EPAREN);
+ return code;
+ }
+ // see if we have an empty alternative:
+ if(mark.peek() == data.index(dat) )
+ {
+ re_syntax_base* para = (re_syntax_base*)((char*)data.data() + mark.peek());
+ if(para->type == syntax_element_jump)
+ {
+ fail(REG_EMPTY);
+ return code;
+ }
+ }
+
+ // pop any pushed alternatives and set the target end destination:
+ dat = (re_syntax_base*)((unsigned char*)data.data() + mark.peek());
+ while(dat->type == syntax_element_jump)
+ {
+ ((re_jump*)dat)->alt.i = data.size();
+ mark.pop();
+ dat = (re_jump*)((unsigned char*)data.data() + mark.peek());
+ if(mark.empty())
+ {
+ fail(REG_EPAREN);
+ return code;
+ }
+ }
+
+ dat = add_simple(0, syntax_element_endmark, sizeof(re_brace));
+ ((re_brace*)dat)->index = markid.peek();
+ markid.pop();
+ last_mark_popped = mark.peek();
+ mark.pop();
+ ++ptr;
+ break;
+ case syntax_char:
+ dat = add_literal(dat, (charT)c);
+ ++ptr;
+ break;
+ case syntax_slash:
+ if(++ptr == end)
+ {
+ fail(REG_EESCAPE);
+ return code;
+ }
+ c = (traits_size_type)(traits_uchar_type)*ptr;
+ switch(traits_type::syntax_type(c MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ case syntax_open_bracket:
+ if(_flags & bk_parens)
+ goto open_bracked_jump;
+ break;
+ case syntax_close_bracket:
+ if(_flags & bk_parens)
+ goto close_bracked_jump;
+ break;
+ case syntax_plus:
+ if((_flags & bk_plus_qm) && ((_flags & limited_ops) == 0))
+ {
+ rep_min = 1;
+ rep_max = (unsigned)-1;
+ goto repeat_jump;
+ }
+ break;
+ case syntax_question:
+ if((_flags & bk_plus_qm) && ((_flags & limited_ops) == 0))
+ {
+ rep_min = 0;
+ rep_max = 1;
+ goto repeat_jump;
+ }
+ break;
+ case syntax_or:
+ if(((_flags & bk_vbar) == 0) || (_flags & limited_ops))
+ break;
+ goto alt_string_jump;
+ case syntax_open_brace:
+ if( ((_flags & bk_braces) == 0) || ((_flags & intervals) == 0))
+ break;
+
+ // we have {x} or {x,} or {x,y}:
+ parse_range(ptr, end, rep_min, rep_max);
+ goto repeat_jump;
+
+ case syntax_digit:
+ if(_flags & bk_refs)
+ {
+ // update previous:
+ int i = traits_type::toi((charT)c MAYBE_PASS_LOCALE(locale_inst));
+ if(i == 0)
+ {
+ // we can have \025 which means take char whose
+ // code is 25 (octal), so parse string:
+ c = traits_type::toi(ptr, end, -8 MAYBE_PASS_LOCALE(locale_inst));
+ --ptr;
+ break;
+ }
+ dat = add_simple(dat, syntax_element_backref, sizeof(re_brace));
+ ((re_brace*)dat)->index = i;
+ ++ptr;
+ continue;
+ }
+ break;
+ case syntax_b: // syntax_element_word_boundary
+ dat = add_simple(dat, syntax_element_word_boundary);
+ ++ptr;
+ continue;
+ case syntax_B:
+ dat = add_simple(dat, syntax_element_within_word);
+ ++ptr;
+ continue;
+ case syntax_left_word:
+ dat = add_simple(dat, syntax_element_word_start);
+ ++ptr;
+ continue;
+ case syntax_right_word:
+ dat = add_simple(dat, syntax_element_word_end);
+ ++ptr;
+ continue;
+ case syntax_w: //syntax_element_word_char
+ dat = compile_set_simple(dat, char_class_word);
+ ++ptr;
+ continue;
+ case syntax_W:
+ dat = compile_set_simple(dat, char_class_word, true);
+ ++ptr;
+ continue;
+ case syntax_d: //syntax_element_word_char
+ dat = compile_set_simple(dat, char_class_digit);
+ ++ptr;
+ continue;
+ case syntax_D:
+ dat = compile_set_simple(dat, char_class_digit, true);
+ ++ptr;
+ continue;
+ case syntax_s: //syntax_element_word_char
+ dat = compile_set_simple(dat, char_class_space);
+ ++ptr;
+ continue;
+ case syntax_S:
+ dat = compile_set_simple(dat, char_class_space, true);
+ ++ptr;
+ continue;
+ case syntax_l: //syntax_element_word_char
+ dat = compile_set_simple(dat, char_class_lower);
+ ++ptr;
+ continue;
+ case syntax_L:
+ dat = compile_set_simple(dat, char_class_lower, true);
+ ++ptr;
+ continue;
+ case syntax_u: //syntax_element_word_char
+ dat = compile_set_simple(dat, char_class_upper);
+ ++ptr;
+ continue;
+ case syntax_U:
+ dat = compile_set_simple(dat, char_class_upper, true);
+ ++ptr;
+ continue;
+ case syntax_Q:
+ ++ptr;
+ while(true)
+ {
+ if(ptr == end)
+ {
+ fail(REG_EESCAPE);
+ return code;
+ }
+ if(traits_type::syntax_type((traits_size_type)(traits_uchar_type)*ptr MAYBE_PASS_LOCALE(locale_inst)) == syntax_slash)
+ {
+ ++ptr;
+ if((ptr != end) && (traits_type::syntax_type((traits_size_type)(traits_uchar_type)*ptr MAYBE_PASS_LOCALE(locale_inst)) == syntax_E))
+ break;
+ else
+ {
+ dat = add_literal(dat, *(ptr-1));
+ continue;
+ }
+ }
+ dat = add_literal(dat, *ptr);
+ ++ptr;
+ }
+ ++ptr;
+ continue;
+ case syntax_C:
+ dat = add_simple(dat, syntax_element_wild);
+ ++ptr;
+ continue;
+ case syntax_X:
+ dat = add_simple(dat, syntax_element_combining);
+ ++ptr;
+ continue;
+ case syntax_Z:
+ dat = add_simple(dat, syntax_element_soft_buffer_end);
+ ++ptr;
+ continue;
+ case syntax_G:
+ dat = add_simple(dat, syntax_element_restart_continue);
+ ++ptr;
+ continue;
+ case syntax_start_buffer:
+ dat = add_simple(dat, syntax_element_buffer_start);
+ ++ptr;
+ continue;
+ case syntax_end_buffer:
+ dat = add_simple(dat, syntax_element_buffer_end);
+ ++ptr;
+ continue;
+ default:
+ c = (traits_size_type)(traits_uchar_type)parse_escape(ptr, end);
+ dat = add_literal(dat, (charT)c);
+ continue;
+ }
+ dat = add_literal(dat, (charT)c);
+ ++ptr;
+ break;
+ case syntax_dollar:
+ dat = add_simple(dat, syntax_element_end_line, sizeof(re_syntax_base));
+ ++ptr;
+ continue;
+ case syntax_caret:
+ dat = add_simple(dat, syntax_element_start_line, sizeof(re_syntax_base));
+ ++ptr;
+ continue;
+ case syntax_dot:
+ dat = add_simple(dat, syntax_element_wild, sizeof(re_syntax_base));
+ ++ptr;
+ continue;
+ case syntax_star:
+ rep_min = 0;
+ rep_max = (unsigned)-1;
+
+ repeat_jump:
+ {
+ unsigned offset;
+ if(dat == 0)
+ {
+ fail(REG_BADRPT);
+ return code;
+ }
+ switch(dat->type)
+ {
+ case syntax_element_endmark:
+ offset = last_mark_popped;
+ break;
+ case syntax_element_literal:
+ if(((re_literal*)dat)->length > 1)
+ {
+ // update previous:
+ charT lit = *(charT*)((char*)dat + sizeof(re_literal) + ((((re_literal*)dat)->length-1)*sizeof(charT)));
+ --((re_literal*)dat)->length;
+ dat = add_simple(dat, syntax_element_literal, sizeof(re_literal) + sizeof(charT));
+ ((re_literal*)dat)->length = 1;
+ *((charT*)(((re_literal*)dat)+1)) = lit;
+ }
+ offset = (char*)dat - (char*)data.data();
+ break;
+ case syntax_element_backref:
+ case syntax_element_long_set:
+ case syntax_element_set:
+ case syntax_element_wild:
+ case syntax_element_combining:
+ // we're repeating a single item:
+ offset = (char*)dat - (char*)data.data();
+ break;
+ default:
+ fail(REG_BADRPT);
+ return code;
+ }
+ data.align();
+ dat->next.i = data.size();
+ //unsigned pos = (char*)dat - (char*)data.data();
+
+ // add the trailing jump:
+ add_simple(dat, syntax_element_jump, re_jump_size);
+
+ // now insert the leading repeater:
+ dat = (re_syntax_base*)data.insert(offset, re_repeater_size);
+ dat->next.i = ((char*)dat - (char*)data.data()) + re_repeater_size;
+ dat->type = syntax_element_rep;
+ ((re_repeat*)dat)->alt.i = data.size();
+ ((re_repeat*)dat)->min = rep_min;
+ ((re_repeat*)dat)->max = rep_max;
+ ((re_repeat*)dat)->leading = false;
+ move_offsets(dat, re_repeater_size);
+ dat = (re_syntax_base*)((char*)data.data() + data.size() - re_jump_size);
+ ((re_repeat*)dat)->alt.i = offset;
+ ++ptr;
+ continue;
+ }
+ case syntax_plus:
+ if(_flags & (bk_plus_qm | limited_ops))
+ {
+ dat = add_literal(dat, (charT)c);
+ ++ptr;
+ continue;
+ }
+ rep_min = 1;
+ rep_max = (unsigned)-1;
+ goto repeat_jump;
+ case syntax_question:
+ if(_flags & (bk_plus_qm | limited_ops))
+ {
+ dat = add_literal(dat, (charT)c);
+ ++ptr;
+ continue;
+ }
+ rep_min = 0;
+ rep_max = 1;
+ goto repeat_jump;
+ case syntax_open_set:
+ // update previous:
+ if(dat)
+ {
+ data.align();
+ dat->next.i = data.size();
+ }
+ // extend:
+ dat = compile_set(ptr, end);
+ if(dat == 0)
+ {
+ if((_flags & regbase::failbit) == 0)
+ fail(REG_EBRACK);
+ return code;
+ }
+ break;
+ case syntax_or:
+ {
+ if(_flags & (bk_vbar | limited_ops))
+ {
+ dat = add_literal(dat, (charT)c);
+ ++ptr;
+ continue;
+ }
+
+ alt_string_jump:
+
+ // update previous:
+ if(dat == 0)
+ {
+ // start of pattern can't have empty "|"
+ fail(REG_EMPTY);
+ return code;
+ }
+ // see if we have an empty alternative:
+ if(mark.empty() == false)
+ if(mark.peek() == data.index(dat))
+ {
+ fail(REG_EMPTY);
+ return code;
+ }
+ // extend:
+ /*dat = */add_simple(dat, syntax_element_jump, re_jump_size);
+ data.align();
+
+ // now work out where to insert:
+ unsigned int offset = 0;
+ if(mark.empty() == false)
+ {
+ // we have a '(' or '|' to go back to:
+ offset = mark.peek();
+ re_syntax_base* base = (re_syntax_base*)((unsigned char*)data.data() + offset);
+ offset = base->next.i;
+ }
+ re_jump* j = (re_jump*)data.insert(offset, re_jump_size);
+ j->type = syntax_element_alt;
+ j->next.i = offset + re_jump_size;
+ j->alt.i = data.size();
+ move_offsets(j, re_jump_size);
+ dat = (re_syntax_base*)((unsigned char*)data.data() + data.size() - re_jump_size);
+ mark.push(data.size() - re_jump_size);
+ ++ptr;
+ break;
+ }
+ case syntax_open_brace:
+ if((_flags & bk_braces) || ((_flags & intervals) == 0))
+ {
+ dat = add_literal(dat, (charT)c);
+ ++ptr;
+ continue;
+ }
+ // we have {x} or {x,} or {x,y}:
+ parse_range(ptr, end, rep_min, rep_max);
+ goto repeat_jump;
+ case syntax_newline:
+ if(_flags & newline_alt)
+ goto alt_string_jump;
+ dat = add_literal(dat, (charT)c);
+ ++ptr;
+ continue;
+ case syntax_close_brace:
+ if(_flags & bk_braces)
+ {
+ dat = add_literal(dat, (charT)c);
+ ++ptr;
+ continue;
+ }
+ fail(REG_BADPAT);
+ return code;
+ default:
+ dat = add_literal(dat, (charT)c);
+ ++ptr;
+ break;
+ } // switch
+ } // while
+
+ //
+ // update previous:
+ if(dat)
+ {
+ data.align();
+ dat->next.i = data.size();
+ }
+
+ // see if we have an empty alternative:
+ if(mark.empty() == false)
+ if(mark.peek() == data.index(dat) )
+ {
+ re_syntax_base* para = (re_syntax_base*)((char*)data.data() + mark.peek());
+ if(para->type == syntax_element_jump)
+ {
+ fail(REG_EMPTY);
+ return code;
+ }
+ }
+ //
+ // set up tail:
+ //
+ if(mark.empty() == false)
+ {
+ // pop any pushed alternatives and set the target end destination:
+ dat = (re_syntax_base*)((unsigned char*)data.data() + mark.peek());
+ while(dat->type == syntax_element_jump)
+ {
+ ((re_jump*)dat)->alt.i = data.size();
+ mark.pop();
+ if(mark.empty() == true)
+ break;
+ dat = (re_jump*)((unsigned char*)data.data() + mark.peek());
+ }
+ }
+
+ dat = (re_brace*)data.extend(sizeof(re_syntax_base));
+ dat->type = syntax_element_match;
+ dat->next.i = 0;
+
+ if(mark.empty() == false)
+ {
+ fail(REG_EPAREN);
+ return code;
+ }
+
+ //
+ // allocate space for start __map:
+ startmap = (unsigned char*)data.extend(256 + ((end - base + 1) * sizeof(charT)));
+ //
+ // and copy the expression we just compiled:
+ _expression = (charT*)((const char*)startmap + 256);
+ memcpy(_expression, base, (end - base) * sizeof(charT));
+ *(_expression + (end - base)) = charT(0);
+
+ //
+ // now we need to apply fixups to the array
+ // so that we can use pointers and not indexes
+ fixup_apply((re_syntax_base*)data.data(), marks);
+
+ // check for error during fixup:
+ if(_flags & regbase::failbit)
+ return code;
+
+ //
+ // finally compile the maps so that we can make intelligent choices
+ // whenever we encounter an alternative:
+ compile_maps();
+ if(pkmp)
+ {
+ kmp_free(pkmp, data.allocator());
+ pkmp = 0;
+ }
+ re_syntax_base* sbase = (re_syntax_base*)data.data();
+ _restart_type = probe_restart(sbase);
+ _leading_len = fixup_leading_rep(sbase, 0);
+ if((sbase->type == syntax_element_literal) && (sbase->next.p->type == syntax_element_match))
+ {
+ _restart_type = restart_fixed_lit;
+ if(0 == pkmp)
+ {
+ charT* p1 = (charT*)((char*)sbase + sizeof(re_literal));
+ charT* p2 = p1 + ((re_literal*)sbase)->length;
+ pkmp = kmp_compile(p1, p2, charT(), kmp_translator<traits>(_flags&regbase::icase), data.allocator() MAYBE_PASS_LOCALE(locale_inst));
+ }
+ }
+ return code;
+}
+
+template <class charT, class traits, class Allocator>
+re_syntax_base* RE_CALL reg_expression<charT, traits, Allocator>::add_simple(re_syntax_base* dat, syntax_element_type type, unsigned int size)
+{
+ if(dat)
+ {
+ data.align();
+ dat->next.i = data.size();
+ }
+ if(size < sizeof(re_syntax_base))
+ size = sizeof(re_syntax_base);
+ dat = (re_syntax_base*)data.extend(size);
+ dat->type = type;
+ dat->next.i = 0;
+ return dat;
+}
+
+template <class charT, class traits, class Allocator>
+re_syntax_base* RE_CALL reg_expression<charT, traits, Allocator>::add_literal(re_syntax_base* dat, charT c)
+{
+ if(dat && (dat->type == syntax_element_literal))
+ {
+ // add another charT to the list:
+ __JM_STDC::ptrdiff_t pos = (unsigned char*)dat - (unsigned char*)data.data();
+ *(charT*)data.extend(sizeof(charT)) = traits::translate(c, (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst));
+ dat = (re_syntax_base*)((unsigned char*)data.data() + pos);
+ ++(((re_literal*)dat)->length);
+ }
+ else
+ {
+ // extend:
+ dat = add_simple(dat, syntax_element_literal, sizeof(re_literal) + sizeof(charT));
+ ((re_literal*)dat)->length = 1;
+ *((charT*)(((re_literal*)dat)+1)) = traits::translate(c, (_flags & regbase::icase) MAYBE_PASS_LOCALE(locale_inst));
+ }
+ return dat;
+}
+
+template <class charT, class traits, class Allocator>
+unsigned int RE_CALL reg_expression<charT, traits, Allocator>::probe_restart(re_syntax_base* dat)
+{
+ switch(dat->type)
+ {
+ case syntax_element_startmark:
+ case syntax_element_endmark:
+ return probe_restart(dat->next.p);
+ case syntax_element_start_line:
+ return regbase::restart_line;
+ case syntax_element_word_start:
+ return regbase::restart_word;
+ case syntax_element_buffer_start:
+ return regbase::restart_buf;
+ case syntax_element_restart_continue:
+ return regbase::restart_continue;
+ default:
+ return regbase::restart_any;
+ }
+}
+
+template <class charT, class traits, class Allocator>
+unsigned int RE_CALL reg_expression<charT, traits, Allocator>::fixup_leading_rep(re_syntax_base* dat, re_syntax_base* end)
+{
+ unsigned int len = 0;
+ bool leading_lit = end ? false : true;
+ while(dat != end)
+ {
+ switch(dat->type)
+ {
+ case syntax_element_literal:
+ len += ((re_literal*)dat)->length;
+ if((leading_lit) && (((re_literal*)dat)->length > 2))
+ {
+ // we can do a literal search for the leading literal string
+ // using Knuth-Morris-Pratt (or whatever), and only then check for
+ // matches. We need a decent length string though to make it
+ // worth while.
+ _leading_string = (charT*)((char*)dat + sizeof(re_literal));
+ _leading_string_len = ((re_literal*)dat)->length;
+ _restart_type = restart_lit;
+ leading_lit = false;
+ const charT* p1 = _leading_string;
+ const charT* p2 = _leading_string + _leading_string_len;
+ pkmp = kmp_compile(p1, p2, charT(), kmp_translator<traits>(_flags&regbase::icase), data.allocator() MAYBE_PASS_LOCALE(locale_inst));
+ }
+ break;
+ case syntax_element_wild:
+ ++len;
+ leading_lit = false;
+ break;
+ case syntax_element_match:
+ return len;
+ case syntax_element_backref:
+ //case syntax_element_jump:
+ case syntax_element_alt:
+ case syntax_element_combining:
+ return 0;
+ case syntax_element_long_set:
+ {
+ // we need to verify that there are no multi-character
+ // collating elements inside the repeat:
+ const charT* p = (const charT*)((const char*)dat + sizeof(re_set_long));
+ unsigned int csingles = ((re_set_long*)dat)->csingles;
+ for(unsigned int i = 0; i < csingles; ++i)
+ {
+ if(re_strlen(p) > 1)
+ return 0;
+ while(*p)++p;
+ ++p;
+ }
+ ++len;
+ leading_lit = false;
+ break;
+ }
+ case syntax_element_set:
+ ++len;
+ leading_lit = false;
+ break;
+ case syntax_element_rep:
+ if(1 == fixup_leading_rep(dat->next.p, ((re_repeat*)dat)->alt.p) )
+ {
+ ((re_repeat*)dat)->leading = true;
+ return len;
+ }
+ return 0;
+ }
+ dat = dat->next.p;
+ }
+ return len;
+}
+
+#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
+} // namespace
+#endif
+
+JM_END_NAMESPACE
+
+
+
+
+
+
+
diff --git a/utils/tfstats/regexp/include/jm/regex.h b/utils/tfstats/regexp/include/jm/regex.h
new file mode 100644
index 0000000..99a038c
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/regex.h
@@ -0,0 +1,1722 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE regex.h
+ * VERSION 2.12
+ */
+
+
+/* start with C compatability API */
+
+#ifndef __REGEX_H
+#define __REGEX_H
+
+#include <cregex>
+
+#ifdef __cplusplus
+
+// what follows is all C++ don't include in C builds!!
+
+#include <new.h>
+#if !defined(JM_NO_TYPEINFO)
+#include <typeinfo>
+#endif
+#include <string.h>
+#include <jm/jstack.h>
+#include <jm/re_raw.h>
+#include <jm/re_nls.h>
+#include <jm/regfac.h>
+#include <jm/re_cls.h>
+#include <jm/re_coll.h>
+#include <jm/re_kmp.h>
+
+
+JM_NAMESPACE(__JM)
+
+//
+// define error hanling classes
+#if !defined(JM_NO_EXCEPTIONS) && !defined(JM_NO_EXCEPTION_H)
+// standard classes are available:
+
+class JM_IX_DECL bad_expression : public __JM_STD::exception
+{
+#ifdef RE_LOCALE_CPP
+ __JM_STD::string code;
+public:
+ bad_expression(const __JM_STD::string& s) : code(s) {}
+#else
+ unsigned int code;
+public:
+ bad_expression(unsigned int err) : code(err) {}
+#endif
+ bad_expression(const bad_expression& e) : __JM_STD::exception(e), code(e.code) {}
+ bad_expression& operator=(const bad_expression& e)
+ {
+ #ifdef _MSC_VER
+ static_cast<__JM_STD::exception*>(this)->operator=(e);
+ #else
+ __JM_STD::exception::operator=(e);
+ #endif
+ code = e.code;
+ return *this;
+ }
+ virtual const char* what()const throw();
+};
+
+#elif !defined(JM_NO_EXCEPTIONS)
+// no standard classes, do it ourselves:
+
+class JM_IX_DECL bad_expression
+{
+#ifdef RE_LOCALE_CPP
+ __JM_STD::string code;
+public:
+ bad_expression(const __JM_STD::string& s) : code(s) {}
+#else
+ unsigned int code;
+public:
+ bad_expression(unsigned int err) : code(err) {}
+#endif
+ bad_expression(const bad_expression& e) : code(e.code) {}
+ bad_expression& operator=(const bad_expression& e) { code = e.code; return *this; }
+ virtual const char* what()const throw();
+};
+
+#endif
+
+//
+// define default traits classes for char and wchar_t types:
+//
+
+struct re_set_long;
+struct re_syntax_base;
+
+enum char_syntax_type
+{
+ syntax_char = 0,
+ syntax_open_bracket = 1, // (
+ syntax_close_bracket = 2, // )
+ syntax_dollar = 3, // $
+ syntax_caret = 4, // ^
+ syntax_dot = 5, // .
+ syntax_star = 6, // *
+ syntax_plus = 7, // +
+ syntax_question = 8, // ?
+ syntax_open_set = 9, // [
+ syntax_close_set = 10, // ]
+ syntax_or = 11, // |
+ syntax_slash = 12, //
+ syntax_hash = 13, // #
+ syntax_dash = 14, // -
+ syntax_open_brace = 15, // {
+ syntax_close_brace = 16, // }
+ syntax_digit = 17, // 0-9
+ syntax_b = 18, // for \b
+ syntax_B = 19, // for \B
+ syntax_left_word = 20, // for \<
+ syntax_right_word = 21, // for \>
+ syntax_w = 22, // for \w
+ syntax_W = 23, // for \W
+ syntax_start_buffer = 24, // for \`
+ syntax_end_buffer = 25, // for \'
+ syntax_newline = 26, // for newline alt
+ syntax_comma = 27, // for {x,y}
+
+ syntax_a = 28, // for \a
+ syntax_f = 29, // for \f
+ syntax_n = 30, // for \n
+ syntax_r = 31, // for \r
+ syntax_t = 32, // for \t
+ syntax_v = 33, // for \v
+ syntax_x = 34, // for \xdd
+ syntax_c = 35, // for \cx
+ syntax_colon = 36, // for [:...:]
+ syntax_equal = 37, // for [=...=]
+
+ // perl ops:
+ syntax_e = 38, // for \e
+ syntax_l = 39, // for \l
+ syntax_L = 40, // for \L
+ syntax_u = 41, // for \u
+ syntax_U = 42, // for \U
+ syntax_s = 43, // for \s
+ syntax_S = 44, // for \S
+ syntax_d = 45, // for \d
+ syntax_D = 46, // for \D
+ syntax_E = 47, // for \Q\E
+ syntax_Q = 48, // for \Q\E
+ syntax_X = 49, // for \X
+ syntax_C = 50, // for \C
+ syntax_Z = 51, // for \Z
+ syntax_G = 52, // for \G
+
+ syntax_max = 53
+};
+
+template <class charT>
+class char_regex_traits
+{
+public:
+ typedef charT char_type;
+ //
+ // uchar_type is the same size as char_type
+ // but must be unsigned:
+ typedef charT uchar_type;
+ //
+ // size_type is normally the same as charT
+ // but could be unsigned int to improve performance
+ // of narrow character types, NB must be unsigned:
+ typedef jm_uintfast32_t size_type;
+
+ // length:
+ // returns the length of a null terminated string
+ // can be left unimplimented for non-character types.
+ static size_t length(const char_type* );
+
+ // syntax_type
+ // returns the syntax type of a given charT
+ // translates customised syntax to a unified enum.
+ static unsigned int syntax_type(size_type c);
+
+ // translate:
+ //
+ static charT RE_CALL translate(charT c, bool icase
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale&
+ #endif
+ );
+
+ // transform:
+ //
+ // converts a string into a sort key for locale dependant
+ // character ranges.
+ static void RE_CALL transform(re_str<charT>& out, const re_str<charT>& in
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale&
+ #endif
+ );
+
+ // transform_primary:
+ //
+ // converts a string into a primary sort key for locale dependant
+ // equivalence classes.
+ static void RE_CALL transform_primary(re_str<charT>& out, const re_str<charT>& in
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale&
+ #endif
+ );
+
+ // is_separator
+ // returns true if c is a newline character
+ static bool RE_CALL is_separator(charT c);
+
+ // is_combining
+ // returns true if the character is a unicode
+ // combining character
+ static bool RE_CALL is_combining(charT c);
+
+ // is_class
+ // returns true if the character is a member
+ // of the specified character class
+ static bool RE_CALL is_class(charT c, jm_uintfast32_t f
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale&
+ #endif
+ );
+
+ // toi
+ // converts c to integer
+ static int RE_CALL toi(charT c
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale&
+ #endif
+ );
+
+ // toi
+ // converts multi-character value to int
+ // updating first as required
+ static int RE_CALL toi(const charT*& first, const charT* last, int radix
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale&
+ #endif
+ );
+
+ // lookup_classname
+ // parses a class declaration of the form [:class:]
+ // On entry first points to the first character of the class name.
+ //
+ static jm_uintfast32_t RE_CALL lookup_classname(const charT* first, const charT* last
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale&
+ #endif
+ );
+
+ // lookup_collatename
+ // parses a collating element declaration of the form [.collating_name.]
+ // On entry first points to the first character of the collating element name.
+ //
+ static bool RE_CALL lookup_collatename(re_str<charT>& s, const charT* first, const charT* last
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale&
+ #endif
+ );
+
+};
+
+JM_TEMPLATE_SPECIALISE
+class char_regex_traits<char>
+{
+public:
+ typedef char char_type;
+ typedef unsigned char uchar_type;
+ typedef unsigned int size_type;
+ static size_t RE_CALL length(const char_type* p)
+ {
+ return strlen(p);
+ }
+ static unsigned int RE_CALL syntax_type(size_type c
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, regfacet<char>).syntax_type((char)c);
+ #else
+ return re_syntax_map[c];
+ #endif
+ }
+ static char RE_CALL translate(char c, bool icase
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ return icase ? JM_USE_FACET(l, __JM_STD::ctype<char>).tolower((char_type)c) : c;
+ #else
+ return icase ? re_lower_case_map[(size_type)(uchar_type)c] : c;
+ #endif
+ }
+ static void RE_CALL transform(re_str<char>& out, const re_str<char>& in
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+#ifndef RE_LOCALE_CPP
+ re_transform(out, in);
+#else
+ out = JM_USE_FACET(l, __JM_STD::collate<char>).transform(in.c_str(), in.c_str() + in.size()).c_str();
+#endif
+ }
+
+ static void RE_CALL transform_primary(re_str<char>& out, const re_str<char>& in
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ transform(out, in MAYBE_PASS_LOCALE(l));
+#ifdef RE_LOCALE_W32
+ re_trunc_primary(out);
+#else
+ unsigned n = in.size() + out.size() / 4;
+ if(n < out.size())
+ out[n] = 0;
+#endif
+ }
+
+ static bool RE_CALL is_separator(char c)
+ {
+ return JM_MAKE_BOOL((c == '\n') || (c == '\r'));
+ }
+
+ static bool RE_CALL is_combining(char)
+ {
+ return false;
+ }
+
+ static bool RE_CALL is_class(char c, jm_uintfast32_t f
+#ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+#endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ if(JM_USE_FACET(l, __JM_STD::ctype<char>).is((__JM_STD::ctype<char>::mask)(f & char_class_all_base), c))
+ return true;
+ if((f & char_class_underscore) && (c == '_'))
+ return true;
+ if((f & char_class_blank) && ((c == ' ') || (c == '\t')))
+ return true;
+ return false;
+ #else
+ return JM_MAKE_BOOL(re_class_map[(size_type)(uchar_type)c] & f);
+ #endif
+ }
+ static int RE_CALL toi(char c
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ return re_toi(c MAYBE_PASS_LOCALE(l));
+ }
+ static int RE_CALL toi(const char*& first, const char* last, int radix
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ return re_toi(first, last, radix MAYBE_PASS_LOCALE(l));
+ }
+
+ static jm_uintfast32_t RE_CALL lookup_classname(const char* first, const char* last
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, regfacet<char>).lookup_classname(first, last);
+ #else
+ return re_lookup_class(first, last);
+ #endif
+ }
+
+ static bool RE_CALL lookup_collatename(re_str<char>& s, const char* first, const char* last
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ re_str<char> n(first, last);
+ return JM_USE_FACET(l, regfacet<char>).lookup_collatename(s, n);
+ #else
+ return re_lookup_collate(s, first, last);
+ #endif
+ }
+};
+
+#ifndef JM_NO_WCSTRING
+JM_TEMPLATE_SPECIALISE
+class char_regex_traits<wchar_t>
+{
+public:
+ typedef wchar_t char_type;
+ typedef unsigned short uchar_type;
+ typedef unsigned int size_type;
+ static size_t RE_CALL length(const char_type* p)
+ {
+ return wcslen(p);
+ }
+ static unsigned int RE_CALL syntax_type(size_type c
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, regfacet<wchar_t>).syntax_type((wchar_t)c);
+ #else
+ return re_get_syntax_type(c);
+ #endif
+ }
+ static wchar_t RE_CALL translate(wchar_t c, bool icase
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ return icase ? JM_USE_FACET(l, __JM_STD::ctype<wchar_t>).tolower((char_type)c) : c;
+ #else
+ return icase ? ((c < 256) ? re_lower_case_map_w[(uchar_type)c] : re_wtolower(c)) : c;
+ #endif
+ }
+
+ static void RE_CALL transform(re_str<wchar_t>& out, const re_str<wchar_t>& in
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+#ifndef RE_LOCALE_CPP
+ re_transform(out, in);
+#else
+ out = JM_USE_FACET(l, __JM_STD::collate<wchar_t>).transform(in.c_str(), in.c_str() + in.size()).c_str();
+#endif
+ }
+
+ static void RE_CALL transform_primary(re_str<wchar_t>& out, const re_str<wchar_t>& in
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ transform(out, in MAYBE_PASS_LOCALE(l));
+#ifdef RE_LOCALE_W32
+ re_trunc_primary(out);
+#else
+ unsigned n = in.size() + out.size() / 4;
+ if(n < out.size())
+ out[n] = 0;
+#endif
+ }
+
+ static bool RE_CALL is_separator(wchar_t c)
+ {
+ return JM_MAKE_BOOL((c == L'\n') || (c == L'\r') || (c == (wchar_t)0x2028) || (c == (wchar_t)0x2029));
+ }
+
+ static bool RE_CALL is_combining(wchar_t c)
+ {
+ return re_is_combining(c);
+ }
+
+ static bool RE_CALL is_class(wchar_t c, jm_uintfast32_t f
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ if(JM_USE_FACET(l, __JM_STD::ctype<wchar_t>).is((__JM_STD::ctype<wchar_t>::mask)(f & char_class_all_base), c))
+ return true;
+ if((f & char_class_underscore) && (c == '_'))
+ return true;
+ if((f & char_class_blank) && ((c == ' ') || (c == '\t')))
+ return true;
+ if((f & char_class_unicode) && (c > (size_type)(uchar_type)255))
+ return true;
+ return false;
+ #else
+ return JM_MAKE_BOOL(((uchar_type)c < 256) ? (re_unicode_classes[(size_type)(uchar_type)c] & f) : re_iswclass(c, f));
+ #endif
+ }
+ static int RE_CALL toi(wchar_t c
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ return re_toi(c MAYBE_PASS_LOCALE(l));
+ }
+ static int RE_CALL toi(const wchar_t*& first, const wchar_t* last, int radix
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ return re_toi(first, last, radix MAYBE_PASS_LOCALE(l));
+ }
+
+ static jm_uintfast32_t RE_CALL lookup_classname(const wchar_t* first, const wchar_t* last
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, regfacet<wchar_t>).lookup_classname(first, last);
+ #else
+ return re_lookup_class(first, last);
+ #endif
+ }
+
+
+ static bool RE_CALL lookup_collatename(re_str<wchar_t>& s, const wchar_t* first, const wchar_t* last
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ re_str<wchar_t> n(first, last);
+ return JM_USE_FACET(l, regfacet<wchar_t>).lookup_collatename(s, n);
+ #else
+ return re_lookup_collate(s, first, last);
+ #endif
+ }
+};
+#endif
+
+//
+// class char_regex_traits_i
+// provides case insensitive traits classes:
+template <class charT>
+class char_regex_traits_i : public char_regex_traits<charT> {};
+
+JM_TEMPLATE_SPECIALISE
+class char_regex_traits_i<char> : public char_regex_traits<char>
+{
+public:
+ typedef char char_type;
+ typedef unsigned char uchar_type;
+ typedef unsigned int size_type;
+ typedef char_regex_traits<char> base_type;
+
+ static char RE_CALL translate(char c, bool
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, __JM_STD::ctype<char>).tolower((char_type)c);
+ #else
+ return re_lower_case_map[(size_type)(uchar_type)c];
+ #endif
+ }
+};
+
+#ifndef JM_NO_WCSTRING
+JM_TEMPLATE_SPECIALISE
+class char_regex_traits_i<wchar_t> : public char_regex_traits<wchar_t>
+{
+public:
+ typedef wchar_t char_type;
+ typedef unsigned short uchar_type;
+ typedef unsigned int size_type;
+ typedef char_regex_traits<wchar_t> base_type;
+
+ static wchar_t RE_CALL translate(wchar_t c, bool
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ #ifdef RE_LOCALE_CPP
+ return JM_USE_FACET(l, __JM_STD::ctype<wchar_t>).tolower((char_type)c);
+ #else
+ return (c < 256) ? re_lower_case_map_w[(uchar_type)c] : re_wtolower(c);
+ #endif
+ }
+ static jm_uintfast32_t RE_CALL lookup_classname(const wchar_t* first, const wchar_t* last
+ #ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+ #endif
+ )
+ {
+ jm_uintfast32_t result = char_regex_traits<wchar_t>::lookup_classname(first, last MAYBE_PASS_LOCALE(l));
+ if((result & char_class_upper) == char_class_upper)
+ result |= char_class_alpha;
+ return result;
+ }
+};
+#endif
+
+enum mask_type
+{
+ mask_take = 1,
+ mask_skip = 2,
+ mask_any = mask_skip | mask_take,
+ mask_all = mask_any
+};
+
+struct __narrow_type{};
+struct __wide_type{};
+
+template <class charT>
+class is_byte;
+
+JM_TEMPLATE_SPECIALISE
+class is_byte<char>
+{
+public:
+ typedef __narrow_type width_type;
+};
+
+JM_TEMPLATE_SPECIALISE
+class is_byte<unsigned char>
+{
+public:
+ typedef __narrow_type width_type;
+};
+
+JM_TEMPLATE_SPECIALISE
+class is_byte<signed char>
+{
+public:
+ typedef __narrow_type width_type;
+};
+
+template <class charT>
+class is_byte
+{
+public:
+ typedef __wide_type width_type;
+};
+
+
+//
+// compiled structures
+//
+// the following defs describe the format of the compiled string
+//
+
+//
+// enum syntax_element_type
+// describes the type of a record
+enum syntax_element_type
+{
+ syntax_element_startmark = 0,
+ syntax_element_endmark = syntax_element_startmark + 1,
+ syntax_element_literal = syntax_element_endmark + 1,
+ syntax_element_start_line = syntax_element_literal + 1,
+ syntax_element_end_line = syntax_element_start_line + 1,
+ syntax_element_wild = syntax_element_end_line + 1,
+ syntax_element_match = syntax_element_wild + 1,
+ syntax_element_word_boundary = syntax_element_match + 1,
+ syntax_element_within_word = syntax_element_word_boundary + 1,
+ syntax_element_word_start = syntax_element_within_word + 1,
+ syntax_element_word_end = syntax_element_word_start + 1,
+ syntax_element_buffer_start = syntax_element_word_end + 1,
+ syntax_element_buffer_end = syntax_element_buffer_start + 1,
+ syntax_element_backref = syntax_element_buffer_end + 1,
+ syntax_element_long_set = syntax_element_backref + 1,
+ syntax_element_set = syntax_element_long_set + 1,
+ syntax_element_jump = syntax_element_set + 1,
+ syntax_element_alt = syntax_element_jump + 1,
+ syntax_element_rep = syntax_element_alt + 1,
+ syntax_element_combining = syntax_element_rep + 1,
+ syntax_element_soft_buffer_end = syntax_element_combining + 1,
+ syntax_element_restart_continue = syntax_element_soft_buffer_end + 1
+};
+
+union offset_type
+{
+ re_syntax_base* p;
+ unsigned i;
+};
+
+//
+// struct re_syntax_base
+// base class for all syntax types:
+struct re_syntax_base
+{
+ syntax_element_type type;
+ offset_type next;
+ unsigned int can_be_null;
+};
+
+//
+// struct re_brace
+// marks start or end of (...)
+struct re_brace : public re_syntax_base
+{
+ unsigned int index;
+};
+
+//
+// struct re_literal
+// marks a literal string and
+// is followed by an array of charT[length]:
+struct re_literal : public re_syntax_base
+{
+ unsigned int length;
+};
+
+//
+// struct re_long_set
+// provides data for sets [...] containing
+// wide characters
+struct re_set_long : public re_syntax_base
+{
+ unsigned int csingles, cranges, cequivalents;
+ jm_uintfast32_t cclasses;
+ bool isnot;
+};
+
+//
+// struct re_set
+// provides a map of bools for sets containing
+// narrow, single byte characters.
+struct re_set : public re_syntax_base
+{
+ unsigned char __map[256];
+};
+
+//
+// struct re_jump
+// provides alternative next destination
+struct re_jump : public re_syntax_base
+{
+ offset_type alt;
+ unsigned char __map[256];
+};
+
+//
+// struct re_repeat
+// provides repeat expressions
+struct re_repeat : public re_jump
+{
+ unsigned min, max;
+ int id;
+ bool leading;
+};
+
+
+//
+// enum re_jump_size_type
+// provides compiled size of re_jump
+// allowing for trailing alignment
+// provide this so we know how many
+// bytes to insert
+enum re_jump_size_type
+{
+ re_jump_size = (sizeof(re_jump) + sizeof(padding) - 1) & ~(sizeof(padding) - 1),
+ re_repeater_size = (sizeof(re_repeat) + sizeof(padding) - 1) & ~(sizeof(padding) - 1)
+};
+
+
+//
+// class basic_regex
+// handles error codes and flags
+
+class JM_IX_DECL regbase
+{
+protected:
+#ifdef RE_LOCALE_CPP
+ __JM_STD::locale locale_inst;
+#endif
+ jm_uintfast32_t _flags;
+ unsigned int code;
+public:
+ enum flag_type
+ {
+ escape_in_lists = 1, // '\' special inside [...]
+ char_classes = escape_in_lists << 1, // [[:CLASS:]] allowed
+ intervals = char_classes << 1, // {x,y} allowed
+ limited_ops = intervals << 1, // all of + ? and | are normal characters
+ newline_alt = limited_ops << 1, // \n is the same as |
+ bk_plus_qm = newline_alt << 1, // uses \+ and \?
+ bk_braces = bk_plus_qm << 1, // uses \{ and \}
+ bk_parens = bk_braces << 1, // uses \( and \)
+ bk_refs = bk_parens << 1, // \d allowed
+ bk_vbar = bk_refs << 1, // uses \|
+ use_except = bk_vbar << 1, // exception on error
+ failbit = use_except << 1, // error flag
+ literal = failbit << 1, // all characters are literals
+ icase = literal << 1, // characters are matched regardless of case
+ nocollate = icase << 1, // don't use locale specific collation
+
+ basic = char_classes | intervals | limited_ops | bk_braces | bk_parens | bk_refs,
+ extended = char_classes | intervals | bk_refs,
+ normal = escape_in_lists | char_classes | intervals | bk_refs | nocollate
+ };
+
+ enum restart_info
+ {
+ restart_any = 0,
+ restart_word = 1,
+ restart_line = 2,
+ restart_buf = 3,
+ restart_continue = 4,
+ restart_lit = 5,
+ restart_fixed_lit = 6
+ };
+
+ unsigned int RE_CALL error_code()const
+ {
+ return code;
+ }
+
+ void RE_CALL fail(unsigned int err);
+
+ jm_uintfast32_t RE_CALL flags()const
+ {
+ return _flags;
+ }
+#ifdef RE_LOCALE_CPP
+ __JM_STD::string RE_CALL errmsg()const
+ {
+ return re_get_error_str(code, locale_inst);
+ }
+#else
+ const char* RE_CALL errmsg()const
+ {
+ return re_get_error_str(code);
+ }
+#endif
+
+ regbase();
+ regbase(const regbase& b);
+
+ #ifdef RE_LOCALE_CPP
+ __JM_STD::locale RE_CALL imbue(const __JM_STD::locale& l);
+
+ const __JM_STD::locale& RE_CALL locale()const
+ {
+ return locale_inst;
+ }
+ #endif
+};
+
+//
+// some forward declarations:
+
+template <class iterator, class Allocator JM_DEF_ALLOC_PARAM(iterator) >
+class reg_match;
+
+template <class iterator, class Allocator>
+class __priv_match_data;
+
+
+//
+// class reg_expression
+// represents the compiled
+// regular expression:
+//
+
+#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
+//
+// Ugly ugly hack,
+// template don't merge if they contain switch statements so declare these
+// templates in unnamed namespace (ie with internal linkage), each translation
+// unit then gets its own local copy, it works seemlessly but bloats the app.
+namespace{
+#endif
+
+template <class charT, class traits JM_TRICKY_DEFAULT_PARAM(char_regex_traits<charT>), class Allocator JM_DEF_ALLOC_PARAM(charT) >
+class reg_expression : public regbase
+{
+public:
+ // typedefs:
+ typedef Allocator alloc_type;
+ typedef typename REBIND_TYPE(charT, alloc_type)::size_type size_type;
+ typedef charT value_type;
+ typedef charT char_type;
+ typedef traits traits_type;
+ typedef typename traits_type::size_type traits_size_type;
+ typedef typename traits_type::uchar_type traits_uchar_type;
+
+private:
+#if defined(RE_LOCALE_C) || defined(RE_LOCALE_W32)
+ re_initialiser<charT> locale_initialiser;
+#endif
+ raw_storage<Allocator> data;
+ unsigned _restart_type;
+ unsigned marks;
+ int repeats;
+ unsigned char* startmap;
+ charT* _expression;
+ unsigned int _leading_len;
+ const charT* _leading_string;
+ unsigned int _leading_string_len;
+ kmp_info<charT>* pkmp;
+
+ void RE_CALL compile_maps();
+ void RE_CALL compile_map(re_syntax_base* node, unsigned char* __map, unsigned int* pnull, unsigned char mask, re_syntax_base* terminal = NULL)const;
+ bool RE_CALL probe_start(re_syntax_base* node, charT c, re_syntax_base* terminal)const;
+ bool RE_CALL probe_start_null(re_syntax_base* node, re_syntax_base* terminal)const;
+ void RE_CALL fixup_apply(re_syntax_base* b, unsigned cbraces);
+ void RE_CALL move_offsets(re_syntax_base* j, unsigned size);
+ re_syntax_base* RE_CALL compile_set(const charT*& first, const charT* last);
+ re_syntax_base* RE_CALL compile_set_aux(jstack<re_str<charT>, Allocator>& singles, jstack<re_str<charT>, Allocator>& ranges, jstack<jm_uintfast32_t, Allocator>& classes, jstack<re_str<charT>, Allocator>& equivalents, bool isnot, const __narrow_type&);
+ re_syntax_base* RE_CALL compile_set_aux(jstack<re_str<charT>, Allocator>& singles, jstack<re_str<charT>, Allocator>& ranges, jstack<jm_uintfast32_t, Allocator>& classes, jstack<re_str<charT>, Allocator>& equivalents, bool isnot, const __wide_type&);
+ re_syntax_base* RE_CALL compile_set_simple(re_syntax_base* dat, unsigned long cls, bool isnot = false);
+ unsigned int RE_CALL parse_inner_set(const charT*& first, const charT* last);
+
+ re_syntax_base* RE_CALL add_simple(re_syntax_base* dat, syntax_element_type type, unsigned int size = sizeof(re_syntax_base));
+ re_syntax_base* RE_CALL add_literal(re_syntax_base* dat, charT c);
+ charT RE_CALL parse_escape(const charT*& first, const charT* last);
+ void RE_CALL parse_range(const charT*& first, const charT* last, unsigned& min, unsigned& max);
+ bool RE_CALL skip_space(const charT*& first, const charT* last);
+ unsigned int RE_CALL probe_restart(re_syntax_base* dat);
+ unsigned int RE_CALL fixup_leading_rep(re_syntax_base* dat, re_syntax_base* end);
+
+public:
+ unsigned int RE_CALL set_expression(const charT* p, const charT* end, jm_uintfast32_t f = regbase::normal);
+ unsigned int RE_CALL set_expression(const charT* p, jm_uintfast32_t f = regbase::normal) { return set_expression(p, p + traits_type::length(p), f); }
+ reg_expression(const Allocator& a = Allocator());
+ reg_expression(const charT* p, jm_uintfast32_t f = regbase::normal, const Allocator& a = Allocator());
+ reg_expression(const charT* p1, const charT* p2, jm_uintfast32_t f = regbase::normal, const Allocator& a = Allocator());
+ reg_expression(const charT* p, size_type len, jm_uintfast32_t f, const Allocator& a = Allocator());
+ reg_expression(const reg_expression&);
+ ~reg_expression();
+ reg_expression& RE_CALL operator=(const reg_expression&);
+
+#ifndef JM_NO_MEMBER_TEMPLATES
+
+ template <class ST, class SA>
+ unsigned int RE_CALL set_expression(const __JM_STD::basic_string<charT, ST, SA>& p, jm_uintfast32_t f = regbase::normal)
+ { return set_expression(p.data(), p.data() + p.size(), f); }
+
+ template <class ST, class SA>
+ reg_expression(const __JM_STD::basic_string<charT, ST, SA>& p, jm_uintfast32_t f = regbase::normal, const Allocator& a = Allocator())
+ : data(a), pkmp(0) { set_expression(p, f); }
+
+#elif !defined(JM_NO_STRING_DEF_ARGS)
+ unsigned int RE_CALL set_expression(const __JM_STD::basic_string<charT>& p, jm_uintfast32_t f = regbase::normal)
+ { return set_expression(p.data(), p.data() + p.size(), f); }
+
+ reg_expression(const __JM_STD::basic_string<charT>& p, jm_uintfast32_t f = regbase::normal, const Allocator& a = Allocator())
+ : data(a), pkmp(0) { set_expression(p, f); }
+
+#endif
+
+
+ bool RE_CALL operator==(const reg_expression&);
+ bool RE_CALL operator<(const reg_expression&);
+ alloc_type RE_CALL allocator()const;
+ const charT* RE_CALL expression()const { return _expression; }
+ unsigned RE_CALL mark_count()const { return marks; }
+
+#if !defined(JM_NO_TEMPLATE_FRIEND) && (!defined(JM_NO_TEMPLATE_SWITCH_MERGE) || defined(JM_NO_NAMESPACES))
+#if 0
+ template <class Predicate, class I, class charT, class traits, class A, class A2>
+ friend unsigned int reg_grep2(Predicate foo, I first, I last, const reg_expression<charT, traits, A>& e, unsigned flags, A2 a);
+
+ template <class I, class A, class charT, class traits, class A2>
+ friend bool query_match(I first, I last, reg_match<I, A>& m, const reg_expression<charT, traits, A2>& e, unsigned flags);
+
+ template <class I, class A, class charT, class traits, class A2>
+ friend bool query_match_aux(I first, I last, reg_match<I, A>& m, const reg_expression<charT, traits, A2>& e,
+ unsigned flags, __priv_match_data<I, A>& pd, I* restart);
+
+ template <class I, class A, class charT, class traits, class A2>
+ friend bool reg_search(I first, I last, reg_match<I, A>& m, const reg_expression<charT, traits, A2>& e, unsigned flags);
+private:
+#endif
+#endif
+
+ int RE_CALL repeat_count() const { return repeats; }
+ unsigned int RE_CALL restart_type()const { return _restart_type; }
+ const re_syntax_base* RE_CALL first()const { return (const re_syntax_base*)data.data(); }
+ const unsigned char* RE_CALL get_map()const { return startmap; }
+ unsigned int RE_CALL leading_length()const { return _leading_len; }
+ const kmp_info<charT>* get_kmp()const { return pkmp; }
+ static bool RE_CALL can_start(charT c, const unsigned char* __map, unsigned char mask, const __wide_type&);
+ static bool RE_CALL can_start(charT c, const unsigned char* __map, unsigned char mask, const __narrow_type&);
+};
+
+#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
+} // namespace
+#endif
+
+
+//
+// class reg_match and reg_match_base
+// handles what matched where
+
+template <class iterator>
+struct sub_match
+{
+ iterator first;
+ iterator second;
+ bool matched;
+#ifndef JM_NO_MEMBER_TEMPLATES
+ template <class charT, class traits, class Allocator>
+ operator __JM_STD::basic_string<charT, traits, Allocator> ()const;
+#elif !defined(JM_NO_STRING_DEF_ARGS)
+ operator __JM_STD::basic_string<char> ()const;
+ operator __JM_STD::basic_string<wchar_t> ()const;
+#endif
+ operator int()const;
+ operator unsigned int()const;
+ operator short()const
+ {
+ return (short)(int)(*this);
+ }
+ operator unsigned short()const
+ {
+ return (unsigned short)(unsigned int)(*this);
+ }
+ sub_match() { matched = false; }
+ sub_match(iterator i) : first(i), second(i), matched(false) {}
+};
+
+#ifndef JM_NO_MEMBER_TEMPLATES
+template <class iterator>
+template <class charT, class traits, class Allocator>
+sub_match<iterator>::operator __JM_STD::basic_string<charT, traits, Allocator> ()const
+{
+#if !defined(JM_NO_EXCEPTIONS) && !defined(JM_NO_TYPEINFO)
+ if(typeid(charT) != typeid(*first))
+ throw __JM_STD::bad_cast();
+#endif
+ __JM_STD::basic_string<charT, traits, Allocator> result;
+ iterator i = first;
+ while(i != second)
+ {
+ result.append(1, *i);
+ ++i;
+ }
+ return result;
+}
+#elif !defined(JM_NO_STRING_DEF_ARGS)
+template <class iterator>
+sub_match<iterator>::operator __JM_STD::basic_string<char> ()const
+{
+#if !defined(JM_NO_EXCEPTIONS) && !defined(JM_NO_TYPEINFO)
+ if(typeid(char) != typeid(*first))
+ throw __JM_STD::bad_cast();
+#endif
+ __JM_STD::basic_string<char> result;
+ iterator i = first;
+ while(i != second)
+ {
+ result.append(1, *i);
+ ++i;
+ }
+ return result;
+}
+template <class iterator>
+sub_match<iterator>::operator __JM_STD::basic_string<wchar_t> ()const
+{
+#if !defined(JM_NO_EXCEPTIONS) && !defined(JM_NO_TYPEINFO)
+ if(typeid(wchar_t) != typeid(*first))
+ throw __JM_STD::bad_cast();
+#endif
+ __JM_STD::basic_string<wchar_t> result;
+ iterator i = first;
+ while(i != second)
+ {
+ result.append(1, *i);
+ ++i;
+ }
+ return result;
+}
+#endif
+template <class iterator>
+sub_match<iterator>::operator int()const
+{
+ iterator i = first;
+ int neg = 1;
+ if((i != second) && (*i == '-'))
+ {
+ neg = -1;
+ ++i;
+ }
+ neg *= (int)re_toi(i, second, 10 MAYBE_PASS_LOCALE(__JM_STD::locale()));
+#if !defined(JM_NO_EXCEPTIONS) && !defined(JM_NO_TYPEINFO)
+ if(i != second)
+ {
+ throw __JM_STD::bad_cast();
+ }
+#endif
+ return neg;
+}
+template <class iterator>
+sub_match<iterator>::operator unsigned int()const
+{
+ iterator i = first;
+ unsigned int result = (int)re_toi(i, second, 10 MAYBE_PASS_LOCALE(__JM_STD::locale()));
+#if !defined(JM_NO_EXCEPTIONS) && !defined(JM_NO_TYPEINFO)
+ if(i != second)
+ {
+ throw __JM_STD::bad_cast();
+ }
+#endif
+ return result;
+}
+
+
+template <class iterator, class Allocator JM_DEF_ALLOC_PARAM(iterator) >
+class reg_match_base
+{
+public:
+ typedef Allocator alloc_type;
+ typedef typename REBIND_TYPE(iterator, Allocator)::size_type size_type;
+ typedef JM_MAYBE_TYPENAME REBIND_TYPE(char, Allocator) c_alloc;
+ typedef iterator value_type;
+
+protected:
+ struct reference : public c_alloc
+ {
+ unsigned int cmatches;
+ unsigned count;
+ sub_match<iterator> head, tail, null;
+ unsigned int lines;
+ iterator line_pos;
+ reference(const Allocator& a) : c_alloc(a) { }
+ };
+
+ reference* ref;
+
+ void RE_CALL cow();
+
+ // protected contructor for derived class...
+ reg_match_base(bool){}
+ void RE_CALL free();
+
+public:
+
+ reg_match_base(const Allocator& a = Allocator());
+
+ reg_match_base(const reg_match_base& m)
+ {
+ ref = m.ref;
+ ++(ref->count);
+ }
+
+ reg_match_base& RE_CALL operator=(const reg_match_base& m);
+
+ ~reg_match_base()
+ {
+ free();
+ }
+
+ size_type RE_CALL size()const
+ {
+ return ref->cmatches;
+ }
+
+ const sub_match<iterator>& RE_CALL operator[](int n) const
+ {
+ if((n >= 0) && ((unsigned int)n < ref->cmatches))
+ return *(sub_match<iterator>*)((char*)ref + sizeof(reference) + sizeof(sub_match<iterator>)*n);
+ return (n == -1) ? ref->head : (n == -2) ? ref->tail : ref->null;
+ }
+
+ Allocator RE_CALL allocator()const;
+
+ size_t RE_CALL length()const
+ {
+ jm_assert(ref->cmatches);
+ size_t n = 0;
+ JM_DISTANCE(((sub_match<iterator>*)(ref+1))->first, ((sub_match<iterator>*)(ref+1))->second, n);
+ return n;
+ }
+
+ unsigned int RE_CALL line()const
+ {
+ return ref->lines;
+ }
+
+ iterator RE_CALL line_start()const
+ {
+ return ref->line_pos;
+ }
+
+ void swap(reg_match_base& that)
+ {
+ reference* t = that.ref;
+ that.ref = ref;
+ ref = t;
+ }
+
+ friend class reg_match<iterator, Allocator>;
+#if !defined(JM_NO_TEMPLATE_FRIEND) && (!defined(JM_NO_TEMPLATE_SWITCH_MERGE) || defined(JM_NO_NAMESPACES))
+private:
+ template <class Predicate, class I, class charT, class traits, class A, class A2>
+ friend unsigned int reg_grep2(Predicate foo, I first, I last, const reg_expression<charT, traits, A>& e, unsigned flags, A2 a);
+
+ template <class I, class A, class charT, class traits, class A2>
+ friend bool query_match(I first, I last, reg_match<I, A>& m, const reg_expression<charT, traits, A2>& e, unsigned flags);
+
+ template <class I, class A, class charT, class traits, class A2>
+ friend bool query_match_aux(I first, I last, reg_match<I, A>& m, const reg_expression<charT, traits, A2>& e,
+ unsigned flags, __priv_match_data<I, A>& pd, I* restart);
+
+ template <class I, class A, class charT, class traits, class A2>
+ friend bool reg_search(I first, I last, reg_match<I, A>& m, const reg_expression<charT, traits, A2>& e, unsigned flags);
+#endif
+ void RE_CALL set_size(size_type n);
+ void RE_CALL set_size(size_type n, iterator i, iterator j);
+ void RE_CALL maybe_assign(const reg_match_base& m);
+ void RE_CALL init_fail(iterator i, iterator j);
+
+ void RE_CALL set_first(iterator i)
+ {
+ cow();
+ ((sub_match<iterator>*)(ref+1))->first = i;
+ ref->head.second = i;
+ ref->head.matched = (ref->head.first == ref->head.second) ? false : true;
+ }
+
+ void RE_CALL set_first(iterator i, size_t pos)
+ {
+ cow();
+ ((sub_match<iterator>*)((char*)ref + sizeof(reference) + sizeof(sub_match<iterator>) * pos))->first = i;
+ if(pos == 0)
+ {
+ ref->head.second = i;
+ ref->head.matched = (ref->head.first == ref->head.second) ? false : true;
+ }
+ }
+
+ void RE_CALL set_second(iterator i)
+ {
+ cow();
+ ((sub_match<iterator>*)(ref+1))->second = i;
+ ((sub_match<iterator>*)(ref+1))->matched = true;
+ ref->tail.first = i;
+ ref->tail.matched = (ref->tail.first == ref->tail.second) ? false : true;
+ }
+
+ void RE_CALL set_second(iterator i, size_t pos)
+ {
+ cow();
+ ((sub_match<iterator>*)((char*)ref + sizeof(reference) + sizeof(sub_match<iterator>) * pos))->second = i;
+ ((sub_match<iterator>*)((char*)ref + sizeof(reference) + sizeof(sub_match<iterator>) * pos))->matched = true;
+ if(pos == 0)
+ {
+ ref->tail.first = i;
+ ref->tail.matched = (ref->tail.first == ref->tail.second) ? false : true;
+ }
+ }
+
+ void RE_CALL set_line(unsigned int i, iterator pos)
+ {
+ ref->lines = i;
+ ref->line_pos = pos;
+ }
+};
+
+template <class iterator, class Allocator>
+reg_match_base<iterator, Allocator>::reg_match_base(const Allocator& a)
+{
+ ref = (reference*)c_alloc(a).allocate(sizeof(sub_match<iterator>) + sizeof(reference));
+#ifndef JM_NO_EXCEPTIONS
+ try
+ {
+#endif
+ new (ref) reference(a);
+ ref->cmatches = 1;
+ ref->count = 1;
+ // construct the sub_match<iterator>:
+#ifndef JM_NO_EXCEPTIONS
+ try
+ {
+#endif
+ new ((sub_match<iterator>*)(ref+1)) sub_match<iterator>();
+#ifndef JM_NO_EXCEPTIONS
+ }
+ catch(...)
+ {
+ jm_destroy(ref);
+ throw;
+ }
+#endif
+#ifndef JM_NO_EXCEPTIONS
+ }
+ catch(...)
+ {
+ c_alloc(a).deallocate((char*)(void*)ref, sizeof(sub_match<iterator>) + sizeof(reference));
+ throw;
+ }
+#endif
+}
+
+template <class iterator, class Allocator>
+Allocator RE_CALL reg_match_base<iterator, Allocator>::allocator()const
+{
+ return *((c_alloc*)ref);
+}
+
+template <class iterator, class Allocator>
+inline reg_match_base<iterator, Allocator>& RE_CALL reg_match_base<iterator, Allocator>::operator=(const reg_match_base<iterator, Allocator>& m)
+{
+ if(ref != m.ref)
+ {
+ free();
+ ref = m.ref;
+ ++(ref->count);
+ }
+ return *this;
+}
+
+
+template <class iterator, class Allocator>
+void RE_CALL reg_match_base<iterator, Allocator>::free()
+{
+ if(--(ref->count) == 0)
+ {
+ c_alloc a(*ref);
+ sub_match<iterator>* p1, *p2;
+ p1 = (sub_match<iterator>*)(ref+1);
+ p2 = p1 + ref->cmatches;
+ while(p1 != p2)
+ {
+ jm_destroy(p1);
+ ++p1;
+ }
+ jm_destroy(ref);
+ a.deallocate((char*)(void*)ref, sizeof(sub_match<iterator>) * ref->cmatches + sizeof(reference));
+ }
+}
+
+template <class iterator, class Allocator>
+void RE_CALL reg_match_base<iterator, Allocator>::set_size(size_type n)
+{
+ if(ref->cmatches != n)
+ {
+ reference* newref = (reference*)ref->allocate(sizeof(sub_match<iterator>) * n + sizeof(reference));
+#ifndef JM_NO_EXCEPTIONS
+ try
+ {
+#endif
+ new (newref) reference(*ref);
+ newref->count = 1;
+ newref->cmatches = n;
+ sub_match<iterator>* p1, *p2;
+ p1 = (sub_match<iterator>*)(newref+1);
+ p2 = p1 + newref->cmatches;
+#ifndef JM_NO_EXCEPTIONS
+ try
+ {
+#endif
+ while(p1 != p2)
+ {
+ new (p1) sub_match<iterator>();
+ ++p1;
+ }
+ free();
+#ifndef JM_NO_EXCEPTIONS
+ }
+ catch(...)
+ {
+ p2 = (sub_match<iterator>*)(newref+1);
+ while(p2 != p1)
+ {
+ jm_destroy(p2);
+ ++p2;
+ }
+ jm_destroy(ref);
+ throw;
+ }
+#endif
+ ref = newref;
+#ifndef JM_NO_EXCEPTIONS
+ }
+ catch(...)
+ {
+ ref->deallocate((char*)(void*)newref, sizeof(sub_match<iterator>) * n + sizeof(reference));
+ throw;
+ }
+#endif
+ }
+}
+
+template <class iterator, class Allocator>
+void RE_CALL reg_match_base<iterator, Allocator>::set_size(size_type n, iterator i, iterator j)
+{
+ if(ref->cmatches != n)
+ {
+ reference* newref = (reference*)ref->allocate(sizeof(sub_match<iterator>) * n + sizeof(reference));;
+#ifndef JM_NO_EXCEPTIONS
+ try{
+#endif
+ new (newref) reference(*ref);
+ newref->count = 1;
+ newref->cmatches = n;
+ sub_match<iterator>* p1, *p2;
+ p1 = (sub_match<iterator>*)(newref+1);
+ p2 = p1 + newref->cmatches;
+#ifndef JM_NO_EXCEPTIONS
+ try
+ {
+#endif
+ while(p1 != p2)
+ {
+ new (p1) sub_match<iterator>(j);
+ ++p1;
+ }
+ free();
+#ifndef JM_NO_EXCEPTIONS
+ }
+ catch(...)
+ {
+ p2 = (sub_match<iterator>*)(newref+1);
+ while(p2 != p1)
+ {
+ jm_destroy(p2);
+ ++p2;
+ }
+ jm_destroy(ref);
+ throw;
+ }
+#endif
+ ref = newref;
+#ifndef JM_NO_EXCEPTIONS
+ }
+ catch(...)
+ {
+ ref->deallocate((char*)(void*)newref, sizeof(sub_match<iterator>) * n + sizeof(reference));
+ throw;
+ }
+#endif
+ }
+ else
+ {
+ cow();
+ // set iterators to be i, matched to false:
+ sub_match<iterator>* p1, *p2;
+ p1 = (sub_match<iterator>*)(ref+1);
+ p2 = p1 + ref->cmatches;
+ while(p1 != p2)
+ {
+ p1->first = j;
+ p1->second = j;
+ p1->matched = false;
+ ++p1;
+ }
+ }
+ ref->head.first = i;
+ ref->tail.second = j;
+ ref->head.matched = ref->tail.matched = true;
+ ref->null.first = ref->null.second = j;
+ ref->null.matched = false;
+}
+
+template <class iterator, class Allocator>
+inline void RE_CALL reg_match_base<iterator, Allocator>::init_fail(iterator i, iterator j)
+{
+ set_size(ref->cmatches, i, j);
+}
+
+template <class iterator, class Allocator>
+void RE_CALL reg_match_base<iterator, Allocator>::maybe_assign(const reg_match_base<iterator, Allocator>& m)
+{
+ sub_match<iterator>* p1, *p2;
+ p1 = (sub_match<iterator>*)(ref+1);
+ p2 = (sub_match<iterator>*)(m.ref+1);
+ unsigned int len1, len2;
+ unsigned int i;
+ for(i = 0; i < ref->cmatches; ++i)
+ {
+ len1 = len2 = 0;
+ JM_DISTANCE(p1->first, p1->second, len1);
+ JM_DISTANCE(p2->first, p2->second, len2);
+ if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))
+ break;
+ if((p1->matched == true) && (p2->matched == false))
+ return;
+ ++p1;
+ ++p2;
+ }
+ if(i == ref->cmatches)
+ return;
+ if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )
+ *this = m;
+}
+
+template <class iterator, class Allocator>
+void RE_CALL reg_match_base<iterator, Allocator>::cow()
+{
+ if(ref->count > 1)
+ {
+ reference* newref = (reference*)ref->allocate(sizeof(sub_match<iterator>) * ref->cmatches + sizeof(reference));
+#ifndef JM_NO_EXCEPTIONS
+ try{
+#endif
+ new (newref) reference(*ref);
+ newref->count = 1;
+ sub_match<iterator>* p1, *p2, *p3;
+ p1 = (sub_match<iterator>*)(newref+1);
+ p2 = p1 + newref->cmatches;
+ p3 = (sub_match<iterator>*)(ref+1);
+#ifndef JM_NO_EXCEPTIONS
+ try{
+#endif
+ while(p1 != p2)
+ {
+ new (p1) sub_match<iterator>(*p3);
+ ++p1;
+ ++p3;
+ }
+#ifndef JM_NO_EXCEPTIONS
+ }
+ catch(...)
+ {
+ p2 = (sub_match<iterator>*)(newref+1);
+ while(p2 != p1)
+ {
+ jm_destroy(p2);
+ ++p2;
+ }
+ jm_destroy(ref);
+ throw;
+ }
+#endif
+ --(ref->count);
+ ref = newref;
+#ifndef JM_NO_EXCEPTIONS
+ }
+ catch(...)
+ {
+ ref->deallocate((char*)(void*)newref, sizeof(sub_match<iterator>) * ref->cmatches + sizeof(reference));
+ throw;
+ }
+#endif
+ }
+}
+
+//
+// class reg_match
+// encapsulates reg_match_base, does a deep copy rather than
+// reference counting to ensure thread safety when copying
+// other reg_match instances
+
+template <class iterator, class Allocator>
+class reg_match : public reg_match_base<iterator, Allocator>
+{
+public:
+ reg_match(const Allocator& a = Allocator())
+ : reg_match_base<iterator, Allocator>(a){}
+
+ reg_match(const reg_match_base<iterator, Allocator>& m)
+ : reg_match_base<iterator, Allocator>(m){}
+
+ reg_match& operator=(const reg_match_base<iterator, Allocator>& m)
+ {
+ // shallow copy
+ reg_match_base<iterator, Allocator>::operator=(m);
+ return *this;
+ }
+
+ reg_match(const reg_match& m);
+ reg_match& operator=(const reg_match& m);
+
+};
+
+template <class iterator, class Allocator>
+reg_match<iterator, Allocator>::reg_match(const reg_match<iterator, Allocator>& m)
+ : reg_match_base<iterator, Allocator>(false)
+{
+ reg_match_base<iterator, Allocator>::ref = (typename reg_match_base<iterator, Allocator>::reference *)m.ref->allocate(sizeof(sub_match<iterator>) * m.ref->cmatches + sizeof(typename reg_match_base<iterator, Allocator>::reference));
+#ifndef JM_NO_EXCEPTIONS
+ try{
+#endif
+ new (reg_match_base<iterator, Allocator>::ref) typename reg_match_base<iterator, Allocator>::reference(*m.ref);
+ reg_match_base<iterator, Allocator>::ref->count = 1;
+ sub_match<iterator>* p1, *p2, *p3;
+ p1 = (sub_match<iterator>*)(reg_match_base<iterator, Allocator>::ref+1);
+ p2 = p1 + reg_match_base<iterator, Allocator>::ref->cmatches;
+ p3 = (sub_match<iterator>*)(m.ref+1);
+#ifndef JM_NO_EXCEPTIONS
+ try{
+#endif
+ while(p1 != p2)
+ {
+ new (p1) sub_match<iterator>(*p3);
+ ++p1;
+ ++p3;
+ }
+#ifndef JM_NO_EXCEPTIONS
+ }
+ catch(...)
+ {
+ p2 = (sub_match<iterator>*)(reg_match_base<iterator, Allocator>::ref+1);
+ while(p2 != p1)
+ {
+ jm_destroy(p2);
+ ++p2;
+ }
+ jm_destroy(ref);
+ throw;
+ }
+ }
+ catch(...)
+ {
+ m.ref->deallocate((char*)(void*)reg_match_base<iterator, Allocator>::ref, sizeof(sub_match<iterator>) * m.ref->cmatches + sizeof(typename reg_match_base<iterator, Allocator>::reference));
+ throw;
+ }
+#endif
+}
+
+template <class iterator, class Allocator>
+reg_match<iterator, Allocator>& reg_match<iterator, Allocator>::operator=(const reg_match<iterator, Allocator>& m)
+{
+ reg_match<iterator, Allocator> t(m);
+ this->swap(t);
+ return *this;
+}
+
+
+template <class iterator, class charT, class traits_type, class Allocator>
+iterator RE_CALL re_is_set_member(iterator next,
+ iterator last,
+ re_set_long* set,
+ const reg_expression<charT, traits_type, Allocator>& e);
+
+JM_END_NAMESPACE // namespace regex
+
+#include <jm/regcomp.h>
+
+JM_NAMESPACE(__JM)
+
+typedef reg_expression<char, char_regex_traits<char>, JM_DEF_ALLOC(char)> regex;
+#ifndef JM_NO_WCSTRING
+typedef reg_expression<wchar_t, char_regex_traits<wchar_t>, JM_DEF_ALLOC(wchar_t)> wregex;
+#endif
+
+typedef reg_match<const char*, regex::alloc_type> cmatch;
+#ifndef JM_NO_WCSTRING
+typedef reg_match<const wchar_t*, wregex::alloc_type> wcmatch;
+#endif
+
+JM_END_NAMESPACE // namespace regex
+
+#include <jm/regmatch.h>
+#include <jm/regfmt.h>
+
+#if !defined(JM_NO_NAMESPACES) && !defined(JM_NO_USING)
+
+#ifndef JM_NO_EXCEPTIONS
+using __JM::bad_expression;
+#endif
+using __JM::char_regex_traits;
+using __JM::char_regex_traits_i;
+using __JM::regbase;
+using __JM::reg_expression;
+using __JM::reg_match;
+using __JM::reg_match_base;
+using __JM::sub_match;
+using __JM::regex;
+using __JM::cmatch;
+#ifndef JM_NO_WCSTRING
+using __JM::wregex;
+using __JM::wcmatch;
+#endif
+using __JM::query_match;
+using __JM::reg_search;
+using __JM::reg_grep;
+using __JM::reg_format;
+using __JM::reg_merge;
+using __JM::jm_def_alloc;
+
+#endif
+
+#endif // __cplusplus
+
+#endif // include
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/utils/tfstats/regexp/include/jm/regfac.h b/utils/tfstats/regexp/include/jm/regfac.h
new file mode 100644
index 0000000..fe45c94
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/regfac.h
@@ -0,0 +1,168 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE regfac.h
+ * VERSION 2.12
+ */
+
+#ifndef REGFAC_H
+#define REGFAC_H
+
+#ifndef JM_CFG_H
+#include <jm/jm_cfg.h>
+#endif
+
+#ifdef RE_LOCALE_CPP
+
+
+#include <string>
+#include <jm/re_str.h>
+#include <jm/re_cls.h>
+#include <list>
+#include <map>
+
+//
+// class regfacet
+//
+// provides syntax data etc, customised versions
+// can be installed in an instance of std::locale and imbue'd
+// into a reg_expression for per-instance localisation.
+//
+
+JM_NAMESPACE(__JM)
+
+template <class charT>
+class regfacet : public __JM_STD::locale::facet
+{
+public:
+ static __JM_STD::locale::id id;
+ regfacet(unsigned int i = 0);
+ jm_uintfast32_t RE_CALL lookup_classname(const charT* first, const charT* last)const;
+ bool RE_CALL lookup_collatename(re_str<charT>& s, const re_str<charT>& name)const;
+ unsigned int RE_CALL syntax_type(charT)const;
+ void RE_CALL update(const __JM_STD::locale&)const;
+ charT RE_CALL zero()const;
+ charT RE_CALL ten()const;
+
+protected:
+ virtual jm_uintfast32_t RE_CALL do_lookup_classname(const charT* first, const charT* last)const = 0;
+ virtual bool RE_CALL do_lookup_collatename(re_str<charT>& s, const re_str<charT>& name)const = 0;
+ virtual unsigned int RE_CALL do_syntax_type(charT)const = 0;
+ virtual void RE_CALL do_update(const __JM_STD::locale&) = 0;
+
+ // required by Rogue Wave, not part of standard:
+ __JM_STD::locale::id& get_id()const { return id; }
+ ~regfacet(){}
+};
+
+JM_TEMPLATE_SPECIALISE
+class JM_IX_DECL regfacet<char> : public __JM_STD::locale::facet
+{
+public:
+ typedef __JM_STD::messages<char>::string_type string_type;
+private:
+ unsigned char syntax_map[256];
+ string_type name;
+ char _zero, _ten;
+ __JM_STD::map<__JM_STD::string, unsigned long, __JM_STD::less<__JM_STD::string> > classes;
+ __JM_STD::map<re_str<char>, re_str<char>, __JM_STD::less<re_str<char> > > collating_elements;
+ regfacet(const regfacet&);
+
+#ifdef RE_THREADS
+ critical_section cs;
+#endif
+
+public:
+ static __JM_STD::locale::id id;
+ regfacet(unsigned int i = 0);
+ jm_uintfast32_t RE_CALL lookup_classname(const char* first, const char* last)const { return do_lookup_classname(first, last); }
+ bool RE_CALL lookup_collatename(re_str<char>& s, const re_str<char>& name)const { return do_lookup_collatename(s, name); }
+ unsigned int RE_CALL syntax_type(char c)const { return do_syntax_type(c); }
+ void RE_CALL update(const __JM_STD::locale& l)const { const_cast<regfacet<char>*>(this)->do_update(l); }
+ char RE_CALL zero()const { return _zero; }
+ char RE_CALL ten()const { return _ten; }
+
+protected:
+ virtual jm_uintfast32_t RE_CALL do_lookup_classname(const char* first, const char* last)const;
+ virtual bool RE_CALL do_lookup_collatename(re_str<char>& s, const re_str<char>& name)const;
+ virtual unsigned int RE_CALL do_syntax_type(char)const;
+ virtual void RE_CALL do_update(const __JM_STD::locale&);
+
+ // required by Rogue Wave, not part of standard:
+ __JM_STD::locale::id& get_id()const { return id; }
+ ~regfacet();
+
+};
+
+JM_TEMPLATE_SPECIALISE
+class JM_IX_DECL regfacet<wchar_t> : public __JM_STD::locale::facet
+{
+public:
+ typedef __JM_STD::messages<wchar_t>::string_type string_type;
+private:
+ __JM_STD::messages<char>::string_type name;
+
+ struct syntax_map
+ {
+ wchar_t c;
+ unsigned int type;
+ };
+
+ __JM_STD::list<syntax_map> syntax;
+ wchar_t _zero, _ten;
+ __JM_STD::map<__JM_STD::wstring, unsigned long, __JM_STD::less<__JM_STD::wstring> > classes;
+ const __JM_STD::locale* ploc;
+ __JM_STD::map<re_str<wchar_t>, re_str<wchar_t>, __JM_STD::less<re_str<wchar_t> > > collating_elements;
+ regfacet(const regfacet&);
+
+#ifdef RE_THREADS
+ critical_section cs;
+#endif
+
+public:
+ static __JM_STD::locale::id id;
+ regfacet(unsigned int i = 0);
+ jm_uintfast32_t RE_CALL lookup_classname(const wchar_t* first, const wchar_t* last)const { return do_lookup_classname(first, last); }
+ bool RE_CALL lookup_collatename(re_str<wchar_t>& s, const re_str<wchar_t>& name)const { return do_lookup_collatename(s, name); }
+ unsigned int RE_CALL syntax_type(wchar_t c)const { return do_syntax_type(c); }
+ void RE_CALL update(const __JM_STD::locale& l)const { const_cast<regfacet<wchar_t>*>(this)->do_update(l); }
+ wchar_t RE_CALL zero()const { return _zero; }
+ wchar_t RE_CALL ten()const { return _ten; }
+
+protected:
+ virtual jm_uintfast32_t RE_CALL do_lookup_classname(const wchar_t* first, const wchar_t* last)const;
+ virtual bool RE_CALL do_lookup_collatename(re_str<wchar_t>& s, const re_str<wchar_t>& name)const;
+ virtual unsigned int RE_CALL do_syntax_type(wchar_t)const;
+ virtual void RE_CALL do_update(const __JM_STD::locale&);
+
+ // required by Rogue Wave, not part of standard:
+ __JM_STD::locale::id& get_id()const { return id; }
+ ~regfacet();
+
+};
+
+JM_END_NAMESPACE
+
+#endif
+
+#endif
diff --git a/utils/tfstats/regexp/include/jm/regfmt.h b/utils/tfstats/regexp/include/jm/regfmt.h
new file mode 100644
index 0000000..dfe3521
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/regfmt.h
@@ -0,0 +1,565 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE regfmt.h
+ * VERSION 2.12
+ *
+ * Provides formatting output routines for search and replace
+ * operations. Note this is an internal header file included
+ * by regex.h, do not include on its own.
+ */
+
+
+#ifndef REGFMT_H
+#define REGFMT_H
+
+
+JM_NAMESPACE(__JM)
+
+template <class O, class I>
+O RE_CALL re_copy_out(O out, I first, I last)
+{
+ while(first != last)
+ {
+ *out = *first;
+ ++out;
+ ++first;
+ }
+ return out;
+}
+
+template <class charT>
+void RE_CALL re_skip_format(const charT*& fmt
+#ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+#endif
+ )
+{
+ #ifdef JM_NO_TEMPLATE_TYPENAME
+ typedef char_regex_traits<charT> re_traits_type;
+ #else
+ typedef typename char_regex_traits<charT> re_traits_type;
+ #endif
+ unsigned int parens = 0;
+ unsigned int c;
+ while(*fmt)
+ {
+ c = re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l));
+ if((c == syntax_colon) && (parens == 0))
+ {
+ ++fmt;
+ return;
+ }
+ else if(c == syntax_close_bracket)
+ {
+ if(parens == 0)
+ {
+ ++fmt;
+ return;
+ }
+ --parens;
+ }
+ else if(c == syntax_open_bracket)
+ ++parens;
+ else if(c == syntax_slash)
+ {
+ ++fmt;
+ if(*fmt == 0)
+ return;
+ }
+ ++fmt;
+ }
+}
+
+#ifdef JM_NO_OI_ASSIGN
+
+//
+// ugly hack for buggy output iterators
+
+template <class T>
+inline void oi_assign(T* p, T v)
+{
+ jm_destroy(p);
+ jm_construct(p, v);
+}
+
+#else
+
+template <class T>
+inline void oi_assign(T* p, T v)
+{
+ //
+ // if you get a compile time error in here then you either
+ // need to rewrite your output iterator to make it assignable
+ // (as is required by the standard), or define JM_NO_OI_ASSIGN
+ // to use the ugly hack above
+ *p = v;
+}
+
+#endif
+
+#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
+//
+// Ugly ugly hack,
+// template don't merge if they contain switch statements so declare these
+// templates in unnamed namespace (ie with internal linkage), each translation
+// unit then gets its own local copy, it works seemlessly but bloats the app.
+namespace{
+#endif
+
+//
+// algorithm reg_format:
+// takes the result of a match and a format string
+// and merges them to produce a new string which
+// is sent to an OutputIterator,
+// __reg_format_aux does the actual work:
+//
+template <class OutputIterator, class iterator, class Allocator, class charT>
+OutputIterator RE_CALL __reg_format_aux(OutputIterator out,
+ const reg_match<iterator, Allocator>& m,
+ const charT*& fmt,
+ bool isif
+#ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& l
+#endif
+ )
+{
+ #ifdef JM_NO_TEMPLATE_TYPENAME
+ typedef char_regex_traits<charT> re_traits_type;
+ #else
+ typedef typename char_regex_traits<charT> re_traits_type;
+ #endif
+
+ const charT* fmt_end = fmt;
+ while(*fmt_end) ++ fmt_end;
+
+ while(*fmt)
+ {
+ switch(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)))
+ {
+ case syntax_dollar:
+ ++fmt;
+ if(*fmt == 0) // oops trailing $
+ {
+ --fmt;
+ *out = *fmt;
+ ++out;
+ return out;
+ }
+ switch(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)))
+ {
+ case syntax_start_buffer:
+ oi_assign(&out, re_copy_out(out, iterator(m[-1].first), iterator(m[-1].second)));
+ ++fmt;
+ continue;
+ case syntax_end_buffer:
+ oi_assign(&out, re_copy_out(out, iterator(m[-2].first), iterator(m[-2].second)));
+ ++fmt;
+ continue;
+ case syntax_digit:
+ {
+ unsigned int index = re_traits_type::toi(fmt, fmt_end, 10 MAYBE_PASS_LOCALE(l));
+ oi_assign(&out, re_copy_out(out, iterator(m[index].first), iterator(m[index].second)));
+ continue;
+ }
+ }
+ // anything else:
+ if(*fmt == '&')
+ {
+ oi_assign(&out, re_copy_out(out, iterator(m[0].first), iterator(m[0].second)));
+ ++fmt;
+ }
+ else
+ {
+ // probably an error, treat as a literal '$'
+ --fmt;
+ *out = *fmt;
+ ++out;
+ ++fmt;
+ }
+ continue;
+ case syntax_slash:
+ {
+ // escape sequence:
+ charT c;
+ ++fmt;
+ if(*fmt == 0)
+ {
+ --fmt;
+ *out = *fmt;
+ ++out;
+ ++fmt;
+ return out;
+ }
+ switch(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)))
+ {
+ case syntax_a:
+ c = '\a';
+ ++fmt;
+ break;
+ case syntax_f:
+ c = '\f';
+ ++fmt;
+ break;
+ case syntax_n:
+ c = '\n';
+ ++fmt;
+ break;
+ case syntax_r:
+ c = '\r';
+ ++fmt;
+ break;
+ case syntax_t:
+ c = '\t';
+ ++fmt;
+ break;
+ case syntax_v:
+ c = '\v';
+ ++fmt;
+ break;
+ case syntax_x:
+ ++fmt;
+ if(fmt == fmt_end)
+ {
+ *out = *--fmt;
+ ++out;
+ return out;
+ }
+ // maybe have \x{ddd}
+ if(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)) == syntax_open_brace)
+ {
+ ++fmt;
+ if(fmt == fmt_end)
+ {
+ fmt -= 2;
+ *out = *fmt;
+ ++out;
+ ++fmt;
+ continue;
+ }
+ if(re_traits_type::is_class(*fmt, char_class_xdigit MAYBE_PASS_LOCALE(l)) == false)
+ {
+ fmt -= 2;
+ *out = *fmt;
+ ++out;
+ ++fmt;
+ continue;
+ }
+ c = (charT)re_traits_type::toi(fmt, fmt_end, -16 MAYBE_PASS_LOCALE(l));
+ if(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)) != syntax_close_brace)
+ {
+ while(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)) != syntax_slash)
+ --fmt;
+ ++fmt;
+ *out = *fmt;
+ ++out;
+ ++fmt;
+ continue;
+ }
+ ++fmt;
+ break;
+ }
+ else
+ {
+ if(re_traits_type::is_class(*fmt, char_class_xdigit MAYBE_PASS_LOCALE(l)) == false)
+ {
+ --fmt;
+ *out = *fmt;
+ ++out;
+ ++fmt;
+ continue;
+ }
+ c = (charT)re_traits_type::toi(fmt, fmt_end, -16 MAYBE_PASS_LOCALE(l));
+ }
+ break;
+ case syntax_c:
+ ++fmt;
+ if(fmt == fmt_end)
+ {
+ --fmt;
+ *out = *fmt;
+ ++out;
+ return out;
+ }
+ if(((typename re_traits_type::uchar_type)(*fmt) < (typename re_traits_type::uchar_type)'@')
+ || ((typename re_traits_type::uchar_type)(*fmt) > (typename re_traits_type::uchar_type)127) )
+ {
+ --fmt;
+ *out = *fmt;
+ ++out;
+ ++fmt;
+ break;
+ }
+ c = (charT)((typename re_traits_type::uchar_type)(*fmt) - (typename re_traits_type::uchar_type)'@');
+ ++fmt;
+ break;
+ case syntax_e:
+ c = (charT)27;
+ ++fmt;
+ break;
+ case syntax_digit:
+ c = (charT)re_traits_type::toi(fmt, fmt_end, -8 MAYBE_PASS_LOCALE(l));
+ break;
+ default:
+ c = *fmt;
+ ++fmt;
+ }
+ *out = c;
+ continue;
+ }
+ case syntax_open_bracket:
+ ++fmt; // recurse
+ oi_assign(&out, __reg_format_aux(out, m, fmt, false MAYBE_PASS_LOCALE(l)));
+ continue;
+ case syntax_close_bracket:
+ ++fmt; // return from recursion
+ return out;
+ case syntax_colon:
+ if(isif)
+ {
+ ++fmt;
+ return out;
+ }
+ *out = *fmt;
+ ++out;
+ ++fmt;
+ continue;
+ case syntax_question:
+ {
+ ++fmt;
+ if(*fmt == 0)
+ {
+ --fmt;
+ *out = *fmt;
+ ++out;
+ ++fmt;
+ return out;
+ }
+ unsigned int id = re_traits_type::toi(fmt, fmt_end, 10 MAYBE_PASS_LOCALE(l));
+ if(m[id].matched)
+ {
+ oi_assign(&out, __reg_format_aux(out, m, fmt, true MAYBE_PASS_LOCALE(l)));
+ if(re_traits_type::syntax_type(*(fmt-1) MAYBE_PASS_LOCALE(l)) == syntax_colon)
+ re_skip_format(fmt MAYBE_PASS_LOCALE(l));
+ }
+ else
+ {
+ re_skip_format(fmt MAYBE_PASS_LOCALE(l));
+ if(re_traits_type::syntax_type(*(fmt-1) MAYBE_PASS_LOCALE(l)) == syntax_colon)
+ oi_assign(&out, __reg_format_aux(out, m, fmt, true MAYBE_PASS_LOCALE(l)));
+ }
+ return out;
+ }
+ default:
+ *out = *fmt;
+ ++out;
+ ++fmt;
+ }
+ }
+
+ return out;
+}
+
+#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
+} // namespace
+#endif
+
+
+template <class OutputIterator, class iterator, class Allocator, class charT>
+OutputIterator RE_CALL reg_format(OutputIterator out,
+ const reg_match<iterator, Allocator>& m,
+ const charT* fmt
+#ifdef RE_LOCALE_CPP
+ , __JM_STD::locale locale_inst = __JM_STD::locale()
+#endif
+ )
+{
+ //
+ // start by updating the locale:
+ //
+#if defined(RE_LOCALE_C) || defined(RE_LOCALE_W32)
+ static re_initialiser<charT> locale_initialiser;
+ locale_initialiser.update();
+#else
+ if(JM_HAS_FACET(locale_inst, regfacet<charT>) == false)
+ {
+#ifdef _MSC_VER
+ locale_inst = __JM_STD::_ADDFAC(locale_inst, new regfacet<charT>());
+#else
+ locale_inst = __JM_STD::locale(locale_inst, new regfacet<charT>());
+#endif
+ }
+ JM_USE_FACET(locale_inst, regfacet<charT>).update(locale_inst);
+#endif
+ return __reg_format_aux(out, m, fmt, false MAYBE_PASS_LOCALE(locale_inst));
+}
+
+template <class S>
+class string_out_iterator
+{
+ S* out;
+public:
+ string_out_iterator(S& s) : out(&s) {}
+ string_out_iterator& operator++() { return *this; }
+ string_out_iterator& operator++(int) { return *this; }
+ string_out_iterator& operator*() { return *this; }
+ string_out_iterator& operator=(typename S::value_type v)
+ {
+ out->append(1, v);
+ return *this;
+ }
+};
+
+#ifndef JM_NO_STRING_DEF_ARGS
+template <class iterator, class Allocator, class charT>
+__JM_STD::basic_string<charT> RE_CALL reg_format(const reg_match<iterator, Allocator>& m, const charT* fmt
+#ifdef RE_LOCALE_CPP
+ , __JM_STD::locale locale_inst = __JM_STD::locale()
+#endif
+ )
+{
+ __JM_STD::basic_string<charT> result;
+ string_out_iterator<__JM_STD::basic_string<charT> > i(result);
+ reg_format(i, m, fmt MAYBE_PASS_LOCALE(locale_inst));
+ return result;
+}
+#elif !defined(JM_NO_STRING_H)
+template <class iterator, class Allocator>
+__JM_STD::string RE_CALL reg_format(const reg_match<iterator, Allocator>& m, const char* fmt
+#ifdef RE_LOCALE_CPP
+ , __JM_STD::locale locale_inst = __JM_STD::locale()
+#endif
+ )
+{
+ __JM_STD::string result;
+ string_out_iterator<__JM_STD::string> i(result);
+ reg_format(i, m, fmt MAYBE_PASS_LOCALE(locale_inst));
+ return result;
+}
+#endif
+
+
+template <class OutputIterator, class iterator, class charT, class Allocator>
+class merge_out_predicate
+{
+ OutputIterator* out;
+ iterator* last;
+ const charT* fmt;
+ bool copy_none;
+
+#ifdef RE_LOCALE_CPP
+ const __JM_STD::locale& l;
+#endif
+
+public:
+ merge_out_predicate(OutputIterator& o, iterator& pi, const charT* f, bool c
+#ifdef RE_LOCALE_CPP
+ , const __JM_STD::locale& loc
+#endif
+ ) : out(&o), last(&pi), fmt(f), copy_none(c)
+#ifdef RE_LOCALE_CPP
+ , l(loc)
+#endif
+ {}
+
+ ~merge_out_predicate() {}
+ bool RE_CALL operator()(const __JM::reg_match<iterator, Allocator>& m)
+ {
+ const charT* f = fmt;
+ if(copy_none)
+ oi_assign(out, re_copy_out(*out, iterator(m[-1].first), iterator(m[-1].second)));
+ oi_assign(out, __reg_format_aux(*out, m, f, false MAYBE_PASS_LOCALE(l)));
+ *last = m[-2].first;
+ return true;
+ }
+};
+
+
+template <class OutputIterator, class iterator, class traits, class Allocator, class charT>
+OutputIterator RE_CALL reg_merge(OutputIterator out,
+ iterator first,
+ iterator last,
+ const reg_expression<charT, traits, Allocator>& e,
+ const charT* fmt,
+ bool copy = true,
+ unsigned int flags = match_default)
+{
+ //
+ // start by updating the locale:
+ //
+#if defined(RE_LOCALE_C) || defined(RE_LOCALE_W32)
+ static re_initialiser<charT> locale_initialiser;
+ locale_initialiser.update();
+#else
+ __JM_STD::locale locale_inst(e.locale());
+ if(JM_HAS_FACET(locale_inst, regfacet<charT>) == false)
+ {
+#ifdef _MSC_VER
+ locale_inst = __JM_STD::_ADDFAC(locale_inst, new regfacet<charT>());
+#else
+ locale_inst = __JM_STD::locale(locale_inst, new regfacet<charT>());
+#endif
+ }
+ JM_USE_FACET(locale_inst, regfacet<charT>).update(locale_inst);
+#endif
+ iterator l = first;
+ merge_out_predicate<OutputIterator, iterator, charT, Allocator> oi(out, l, fmt, copy MAYBE_PASS_LOCALE(locale_inst));
+ reg_grep(oi, first, last, e, flags);
+ return copy ? re_copy_out(out, l, last) : out;
+}
+
+#ifndef JM_NO_STRING_DEF_ARGS
+template <class traits, class Allocator, class charT>
+__JM_STD::basic_string<charT> RE_CALL reg_merge(const __JM_STD::basic_string<charT>& s,
+ const reg_expression<charT, traits, Allocator>& e,
+ const charT* fmt,
+ bool copy = true,
+ unsigned int flags = match_default)
+{
+ __JM_STD::basic_string<charT> result;
+ string_out_iterator<__JM_STD::basic_string<charT> > i(result);
+ reg_merge(i, s.begin(), s.end(), e, fmt, copy, flags);
+ return result;
+}
+#elif !defined(JM_NO_STRING_H)
+template <class traits, class Allocator>
+__JM_STD::string RE_CALL reg_merge(const __JM_STD::string& s,
+ const reg_expression<char, traits, Allocator>& e,
+ const char* fmt,
+ bool copy = true,
+ unsigned int flags = match_default)
+{
+ __JM_STD::string result;
+ string_out_iterator<__JM_STD::string> i(result);
+ reg_merge(i, s.begin(), s.end(), e, fmt, copy, flags);
+ return result;
+}
+#endif
+
+
+JM_END_NAMESPACE
+
+#endif
+
+
+
diff --git a/utils/tfstats/regexp/include/jm/regmatch.h b/utils/tfstats/regexp/include/jm/regmatch.h
new file mode 100644
index 0000000..8acc0f5
--- /dev/null
+++ b/utils/tfstats/regexp/include/jm/regmatch.h
@@ -0,0 +1,1707 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+/*
+ *
+ * Copyright (c) 1998-9
+ * Dr John Maddock
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Dr John Maddock makes no representations
+ * about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ */
+
+ /*
+ * FILE regmatch.h
+ * VERSION 2.12
+ * regular expression matching algorithms
+ */
+
+
+#ifndef __REGMATCH_H
+#define __REGMATCH_H
+
+
+JM_NAMESPACE(__JM)
+
+template <class iterator, class charT, class traits_type, class Allocator>
+iterator RE_CALL re_is_set_member(iterator next,
+ iterator last,
+ re_set_long* set,
+ const reg_expression<charT, traits_type, Allocator>& e)
+{
+ const charT* p = (const charT*)(set+1);
+ iterator ptr;
+ unsigned int i;
+ bool icase = e.flags() & regbase::icase;
+
+ // try and match a single character, could be a multi-character
+ // collating element...
+ for(i = 0; i < set->csingles; ++i)
+ {
+ ptr = next;
+ while(*p && (ptr != last))
+ {
+ if(traits_type::translate(*ptr, icase MAYBE_PASS_LOCALE(e.locale())) != *p)
+ break;
+ ++p;
+ ++ptr;
+ }
+ if(*p == 0) // if null we've matched
+ return set->isnot ? next : (ptr == next) ? ++next : ptr;
+
+ while(*p)++p;
+ ++p; // skip null
+ }
+
+ charT col = traits_type::translate(*next, icase MAYBE_PASS_LOCALE(e.locale()));
+
+
+ if(set->cranges || set->cequivalents)
+ {
+ re_str<charT> s2(col);
+ re_str<charT> s1;
+ //
+ // try and match a range, NB only a single character can match
+ if(set->cranges)
+ {
+ if(e.flags() & regbase::nocollate)
+ s1 = s2;
+ else
+ traits_type::transform(s1, s2 MAYBE_PASS_LOCALE(e.locale()));
+ for(i = 0; i < set->cranges; ++i)
+ {
+ if(s1 <= p)
+ {
+ while(*p)++p;
+ ++p;
+ if(s1 >= p)
+ return set->isnot ? next : ++next;
+ }
+ else
+ {
+ // skip first string
+ while(*p)++p;
+ ++p;
+ }
+ // skip second string
+ while(*p)++p;
+ ++p;
+ }
+ }
+ //
+ // try and match an equivalence class, NB only a single character can match
+ if(set->cequivalents)
+ {
+ traits_type::transform_primary(s1, s2 MAYBE_PASS_LOCALE(e.locale()));
+ for(i = 0; i < set->cequivalents; ++i)
+ {
+ if(s1 == p)
+ return set->isnot ? next : ++next;
+ // skip string
+ while(*p)++p;
+ ++p;
+ }
+ }
+ }
+
+ if(traits_type::is_class(col, set->cclasses MAYBE_PASS_LOCALE(e.locale())) == true)
+ return set->isnot ? next : ++next;
+ return set->isnot ? ++next : next;
+}
+
+template <class iterator, class Allocator>
+class __priv_match_data
+{
+public:
+ typedef JM_MAYBE_TYPENAME REBIND_TYPE(int, Allocator) i_alloc;
+ typedef JM_MAYBE_TYPENAME REBIND_TYPE(iterator, Allocator) it_alloc;
+
+ reg_match_base<iterator, Allocator> temp_match;
+ // failure stacks:
+ jstack<reg_match_base<iterator, Allocator>, Allocator> matches;
+ jstack<iterator, Allocator> prev_pos;
+ jstack<const re_syntax_base*, Allocator> prev_record;
+ jstack<int, Allocator> prev_acc;
+ int* accumulators;
+ unsigned int caccumulators;
+ iterator* loop_starts;
+
+ __priv_match_data(const reg_match_base<iterator, Allocator>&);
+
+ ~__priv_match_data()
+ {
+ free();
+ }
+ void free();
+ void set_accumulator_size(unsigned int size);
+ int* get_accumulators()
+ {
+ return accumulators;
+ }
+ iterator* get_loop_starts()
+ {
+ return loop_starts;
+ }
+};
+
+template <class iterator, class Allocator>
+__priv_match_data<iterator, Allocator>::__priv_match_data(const reg_match_base<iterator, Allocator>& m)
+ : temp_match(m), matches(64, m.allocator()), prev_pos(64, m.allocator()), prev_record(64, m.allocator())
+{
+ accumulators = 0;
+ caccumulators = 0;
+ loop_starts = 0;
+}
+
+template <class iterator, class Allocator>
+void __priv_match_data<iterator, Allocator>::set_accumulator_size(unsigned int size)
+{
+ if(size > caccumulators)
+ {
+ free();
+ caccumulators = size;
+ accumulators = i_alloc(temp_match.allocator()).allocate(caccumulators);
+ loop_starts = it_alloc(temp_match.allocator()).allocate(caccumulators);
+ for(unsigned i = 0; i < caccumulators; ++i)
+ new (loop_starts + i) iterator();
+ }
+}
+
+template <class iterator, class Allocator>
+void __priv_match_data<iterator, Allocator>::free()
+{
+ if(caccumulators)
+ {
+ //REBIND_INSTANCE(int, Allocator, temp_match.allocator()).deallocate(accumulators, caccumulators);
+ i_alloc temp1(temp_match.allocator());
+ temp1.deallocate(accumulators, caccumulators);
+ for(unsigned i = 0; i < caccumulators; ++i)
+ jm_destroy(loop_starts + i);
+ //REBIND_INSTANCE(iterator, Allocator, temp_match.allocator()).deallocate(loop_starts, caccumulators);
+ it_alloc temp2(temp_match.allocator());
+ temp2.deallocate(loop_starts, caccumulators);
+ }
+}
+
+//
+// proc query_match
+// returns true if the specified regular expression matches
+// at position first. Fills in what matched in m.
+//
+template <class iterator, class Allocator, class charT, class traits, class Allocator2>
+bool query_match(iterator first, iterator last, reg_match<iterator, Allocator>& m, const reg_expression<charT, traits, Allocator2>& e, unsigned flags = match_default)
+{
+ // prepare m for failure:
+ if((flags & match_init) == 0)
+ {
+ m.set_size(e.mark_count(), first, last);
+ }
+ __priv_match_data<iterator, Allocator> pd(m);
+ iterator restart;
+ return query_match_aux(first, last, m, e, flags, pd, &restart);
+}
+
+//
+// query_match convenience interfaces:
+#ifndef JM_NO_PARTIAL_FUNC_SPEC
+//
+// this isn't really a partial specialisation, but template function
+// overloading - if the compiler doesn't support partial specialisation
+// then it really won't support this either:
+template <class charT, class Allocator, class traits, class Allocator2>
+inline bool query_match(const charT* str,
+ reg_match<const charT*, Allocator>& m,
+ const reg_expression<charT, traits, Allocator2>& e,
+ unsigned flags = match_default)
+{
+ return query_match(str, str + traits::length(str), m, e, flags);
+}
+
+#ifndef JM_NO_STRING_H
+template <class ST, class SA, class Allocator, class charT, class traits, class Allocator2>
+inline bool query_match(const __JM_STD::basic_string<charT, ST, SA>& s,
+ reg_match<typename __JM_STD::basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
+ const reg_expression<charT, traits, Allocator2>& e,
+ unsigned flags = match_default)
+{
+ return query_match(s.begin(), s.end(), m, e, flags);
+}
+#endif
+#else // partial specialisation
+inline bool query_match(const char* str,
+ cmatch& m,
+ const regex& e,
+ unsigned flags = match_default)
+{
+ return query_match(str, str + regex::traits_type::length(str), m, e, flags);
+}
+#ifndef JM_NO_WCSTRING
+inline bool query_match(const wchar_t* str,
+ wcmatch& m,
+ const wregex& e,
+ unsigned flags = match_default)
+{
+ return query_match(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+#endif
+#ifndef JM_NO_STRING_H
+inline bool query_match(const __JM_STD::string& s,
+ reg_match<__JM_STD::string::const_iterator, regex::alloc_type>& m,
+ const regex& e,
+ unsigned flags = match_default)
+{
+ return query_match(s.begin(), s.end(), m, e, flags);
+}
+#if !defined(JM_NO_STRING_DEF_ARGS) && !defined(JM_NO_WCSTRING)
+inline bool query_match(const __JM_STD::basic_string<wchar_t>& s,
+ reg_match<__JM_STD::basic_string<wchar_t>::const_iterator, wregex::alloc_type>& m,
+ const wregex& e,
+ unsigned flags = match_default)
+{
+ return query_match(s.begin(), s.end(), m, e, flags);
+}
+#endif
+
+#endif
+
+#endif
+
+
+#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
+//
+// Ugly ugly hack,
+// template don't merge if they contain switch statements so declare these
+// templates in unnamed namespace (ie with internal linkage), each translation
+// unit then gets its own local copy, it works seemlessly but bloats the app.
+namespace{
+#endif
+
+template <class iterator, class Allocator, class charT, class traits, class Allocator2>
+bool query_match_aux(iterator first,
+ iterator last,
+ reg_match<iterator, Allocator>& m,
+ const reg_expression<charT, traits, Allocator2>& e,
+ unsigned flags,
+ __priv_match_data<iterator, Allocator>& pd,
+ iterator* restart)
+{
+ if(e.flags() & regbase::failbit)
+ return false;
+
+ typedef typename traits::size_type traits_size_type;
+ typedef typename traits::uchar_type traits_uchar_type;
+ typedef typename is_byte<charT>::width_type width_type;
+
+ #ifdef RE_LOCALE_CPP
+ const __JM_STD::locale& locale_inst = e.locale();
+ #endif
+
+ // declare some local aliases to reduce pointer loads
+ // good optimising compilers should make this unnecessary!!
+ jstack<reg_match_base<iterator, Allocator>, Allocator>& matches = pd.matches;
+ jstack<iterator, Allocator>& prev_pos = pd.prev_pos;
+ jstack<const re_syntax_base*, Allocator>& prev_record = pd.prev_record;
+ jstack<int, Allocator>& prev_acc = pd.prev_acc;
+ reg_match_base<iterator, Allocator>& temp_match = pd.temp_match;
+ temp_match.set_first(first);
+
+ //temp_match.set_size(e.mark_count(), first, last);
+ register const re_syntax_base* ptr = e.first();
+ bool match_found = false;
+ bool need_push_match = (e.mark_count() > 1);
+ int cur_acc = -1; // no active accumulator
+ pd.set_accumulator_size(e.repeat_count());
+ int* accumulators = pd.get_accumulators();
+ iterator* start_loop = pd.get_loop_starts();
+ int k; // for loops
+ bool icase = e.flags() & regbase::icase;
+ *restart = first;
+ iterator base = first;
+
+ // prepare m for failure:
+ /*
+ if((flags & match_init) == 0)
+ {
+ m.init_fail(first, last);
+ } */
+
+ retry:
+
+ while(first != last)
+ {
+ jm_assert(ptr);
+ switch(ptr->type)
+ {
+ case syntax_element_match:
+ match_jump:
+ {
+ // match found, save then fallback in case we missed a
+ // longer one.
+ if((flags & match_not_null) && (first == temp_match[0].first))
+ goto failure;
+ temp_match.set_second(first);
+ m.maybe_assign(temp_match);
+ match_found = true;
+ if((flags & match_any) || ((first == last) && (need_push_match == false)))
+ {
+ // either we don't care what we match or we've matched
+ // the whole string and can't match anything longer.
+ while(matches.empty() == false)
+ matches.pop();
+ while(prev_pos.empty() == false)
+ prev_pos.pop();
+ while(prev_record.empty() == false)
+ prev_record.pop();
+ while(prev_acc.empty() == false)
+ prev_acc.pop();
+ return true;
+ }
+ }
+ goto failure;
+ case syntax_element_startmark:
+ temp_match.set_first(first, ((re_brace*)ptr)->index);
+ ptr = ptr->next.p;
+ break;
+ case syntax_element_endmark:
+ temp_match.set_second(first, ((re_brace*)ptr)->index);
+ ptr = ptr->next.p;
+ break;
+ case syntax_element_literal:
+ {
+ unsigned int len = ((re_literal*)ptr)->length;
+ charT* what = (charT*)(((re_literal*)ptr) + 1);
+ //
+ // compare string with what we stored in
+ // our records:
+ for(unsigned int i = 0; i < len; ++i, ++first)
+ {
+ if((first == last) || (traits::translate(*first, icase MAYBE_PASS_LOCALE(locale_inst)) != what[i]))
+ goto failure;
+ }
+ ptr = ptr->next.p;
+ break;
+ }
+ case syntax_element_start_line:
+ outer_line_check:
+ if(first == temp_match[0].first)
+ {
+ // we're at the start of the buffer
+ if(flags & match_prev_avail)
+ {
+ inner_line_check:
+ // check the previous value even though its before
+ // the start of our "buffer".
+ iterator t(first);
+ --t;
+ if(traits::is_separator(*t) && !((*t == '\r') && (*first == '\n')) )
+ {
+ ptr = ptr->next.p;
+ continue;
+ }
+ goto failure;
+ }
+ if((flags & match_not_bol) == 0)
+ {
+ ptr = ptr->next.p;
+ continue;
+ }
+ goto failure;
+ }
+ // we're in the middle of the string
+ goto inner_line_check;
+ case syntax_element_end_line:
+ // we're not yet at the end so *first is always valid:
+ if(traits::is_separator(*first))
+ {
+ if((first != base) || (flags & match_prev_avail))
+ {
+ // check that we're not in the middle of \r\n sequence
+ iterator t(first);
+ --t;
+ if((*t == '\r') && (*first == '\n'))
+ {
+ goto failure;
+ }
+ }
+ ptr = ptr->next.p;
+ continue;
+ }
+ goto failure;
+ case syntax_element_wild:
+ // anything except possibly NULL or \n:
+ if(traits::is_separator(*first))
+ {
+ if(flags & match_not_dot_newline)
+ goto failure;
+ ptr = ptr->next.p;
+ ++first;
+ continue;
+ }
+ if(*first == charT(0))
+ {
+ if(flags & match_not_dot_null)
+ goto failure;
+ ptr = ptr->next.p;
+ ++first;
+ continue;
+ }
+ ptr = ptr->next.p;
+ ++first;
+ break;
+ case syntax_element_word_boundary:
+ {
+ // prev and this character must be opposites:
+ bool b = traits::is_class(*first, char_class_word MAYBE_PASS_LOCALE(locale_inst));
+ if((first == temp_match[0].first) && ((flags & match_prev_avail) == 0))
+ {
+ if(flags & match_not_bow)
+ b ^= true;
+ else
+ b ^= false;
+ }
+ else
+ {
+ --first;
+ b ^= traits::is_class(*first, char_class_word MAYBE_PASS_LOCALE(locale_inst));
+ ++first;
+ }
+ if(b)
+ {
+ ptr = ptr->next.p;
+ continue;
+ }
+ goto failure;
+ }
+ case syntax_element_within_word:
+ // both prev and this character must be char_class_word:
+ if(traits::is_class(*first, char_class_word MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ bool b;
+ if((first == temp_match[0].first) && ((flags & match_prev_avail) == 0))
+ b = false;
+ else
+ {
+ --first;
+ b = traits::is_class(*first, char_class_word MAYBE_PASS_LOCALE(locale_inst));
+ ++first;
+ }
+ if(b)
+ {
+ ptr = ptr->next.p;
+ continue;
+ }
+ }
+ goto failure;
+ case syntax_element_word_start:
+ if((first == temp_match[0].first) && ((flags & match_prev_avail) == 0))
+ {
+ // start of buffer:
+ if(flags & match_not_bow)
+ goto failure;
+ if(traits::is_class(*first, char_class_word MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ ptr = ptr->next.p;
+ continue;
+ }
+ goto failure;
+ }
+ // otherwise inside buffer:
+ if(traits::is_class(*first, char_class_word MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ iterator t(first);
+ --t;
+ if(traits::is_class(*t, char_class_word MAYBE_PASS_LOCALE(locale_inst)) == false)
+ {
+ ptr = ptr->next.p;
+ continue;
+ }
+ }
+ goto failure; // if we fall through to here then we've failed
+ case syntax_element_word_end:
+ if((first == temp_match[0].first) && ((flags & match_prev_avail) == 0))
+ goto failure; // start of buffer can't be end of word
+
+ // otherwise inside buffer:
+ if(traits::is_class(*first, char_class_word MAYBE_PASS_LOCALE(locale_inst)) == false)
+ {
+ iterator t(first);
+ --t;
+ if(traits::is_class(*t, char_class_word MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ ptr = ptr->next.p;
+ continue;
+ }
+ }
+ goto failure; // if we fall through to here then we've failed
+ case syntax_element_buffer_start:
+ if((first != temp_match[0].first) || (flags & match_not_bob))
+ goto failure;
+ // OK match:
+ ptr = ptr->next.p;
+ break;
+ case syntax_element_buffer_end:
+ if((first != last) || (flags & match_not_eob))
+ goto failure;
+ // OK match:
+ ptr = ptr->next.p;
+ break;
+ case syntax_element_backref:
+ {
+ // compare with what we previously matched:
+ iterator i = temp_match[((re_brace*)ptr)->index].first;
+ iterator j = temp_match[((re_brace*)ptr)->index].second;
+ while(i != j)
+ {
+ if((first == last) || (traits::translate(*first, icase MAYBE_PASS_LOCALE(locale_inst)) != traits::translate(*i, icase MAYBE_PASS_LOCALE(locale_inst))))
+ goto failure;
+ ++i;
+ ++first;
+ }
+ ptr = ptr->next.p;
+ break;
+ }
+ case syntax_element_long_set:
+ {
+ // let the traits class do the work:
+ iterator t = re_is_set_member(first, last, (re_set_long*)ptr, e);
+ if(t != first)
+ {
+ ptr = ptr->next.p;
+ first = t;
+ continue;
+ }
+ goto failure;
+ }
+ case syntax_element_set:
+ // lookup character in table:
+ if(((re_set*)ptr)->__map[(traits_uchar_type)traits::translate(*first, icase MAYBE_PASS_LOCALE(locale_inst))])
+ {
+ ptr = ptr->next.p;
+ ++first;
+ continue;
+ }
+ goto failure;
+ case syntax_element_jump:
+ ptr = ((re_jump*)ptr)->alt.p;
+ continue;
+ case syntax_element_alt:
+ {
+ // alt_jump:
+ if(reg_expression<charT, traits, Allocator2>::can_start(*first, ((re_jump*)ptr)->__map, (unsigned char)mask_take, width_type()))
+ {
+ // we can take the first alternative,
+ // see if we need to push next alternative:
+ if(reg_expression<charT, traits, Allocator2>::can_start(*first, ((re_jump*)ptr)->__map, mask_skip, width_type()))
+ {
+ if(need_push_match)
+ matches.push(temp_match);
+ for(k = 0; k <= cur_acc; ++k)
+ prev_pos.push(start_loop[k]);
+ prev_pos.push(first);
+ prev_record.push(ptr);
+ for(k = 0; k <= cur_acc; ++k)
+ prev_acc.push(accumulators[k]);
+ prev_acc.push(cur_acc);
+ }
+ ptr = ptr->next.p;
+ continue;
+ }
+ if(reg_expression<charT, traits, Allocator2>::can_start(*first, ((re_jump*)ptr)->__map, mask_skip, width_type()))
+ {
+ ptr = ((re_jump*)ptr)->alt.p;
+ continue;
+ }
+ goto failure; // neither option is possible
+ }
+ case syntax_element_rep:
+ {
+ // repeater_jump:
+ // if we're moving to a higher id (nested repeats etc)
+ // zero out our accumualtors:
+ if(cur_acc < ((re_repeat*)ptr)->id)
+ {
+ cur_acc = ((re_repeat*)ptr)->id;
+ accumulators[cur_acc] = 0;
+ start_loop[cur_acc] = iterator();
+ }
+
+ cur_acc = ((re_repeat*)ptr)->id;
+
+ if(((re_repeat*)ptr)->leading)
+ *restart = first;
+
+ //charT c = traits::translate(*first MAYBE_PASS_LOCALE(locale_inst));
+
+ // first of all test for special case where this is last element,
+ // if that is the case then repeat as many times as possible:
+
+ if(((re_repeat*)ptr)->alt.p->type == syntax_element_match)
+ {
+ // see if we can take the repeat:
+ if(((unsigned int)accumulators[cur_acc] < ((re_repeat*)ptr)->max)
+ && reg_expression<charT, traits, Allocator2>::can_start(*first, ((re_repeat*)ptr)->__map, mask_take, width_type()))
+ {
+ // push terminating match as fallback:
+ if((unsigned int)accumulators[cur_acc] >= ((re_repeat*)ptr)->min)
+ {
+ if((prev_record.empty() == false) && (prev_record.peek() == ((re_repeat*)ptr)->alt.p))
+ {
+ // we already have the required fallback
+ // don't add any more, just update this one:
+ if(need_push_match)
+ matches.peek() = temp_match;
+ prev_pos.peek() = first;
+ }
+ else
+ {
+ if(need_push_match)
+ matches.push(temp_match);
+ prev_pos.push(first);
+ prev_record.push(((re_repeat*)ptr)->alt.p);
+ }
+ }
+ // move to next item in list:
+ if(first != start_loop[cur_acc])
+ {
+ ++accumulators[cur_acc];
+ ptr = ptr->next.p;
+ start_loop[cur_acc] = first;
+ continue;
+ }
+ goto failure;
+ }
+ // see if we can skip the repeat:
+ if(((unsigned int)accumulators[cur_acc] >= ((re_repeat*)ptr)->min)
+ && reg_expression<charT, traits, Allocator2>::can_start(*first, ((re_repeat*)ptr)->__map, mask_skip, width_type()))
+ {
+ ptr = ((re_repeat*)ptr)->alt.p;
+ continue;
+ }
+ // otherwise fail:
+ goto failure;
+ }
+
+ // see if we can skip the repeat:
+ if(((unsigned int)accumulators[cur_acc] >= ((re_repeat*)ptr)->min)
+ && reg_expression<charT, traits, Allocator2>::can_start(*first, ((re_repeat*)ptr)->__map, mask_skip, width_type()))
+ {
+ // see if we can push failure info:
+ if(((unsigned int)accumulators[cur_acc] < ((re_repeat*)ptr)->max)
+ && reg_expression<charT, traits, Allocator2>::can_start(*first, ((re_repeat*)ptr)->__map, mask_take, width_type()))
+ {
+ // check to see if the last loop matched a NULL string
+ // if so then we really don't want to loop again:
+ if(((unsigned int)accumulators[cur_acc] == ((re_repeat*)ptr)->min)
+ || (first != start_loop[cur_acc]))
+ {
+ if(need_push_match)
+ matches.push(temp_match);
+ prev_pos.push(first);
+ prev_record.push(ptr);
+ for(k = 0; k <= cur_acc; ++k)
+ prev_acc.push(accumulators[k]);
+ //prev_acc.push(cur_acc);
+ }
+ }
+ ptr = ((re_repeat*)ptr)->alt.p;
+ continue;
+ }
+
+ // otherwise see if we can take the repeat:
+ if(((unsigned int)accumulators[cur_acc] < ((re_repeat*)ptr)->max)
+ && reg_expression<charT, traits, Allocator2>::can_start(*first, ((re_repeat*)ptr)->__map, mask_take, width_type()) &&
+ (first != start_loop[cur_acc]))
+ {
+ // move to next item in list:
+ ++accumulators[cur_acc];
+ ptr = ptr->next.p;
+ start_loop[cur_acc] = first;
+ continue;
+ }
+
+ // if we get here then neither option is allowed so fail:
+ goto failure;
+
+ }
+ case syntax_element_combining:
+ if(traits::is_combining(traits::translate(*first, icase MAYBE_PASS_LOCALE(locale_inst))))
+ goto failure;
+ ++first;
+ while((first != last) && traits::is_combining(traits::translate(*first, icase MAYBE_PASS_LOCALE(locale_inst))))++first;
+ ptr = ptr->next.p;
+ continue;
+ case syntax_element_soft_buffer_end:
+ {
+ if(flags & match_not_eob)
+ goto failure;
+ iterator p(first);
+ while((p != last) && traits::is_separator(traits::translate(*first, icase MAYBE_PASS_LOCALE(locale_inst))))++p;
+ if(p != last)
+ goto failure;
+ ptr = ptr->next.p;
+ continue;
+ }
+ case syntax_element_restart_continue:
+ if(first != temp_match[-1].first)
+ goto failure;
+ ptr = ptr->next.p;
+ continue;
+ default:
+ jm_assert(0); // should never get to here!!
+ return false;
+ }
+ }
+
+ //
+ // if we get to here then we've run out of characters to match against,
+ // we could however still have non-character regex items left
+ if(ptr->can_be_null == 0)
+ goto failure;
+ while(true)
+ {
+ jm_assert(ptr);
+ switch(ptr->type)
+ {
+ case syntax_element_match:
+ goto match_jump;
+ case syntax_element_startmark:
+ temp_match.set_first(first, ((re_brace*)ptr)->index);
+ ptr = ptr->next.p;
+ break;
+ case syntax_element_endmark:
+ temp_match.set_second(first, ((re_brace*)ptr)->index);
+ ptr = ptr->next.p;
+ break;
+ case syntax_element_start_line:
+ goto outer_line_check;
+ case syntax_element_end_line:
+ // we're at the end so *first is never valid:
+ if((flags & match_not_eol) == 0)
+ {
+ ptr = ptr->next.p;
+ continue;
+ }
+ goto failure;
+ case syntax_element_word_boundary:
+ case syntax_element_word_end:
+ if(((flags & match_not_eow) == 0) && (first != temp_match[0].first))
+ {
+ iterator t(first);
+ --t;
+ if(traits::is_class(*t, char_class_word MAYBE_PASS_LOCALE(locale_inst)))
+ {
+ ptr = ptr->next.p;
+ continue;
+ }
+ }
+ goto failure;
+ case syntax_element_buffer_end:
+ case syntax_element_soft_buffer_end:
+ if(flags & match_not_eob)
+ goto failure;
+ // OK match:
+ ptr = ptr->next.p;
+ break;
+ case syntax_element_jump:
+ ptr = ((re_jump*)ptr)->alt.p;
+ continue;
+ case syntax_element_alt:
+ if(ptr->can_be_null & mask_take)
+ {
+ // we can test the first alternative,
+ // see if we need to push next alternative:
+ if(ptr->can_be_null & mask_skip)
+ {
+ if(need_push_match)
+ matches.push(temp_match);
+ for(k = 0; k <= cur_acc; ++k)
+ prev_pos.push(start_loop[k]);
+ prev_pos.push(first);
+ prev_record.push(ptr);
+ for(k = 0; k <= cur_acc; ++k)
+ prev_acc.push(accumulators[k]);
+ prev_acc.push(cur_acc);
+ }
+ ptr = ptr->next.p;
+ continue;
+ }
+ if(ptr->can_be_null & mask_skip)
+ {
+ ptr = ((re_jump*)ptr)->alt.p;
+ continue;
+ }
+ goto failure; // neither option is possible
+ case syntax_element_rep:
+ // if we're moving to a higher id (nested repeats etc)
+ // zero out our accumualtors:
+ if(cur_acc < ((re_repeat*)ptr)->id)
+ {
+ cur_acc = ((re_repeat*)ptr)->id;
+ accumulators[cur_acc] = 0;
+ start_loop[cur_acc] = first;
+ }
+
+ cur_acc = ((re_repeat*)ptr)->id;
+
+ // see if we can skip the repeat:
+ if(((unsigned int)accumulators[cur_acc] >= ((re_repeat*)ptr)->min)
+ && (ptr->can_be_null & mask_skip))
+ {
+ // don't push failure info, there's no point:
+ ptr = ((re_repeat*)ptr)->alt.p;
+ continue;
+ }
+
+ // otherwise see if we can take the repeat:
+ if(((unsigned int)accumulators[cur_acc] < ((re_repeat*)ptr)->max)
+ && ((ptr->can_be_null & (mask_take | mask_skip)) == (mask_take | mask_skip)))
+ {
+ // move to next item in list:
+ ++accumulators[cur_acc];
+ ptr = ptr->next.p;
+ start_loop[cur_acc] = first;
+ continue;
+ }
+
+ // if we get here then neither option is allowed so fail:
+ goto failure;
+ case syntax_element_restart_continue:
+ if(first != temp_match[-1].first)
+ goto failure;
+ ptr = ptr->next.p;
+ continue;
+ default:
+ goto failure;
+ }
+ }
+
+ failure:
+
+ if(prev_record.empty() == false)
+ {
+ ptr = prev_record.peek();
+ switch(ptr->type)
+ {
+ case syntax_element_alt:
+ // get next alternative:
+ ptr = ((re_jump*)ptr)->alt.p;
+ if(need_push_match)
+ matches.pop(temp_match);
+ prev_acc.pop(cur_acc);
+ for(k = cur_acc; k >= 0; --k)
+ prev_acc.pop(accumulators[k]);
+ prev_pos.pop(first);
+ for(k = cur_acc; k >= 0; --k)
+ prev_pos.pop(start_loop[k]);
+ prev_record.pop();
+ goto retry;
+ case syntax_element_rep:
+ // we're doing least number of repeats first,
+ // increment count and repeat again:
+ if(need_push_match)
+ matches.pop(temp_match);
+ prev_pos.pop(first);
+ cur_acc = ((re_repeat*)ptr)->id;
+ for(k = cur_acc; k >= 0; --k)
+ prev_acc.pop(accumulators[k]);
+ prev_record.pop();
+ if((unsigned int)++accumulators[cur_acc] > ((re_repeat*)ptr)->max)
+ goto failure; // repetions exhausted.
+ ptr = ptr->next.p;
+ start_loop[cur_acc] = first;
+ goto retry;
+ case syntax_element_match:
+ if(need_push_match)
+ matches.pop(temp_match);
+ prev_pos.pop(first);
+ prev_record.pop();
+ goto retry;
+ default:
+ jm_assert(0);
+ // mustn't get here!!
+ }
+ }
+
+ if(match_found)
+ return true;
+
+ // if we get to here then everything has failed
+ // and no match was found:
+ return false;
+}
+#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
+} // namespace
+#endif
+
+
+template <class iterator>
+void __skip_and_inc(unsigned int& clines, iterator& last_line, iterator& first, const iterator last)
+{
+ while(first != last)
+ {
+ if(*first == '\n')
+ {
+ last_line = ++first;
+ ++clines;
+ }
+ else
+ ++first;
+ }
+}
+
+template <class iterator>
+void __skip_and_dec(unsigned int& clines, iterator& last_line, iterator& first, iterator base, unsigned int len)
+{
+ bool need_line = false;
+ for(unsigned int i = 0; i < len; ++i)
+ {
+ --first;
+ if(*first == '\n')
+ {
+ need_line = true;
+ --clines;
+ }
+ }
+
+ if(need_line)
+ {
+ last_line = first;
+
+ if(last_line != base)
+ --last_line;
+ else
+ return;
+
+ while((last_line != base) && (*last_line != '\n'))
+ --last_line;
+ if(*last_line == '\n')
+ ++last_line;
+ }
+}
+
+template <class iterator>
+inline void __inc_one(unsigned int& clines, iterator& last_line, iterator& first)
+{
+ if(*first == '\n')
+ {
+ last_line = ++first;
+ ++clines;
+ }
+ else
+ ++first;
+}
+
+template <class iterator, class Allocator>
+struct grep_search_predicate
+{
+ reg_match<iterator, Allocator>* pm;
+ grep_search_predicate(reg_match<iterator, Allocator>* p) : pm(p) {}
+ bool operator()(const reg_match<iterator, Allocator>& m)
+ {
+ *pm = static_cast<const reg_match_base<iterator, Allocator>&>(m);
+ return false;
+ }
+};
+
+#if !defined(JM_NO_TEMPLATE_RETURNS) && !defined(JM_NO_PARTIAL_FUNC_SPEC)
+
+template <class iterator, class Allocator>
+inline const reg_match_base<iterator, Allocator>& grep_out_type(const grep_search_predicate<iterator, Allocator>& o, const Allocator&)
+{
+ return *(o.pm);
+}
+
+#endif
+
+template <class T, class Allocator>
+inline const Allocator& grep_out_type(const T&, const Allocator& a)
+{
+ return a;
+}
+
+#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
+//
+// Ugly ugly hack,
+// template don't merge if they contain switch statements so declare these
+// templates in unnamed namespace (ie with internal linkage), each translation
+// unit then gets its own local copy, it works seemlessly but bloats the app.
+namespace{
+#endif
+
+//
+// reg_grep2:
+// find all non-overlapping matches within the sequence first last:
+//
+template <class Predicate, class I, class charT, class traits, class A, class A2>
+unsigned int reg_grep2(Predicate foo, I first, I last, const reg_expression<charT, traits, A>& e, unsigned flags, A2 a)
+{
+ if(e.flags() & regbase::failbit)
+ return 0;
+
+ typedef typename traits::size_type traits_size_type;
+ typedef typename traits::uchar_type traits_uchar_type;
+ typedef typename is_byte<charT>::width_type width_type;
+
+ reg_match<I, A2> m(grep_out_type(foo, a));
+ I restart;
+ m.set_size(e.mark_count(), first, last);
+ m.set_line(1, first);
+
+ #ifdef RE_LOCALE_CPP
+ const __JM_STD::locale& locale_inst = e.locale();
+ #endif
+
+ unsigned int clines = 1;
+ unsigned int cmatches = 0;
+ I last_line = first;
+ I next_base;
+ I base = first;
+ bool need_init;
+
+ flags |= match_init;
+
+ __priv_match_data<I, A2> pd(m);
+
+ const unsigned char* __map = e.get_map();
+ unsigned int type;
+
+ if(first == last)
+ {
+ // special case, only test if can_be_null,
+ // don't dereference any pointers!!
+ if(e.first()->can_be_null)
+ if(query_match_aux(first, last, m, e, flags, pd, &restart))
+ {
+ foo(m);
+ ++cmatches;
+ }
+ return cmatches;
+ }
+
+ // try one time whatever:
+ if( reg_expression<charT, traits, A>::can_start(*first, __map, (unsigned char)mask_any, width_type() ) )
+ {
+ if(query_match_aux(first, last, m, e, flags, pd, &restart))
+ {
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ // update to end of what matched
+ // trying to match again with match_not_null set if this
+ // is a null match...
+ need_init = true;
+ if(first == m[0].second)
+ {
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
+ {
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ }
+ else
+ {
+ need_init = false;
+ for(unsigned int i = 0; (restart != first) && (i < e.leading_length()); ++i, --restart);
+ if(restart != last)
+ ++restart;
+ __skip_and_inc(clines, last_line, first, restart);
+ }
+ }
+ if(need_init)
+ {
+ __skip_and_inc(clines, last_line, first, m[0].second);
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ }
+ }
+ else
+ {
+ for(unsigned int i = 0; (restart != first) && (i < e.leading_length()); ++i, --restart);
+ if(restart != last)
+ ++restart;
+ __skip_and_inc(clines, last_line, first, restart);
+ }
+ }
+ else
+ __inc_one(clines, last_line, first);
+ flags |= match_prev_avail | match_not_bob;
+
+
+ // depending on what the first record is we may be able to
+ // optimise the search:
+ type = (flags & match_continuous) ? regbase::restart_continue : e.restart_type();
+
+ if(type == regbase::restart_buf)
+ return cmatches;
+
+ switch(type)
+ {
+ case regbase::restart_lit:
+ case regbase::restart_fixed_lit:
+ {
+ const kmp_info<charT>* info = e.get_kmp();
+ int len = info->len;
+ const charT* x = info->pstr;
+ int j = 0;
+ bool icase = e.flags() & regbase::icase;
+ while (first != last)
+ {
+ while((j > -1) && (x[j] != traits::translate(*first, icase MAYBE_PASS_LOCALE(locale_inst))))
+ j = info->kmp_next[j];
+ __inc_one(clines, last_line, first);
+ ++j;
+ if(j >= len)
+ {
+ if(type == regbase::restart_fixed_lit)
+ {
+ __skip_and_dec(clines, last_line, first, base, j);
+ restart = first;
+ restart += len;
+ m.set_first(first);
+ m.set_second(restart);
+ m.set_line(clines, last_line);
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ __skip_and_inc(clines, last_line, first, restart);
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ j = 0;
+ }
+ else
+ {
+ restart = first;
+ __skip_and_dec(clines, last_line, first, base, j);
+ if(query_match_aux(first, last, m, e, flags, pd, &restart))
+ {
+
+ m.set_line(clines, last_line);
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ // update to end of what matched
+ __skip_and_inc(clines, last_line, first, m[0].second);
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ j = 0;
+ }
+ else
+ {
+ for(int k = 0; (restart != first) && (k < j); ++k, --restart);
+ if(restart != last)
+ ++restart;
+ __skip_and_inc(clines, last_line, first, restart);
+ j = 0; //we could do better than this...
+ }
+ }
+ }
+ }
+ break;
+ }
+ case regbase::restart_any:
+ {
+ while(first != last)
+ {
+ if( reg_expression<charT, traits, A>::can_start(*first, __map, (unsigned char)mask_any, width_type()) )
+ {
+ if(query_match_aux(first, last, m, e, flags, pd, &restart))
+ {
+
+ m.set_line(clines, last_line);
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ // update to end of what matched
+ // trying to match again with match_not_null set if this
+ // is a null match...
+ need_init = true;
+ if(first == m[0].second)
+ {
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
+ {
+ m.set_line(clines, last_line);
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ }
+ else
+ {
+ need_init = false;
+ for(unsigned int i = 0; (restart != first) && (i < e.leading_length()); ++i, --restart);
+ if(restart != last)
+ ++restart;
+ __skip_and_inc(clines, last_line, first, restart);
+ }
+ }
+ if(need_init)
+ {
+ __skip_and_inc(clines, last_line, first, m[0].second);
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ }
+ continue;
+ }
+ else
+ {
+ for(unsigned int i = 0; (restart != first) && (i < e.leading_length()); ++i, --restart);
+ if(restart != last)
+ ++restart;
+ __skip_and_inc(clines, last_line, first, restart);
+ }
+ }
+ else
+ __inc_one(clines, last_line, first);
+ }
+ }
+ break;
+ case regbase::restart_word:
+ {
+ // do search optimised for word starts:
+ while(first != last)
+ {
+ --first;
+ if(*first == '\n')
+ --clines;
+ // skip the word characters:
+ while((first != last) && traits::is_class(*first, char_class_word MAYBE_PASS_LOCALE(locale_inst)))
+ ++first;
+ // now skip the white space:
+ while((first != last) && (traits::is_class(*first, char_class_word MAYBE_PASS_LOCALE(locale_inst)) == false))
+ __inc_one(clines, last_line, first);
+ if(first == last)
+ break;
+
+ if( reg_expression<charT, traits, A>::can_start(*first, __map, (unsigned char)mask_any, width_type()) )
+ {
+ if(query_match_aux(first, last, m, e, flags, pd, &restart))
+ {
+ m.set_line(clines, last_line);
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ // update to end of what matched
+ // trying to match again with match_not_null set if this
+ // is a null match...
+ need_init = true;
+ if(first == m[0].second)
+ {
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
+ {
+ m.set_line(clines, last_line);
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ }
+ else
+ {
+ need_init = false;
+ for(unsigned int i = 0; (restart != first) && (i < e.leading_length()); ++i, --restart);
+ if(restart != last)
+ ++restart;
+ __skip_and_inc(clines, last_line, first, restart);
+ }
+ }
+ if(need_init)
+ {
+ __skip_and_inc(clines, last_line, first, m[0].second);
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ }
+ }
+ else
+ {
+ for(unsigned int i = 0; (restart != first) && (i < e.leading_length()); ++i, --restart);
+ if(restart != last)
+ ++restart;
+ __skip_and_inc(clines, last_line, first, restart);
+ }
+ }
+ else
+ __inc_one(clines, last_line, first);
+ }
+ }
+ break;
+ case regbase::restart_line:
+ {
+ // do search optimised for line starts:
+ while(first != last)
+ {
+ // find first charcter after a line break:
+ --first;
+ if(*first == '\n')
+ --clines;
+ while((first != last) && (*first != '\n'))
+ ++first;
+ if(first == last)
+ break;
+ ++first;
+ if(first == last)
+ break;
+
+ ++clines;
+ last_line = first;
+
+ if( reg_expression<charT, traits, A>::can_start(*first, __map, (unsigned char)mask_any, width_type()) )
+ {
+ if(query_match_aux(first, last, m, e, flags, pd, &restart))
+ {
+ m.set_line(clines, last_line);
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ // update to end of what matched
+ // trying to match again with match_not_null set if this
+ // is a null match...
+ need_init = true;
+ if(first == m[0].second)
+ {
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
+ {
+ m.set_line(clines, last_line);
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ }
+ else
+ {
+ need_init = false;
+ for(unsigned int i = 0; (restart != first) && (i < e.leading_length()); ++i, --restart);
+ if(restart != last)
+ ++restart;
+ __skip_and_inc(clines, last_line, first, restart);
+ }
+ }
+ if(need_init)
+ {
+ __skip_and_inc(clines, last_line, first, m[0].second);
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ }
+ }
+ else
+ {
+ for(unsigned int i = 0; (restart != first) && (i < e.leading_length()); ++i, --restart);
+ if(restart != last)
+ ++restart;
+ __skip_and_inc(clines, last_line, first, restart);
+ }
+ }
+ else
+ __inc_one(clines, last_line, first);
+ }
+ }
+ break;
+ case regbase::restart_continue:
+ {
+ while(first != last)
+ {
+ if( reg_expression<charT, traits, A>::can_start(*first, __map, (unsigned char)mask_any, width_type()) )
+ {
+ if(query_match_aux(first, last, m, e, flags, pd, &restart))
+ {
+ m.set_line(clines, last_line);
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ // update to end of what matched
+ // trying to match again with match_not_null set if this
+ // is a null match...
+ if(first == m[0].second)
+ {
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
+ {
+ m.set_line(clines, last_line);
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ }
+ else
+ return cmatches; // can't continue from null match
+ }
+ __skip_and_inc(clines, last_line, first, m[0].second);
+ next_base = m[0].second;
+ pd.temp_match.init_fail(next_base, last);
+ m.init_fail(next_base, last);
+ continue;
+ }
+ }
+ return cmatches;
+ }
+ }
+ break;
+ }
+
+
+ // finally check trailing null string:
+ if(e.first()->can_be_null)
+ {
+ if(query_match_aux(first, last, m, e, flags, pd, &restart))
+ {
+ m.set_line(clines, last_line);
+ ++cmatches;
+ if(foo(m) == false)
+ return cmatches;
+ }
+ }
+
+ return cmatches;
+}
+#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
+} // namespace
+#endif
+
+
+template <class iterator, class Allocator, class charT, class traits, class Allocator2>
+bool reg_search(iterator first, iterator last, reg_match<iterator, Allocator>& m, const reg_expression<charT, traits, Allocator2>& e, unsigned flags = match_default)
+{
+ if(e.flags() & regbase::failbit)
+ return false;
+
+ typedef typename traits::size_type traits_size_type;
+ typedef typename traits::uchar_type traits_uchar_type;
+
+ // prepare m for failure:
+ if((flags & match_init) == 0)
+ {
+ m.set_size(e.mark_count(), first, last);
+ }
+
+ flags |= match_init;
+ return reg_grep2(grep_search_predicate<iterator, Allocator>(&m), first, last, e, flags, m.allocator());
+}
+
+//
+// reg_search convenience interfaces:
+#ifndef JM_NO_PARTIAL_FUNC_SPEC
+//
+// this isn't really a partial specialisation, but template function
+// overloading - if the compiler doesn't support partial specialisation
+// then it really won't support this either:
+template <class charT, class Allocator, class traits, class Allocator2>
+inline bool reg_search(const charT* str,
+ reg_match<const charT*, Allocator>& m,
+ const reg_expression<charT, traits, Allocator2>& e,
+ unsigned flags = match_default)
+{
+ return reg_search(str, str + traits::length(str), m, e, flags);
+}
+
+#ifndef JM_NO_STRING_H
+template <class ST, class SA, class Allocator, class charT, class traits, class Allocator2>
+inline bool reg_search(const __JM_STD::basic_string<charT, ST, SA>& s,
+ reg_match<typename __JM_STD::basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
+ const reg_expression<charT, traits, Allocator2>& e,
+ unsigned flags = match_default)
+{
+ return reg_search(s.begin(), s.end(), m, e, flags);
+}
+#endif
+#else // partial specialisation
+inline bool reg_search(const char* str,
+ cmatch& m,
+ const regex& e,
+ unsigned flags = match_default)
+{
+ return reg_search(str, str + regex::traits_type::length(str), m, e, flags);
+}
+#ifndef JM_NO_WCSTRING
+inline bool reg_search(const wchar_t* str,
+ wcmatch& m,
+ const wregex& e,
+ unsigned flags = match_default)
+{
+ return reg_search(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+#endif
+#ifndef JM_NO_STRING_H
+inline bool reg_search(const __JM_STD::string& s,
+ reg_match<__JM_STD::string::const_iterator, regex::alloc_type>& m,
+ const regex& e,
+ unsigned flags = match_default)
+{
+ return reg_search(s.begin(), s.end(), m, e, flags);
+}
+#if !defined(JM_NO_STRING_DEF_ARGS) && !defined(JM_NO_WCSTRING)
+inline bool reg_search(const __JM_STD::basic_string<wchar_t>& s,
+ reg_match<__JM_STD::basic_string<wchar_t>::const_iterator, wregex::alloc_type>& m,
+ const wregex& e,
+ unsigned flags = match_default)
+{
+ return reg_search(s.begin(), s.end(), m, e, flags);
+}
+#endif
+
+#endif
+
+#endif
+
+
+//
+// reg_grep:
+// find all non-overlapping matches within the sequence first last:
+//
+template <class Predicate, class iterator, class charT, class traits, class Allocator>
+inline unsigned int reg_grep(Predicate foo, iterator first, iterator last, const reg_expression<charT, traits, Allocator>& e, unsigned flags = match_default)
+{
+ return reg_grep2(foo, first, last, e, flags, e.allocator());
+}
+
+//
+// reg_grep convenience interfaces:
+#ifndef JM_NO_PARTIAL_FUNC_SPEC
+//
+// this isn't really a partial specialisation, but template function
+// overloading - if the compiler doesn't support partial specialisation
+// then it really won't support this either:
+template <class Predicate, class charT, class Allocator, class traits>
+inline bool reg_grep(Predicate foo, const charT* str,
+ const reg_expression<charT, traits, Allocator>& e,
+ unsigned flags = match_default)
+{
+ return reg_grep(foo, str, str + traits::length(str), e, flags);
+}
+
+#ifndef JM_NO_STRING_H
+template <class Predicate, class ST, class SA, class Allocator, class charT, class traits>
+inline bool reg_grep(Predicate foo, const __JM_STD::basic_string<charT, ST, SA>& s,
+ const reg_expression<charT, traits, Allocator>& e,
+ unsigned flags = match_default)
+{
+ return reg_grep(foo, s.begin(), s.end(), e, flags);
+}
+#endif
+#else // partial specialisation
+inline bool reg_grep(bool (*foo)(const cmatch&), const char* str,
+ const regex& e,
+ unsigned flags = match_default)
+{
+ return reg_grep(foo, str, str + regex::traits_type::length(str), e, flags);
+}
+#ifndef JM_NO_WCSTRING
+inline bool reg_grep(bool (*foo)(const wcmatch&), const wchar_t* str,
+ const wregex& e,
+ unsigned flags = match_default)
+{
+ return reg_grep(foo, str, str + wregex::traits_type::length(str), e, flags);
+}
+#endif
+#ifndef JM_NO_STRING_H
+inline bool reg_grep(bool (*foo)(const reg_match<__JM_STD::string::const_iterator, regex::alloc_type>&), const __JM_STD::string& s,
+ const regex& e,
+ unsigned flags = match_default)
+{
+ return reg_grep(foo, s.begin(), s.end(), e, flags);
+}
+#if !defined(JM_NO_STRING_DEF_ARGS) && !defined(JM_NO_WCSTRING)
+inline bool reg_grep(bool (*foo)(const reg_match<__JM_STD::basic_string<wchar_t>::const_iterator, wregex::alloc_type>&),
+ const __JM_STD::basic_string<wchar_t>& s,
+ const wregex& e,
+ unsigned flags = match_default)
+{
+ return reg_grep(foo, s.begin(), s.end(), e, flags);
+}
+#endif
+
+#endif
+
+#endif
+
+
+//
+// finally for compatablity with version 1.x of the library
+// we need a form of reg_grep that takes an output iterator
+// as its first argument:
+//
+
+//
+// struct grep_match:
+// stores what matched during a reg_grep,
+// the output iterator type passed to reg_grep must have an
+// operator*() that returns a type with an
+// operator=(const grep_match<iterator, Allocator>&);
+//
+template <class iterator, class Allocator>
+struct grep_match
+{
+ unsigned int line;
+ iterator line_start;
+ reg_match<iterator, Allocator> what;
+
+ grep_match(Allocator a = Allocator()) : what(a) {}
+
+ grep_match(unsigned int l, iterator p1, const reg_match<iterator, Allocator>& m)
+ : what(m) { line = l; line_start = p1; }
+
+ bool operator == (const grep_match& )
+ { return false; }
+
+ bool operator < (const grep_match&)
+ { return false; }
+};
+
+template <class O, class I, class A>
+struct grep_adaptor
+{
+ O oi;
+ reg_match<I, A> m;
+ grep_adaptor(O i, A a) : m(a), oi(i) {}
+ bool operator()(const reg_match_base<I, A>& w)
+ {
+ m.what = w;
+ m.line = w.line();
+ m.line_start = w.line_start();
+ *oi = m;
+ ++oi;
+ return true;
+ }
+};
+
+template <class Out, class iterator, class charT, class traits, class Allocator>
+inline unsigned int reg_grep_old(Out oi, iterator first, iterator last, const reg_expression<charT, traits, Allocator>& e, unsigned flags = match_default)
+{
+ return reg_grep2(grep_adaptor<Out, iterator, Allocator>(oi, e.allocator()), first, last, e, flags, e.allocator());
+}
+
+
+
+JM_END_NAMESPACE // namespace regex
+
+#endif // __REGMATCH_H
+
+
+
+
+
+
+
diff --git a/utils/tfstats/regexp/include/regex b/utils/tfstats/regexp/include/regex
new file mode 100644
index 0000000..65b885a
--- /dev/null
+++ b/utils/tfstats/regexp/include/regex
@@ -0,0 +1,3 @@
+#ifndef __REGEX_H
+#include <jm/regex.h>
+#endif
diff --git a/utils/tfstats/regexp/include/regex.h b/utils/tfstats/regexp/include/regex.h
new file mode 100644
index 0000000..dda5c75
--- /dev/null
+++ b/utils/tfstats/regexp/include/regex.h
@@ -0,0 +1,16 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef __REGEX_H
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#pragma warning(disable: 4800)
+#endif
+
+#include <jm/regex.h>
+#endif
diff --git a/utils/tfstats/regexp/lib/libregex++.a b/utils/tfstats/regexp/lib/libregex++.a
new file mode 100644
index 0000000..3adf565
--- /dev/null
+++ b/utils/tfstats/regexp/lib/libregex++.a
Binary files differ
diff --git a/utils/tfstats/regexp/lib/mre200.lib b/utils/tfstats/regexp/lib/mre200.lib
new file mode 100644
index 0000000..f9bbc17
--- /dev/null
+++ b/utils/tfstats/regexp/lib/mre200.lib
Binary files differ
diff --git a/utils/tfstats/regexp/lib/mre200d.lib b/utils/tfstats/regexp/lib/mre200d.lib
new file mode 100644
index 0000000..60364a5
--- /dev/null
+++ b/utils/tfstats/regexp/lib/mre200d.lib
Binary files differ