diff options
Diffstat (limited to 'tools/intergen/utils')
-rw-r--r-- | tools/intergen/utils/CMakeLists.txt | 22 | ||||
-rw-r--r-- | tools/intergen/utils/include/utils/common_types.h | 132 | ||||
-rw-r--r-- | tools/intergen/utils/include/utils/macro.h | 48 | ||||
-rw-r--r-- | tools/intergen/utils/include/utils/safeformat.h | 579 | ||||
-rw-r--r-- | tools/intergen/utils/include/utils/stl_utils.h | 101 | ||||
-rw-r--r-- | tools/intergen/utils/include/utils/string_utils.h | 161 | ||||
-rw-r--r-- | tools/intergen/utils/include/utils/xml_utils.h | 54 | ||||
-rw-r--r-- | tools/intergen/utils/src/utils/common_types.cc | 77 | ||||
-rw-r--r-- | tools/intergen/utils/src/utils/safeformat.cc | 107 | ||||
-rw-r--r-- | tools/intergen/utils/src/utils/xml_utils.cc | 52 |
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 |