summaryrefslogtreecommitdiff
path: root/utils/tfstats/regexp/include/jm/regfmt.h
diff options
context:
space:
mode:
Diffstat (limited to 'utils/tfstats/regexp/include/jm/regfmt.h')
-rw-r--r--utils/tfstats/regexp/include/jm/regfmt.h565
1 files changed, 565 insertions, 0 deletions
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
+
+
+