summaryrefslogtreecommitdiff
path: root/tools/intergen/utils
diff options
context:
space:
mode:
Diffstat (limited to 'tools/intergen/utils')
-rw-r--r--tools/intergen/utils/CMakeLists.txt22
-rw-r--r--tools/intergen/utils/include/utils/common_types.h132
-rw-r--r--tools/intergen/utils/include/utils/macro.h48
-rw-r--r--tools/intergen/utils/include/utils/safeformat.h579
-rw-r--r--tools/intergen/utils/include/utils/stl_utils.h101
-rw-r--r--tools/intergen/utils/include/utils/string_utils.h161
-rw-r--r--tools/intergen/utils/include/utils/xml_utils.h54
-rw-r--r--tools/intergen/utils/src/utils/common_types.cc77
-rw-r--r--tools/intergen/utils/src/utils/safeformat.cc107
-rw-r--r--tools/intergen/utils/src/utils/xml_utils.cc52
10 files changed, 1333 insertions, 0 deletions
diff --git a/tools/intergen/utils/CMakeLists.txt b/tools/intergen/utils/CMakeLists.txt
new file mode 100644
index 000000000..8e2ccbd67
--- /dev/null
+++ b/tools/intergen/utils/CMakeLists.txt
@@ -0,0 +1,22 @@
+include_directories(
+ include
+ ${pugixml_SOURCE_DIR}/../src
+)
+
+set (HEADERS
+ include/utils/common_types.h
+ include/utils/macro.h
+ include/utils/safeformat.h
+ include/utils/stl_utils.h
+ include/utils/string_utils.h
+ include/utils/xml_utils.h
+)
+
+set (SOURCES
+ src/utils/common_types.cc
+ src/utils/safeformat.cc
+ src/utils/xml_utils.cc
+)
+
+add_library(intergen_utils ${HEADERS} ${SOURCES})
+target_link_libraries(intergen_utils pugixml)
diff --git a/tools/intergen/utils/include/utils/common_types.h b/tools/intergen/utils/include/utils/common_types.h
new file mode 100644
index 000000000..aff817b63
--- /dev/null
+++ b/tools/intergen/utils/include/utils/common_types.h
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef COMMON_TYPES_H_
+#define COMMON_TYPES_H_
+
+#include <string>
+#include <vector>
+
+#include "utils/string_utils.h"
+
+namespace codegen {
+/*
+ * Entity description, a set of text strings.
+ */
+typedef std::vector<std::string> Description;
+
+/*
+ * Natural fraction class
+ */
+class Fraction {
+ public:
+ // Constructs fraction with value of 0/1
+ Fraction();
+ // Constructs fraction from given values
+ Fraction(int64_t numer, int64_t denumer);
+ // Parses string |literal| containing float point string definition, result is stored in
+ // |fraction| parameter.
+ // If |literal| can not be parsed, returns false.
+ static bool FromFloatPointString(const std::string& literal, Fraction* fraction);
+ // Field accessors
+ int64_t numer() const;
+ int64_t denumer() const;
+
+ private:
+ int64_t numer_;
+ int64_t denumer_;
+
+};
+
+/*
+ * Template class representing generic range with lower
+ * and upper bounds (min and max).
+ * Allows value or another range to be tested for inclusion.
+ * Range boundaries are always included in tests.
+ */
+template<typename T>
+class BasicRange {
+ public:
+ typedef T value_type;
+ // Create a range with specified bounds
+ BasicRange(value_type min, value_type max)
+ : min_(min),
+ max_(max) {
+ Fraction::FromFloatPointString(NumberToString(min_), &min_fract_);
+ Fraction::FromFloatPointString(NumberToString(max_), &max_fract_);
+ }
+ // Constructs the range from given string representations of value.
+ // Used to avoid converting fractional boundaries to floating point
+ // Representation.
+ BasicRange(const std::string& min_str, const std::string& max_str)
+ : min_(0),
+ max_(0) {
+ bool valid_min = StringToNumber(min, &min_)
+ && Fraction::FromFloatPointString(min, &min_fract_);
+ bool valid_max = StringToNumber(max, &max_)
+ && Fraction::FromFloatPointString(max, &max_fract_);
+ assert(valid_min && valid_max);
+ }
+ // Tells if |value| belongs to current range (boundaries are included)
+ bool Includes(value_type value) const {
+ return min_ <= value && value <= max_;
+ }
+
+ // Tells if another range completely belongs to current range
+ // (boundaries are included)
+ bool Includes(const BasicRange& that) {
+ return min() <= that.min() && max() >= that.max();
+ }
+
+ // Field access methods
+ value_type min() const {
+ return min_;
+ }
+ value_type max() const {
+ return max_;
+ }
+ const Fraction& min_fract() const {
+ return min_fract_;
+ }
+ const Fraction& max_fract() const {
+ return max_fract_;
+ }
+ private:
+ value_type min_;
+ value_type max_;
+ Fraction min_fract_;
+ Fraction max_fract_;
+};
+
+} // namespace codegen
+
+#endif /* COMMON_TYPES_H_ */
diff --git a/tools/intergen/utils/include/utils/macro.h b/tools/intergen/utils/include/utils/macro.h
new file mode 100644
index 000000000..328f24932
--- /dev/null
+++ b/tools/intergen/utils/include/utils/macro.h
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MACRO_H_
+#define MACRO_H_
+
+/*
+ * Copy prevention helper macro
+ */
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&)
+
+/*
+ * C++11 optional override support macro
+ */
+#define OVERRIDE
+
+#endif /* MACRO_H_ */
diff --git a/tools/intergen/utils/include/utils/safeformat.h b/tools/intergen/utils/include/utils/safeformat.h
new file mode 100644
index 000000000..a8f5d09d6
--- /dev/null
+++ b/tools/intergen/utils/include/utils/safeformat.h
@@ -0,0 +1,579 @@
+/*
+* Typesafe printf-like wrapper around std streams
+* by Igor Kozyrenko, 2013
+*/
+
+#include <cstring>
+#include <cwchar>
+#include <ostream>
+#include <sstream>
+
+namespace typesafe_format {
+namespace impl {
+
+// Pointer avoidance magic
+template<class T> struct no_pointers { enum { allowed = 1 }; };
+template<> struct no_pointers<char*> { enum { allowed = 1 }; };
+template<> struct no_pointers<const char*> { enum { allowed = 1 }; };
+template<> struct no_pointers<wchar_t*> { enum { allowed = 1 }; };
+template<> struct no_pointers<const wchar_t*>{ enum { allowed = 1 }; };
+template<class T> struct no_pointers<T*> { enum { allowed = 0 }; };
+
+// Static assert helper
+template<bool b> struct my_static_assert {};
+template<> struct my_static_assert<true> { enum { here }; };
+
+template <typename CT>
+struct Streamable {
+ virtual void OutputToStream(std::basic_ostream<CT>& stream) const = 0;
+ virtual ~Streamable() {}
+};
+
+template <typename CT, typename T>
+struct StreamableValue: public Streamable<CT> {
+ StreamableValue(const T& val): val_(val) {
+ // You can wrap pointer with typesafe_format::ptr to pass this check
+ (void)my_static_assert<no_pointers<T>::allowed>::here;
+ }
+ void OutputToStream(std::basic_ostream<CT>& stream) const {
+ stream<<val_;
+ }
+private:
+ const T& val_;
+};
+
+inline size_t len(const char* str) { return std::strlen(str); }
+inline size_t len(const wchar_t* str) { return std::wcslen(str); }
+
+void format_params(const char* fmt, size_t fmt_length, std::ostream& os,
+ const Streamable<char>* params[], size_t params_count);
+void format_params(const wchar_t* fmt, size_t fmt_length, std::wostream& os,
+ const Streamable<wchar_t>* params[], size_t params_count);
+} // namespace impl
+
+// Wrapper class to pass anti-pointer protection
+struct ptr {
+ explicit ptr(void* ptr): ptr_(ptr) {}
+private:
+ void* ptr_;
+ template <typename CT>
+ friend std::basic_ostream<CT>& operator<<(std::basic_ostream<CT>&,
+ const ptr&);
+};
+template <typename CT>
+inline std::basic_ostream<CT>& operator<<(std::basic_ostream<CT>& os,
+ const ptr& ptr) {
+ return os<<ptr.ptr_;
+}
+
+// stream format overloads
+template <typename CT>
+std::basic_ostream<CT>& strmfmtl(
+ std::basic_ostream<CT>& os, const CT* fmt, size_t fmt_length) {
+ return os.write(fmt, fmt_length);
+}
+
+template <typename CT,
+ typename T0>
+std::basic_ostream<CT>& strmfmtl(
+ std::basic_ostream<CT>& os, const CT* fmt, size_t fmt_length,
+ const T0& p0) {
+ impl::StreamableValue<CT, T0> s0(p0);
+ const impl::Streamable<CT>* params[] =
+ {&s0};
+ impl::format_params(fmt, fmt_length, os,
+ params, sizeof params/sizeof params[0]);
+ return os;
+}
+
+template <typename CT,
+ typename T0, typename T1>
+std::basic_ostream<CT>& strmfmtl(
+ std::basic_ostream<CT>& os, const CT* fmt, size_t fmt_length,
+ const T0& p0, const T1& p1) {
+ impl::StreamableValue<CT, T0> s0(p0);
+ impl::StreamableValue<CT, T1> s1(p1);
+ const impl::Streamable<CT>* params[] =
+ {&s0, &s1};
+ impl::format_params(fmt, fmt_length, os,
+ params, sizeof params/sizeof params[0]);
+ return os;
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2>
+std::basic_ostream<CT>& strmfmtl(
+ std::basic_ostream<CT>& os, const CT* fmt, size_t fmt_length,
+ const T0& p0, const T1& p1, const T2& p2) {
+ impl::StreamableValue<CT, T0> s0(p0);
+ impl::StreamableValue<CT, T1> s1(p1);
+ impl::StreamableValue<CT, T2> s2(p2);
+ const impl::Streamable<CT>* params[] =
+ {&s0, &s1, &s2};
+ impl::format_params(fmt, fmt_length, os,
+ params, sizeof params/sizeof params[0]);
+ return os;
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3>
+std::basic_ostream<CT>& strmfmtl(
+ std::basic_ostream<CT>& os, const CT* fmt, size_t fmt_length,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3) {
+ impl::StreamableValue<CT, T0> s0(p0);
+ impl::StreamableValue<CT, T1> s1(p1);
+ impl::StreamableValue<CT, T2> s2(p2);
+ impl::StreamableValue<CT, T3> s3(p3);
+ const impl::Streamable<CT>* params[] =
+ {&s0, &s1, &s2, &s3};
+ impl::format_params(fmt, fmt_length, os,
+ params, sizeof params/sizeof params[0]);
+ return os;
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4>
+std::basic_ostream<CT>& strmfmtl(
+ std::basic_ostream<CT>& os, const CT* fmt, size_t fmt_length,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4) {
+ impl::StreamableValue<CT, T0> s0(p0);
+ impl::StreamableValue<CT, T1> s1(p1);
+ impl::StreamableValue<CT, T2> s2(p2);
+ impl::StreamableValue<CT, T3> s3(p3);
+ impl::StreamableValue<CT, T4> s4(p4);
+ const impl::Streamable<CT>* params[] =
+ {&s0, &s1, &s2, &s3, &s4};
+ impl::format_params(fmt, fmt_length, os,
+ params, sizeof params/sizeof params[0]);
+ return os;
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5>
+std::basic_ostream<CT>& strmfmtl(
+ std::basic_ostream<CT>& os, const CT* fmt, size_t fmt_length,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5) {
+ impl::StreamableValue<CT, T0> s0(p0);
+ impl::StreamableValue<CT, T1> s1(p1);
+ impl::StreamableValue<CT, T2> s2(p2);
+ impl::StreamableValue<CT, T3> s3(p3);
+ impl::StreamableValue<CT, T4> s4(p4);
+ impl::StreamableValue<CT, T5> s5(p5);
+ const impl::Streamable<CT>* params[] =
+ {&s0, &s1, &s2, &s3, &s4, &s5};
+ impl::format_params(fmt, fmt_length, os,
+ params, sizeof params/sizeof params[0]);
+ return os;
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6>
+std::basic_ostream<CT>& strmfmtl(
+ std::basic_ostream<CT>& os, const CT* fmt, size_t fmt_length,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6) {
+ impl::StreamableValue<CT, T0> s0(p0);
+ impl::StreamableValue<CT, T1> s1(p1);
+ impl::StreamableValue<CT, T2> s2(p2);
+ impl::StreamableValue<CT, T3> s3(p3);
+ impl::StreamableValue<CT, T4> s4(p4);
+ impl::StreamableValue<CT, T5> s5(p5);
+ impl::StreamableValue<CT, T6> s6(p6);
+ const impl::Streamable<CT>* params[] =
+ {&s0, &s1, &s2, &s3, &s4, &s5, &s6};
+ impl::format_params(fmt, fmt_length, os,
+ params, sizeof params/sizeof params[0]);
+ return os;
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7>
+std::basic_ostream<CT>& strmfmtl(
+ std::basic_ostream<CT>& os, const CT* fmt, size_t fmt_length,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7) {
+ impl::StreamableValue<CT, T0> s0(p0);
+ impl::StreamableValue<CT, T1> s1(p1);
+ impl::StreamableValue<CT, T2> s2(p2);
+ impl::StreamableValue<CT, T3> s3(p3);
+ impl::StreamableValue<CT, T4> s4(p4);
+ impl::StreamableValue<CT, T5> s5(p5);
+ impl::StreamableValue<CT, T6> s6(p6);
+ impl::StreamableValue<CT, T7> s7(p7);
+ const impl::Streamable<CT>* params[] =
+ {&s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7};
+ impl::format_params(fmt, fmt_length, os,
+ params, sizeof params/sizeof params[0]);
+ return os;
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8>
+std::basic_ostream<CT>& strmfmtl(
+ std::basic_ostream<CT>& os, const CT* fmt, size_t fmt_length,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7, const T8& p8) {
+ impl::StreamableValue<CT, T0> s0(p0);
+ impl::StreamableValue<CT, T1> s1(p1);
+ impl::StreamableValue<CT, T2> s2(p2);
+ impl::StreamableValue<CT, T3> s3(p3);
+ impl::StreamableValue<CT, T4> s4(p4);
+ impl::StreamableValue<CT, T5> s5(p5);
+ impl::StreamableValue<CT, T6> s6(p6);
+ impl::StreamableValue<CT, T7> s7(p7);
+ impl::StreamableValue<CT, T8> s8(p8);
+ const impl::Streamable<CT>* params[] =
+ {&s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7, &s8};
+ impl::format_params(fmt, fmt_length, os,
+ params, sizeof params/sizeof params[0]);
+ return os;
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8, typename T9>
+std::basic_ostream<CT>& strmfmtl(
+ std::basic_ostream<CT>& os, const CT* fmt, size_t fmt_length,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7, const T8& p8, const T9& p9) {
+ impl::StreamableValue<CT, T0> s0(p0);
+ impl::StreamableValue<CT, T1> s1(p1);
+ impl::StreamableValue<CT, T2> s2(p2);
+ impl::StreamableValue<CT, T3> s3(p3);
+ impl::StreamableValue<CT, T4> s4(p4);
+ impl::StreamableValue<CT, T5> s5(p5);
+ impl::StreamableValue<CT, T6> s6(p6);
+ impl::StreamableValue<CT, T7> s7(p7);
+ impl::StreamableValue<CT, T8> s8(p8);
+ impl::StreamableValue<CT, T9> s9(p9);
+ const impl::Streamable<CT>* params[] =
+ {&s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7, &s8, &s9};
+ impl::format_params(fmt, fmt_length, os,
+ params, sizeof params/sizeof params[0]);
+ return os;
+}
+
+/*
+ * Stream format overloads
+ * */
+template <typename CT>
+std::basic_ostream<CT>& strmfmt(
+ std::basic_ostream<CT>& os, const CT* fmt) {
+ return strmfmtl(os, fmt, impl::len(fmt));
+}
+
+template <typename CT,
+ typename T0>
+std::basic_ostream<CT>& strmfmt(
+ std::basic_ostream<CT>& os, const CT* fmt, const T0& p0) {
+ return strmfmtl(os, fmt, impl::len(fmt), p0);
+}
+
+template <typename CT,
+ typename T0, typename T1>
+std::basic_ostream<CT>& strmfmt(
+ std::basic_ostream<CT>& os, const CT* fmt,
+ const T0& p0, const T1& p1) {
+ return strmfmtl(os, fmt, impl::len(fmt), p0, p1);
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2>
+std::basic_ostream<CT>& strmfmt(
+ std::basic_ostream<CT>& os, const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2) {
+ return strmfmtl(os, fmt, impl::len(fmt), p0, p1, p2);
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3>
+std::basic_ostream<CT>& strmfmt(
+ std::basic_ostream<CT>& os, const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3) {
+ return strmfmtl(os, fmt, impl::len(fmt), p0, p1, p2, p3);
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4>
+std::basic_ostream<CT>& strmfmt(
+ std::basic_ostream<CT>& os, const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4) {
+ return strmfmtl(os, fmt, impl::len(fmt), p0, p1, p2, p3, p4);
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5>
+std::basic_ostream<CT>& strmfmt(
+ std::basic_ostream<CT>& os, const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5) {
+ return strmfmtl(os, fmt, impl::len(fmt), p0, p1, p2, p3, p4, p5);
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6>
+std::basic_ostream<CT>& strmfmt(
+ std::basic_ostream<CT>& os, const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6) {
+ return strmfmtl(os, fmt, impl::len(fmt), p0, p1, p2, p3, p4, p5, p6);
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7>
+std::basic_ostream<CT>& strmfmt(
+ std::basic_ostream<CT>& os, const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7) {
+ return strmfmtl(os, fmt, impl::len(fmt), p0, p1, p2, p3, p4, p5, p6, p7);
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8>
+std::basic_ostream<CT>& strmfmt(
+ std::basic_ostream<CT>& os, const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7, const T8& p8) {
+ return strmfmtl(os, fmt, impl::len(fmt), p0, p1, p2, p3, p4, p5, p6, p7, p8);
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8, typename T9>
+std::basic_ostream<CT>& strmfmt(
+ std::basic_ostream<CT>& os, const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7, const T8& p8, const T9& p9) {
+ return strmfmtl(os, fmt, impl::len(fmt), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+}
+
+/*
+*
+* Char array format overloads
+*
+*/
+template <typename CT,
+ typename T0>
+std::basic_string<CT> format(const CT* fmt,
+ const T0& p0) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt, impl::len(fmt), p0);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1>
+std::basic_string<CT> format(const CT* fmt,
+ const T0& p0, const T1& p1) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt, impl::len(fmt), p0, p1);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2>
+std::basic_string<CT> format(const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt, impl::len(fmt), p0, p1, p2);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3>
+std::basic_string<CT> format(const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt, impl::len(fmt), p0, p1, p2, p3);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4>
+std::basic_string<CT> format(const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt, impl::len(fmt), p0, p1, p2, p3, p4);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5>
+std::basic_string<CT> format(const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt, impl::len(fmt), p0, p1, p2, p3, p4, p5);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6>
+std::basic_string<CT> format(const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt, impl::len(fmt), p0, p1, p2, p3, p4, p5, p6);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7>
+std::basic_string<CT> format(const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt, impl::len(fmt), p0, p1, p2, p3, p4, p5, p6, p7);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8>
+std::basic_string<CT> format(const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7, const T8& p8) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt, impl::len(fmt), p0, p1, p2, p3, p4, p5, p6, p7, p8);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8, typename T9>
+std::basic_string<CT> format(const CT* fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7, const T8& p8, const T9& p9) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt, impl::len(fmt), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+ return stream.str();
+}
+
+/*
+*
+* STL string overloads
+*
+*/
+template <typename CT,
+ typename T0>
+std::basic_string<CT> format(const std::basic_string<CT> fmt,
+ const T0& p0) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt.c_str(), fmt.size(),
+ p0);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1>
+std::basic_string<CT> format(const std::basic_string<CT> fmt,
+ const T0& p0, const T1& p1) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt.c_str(), fmt.size(),
+ p0, p1);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2>
+std::basic_string<CT> format(const std::basic_string<CT> fmt,
+ const T0& p0, const T1& p1, const T2& p2) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt.c_str(), fmt.size(),
+ p0, p1, p2);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3>
+std::basic_string<CT> format(const std::basic_string<CT> fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt.c_str(), fmt.size(),
+ p0, p1, p2, p3);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4>
+std::basic_string<CT> format(const std::basic_string<CT> fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt.c_str(), fmt.size(),
+ p0, p1, p2, p3, p4);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5>
+std::basic_string<CT> format(const std::basic_string<CT> fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt.c_str(), fmt.size(),
+ p0, p1, p2, p3, p4, p5);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6>
+std::basic_string<CT> format(const std::basic_string<CT> fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt.c_str(), fmt.size(),
+ p0, p1, p2, p3, p4, p5, p6);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7>
+std::basic_string<CT> format(const std::basic_string<CT> fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt.c_str(), fmt.size(),
+ p0, p1, p2, p3, p4, p5, p6, p7);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8>
+std::basic_string<CT> format(const std::basic_string<CT> fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7, const T8& p8) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt.c_str(), fmt.size(),
+ p0, p1, p2, p3, p4, p5, p6, p7, p8);
+ return stream.str();
+}
+
+template <typename CT,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8, typename T9>
+std::basic_string<CT> format(const std::basic_string<CT> fmt,
+ const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+ const T5& p5, const T6& p6, const T7& p7, const T8& p8, const T9& p9) {
+ std::basic_stringstream<CT> stream;
+ strmfmtl(stream, fmt.c_str(), fmt.size(),
+ p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+ return stream.str();
+}
+
+} // namespace typesafe_format
diff --git a/tools/intergen/utils/include/utils/stl_utils.h b/tools/intergen/utils/include/utils/stl_utils.h
new file mode 100644
index 000000000..0b3718947
--- /dev/null
+++ b/tools/intergen/utils/include/utils/stl_utils.h
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef STL_UTILS_H_
+#define STL_UTILS_H_
+
+/*
+ * Common helper functions that work with STL types
+ */
+
+#include <cassert>
+#include <map>
+#include <set>
+
+namespace utils {
+
+/*
+ * Collects all the keys from given map |m|
+ */
+template<typename K, typename V>
+std::set<K> MapKeys(const std::map<K, V> m) {
+ std::set<K> keys;
+ for (typename std::map<K, V>::const_iterator i = m.begin(), end = m.end();
+ i != end; ++i) {
+ keys.insert(i->first);
+ }
+ return keys;
+}
+
+/*
+ * Automatcally deletes all the values |cont| elements are pointing to.
+ */
+template<typename T>
+class StdContainerDeleter {
+ public:
+ explicit StdContainerDeleter(T* cont)
+ : cont_(cont) {
+ }
+ ~StdContainerDeleter() {
+ for (typename T::iterator i = cont_->begin(), end = cont_->end(); i != end;
+ ++i) {
+ delete *i;
+ }
+ }
+ private:
+ T* cont_;
+};
+
+/*
+ * Automatcally deletes all map values |cont| elements are pointing to.
+ */
+template<typename T>
+ class StdMapDeleter {
+public:
+ explicit StdMapDeleter(T* cont)
+ : cont_(cont) {
+ }
+ ~StdMapDeleter() {
+ for (typename T::iterator i = cont_->begin(), end = cont_->end(); i != end;
+ ++i) {
+ delete i->second;
+ }
+ }
+private:
+ T* cont_;
+};
+
+
+
+}
+
+#endif /* STL_UTILS_H_ */
diff --git a/tools/intergen/utils/include/utils/string_utils.h b/tools/intergen/utils/include/utils/string_utils.h
new file mode 100644
index 000000000..78c1b87aa
--- /dev/null
+++ b/tools/intergen/utils/include/utils/string_utils.h
@@ -0,0 +1,161 @@
+/**
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef STRING_UTILS_H_
+#define STRING_UTILS_H_
+
+#include <stdint.h>
+#include <algorithm>
+#include <cassert>
+#include <cctype>
+#include <functional>
+#include <ostream>
+#include <sstream>
+#include <string>
+
+/*
+ * Commonly used string processing functions
+ */
+
+/*
+ * Stream indentation helper class. Hooks the stream that is
+ * passed to it's constructor processing all the input to that stream
+ * and issuing indentation spaces when newline symbol is put to the stream.
+ * Unhooks from stream on destruction.
+ */
+class Indent: private std::streambuf {
+public:
+ /*
+ * Constructs indentation 'sentry' object hooking on |dest| stream.
+ * |ident_size| is the indentation width (spaces).
+ */
+ explicit Indent(std::ostream& dest, size_t ident_size = 2)
+ : dest_buf_(dest.rdbuf()),
+ new_line_started_(true),
+ ident_(ident_size, ' '),
+ owner_(&dest) {
+ owner_->rdbuf(this);
+ }
+ ~Indent() {
+ owner_->rdbuf( dest_buf_ );
+ }
+private:
+ virtual int overflow( int ch ) {
+ if ( new_line_started_ && ch != '\n' ) {
+ dest_buf_->sputn(ident_.data(), ident_.size());
+ }
+ new_line_started_ = ch == '\n';
+ return dest_buf_->sputc(ch);
+ }
+private:
+ std::streambuf* dest_buf_;
+ bool new_line_started_;
+ std::string ident_;
+ std::ostream* owner_;
+};
+
+/*
+ * String to numerical (int, double) conversion function.
+ * Checks wether |str_val| contains a number and converts
+ * it to |out_val|.
+ * Returns false on failure.
+ */
+template<typename T>
+bool StringToNumber(const std::string& str_val, T* out_val) {
+ assert(out_val);
+ std::stringstream stream(str_val);
+ stream>>(*out_val);
+ return bool(stream);
+}
+
+/*
+ * Number to string conversion function.
+ */
+template<typename T>
+inline std::string NumberToString(T number) {
+ std::stringstream stream;
+ std::string result;
+ stream<<number;
+ stream>>result;
+ return result;
+}
+
+/*
+ * In-place string trimming function, trims spaces at string beginning
+ */
+inline std::string& ltrim(std::string &s) {
+ s.erase(
+ s.begin(),
+ std::find_if(s.begin(), s.end(),
+ std::not1(std::ptr_fun<int, int>(std::isspace))));
+ return s;
+}
+
+/*
+ * In-place string trimming function, trims spaces at string end
+ */
+inline std::string& rtrim(std::string &s) {
+ s.erase(
+ std::find_if(s.rbegin(), s.rend(),
+ std::not1(std::ptr_fun<int, int>(std::isspace))).base(),
+ s.end());
+ return s;
+}
+
+/*
+ * In-place string trimming function, trims spaces around text
+ */
+inline std::string& trim(std::string &s) {
+ return ltrim(rtrim(s));
+}
+
+/*
+ * Converts ASCII string to lowercase
+ */
+inline std::string to_lower(std::string str) {
+ for (std::string::iterator i = str.begin(); i != str.end(); ++i) {
+ *i = std::tolower(*i);
+ }
+ return str;
+}
+
+/*
+ * Converts ASCII string to uppercase
+ */
+inline std::string to_upper(std::string str) {
+ for (std::string::iterator i = str.begin(); i != str.end(); ++i) {
+ *i = std::toupper(*i);
+ }
+ return str;
+}
+
+#endif /* STRING_UTILS_H_ */
diff --git a/tools/intergen/utils/include/utils/xml_utils.h b/tools/intergen/utils/include/utils/xml_utils.h
new file mode 100644
index 000000000..6c5c3ed3b
--- /dev/null
+++ b/tools/intergen/utils/include/utils/xml_utils.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef XML_UTILS_H_
+#define XML_UTILS_H_
+
+/*
+ * This file contains commonly used XML functions
+ */
+
+#include "utils/common_types.h"
+
+namespace pugi {
+class xml_node;
+}
+
+namespace codegen {
+
+// Extract all the non-empty description sub-nodes and collect them in
+// Description object
+Description CollectDescription(const pugi::xml_node& node);
+
+} // namespace codegen
+
+#endif /* XML_UTILS_H_ */
diff --git a/tools/intergen/utils/src/utils/common_types.cc b/tools/intergen/utils/src/utils/common_types.cc
new file mode 100644
index 000000000..535ce5a74
--- /dev/null
+++ b/tools/intergen/utils/src/utils/common_types.cc
@@ -0,0 +1,77 @@
+/**
+* Copyright (c) 2014, Ford Motor Company
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of the Ford Motor Company nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "utils/common_types.h"
+
+#include <cmath>
+
+namespace codegen {
+
+using std::string;
+
+Fraction::Fraction()
+ : numer_(0),
+ denumer_(1) {
+}
+
+Fraction::Fraction(int64_t numer, int64_t denumer)
+: numer_(numer), denumer_(denumer) {
+}
+
+// static
+bool Fraction::FromFloatPointString(const std::string& literal, Fraction* fraction) {
+ size_t dot_position = literal.find('.');
+ string wholes_str = literal.substr(0, dot_position);
+ string decs_str;
+ if (dot_position != literal.npos) {
+ decs_str = literal.substr(dot_position + 1);
+ }
+ int64_t numer_val = 0;
+ if (StringToNumber(wholes_str + decs_str, &numer_val)) {
+ int64_t denumer_val = pow(10, decs_str.size());
+ *fraction = Fraction(numer_val, denumer_val);
+ return true;
+ }
+ return false;
+}
+
+int64_t Fraction::numer() const {
+ return numer_;
+}
+
+int64_t Fraction::denumer() const {
+ return denumer_;
+}
+
+} // namespace codegen
+
+
diff --git a/tools/intergen/utils/src/utils/safeformat.cc b/tools/intergen/utils/src/utils/safeformat.cc
new file mode 100644
index 000000000..0db0bebe6
--- /dev/null
+++ b/tools/intergen/utils/src/utils/safeformat.cc
@@ -0,0 +1,107 @@
+/*
+* Typesafe printf-like wrapper around std streams
+* by Igor Kozyrenko, 2013
+*/
+
+#include "utils/safeformat.h"
+
+#include <sstream>
+#include <algorithm>
+#include <iterator>
+
+namespace typesafe_format {
+namespace impl {
+
+const char kPlaceholderPrefix = '{';
+const char kPlaceholderSuffix = '}';
+
+struct Placeholder {
+ bool escaped;
+ size_t escaped_prefixes;
+ size_t number;
+ size_t length;
+};
+
+void missing_parameter(std::ostream& os, size_t param_number) {
+ os<<"{Parameter "<<param_number<<" is missing}";
+}
+
+void missing_parameter(std::wostream& os, size_t param_number) {
+ os<<L"{Parameter "<<param_number<<L" is missing}";
+}
+
+template <typename CT>
+const CT* find_placeholder_tmpl(const CT* text, const CT* end,
+ Placeholder& ph) {
+ const CT* prefix_begin = text;
+ bool done = false;
+ do {
+ prefix_begin = std::find(prefix_begin, end, kPlaceholderPrefix);
+ // there must be at least two symbols after prefix
+ if (std::distance(prefix_begin, end) > 2) {
+ const CT* prefix_end = prefix_begin + 1;
+ // count prefix escapes if any
+ while(*prefix_end == kPlaceholderPrefix &&
+ std::distance(prefix_end, end) > 2)
+ ++prefix_end;
+ size_t prefixes = std::distance(prefix_begin, prefix_end);
+ size_t prefix_number = *prefix_end - '0';
+ const CT* suffix = prefix_end + 1;
+ if (prefix_number < 10 && // it is in range of valid placeholders
+ *suffix == kPlaceholderSuffix) {
+ ph.escaped = prefixes % 2 == 0;
+ ph.escaped_prefixes = prefixes / 2;
+ ph.number = prefix_number;
+ ph.length = (suffix - prefix_begin) + 1;
+ done = true;
+ } else {
+ prefix_begin = suffix; // continue from the symbol after number
+ }
+ } else { // prefix_begin is not at least last but two
+ prefix_begin = end;
+ done = true;
+ }
+ } while (!done);
+ return prefix_begin;
+}
+
+template <typename CT>
+void format_params_tmpl(const CT* fmt, size_t fmt_length,
+ std::basic_ostream<CT>& os,
+ const Streamable<CT>* params[], size_t params_count) {
+ const CT* text = fmt;
+ const CT* end = fmt + fmt_length;
+ Placeholder placeholder;
+ for (const CT* ph_pos = find_placeholder_tmpl(text, end, placeholder);
+ ph_pos != end;
+ ph_pos = find_placeholder_tmpl(text, end, placeholder)) {
+ os.write(text, ph_pos - text);
+ for (size_t i = 0; i != placeholder.escaped_prefixes; ++i)
+ os.put(kPlaceholderPrefix);
+ if (placeholder.escaped) {
+ os<<placeholder.number<<kPlaceholderSuffix;
+ } else {
+ if (placeholder.number < params_count)
+ params[placeholder.number]->OutputToStream(os);
+ else {
+ missing_parameter(os, placeholder.number);
+ }
+ }
+ text = ph_pos + placeholder.length;
+ }
+ os.write(text, end - text);
+}
+
+void format_params(const char* fmt, size_t fmt_length, std::ostream& os,
+ const Streamable<char>* params[], size_t params_count) {
+ format_params_tmpl(fmt, fmt_length, os, params, params_count);
+}
+void format_params(const wchar_t* fmt, size_t fmt_length, std::wostream& os,
+ const Streamable<wchar_t>* params[], size_t params_count) {
+ format_params_tmpl(fmt, fmt_length, os, params, params_count);
+}
+
+
+
+} // namespace impl
+} // namespace typesafe_format
diff --git a/tools/intergen/utils/src/utils/xml_utils.cc b/tools/intergen/utils/src/utils/xml_utils.cc
new file mode 100644
index 000000000..a66fbce90
--- /dev/null
+++ b/tools/intergen/utils/src/utils/xml_utils.cc
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "utils/xml_utils.h"
+
+#include "pugixml.hpp"
+#include "utils/string_utils.h"
+
+namespace codegen {
+
+Description CollectDescription(const pugi::xml_node& node) {
+ Description description;
+ for (pugi::xml_node i = node.child("description"); i;
+ i = i.next_sibling("description")) {
+ std::string description_string = i.child_value();
+ trim(description_string);
+ if (!description_string.empty()) {
+ description.push_back(description_string);
+ }
+ }
+ return description;
+}
+
+} // namespace codegen