Squashed 'third_party/ctemplate/' content from commit 6742f62
Change-Id: I828e4e4c906f13ba19944d78a8a78652b62949af
git-subtree-dir: third_party/ctemplate
git-subtree-split: 6742f6233db12f545e90baa8f34f5c29c4eb396a
diff --git a/src/windows/config.h b/src/windows/config.h
new file mode 100644
index 0000000..d8a1e94
--- /dev/null
+++ b/src/windows/config.h
@@ -0,0 +1,222 @@
+/* A manual version of config.h fit for windows machines. */
+
+/* Sometimes we accidentally #include this config.h instead of the one
+ in .. -- this is particularly true for msys/mingw, which uses the
+ unix config.h but also runs code in the windows directory.
+*/
+#if defined(__MINGW32__) || defined(__MING64__)
+#define CTEMPLATE_DLL_DECL
+// These two lines make sure we read the unix-style config.h, and not the
+// windows-style config.h -- it would be bad if we tried to read both!
+#include "../config.h"
+#define GOOGLE_CTEMPLATE_WINDOWS_CONFIG_H_
+#endif
+
+#ifndef GOOGLE_CTEMPLATE_WINDOWS_CONFIG_H_
+#define GOOGLE_CTEMPLATE_WINDOWS_CONFIG_H_
+
+/* Namespace for Google classes */
+#define GOOGLE_NAMESPACE ctemplate
+
+/* the location of <unordered_map> or <hash_map> */
+#define HASH_MAP_H <hash_map>
+
+/* the namespace of hash_map/hash_set */
+#define HASH_NAMESPACE stdext
+
+/* the location of <unordered_set> or <hash_set> */
+#define HASH_SET_H <hash_set>
+
+/* Define to 1 if you have the <byteswap.h> header file. */
+#undef HAVE_BYTESWAP_H
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <endian.h> header file. */
+#undef HAVE_ENDIAN_H
+
+/* Define to 1 if you have the `getopt' function. */
+#undef HAVE_GETOPT
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#undef HAVE_GETOPT_H
+
+/* Define to 1 if you have the `getopt_long' function. */
+#undef HAVE_GETOPT_LONG
+
+/* define if the compiler has hash_map */
+#define HAVE_HASH_MAP 1
+
+/* define if the compiler has hash_set */
+#define HAVE_HASH_SET 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
+#undef HAVE_LIBKERN_OSBYTEORDER_H
+
+/* Define to 1 if you have the <machine/endian.h> header file. */
+#undef HAVE_MACHINE_ENDIAN_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* define if the compiler implements namespaces */
+#define HAVE_NAMESPACES 1
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* define if the compiler implements pthread_rwlock_* */
+#undef HAVE_RWLOCK
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/byteorder.h> header file. */
+#undef HAVE_SYS_BYTEORDER_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/endian.h> header file. */
+#undef HAVE_SYS_ENDIAN_H
+
+/* Define to 1 if you have the <sys/isa_defs.h> header file. */
+#undef HAVE_SYS_ISA_DEFS_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if the system has the type `uint32_t'. */
+#undef HAVE_UINT32_T
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#undef HAVE_UINT64_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* define if the compiler supports unordered_{map,set} */
+#undef HAVE_UNORDERED_MAP
+
+/* Define to 1 if you have the <utime.h> header file. */
+#undef HAVE_UTIME_H
+
+/* Define to 1 if the system has the type `u_int32_t'. */
+#undef HAVE_U_INT32_T
+
+/* Define to 1 if the system has the type `u_int64_t'. */
+#undef HAVE_U_INT64_T
+
+/* define if your compiler has __attribute__ */
+#undef HAVE___ATTRIBUTE__
+
+/* Define to 1 if the system has the type `__uint32. */
+#define HAVE___INT32 1
+
+/* Define to 1 if the system has the type `__uint64. */
+#define HAVE___INT64 1
+
+/* The namespace to put the htmlparser code. */
+#define HTMLPARSER_NAMESPACE google_ctemplate_streamhtmlparser
+
+/* define if first argument to InterlockedExchange is just LONG */
+#undef INTERLOCKED_EXCHANGE_NONVOLATILE
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "ctemplate 1.1"
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* printf format code for printing a size_t and ssize_t */
+#define PRIdS "Id"
+
+/* printf format code for printing a size_t and ssize_t */
+#define PRIuS "Iu"
+
+/* printf format code for printing a size_t and ssize_t */
+#define PRIxS "Ix"
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* the namespace where STL code like vector<> is defined */
+#define STL_NAMESPACE std
+
+/* Version number of package */
+#undef VERSION
+
+/* Stops putting the code inside the Google namespace */
+#define _END_GOOGLE_NAMESPACE_ }
+
+/* Puts following code inside the Google namespace */
+#define _START_GOOGLE_NAMESPACE_ namespace ctemplate {
+
+// ---------------------------------------------------------------------
+// Extra stuff not found in config.h.in
+
+// This must be defined before anything else in our project: make sure
+// that when compiling the dll, we export our functions/classes. Safe
+// to define this here because this file is only used internally, to
+// compile the DLL, and every dll source file #includes "config.h"
+// before anything else.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllexport)
+# define CTEMPLATE_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
+#endif
+
+// TODO(csilvers): include windows/port.h in every relevant source file instead?
+#include "windows/port.h"
+
+#endif /* GOOGLE_CTEMPLATE_WINDOWS_CONFIG_H_ */
diff --git a/src/windows/ctemplate/find_ptr.h b/src/windows/ctemplate/find_ptr.h
new file mode 100644
index 0000000..8e6fec5
--- /dev/null
+++ b/src/windows/ctemplate/find_ptr.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2012, Olaf van der Spek <olafvdspek@gmail.com>
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+// Author: Olaf van der Spek <olafvdspek@gmail.com>
+
+#ifndef TEMPLATE_FIND_PTR_H_
+#define TEMPLATE_FIND_PTR_H_
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+
+template <class T, class U>
+typename T::value_type::second_type* find_ptr(T& c, U v)
+{
+ typename T::iterator i = c.find(v);
+ return i == c.end() ? NULL : &i->second;
+}
+
+template <class T, class U>
+const typename T::value_type::second_type* find_ptr(const T& c, U v)
+{
+ typename T::const_iterator i = c.find(v);
+ return i == c.end() ? NULL : &i->second;
+}
+
+template <class T, class U>
+typename T::value_type::second_type find_ptr2(T& c, U v)
+{
+ typename T::iterator i = c.find(v);
+ return i == c.end() ? NULL : i->second;
+}
+
+template <class T, class U>
+const typename T::value_type::second_type find_ptr2(const T& c, U v)
+{
+ typename T::const_iterator i = c.find(v);
+ return i == c.end() ? NULL : i->second;
+}
+
+}
+
+#endif // TEMPLATE_FIND_PTR_H_
diff --git a/src/windows/ctemplate/per_expand_data.h b/src/windows/ctemplate/per_expand_data.h
new file mode 100644
index 0000000..6abce97
--- /dev/null
+++ b/src/windows/ctemplate/per_expand_data.h
@@ -0,0 +1,154 @@
+// Copyright (c) 2008, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+// Author: csilvers@google.com (Craig Silverstein)
+//
+// In addition to a TemplateDictionary, there is also a PerExpandData
+// dictionary. This dictionary holds information that applies to one
+// call to Expand, such as whether to annotate the template expansion
+// output. A template dictionary is associated with a template (.tpl)
+// file; a per-expand dictionary is associated to a particular call to
+// Expand() in a .cc file.
+//
+// For (many) more details, see the doc/ directory.
+
+#ifndef TEMPLATE_PER_EXPAND_DATA_H_
+#define TEMPLATE_PER_EXPAND_DATA_H_
+
+#include <stdlib.h> // for NULL
+#include <string.h> // for strcmp
+#include <sys/types.h>
+#include <hash_map>
+#include <ctemplate/template_string.h> // for StringHash
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+
+class TemplateModifier;
+class TemplateAnnotator;
+
+class CTEMPLATE_DLL_DECL PerExpandData {
+ public:
+ PerExpandData()
+ : annotate_path_(NULL),
+ annotator_(NULL),
+ expand_modifier_(NULL),
+ map_(NULL) { }
+
+ ~PerExpandData();
+
+ // Indicate that annotations should be inserted during template expansion.
+ // template_path_start - the start of a template path. When
+ // printing the filename for template-includes, anything before and
+ // including template_path_start is elided. This can make the
+ // output less dependent on filesystem location for template files.
+ void SetAnnotateOutput(const char* template_path_start) {
+ annotate_path_ = template_path_start;
+ }
+
+ // Whether to annotate the expanded output.
+ bool annotate() const { return annotate_path_ != NULL; }
+
+ // The annotate-path; undefined if annotate() != true
+ const char* annotate_path() const { return annotate_path_; }
+
+ // This sets the TemplateAnnotator to be used when annotating is on.
+ // This allows you to override the default text-based annotator
+ // that will be used if you do not call this. The passed annotator
+ // will be aliased by this object and returned by annotator().
+ // Passing NULL has the special behavior of causing annotator() to
+ // revert to returning its built-in instance.
+ void SetAnnotator(TemplateAnnotator* annotator) {
+ annotator_ = annotator;
+ }
+
+ // This returns the TemplateAnnotator to be used when annotating is on.
+ // The value returned will be either an instance previously provided
+ // to SetAnnotator() or the callable built-in text-based annotator.
+ TemplateAnnotator* annotator() const;
+
+ // This is a TemplateModifier to be applied to all templates
+ // expanded via this call to Expand(). That is, this modifier is
+ // applies to the template (.tpl) file we expand, as well as
+ // sub-templates that are expanded due to {{>INCLUDE}} directives.
+ // Caller is responsible for ensuring that modifier exists for the
+ // lifetime of this object.
+ void SetTemplateExpansionModifier(const TemplateModifier* modifier) {
+ expand_modifier_ = modifier;
+ }
+
+ const TemplateModifier* template_expansion_modifier() const {
+ return expand_modifier_;
+ }
+
+ // Store data in this structure, to be used by template modifiers
+ // (see template_modifiers.h). Call with value set to NULL to clear
+ // any value previously set. Caller is responsible for ensuring key
+ // and value point to valid data for the lifetime of this object.
+ void InsertForModifiers(const char* key, const void* value);
+
+ // Retrieve data specific to this Expand call. Returns NULL if key
+ // is not found. This should only be used by template modifiers.
+ const void* LookupForModifiers(const char* key) const;
+
+ // Same as Lookup, but casts the result to a c string.
+ const char* LookupForModifiersAsString(const char* key) const {
+ return static_cast<const char*>(LookupForModifiers(key));
+ }
+
+ private:
+#ifdef _MSC_VER
+ typedef stdext::hash_map<const char*, const void*, StringHash> DataMap;
+#else
+ struct DataEq {
+ bool operator()(const char* s1, const char* s2) const;
+ };
+ typedef stdext::hash_map<const char*, const void*, StringHash, DataEq>
+ DataMap;
+#endif
+
+ const char* annotate_path_;
+ TemplateAnnotator* annotator_;
+ const TemplateModifier* expand_modifier_;
+ DataMap* map_;
+
+ PerExpandData(const PerExpandData&); // disallow evil copy constructor
+ void operator=(const PerExpandData&); // disallow evil operator=
+};
+
+}
+
+#endif // TEMPLATE_PER_EXPAND_DATA_H_
diff --git a/src/windows/ctemplate/str_ref.h b/src/windows/ctemplate/str_ref.h
new file mode 100644
index 0000000..20a2663
--- /dev/null
+++ b/src/windows/ctemplate/str_ref.h
@@ -0,0 +1,134 @@
+// Copyright (c) 2012, Olaf van der Spek <olafvdspek@gmail.com>
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+// Author: Olaf van der Spek <olafvdspek@gmail.com>
+
+#ifndef TEMPLATE_STR_REF_H_
+#define TEMPLATE_STR_REF_H_
+
+#include <cstddef>
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+
+template <class T>
+class str_ref_basic
+{
+public:
+ str_ref_basic()
+ {
+ clear();
+ }
+
+ template <class U>
+ str_ref_basic(const U& c)
+ {
+ if (c.end() != c.begin())
+ assign(&*c.begin(), c.end() - c.begin() + &*c.begin());
+ else
+ clear();
+ }
+
+ str_ref_basic(const void* b, const void* e)
+ {
+ assign(b, e);
+ }
+
+ str_ref_basic(const void* b, size_t sz)
+ {
+ assign(b, sz);
+ }
+
+ str_ref_basic(const char* b)
+ {
+ if (b)
+ assign(b, strlen(b));
+ else
+ clear();
+ }
+
+ void clear()
+ {
+ begin_ = end_ = NULL;
+ }
+
+ void assign(const void* b, const void* e)
+ {
+ begin_ = reinterpret_cast<T>(b);
+ end_ = reinterpret_cast<T>(e);
+ }
+
+ void assign(const void* b, size_t sz)
+ {
+ begin_ = reinterpret_cast<T>(b);
+ end_ = begin_ + sz;
+ }
+
+ T begin() const
+ {
+ return begin_;
+ }
+
+ T end() const
+ {
+ return end_;
+ }
+
+ T data() const
+ {
+ return begin();
+ }
+
+ size_t size() const
+ {
+ return end() - begin();
+ }
+
+ bool empty() const
+ {
+ return begin() == end();
+ }
+private:
+ T begin_;
+ T end_;
+};
+
+typedef str_ref_basic<const unsigned char*> data_ref;
+typedef str_ref_basic<const char*> str_ref;
+
+}
+
+#endif // TEMPLATE_STR_REF_H_
diff --git a/src/windows/ctemplate/template.h b/src/windows/ctemplate/template.h
new file mode 100644
index 0000000..4d12cb7
--- /dev/null
+++ b/src/windows/ctemplate/template.h
@@ -0,0 +1,492 @@
+// Copyright (c) 2006, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+//
+// This file implements the Template class. For information about
+// how to use this class, and to write the templates it takes as input,
+// see the doc/ directory.
+
+#ifndef CTEMPLATE_TEMPLATE_H_
+#define CTEMPLATE_TEMPLATE_H_
+
+#include <time.h> // for time_t
+#include <string>
+#include <ctemplate/template_cache.h>
+#include <ctemplate/template_enums.h>
+#include <ctemplate/template_string.h>
+
+// We include this just so folks don't have to include both template.h
+// and template_dictionary.h, or template_namelist.h etc, to use the
+// template system; we don't actually use anything in these files
+// ourselves.
+#if 1
+#include <ctemplate/template_dictionary.h>
+#include <ctemplate/template_namelist.h>
+#include <ctemplate/per_expand_data.h>
+#else
+namespace ctemplate {
+class TemplateDictionaryInterface;
+class PerExpandData;
+}
+#endif
+
+namespace google_ctemplate_streamhtmlparser {
+class HtmlParser;
+}
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+
+// These free functions form the "simple" template API, and support
+// the most common operations (expanding a template from a file, and
+// from a string). They all just delegate to a default instance of
+// the TemplateCache object.
+//
+// For more sophisticated use of the template system, you may need
+// to create your own TemplateCache object, and work directly with
+// it. See template_cache.h for details.
+
+extern CTEMPLATE_DLL_DECL const TemplateCache* default_template_cache();
+extern CTEMPLATE_DLL_DECL TemplateCache* mutable_default_template_cache();
+
+
+// ---- EXPANDING A TEMPLATE -------
+// ExpandTemplate
+// ExpandWithData
+
+// Loads the template named filename from disk if necessary -- it
+// gets it from the cache instead, if the template had been loaded
+// before or if it had been put explicitly in the cache via a call
+// to StringToTemplateCache() -- and expands it using the given
+// dictionary.
+// The first version is the most general, followed by common-case code.
+inline bool ExpandTemplate(const TemplateString& filename, Strip strip,
+ const TemplateDictionaryInterface *dictionary,
+ ExpandEmitter* output) {
+ return mutable_default_template_cache()->ExpandWithData(
+ filename, strip, dictionary, NULL, output);
+}
+inline bool ExpandTemplate(const TemplateString& filename, Strip strip,
+ const TemplateDictionaryInterface* dictionary,
+ std::string* output_buffer) {
+ return mutable_default_template_cache()->ExpandWithData(
+ filename, strip, dictionary, NULL, output_buffer);
+}
+
+// If you want any per-expand data to be used at expand time, call
+// this routine instead of Expand. You pass in an extra
+// PerExpandData structure (see per_expand_data.h) which sets this
+// data: whether or not you want the template to be annotated, and
+// any data you want to pass in to template modifers. If
+// per_expand_data is NULL, this is exactly the same as Expand().
+// The first version is the most general, followed by common-case code.
+inline bool ExpandWithData(const TemplateString& filename, Strip strip,
+ const TemplateDictionaryInterface *dictionary,
+ PerExpandData* per_expand_data,
+ ExpandEmitter* output) {
+ return mutable_default_template_cache()->ExpandWithData(
+ filename, strip, dictionary, per_expand_data, output);
+}
+inline bool ExpandWithData(const TemplateString& filename, Strip strip,
+ const TemplateDictionaryInterface* dictionary,
+ PerExpandData* per_expand_data,
+ std::string* output_buffer) {
+ return mutable_default_template_cache()->ExpandWithData(
+ filename, strip, dictionary, per_expand_data, output_buffer);
+}
+
+// ---- INSERTING INTO THE CACHE -------
+// LoadTemplate
+// StringToTemplateCache
+
+// Reads a file from disk and inserts it into the template, if it's
+// not already there. Returns true on success or false if the
+// template could not be found, or could not be parsed. It's never
+// necessary to call this -- Expand() will load templates lazily if
+// needed -- but you may want to if you want to make sure templates
+// exist before trying to expand them, or because you want to
+// control disk access patterns, or for some other reason.
+inline bool LoadTemplate(const TemplateString& filename, Strip strip) {
+ return mutable_default_template_cache()->LoadTemplate(filename, strip);
+}
+
+// Inserts the given string into the default template cache, as if
+// it were a file read from disk. You can call Expand() with its
+// first arg (filename) the same as the key you use here. You can
+// also use this key as the 'filename' for sub-included templates,
+// in TemplateDictionary::SetFilename().
+inline bool StringToTemplateCache(const TemplateString& key,
+ const TemplateString& content,
+ Strip strip) {
+ return mutable_default_template_cache()->StringToTemplateCache(
+ key, content, strip);
+}
+inline bool StringToTemplateCache(const TemplateString& key,
+ const char* content, size_t content_len,
+ Strip strip) {
+ return mutable_default_template_cache()->StringToTemplateCache(
+ key, content, content_len, strip);
+}
+
+
+// ---------------------------------------------------------------------
+// The follow are deprecated.
+// TODO(csilvers): move to parsed_template.h
+
+// TemplateState of a template is:
+// - TS_EMPTY before parsing is complete,
+// - TS_ERROR if a syntax error was found during parsing, and
+// - TS_READY if parsing has completed successfully
+// (TS_UNUSED is not used)
+enum TemplateState { TS_UNUSED, TS_EMPTY, TS_ERROR, TS_READY };
+
+// Used for Auto-Escape. It represents the different contexts a template may
+// be initialized in via the AUTOESCAPE pragma in the template file
+// (or string). It is only public for testing. The contexts are:
+// - TC_HTML: The template contains HTML code. Need not be a complete HTML
+// page just content the browser interprets in the context of
+// HTML parsing. This should be the most common context to use.
+// This mode activates our HTML parser.
+// - TC_JS: The template contains raw javascript. If your template
+// starts with <script> tag, it is of type TC_HTML not TC_JS.
+// TC_JS is typically associated with a content-type of
+// text/javascript. This mode activates our HTML parser.
+// - TC_CSS: The template contains CSS (cascaded style-sheet). If your
+// template starts with a <style> tag, it is of type TC_HTML
+// not TC_CSS. A TC_CSS template is typically associated with a
+// text/css content-type header. Currently treated same as
+// TC_HTML but don't rely on that. We may later develop
+// CSS-specific sanitizers and parsers.
+// - TC_JSON: The template contains raw JSON. Applies javascript_escape
+// to variables. Note: javascript_escape is safer than
+// json_escape which we may want to remove.
+// - TC_XML: The template contains raw XML. Applies xml_escape to variables.
+// CAUTION: This mode is not suitable for cases where the
+// application data encapsulated in XML requires special
+// escaping, such as the case of XHTML.
+// TC_XML is typically associated with text/xml content-type.
+// - TC_MANUAL: Equivalent to not specifying auto-escaping at all.
+//
+// TODO(csilvers): Make this a private part of the Template class.
+enum TemplateContext { TC_UNUSED, TC_HTML, TC_JS, TC_CSS, TC_JSON,
+ TC_XML, TC_MANUAL };
+
+
+// This class is deprecated. Old code uses this class heavily (via
+// GetTemplate() to obtain a Template*, and then methods on that
+// Template*) but new code should use the free functions above.
+class CTEMPLATE_DLL_DECL Template {
+ public:
+ // ---- METHODS FOR TOOLS ----
+ // These are not intended for normal use, but are public so a
+ // tool can use them.
+
+ // Used by make_tpl_varnames_h.cc.
+ void WriteHeaderEntries(std::string *outstring) const;
+
+ // ---- DEPRECATED METHODS ----
+ // These methods used to be the primary way of using the Template
+ // object, but have been deprecated in favor of the (static)
+ // methods above. If you are using these deprecated methods,
+ // consider moving to the above methods instead, or to moving to
+ // using your own TemplateCache (which supports richer operations
+ // on parsed templates).
+
+ // Loads a template from disk or cache or string, and returns the Template*.
+ // INSTEAD, use the static Expand that takes a filename.
+ static Template *GetTemplate(const TemplateString& filename, Strip strip);
+ virtual ~Template(); // when the time comes to delete these Template*'s.
+
+ // Parses a string immediately and returns the resulting Template*.
+ // You can call the (deprecated) non-static Expand() method on this
+ // template in order to expand it with a dictionary. You are
+ // responsible for deleting the Template* when you are done with it.
+ // INSTEAD, use StringToTemplateCache (with a key) plus the static Expand().
+ // TOOO(csilvers): return a const Template* instead.
+ static Template* StringToTemplate(const TemplateString& content,
+ Strip strip);
+ static Template* StringToTemplate(const char* content, size_t content_len,
+ Strip strip) {
+ return StringToTemplate(TemplateString(content, content_len), strip);
+ }
+
+ // Non-static Expand*() works on a Template* returned from GetTemplate().
+ // INSTEAD, use static expand with a filename (or key-name for strings).
+ bool ExpandWithData(ExpandEmitter* output,
+ const TemplateDictionaryInterface* dictionary,
+ PerExpandData* per_expand_data) const {
+ return ExpandWithDataAndCache(output, dictionary, per_expand_data,
+ default_template_cache());
+ }
+ bool ExpandWithData(std::string* output_buffer,
+ const TemplateDictionaryInterface* dictionary,
+ PerExpandData* per_expand_data) const {
+ if (output_buffer == NULL) return false;
+ StringEmitter e(output_buffer);
+ return ExpandWithData(&e, dictionary, per_expand_data);
+ }
+ bool Expand(ExpandEmitter* output,
+ const TemplateDictionaryInterface* dictionary) const {
+ return ExpandWithData(output, dictionary, NULL);
+ }
+ bool Expand(std::string* output_buffer,
+ const TemplateDictionaryInterface* dictionary) const {
+ return ExpandWithData(output_buffer, dictionary, NULL);
+ }
+
+ // Dump to stdout or a string. filename is just used to annotate output.
+ void Dump(const char *filename) const;
+ void DumpToString(const char *filename, std::string *out) const;
+
+ // Retrieves the state, template-file, or strip mode of this Template.
+ TemplateState state() const;
+ const char *template_file() const;
+ const char *original_filename() const;
+ Strip strip() const;
+
+ // Work at the level of groups of templates, so just call through to
+ // the default TemplateCache; see template_cache.h for what these do.
+ // INSTEAD, create your own TemplateCache and call these methods on that.
+ static bool SetTemplateRootDirectory(const std::string& dir) {
+ return mutable_default_template_cache()->SetTemplateRootDirectory(dir);
+ }
+ static bool AddAlternateTemplateRootDirectory(const std::string& dir) {
+ return mutable_default_template_cache()->AddAlternateTemplateRootDirectory(
+ dir);
+ }
+ static std::string template_root_directory() {
+ return default_template_cache()->template_root_directory();
+ }
+ static std::string FindTemplateFilename(
+ const std::string& unresolved) {
+ return default_template_cache()->FindTemplateFilename(unresolved);
+ }
+ static void RemoveStringFromTemplateCache(const std::string& key) {
+ mutable_default_template_cache()->Delete(key);
+ }
+ static void ClearCache() {
+ mutable_default_template_cache()->ClearCache();
+ }
+ static void ReloadAllIfChanged() {
+ mutable_default_template_cache()->ReloadAllIfChanged(
+ TemplateCache::LAZY_RELOAD);
+ }
+
+ // ---- EXTRA-DEPRECATED METHODS ----
+ // These methods were deprecated even before the move to
+ // TemplateCache. We'd really like you to move from these to one
+ // of the "approved" methods, or even one of the deprecated
+ // methods. Comments here don't even describe what these
+ // functions do, just how to transition off of using them.
+
+ // INSTEAD, use the StringToTemplateCache function that takes the strip mode.
+ static bool StringToTemplateCache(const TemplateString& key,
+ const TemplateString& content);
+ static bool StringToTemplateCache(const TemplateString& key,
+ const char* content, size_t content_len) {
+ return StringToTemplateCache(key, TemplateString(content, content_len));
+ }
+ // This is to prevent against typos: you want the global (free-function)
+ // StringToTemplateCache here, not the one in Template.
+ static bool StringToTemplateCache(const TemplateString& key,
+ const char* content, Strip);
+
+ // INSTEAD, use ReloadAllIfChanged.
+ bool ReloadIfChanged();
+
+ protected:
+ friend class SectionTemplateNode; // for access to set_state(), ParseState
+ friend class TemplateTemplateNode; // for recursive call to Expand()
+
+ // Template constructor
+ // Reads the template file and parses it into a parse tree of TemplateNodes
+ // by calling the method ReloadIfChanged
+ // The top node is a section node with the arbitrary name "__{{MAIN}}__"
+ // 'Strip' indicates how to handle whitespace when expanding the
+ // template. DO_NOT_STRIP keeps the template exactly as-is.
+ // STRIP_BLANK_LINES elides all blank lines in the template.
+ // STRIP_WHITESPACE elides all blank lines, and also all whitespace
+ // at either the beginning or end of a line. It also removes
+ // any linefeed (possibly following whitespace) that follows a closing
+ // '}}' of any kind of template marker EXCEPT a template variable.
+ // This means a linefeed may be removed anywhere by simply placing
+ // a comment marker as the last element on the line.
+ // These two options allow the template to include whitespace for
+ // readability without adding to the expanded output.
+ Template(const TemplateString& filename, Strip strip, TemplateCache* owner);
+
+ // MaybeInitHtmlParser
+ // In TemplateContexts where the HTML parser is needed, we
+ // initialize it in the appropriate mode. Also we do a sanity
+ // check (cannot fail) on the template filename. This function is
+ // called at most once for a Template. In_tag is only meaningful
+ // for TC_HTML: It is true for templates that start inside an HTML
+ // tag and hence are expected to contain HTML attribute name/value
+ // pairs only. It is false for standard HTML templates.
+ void MaybeInitHtmlParser(bool in_tag);
+
+ // BuildTree
+ // Parses the contents of the file (retrieved via ReloadIfChanged)
+ // and stores the resulting parse structure in tree_. Returns true
+ // iff the tree-builder encountered no errors. Note: takes
+ // ownership of input_buffer, and will delete it. It should have
+ // been created via new[].
+ bool BuildTree(const char *input_buffer, const char* input_buffer_end);
+
+ // Internal version of ReloadIfChanged, used when the function already
+ // has a write-lock on g_template_mutex.
+ bool ReloadIfChangedLocked();
+
+ // set_state
+ // Sets the state of the template. Used during BuildTree().
+ void set_state(TemplateState new_state);
+
+ // StripBuffer
+ // Modifies buffer in-place based on the strip_ mode, to remove
+ // extra whitespace. May delete[] the input buffer and replace
+ // it with a new buffer. Used by ReloadIfChanged().
+ void StripBuffer(char **buffer, size_t* len);
+
+ // The file we originally got from the Template() constructor
+ const std::string original_filename_;
+ // The pathname as fully resolved on the filesystem
+ std::string resolved_filename_;
+ time_t filename_mtime_; // lastmod time for filename last time we loaded it
+
+ // What to do with whitespace at template-expand time
+ Strip strip_;
+
+ // Keeps track of where we are in reloading, or if there was an error loading
+ TemplateState state_;
+
+ // The cache we got this template from. This is not well-defined: a
+ // Template can be in more than one cache.
+ // TODO(csilvers): remove this once we deprecate the one user, which
+ // is ReloadIfChanged.
+ TemplateCache* template_cache_;
+
+ // The current template-contents, as read from the file
+ const char* template_text_;
+ int template_text_len_;
+
+ // The current parsed template structure. Has pointers into template_text_.
+ class SectionTemplateNode *tree_; // defined in template.cc
+
+ // Template markers have the form {{VARIABLE}}, etc. These constants
+ // define the {{ and }} that delimit template markers.
+ struct CTEMPLATE_DLL_DECL MarkerDelimiters {
+ const char* start_marker;
+ size_t start_marker_len;
+ const char* end_marker;
+ size_t end_marker_len;
+
+ MarkerDelimiters() {
+ start_marker = "{{"; // The default start-marker
+ start_marker_len = strlen(start_marker);
+ end_marker = "}}";
+ end_marker_len = strlen(end_marker);
+ }
+ };
+
+ // The current parsing state. Used in BuildTree() and subroutines
+ struct CTEMPLATE_DLL_DECL ParseState {
+ const char* bufstart;
+ const char* bufend;
+ enum { PS_UNUSED, GETTING_TEXT, GETTING_NAME } phase;
+ MarkerDelimiters current_delimiters;
+ ParseState()
+ : bufstart(NULL), bufend(NULL), phase(PS_UNUSED), current_delimiters()
+ {}
+ };
+ ParseState parse_state_;
+
+ // All templates are initialized to TC_MANUAL (no Auto-Escape). Then,
+ // during template parsing (BuildTree()), if an AUTOESCAPE pragma is
+ // encountered, the context changes appropriately.
+ TemplateContext initial_context_;
+ // Non-null if the template was initialized in an Auto-Escape mode that
+ // requires a parser (currently TC_HTML, TC_CSS and TC_JS).
+ google_ctemplate_streamhtmlparser::HtmlParser *htmlparser_;
+
+ // A sorted list of trusted variable names, declared here because a unittest
+ // needs to verify that it is appropriately sorted (an unsorted array would
+ // lead to the binary search of this array failing).
+ static const char * const kSafeWhitelistedVariables[];
+ static const size_t kNumSafeWhitelistedVariables;
+
+ private:
+ friend class TemplateCache;
+ friend class TemplateCachePeer; // to access num_deletes_
+
+ // Internal implementation of Expand
+ bool ExpandWithDataAndCache(ExpandEmitter* output,
+ const TemplateDictionaryInterface *dictionary,
+ PerExpandData* per_expand_data,
+ const TemplateCache* cache) const;
+
+ // This is called for recursive expands, when we already hold template_lock.
+ bool ExpandLocked(ExpandEmitter* output,
+ const TemplateDictionaryInterface *dictionary,
+ PerExpandData* per_expand_data,
+ const TemplateCache* cache) const;
+
+ // Returns the lastmod time in mtime_
+ // For string-based templates, not backed by a file, this returns 0
+ time_t mtime() const;
+
+ // These are helper routines to StripFile. I would make them static
+ // inside template.cc, but they use the MarerDelimiters struct.
+ static bool ParseDelimiters(const char* text, size_t textlen,
+ MarkerDelimiters* delim);
+ static bool IsBlankOrOnlyHasOneRemovableMarker(const char** line, size_t* len,
+ const MarkerDelimiters& delim);
+ static size_t InsertLine(const char *line, size_t len, Strip strip,
+ const MarkerDelimiters& delim, char* buffer);
+
+ // This is only used by template_cache_test, via TemplateCachePeer.
+ static int num_deletes() { return num_deletes_; }
+
+ static int num_deletes_; // how many times the destructor has been called
+
+ // Can't invoke copy constructor or assignment operator
+ Template(const Template&);
+ void operator=(const Template &);
+};
+
+}
+
+
+#endif // CTEMPLATE_TEMPLATE_H_
diff --git a/src/windows/ctemplate/template_annotator.h b/src/windows/ctemplate/template_annotator.h
new file mode 100644
index 0000000..e7daf6d
--- /dev/null
+++ b/src/windows/ctemplate/template_annotator.h
@@ -0,0 +1,142 @@
+// Copyright (c) 2009, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+//
+// The template expansion system provides a set of hooks that allow for
+// the insertion of diagnostic content into the output stream for the use
+// by content developers and testers. For instance, the default text
+// annotation mode inserts strings bracketed by {{ }} to describe every
+// occurrence of a dynamic substitution feature. That mode turns the
+// rendering into a logical text description of the construction of
+// template-based output. It is useful for regression testing of output
+// in conjunction with text-based diffing tools.
+//
+// An annotation mode is implemented with the TemplateAnnotator interface.
+// When template annotation is turned on, then during template expansion
+// whenever a dynamic substitution feature is encountered, a call is made
+// to one of the TemplateAnnotator functions. In response to a call
+// an implementation can render any additional content into the passed
+// emitter, which is the same emitter that the rendering output is going
+// to.
+//
+// Template annotation is turned on and the template annotator subclass
+// set by methods in ctemplate::PerExpandData.
+
+#ifndef TEMPLATE_TEMPLATE_ANNOTATOR_H_
+#define TEMPLATE_TEMPLATE_ANNOTATOR_H_
+
+#include <string>
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+
+class ExpandEmitter;
+
+// This is the abstract interface for an annotation mode. A new annotation
+// mode is introduced by subclassing and implementing each function
+// to add annotation content. There is one function for each internal
+// template expansion event type. The emitter argument passed to the
+// function is the same stream that the expanding content is being output to;
+// so the action of an implementation will be to add additional inline
+// content. The emitter argument is never to be remembered beyond each
+// function call.
+class CTEMPLATE_DLL_DECL TemplateAnnotator {
+ public:
+ TemplateAnnotator() { }
+ virtual ~TemplateAnnotator() { }
+
+ // Called before processing a subtemplate include marker.
+ // Passed value is the include marker name.
+ virtual void EmitOpenInclude(ExpandEmitter* emitter, const std::string& value) = 0;
+ // Called after processing a subtemplate include marker.
+ virtual void EmitCloseInclude(ExpandEmitter* emitter) = 0;
+
+ // Called before opening a template or subtemplate file for processing.
+ // Passed value is the filename.
+ virtual void EmitOpenFile(ExpandEmitter* emitter, const std::string& value) = 0;
+ // Called after processing a template or subtemplate file.
+ virtual void EmitCloseFile(ExpandEmitter* emitter) = 0;
+
+ // Called before processing a section.
+ // Passed value is the section name.
+ virtual void EmitOpenSection(ExpandEmitter* emitter, const std::string& value) = 0;
+ // Called after processing a section.
+ virtual void EmitCloseSection(ExpandEmitter* emitter) = 0;
+
+ // Called before processing a variable marker.
+ // Passed value is the variable name.
+ virtual void EmitOpenVariable(ExpandEmitter* emitter,
+ const std::string& value) = 0;
+ // Called after processing a variable marker.
+ virtual void EmitCloseVariable(ExpandEmitter* emitter) = 0;
+
+ virtual void EmitFileIsMissing(ExpandEmitter* emitter,
+ const std::string& value) = 0;
+
+ private:
+ // Can't invoke copy constructor or assignment operator
+ TemplateAnnotator(const TemplateAnnotator&);
+ void operator=(const TemplateAnnotator&);
+};
+
+// This is a concrete template annotator class that inserts annotations
+// that have a standard text form bracketed by {{ }}. It is used as
+// the default annotation implementation when annotation is turned on
+// by PerExpandData and no annotator type is specified.
+class CTEMPLATE_DLL_DECL TextTemplateAnnotator : public TemplateAnnotator {
+ public:
+ TextTemplateAnnotator() { }
+ virtual void EmitOpenInclude(ExpandEmitter* emitter, const std::string& value);
+ virtual void EmitCloseInclude(ExpandEmitter* emitter);
+ virtual void EmitOpenFile(ExpandEmitter* emitter, const std::string& value);
+ virtual void EmitCloseFile(ExpandEmitter* emitter);
+ virtual void EmitOpenSection(ExpandEmitter* emitter, const std::string& value);
+ virtual void EmitCloseSection(ExpandEmitter* emitter);
+ virtual void EmitOpenVariable(ExpandEmitter* emitter, const std::string& value);
+ virtual void EmitCloseVariable(ExpandEmitter* emitter);
+ virtual void EmitFileIsMissing(ExpandEmitter* emitter,
+ const std::string& value);
+
+ private:
+ // Can't invoke copy constructor or assignment operator
+ TextTemplateAnnotator(const TextTemplateAnnotator&);
+ void operator=(const TextTemplateAnnotator&);
+};
+
+}
+
+
+#endif // TEMPLATE_TEMPLATE_ANNOTATOR_H_
diff --git a/src/windows/ctemplate/template_cache.h b/src/windows/ctemplate/template_cache.h
new file mode 100644
index 0000000..2ee6b67
--- /dev/null
+++ b/src/windows/ctemplate/template_cache.h
@@ -0,0 +1,378 @@
+// Copyright (c) 2009, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+//
+// This file implements the Template Cache used to store templates.
+
+#ifndef TEMPLATE_TEMPLATE_CACHE_H_
+#define TEMPLATE_TEMPLATE_CACHE_H_
+
+#include <hash_map> // for stdext::hash_map<>
+#include <string> // for string
+#include <utility> // for pair
+#include <vector> // for vector<>
+#include <ctemplate/template_emitter.h> // for ExpandEmitter, etc
+#include <ctemplate/template_enums.h> // for Strip
+#include <ctemplate/template_string.h>
+#include <ctemplate/per_expand_data.h>
+namespace ctemplate {
+class FileStat;
+}
+class Mutex;
+class TemplateCacheUnittest;
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+extern template class __declspec(dllimport) std::allocator<std::string>;
+extern template class __declspec(dllimport) std::vector<std::string>;
+#else
+template class __declspec(dllexport) std::allocator<std::string>;
+template class __declspec(dllexport) std::vector<std::string>;
+#endif
+
+namespace ctemplate {
+
+class PerExpandData;
+class Template;
+class TemplateCachePeer;
+class TemplateDictionaryInterface;
+
+// A cache to store parsed templates.
+class CTEMPLATE_DLL_DECL TemplateCache {
+ public:
+ TemplateCache();
+ ~TemplateCache();
+
+ // ---- CREATING A TEMPLATE OBJECT -------
+ // LoadTemplate
+ // StringToTemplateCache
+
+ // Attempts to load the template object stored under its filename,
+ // into the template cache. It first checks if the object is already
+ // in the cache. Any object retrieved from the cache is then
+ // checked to see if its status is marked for "reload if changed."
+ // If so, ReloadIfChanged is called on the retrieved object. Returns
+ // true if the object is loaded. Also returns true if the object
+ // already exists, and no reload was required.
+ //
+ // When it fails to retrieve one from the cache, it creates a new
+ // template object, passing the filename and 'strip' values to the
+ // constructor. (See constructor below for the meaning of the
+ // flags.) If it succeeds in creating an object, including loading
+ // and parsing the associated template file, the object is stored in
+ // the cache, and the method returns true.
+ //
+ // If it fails in loading and parsing the template file, either
+ // because the file was not found or it contained syntax errors,
+ // then the newly created object is deleted and the method returns
+ // false. (NOTE: This description is much longer and less precise
+ // and probably harder to understand than the method itself. Read
+ // the code.)
+ //
+ // To enable Auto-Escape on that template, place the corresponding
+ // AUTOESCAPE pragma at the top of the template file. The template
+ // will then be Auto-Escaped independently of the template it may be
+ // included from or the templates it may include.
+ //
+ // 'Strip' indicates how to handle whitespace when expanding the
+ // template. DO_NOT_STRIP keeps the template exactly as-is.
+ // STRIP_BLANK_LINES elides all blank lines in the template.
+ // STRIP_WHITESPACE elides all blank lines, and also all whitespace
+ // at either the beginning or end of a line. See template constructor
+ // for more details.
+ bool LoadTemplate(const TemplateString& filename, Strip strip);
+
+ // Parses the string as a template file (e.g. "Hello {{WORLD}}"),
+ // and inserts it into the parsed template cache, so it can later be
+ // used by the user. The user specifies a key and a strip, which are
+ // later passed in to expand the template.
+ // Returns true if the template was successfully parsed and
+ // inserted to the template cache, or false otherwise. In particular,
+ // we return false if a string was already cached with the given key.
+ // NOTE: to include this template from within another template (via
+ // "{{>TEMPLATE_THAT_COMES_FROM_A_STRING}}"), the argument you pass
+ // to TemplateDictionary::SetFilename() is the key you used to register
+ // the string-template.
+ bool StringToTemplateCache(const TemplateString& key,
+ const TemplateString& content,
+ Strip strip);
+ bool StringToTemplateCache(const TemplateString& key,
+ const char* content,
+ size_t content_len,
+ Strip strip) {
+ return StringToTemplateCache(key,
+ TemplateString(content, content_len),
+ strip);
+ }
+
+ // ---- EXPANDING A TEMPLATE -------
+ // ExpandWithData
+ // ExpandFrozen
+
+ // This returns false if the expand failed for some reason: filename
+ // could not be found on disk (and isn't already in the cache), or
+ // the template is mal-formed, or a sub-included template couldn't
+ // be found. Note that even if it returns false, it may have emitted
+ // some output to ExpandEmitter, before it noticed the problem.
+ bool ExpandWithData(const TemplateString& filename, Strip strip,
+ const TemplateDictionaryInterface *dictionary,
+ PerExpandData* per_expand_data,
+ ExpandEmitter* output);
+ bool ExpandWithData(const TemplateString& filename, Strip strip,
+ const TemplateDictionaryInterface* dictionary,
+ PerExpandData* per_expand_data,
+ std::string* output_buffer) {
+ if (output_buffer == NULL) return false;
+ StringEmitter e(output_buffer);
+ return ExpandWithData(filename, strip, dictionary, per_expand_data, &e);
+ }
+
+ // Const version of ExpandWithData, intended for use with frozen
+ // caches. This method returns false if the requested
+ // template-filename is not found in the cache, rather than fetching
+ // the template from disk and continuing, as ExpandWithData does.
+ // (That is why the method can be const.) Likewise, it will return
+ // false, rather than fetch, if any sub-included template filename
+ // is not found in the cache.
+ // Unfortunately, the only way to enforce this last requirement at
+ // the moment is to have the template-cache be Frozen(). So that
+ // is a pre-requisite for calling this method. It may be relaxed
+ // in the future (if we rewrite the control flow to pass around the
+ // necessary state).
+ // Like ExpandWithData(), this may write partial results into output
+ // even if it returns false (due to template error or file not found).
+ bool ExpandNoLoad(const TemplateString& filename, Strip strip,
+ const TemplateDictionaryInterface *dictionary,
+ PerExpandData* per_expand_data,
+ ExpandEmitter* output) const;
+ bool ExpandNoLoad(const TemplateString& filename, Strip strip,
+ const TemplateDictionaryInterface* dictionary,
+ PerExpandData* per_expand_data,
+ std::string* output_buffer) const {
+ if (output_buffer == NULL) return false;
+ StringEmitter e(output_buffer);
+ return ExpandNoLoad(filename, strip, dictionary, per_expand_data, &e);
+ }
+
+ // ---- FINDING A TEMPLATE FILE -------
+
+ // Sets the root directory for all templates used by the program.
+ // After calling this method, the filename passed to GetTemplate may
+ // be a relative pathname (no leading '/'), in which case this
+ // root-directory is prepended to the filename. This clears the old
+ // 'main' root directory, and also all alternate root directories
+ // that may had been added previously.
+ bool SetTemplateRootDirectory(const std::string& directory);
+
+ // Adds an additional search path for all templates used by the
+ // program. You may call this multiple times.
+ bool AddAlternateTemplateRootDirectory(const std::string& directory);
+
+ // Returns the 'main' root directory set by SetTemplateRootDirectory().
+ std::string template_root_directory() const;
+
+ // Given an unresolved filename, look through the template search
+ // path to see if the template can be found. If so, return the path
+ // of the resolved filename, otherwise return an empty string.
+ std::string FindTemplateFilename(const std::string& unresolved)
+ const;
+
+ // ---- MANAGING THE CACHE -------
+ // Freeze
+ // Delete
+ // ClearCache
+ // ReloadAllIfChanged
+ // Clone
+
+ // Marks the template cache as immutable. After this method is called,
+ // the cache can no longer be modified by loading new templates or
+ // reloading existing templates. During expansion only cached
+ // included templates will be used, they won't be loaded on-demand.
+ void Freeze();
+
+ // Delete
+ // Deletes one template object from the cache, if it exists.
+ // This can be used for either file- or string-based templates.
+ // Returns true if the object was deleted, false otherwise.
+ bool Delete(const TemplateString& key);
+
+ // ClearCache
+ // Deletes all the template objects in the cache and all raw
+ // contents cached from StringToTemplateCache. This should only
+ // be done once, just before exiting the program and after all
+ // template expansions are completed. (If you want to refresh the
+ // cache, the correct method to use is ReloadAllIfChanged, not
+ // this one.) Note: this method is not necessary unless you are
+ // testing for memory leaks. Calling this before exiting the
+ // program will prevent unnecessary reporting in that case.
+ void ClearCache();
+
+ // ReloadAllIfChanged
+ // If IMMEDIATE_RELOAD, reloads and parses all templates right away,
+ // if the corresponding template files have changed.
+ // If LAZY_RELOAD, then sets the reload bit on all templates.
+ // Subsequent call to GetTemplate() checks if file has changed, and if so
+ // reloads and parses the file into the cache.
+ //
+ // IMMEDIATE_RELOAD gives a more consistent snapshot of the current
+ // templates, since all templates in the cache are reloaded at
+ // (approximately) the same time. On the other hand, LAZY_RELOAD
+ // causes less of a latency spike, since it does not require
+ // loading lots of templates from disk at the same time. If in
+ // doubt, LAZY_RELOAD is probably a better choice.
+
+ // If a file with the same name as an existing template-file, is added
+ // in another search path, ReloadAllIfChanged will pick up the file in the
+ // earlier search-path.
+ enum ReloadType { LAZY_RELOAD, IMMEDIATE_RELOAD };
+ void ReloadAllIfChanged(ReloadType reload_tyle);
+
+ // Clone
+ // Returns a copy of the cache. It makes a shallow copy of the
+ // parsed_template_cache_, incrementing refcount of templates.
+ // The caller is responsible for deallocating the returned TemplateCache.
+ // NOTE(user): Annotalysis expects this method to have a lock for
+ // a TemplateCache instance local to the method, but we
+ // know that no other threads will have access to the
+ // instance, so ignore thread safety errors.
+ TemplateCache* Clone() const;
+
+ // ---- INSPECTING THE CACHE -------
+ // Dump
+ // DumpToString
+ // TODO(csilvers): implement these?
+
+ private:
+ // TODO(csilvers): nix Template friend once Template::ReloadIfChanged is gone
+ friend class Template; // for ResolveTemplateFilename
+ friend class TemplateTemplateNode; // for ExpandLocked
+ friend class TemplateCachePeer; // for unittests
+ friend class ::TemplateCacheUnittest; // for unittests
+
+ class RefcountedTemplate;
+ struct CachedTemplate;
+ class TemplateCacheHash;
+ class RefTplPtrHash;
+ // due to a bug(?) in MSVC, TemplateCachePeer won't compile unless this
+ // particular typedef is public. Ugh.
+ public:
+ typedef std::pair<TemplateId, int> TemplateCacheKey;
+ private:
+ typedef stdext::hash_map<TemplateCacheKey, CachedTemplate, TemplateCacheHash>
+ TemplateMap;
+ typedef stdext::hash_map<RefcountedTemplate*, int, RefTplPtrHash> TemplateCallMap;
+ // Where to search for files.
+ typedef std::vector<std::string> TemplateSearchPath;
+
+ // GetTemplate
+ // This method is deprecated. It exists here because it is called by
+ // Template::GetTemplate. Also this is used in tests.
+ const Template* GetTemplate(const TemplateString& key, Strip strip);
+
+ bool ResolveTemplateFilename(const std::string& unresolved,
+ std::string* resolved,
+ FileStat* statbuf) const;
+
+ // This is used only for internal (recursive) calls to Expand due
+ // to internal template-includes. It doesn't try to acquire the
+ // global template_lock again, in template.cc.
+ // TODO(csilvers): remove this when template.cc's g_template_lock goes away.
+ bool ExpandLocked(const TemplateString& filename, Strip strip,
+ ExpandEmitter* output,
+ const TemplateDictionaryInterface *dictionary,
+ PerExpandData* per_expand_data);
+
+ bool AddAlternateTemplateRootDirectoryHelper(
+ const std::string& directory,
+ bool clear_template_search_path);
+
+ // DoneWithGetTemplatePtrs
+ // For historical reasons, GetTemplate() returns a raw Template
+ // pointer rather than a refcounted pointer. So it's impossible
+ // for the user to call DecRef on the template when it's done
+ // using it. To make up for that, we provide this routine, which
+ // says "call DecRef()" on *all* Templates ever used by
+ // GetTemplate(). It's safe for the client to call this when it's
+ // done using all templates it's ever retrieved before (via
+ // GetTemplate). Most likely, the user will call this indirectly,
+ // via ClearCache().
+ // TODO(panicker): Consider making this method public.
+ void DoneWithGetTemplatePtrs();
+
+ // ValidTemplateFilename
+ // Validates the user provided filename before constructing the template
+ bool IsValidTemplateFilename(const std::string& filename,
+ std::string* resolved_filename,
+ FileStat* statbuf) const;
+
+ // GetTemplateLocked
+ // Internal version of GetTemplate. It's used when the function already
+ // has a write-lock on mutex_. It returns a pointer to a refcounted
+ // template (in the cache), or NULL if the template is not found.
+ // Its used by GetTemplate & ForceReloadAllIfChanged.
+ RefcountedTemplate* GetTemplateLocked(
+ const TemplateString& filename,
+ Strip strip,
+ const TemplateCacheKey& key);
+
+ // Refcount
+ // Testing only. Returns the refcount of a template, given its cache key.
+ int Refcount(const TemplateCacheKey template_cache_key) const;
+
+ // GetCachedTemplate
+ // Debug only. Returns whether the cache key is in the parsed cache.
+ bool TemplateIsCached(const TemplateCacheKey template_cache_key) const;
+
+ TemplateMap* parsed_template_cache_;
+ bool is_frozen_;
+ TemplateSearchPath search_path_;
+
+ // Since GetTemplate() returns a raw pointer, it's impossible for
+ // the caller to call DecRef() on the returned template when it's
+ // done using it. To make up for that, we store each retval of
+ // GetTemplate in this data structure. Then the user can call
+ // DecRef() on all of them at once, via a DoneWithGetTemplatePtrs()
+ // (which they will probably get at via a call to ClearCache()).
+ TemplateCallMap* get_template_calls_;
+
+ Mutex* const mutex_;
+ Mutex* const search_path_mutex_;
+
+ // Can't invoke copy constructor or assignment operator
+ TemplateCache(const TemplateCache&);
+ void operator=(const TemplateCache &);
+};
+
+}
+
+#endif // TEMPLATE_TEMPLATE_CACHE_H_
diff --git a/src/windows/ctemplate/template_dictionary.h b/src/windows/ctemplate/template_dictionary.h
new file mode 100644
index 0000000..c1f3869
--- /dev/null
+++ b/src/windows/ctemplate/template_dictionary.h
@@ -0,0 +1,464 @@
+// Copyright (c) 2006, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+// Author: csilvers@google.com (Craig Silverstein)
+//
+// Based on the 'old' TemplateDictionary by Frank Jernigan.
+//
+// A template dictionary maps names (as found in template files)
+// to their values. There are three types of names:
+// variables: value is a string.
+// sections: value is a list of sub-dicts to use when expanding the section;
+// the section is expanded once per sub-dict.
+// template-include: value is a list of pairs: name of the template file
+// to include, and the sub-dict to use when expanding it.
+// TemplateDictionary has routines for setting these values.
+//
+// For (many) more details, see the doc/ directory.
+
+#ifndef TEMPLATE_TEMPLATE_DICTIONARY_H_
+#define TEMPLATE_TEMPLATE_DICTIONARY_H_
+
+#include <stdarg.h> // for StringAppendV()
+#include <stddef.h> // for size_t and ptrdiff_t
+#include <stdlib.h> // for NULL
+#include <sys/types.h>
+#include <functional> // for less<>
+#include <map>
+#include <string>
+#include <vector>
+
+#include <ctemplate/str_ref.h>
+#include <ctemplate/template_dictionary_interface.h>
+#include <ctemplate/template_modifiers.h>
+#include <ctemplate/template_string.h>
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+template <class T, class C> class ArenaAllocator;
+class UnsafeArena;
+template<typename A, int B, typename C, typename D> class small_map;
+template<typename NormalMap> class small_map_default_init; // in small_map.h
+}
+
+namespace ctemplate {
+
+
+class CTEMPLATE_DLL_DECL TemplateDictionary : public TemplateDictionaryInterface {
+ public:
+ // name is used only for debugging.
+ // arena is used to store all names and values. It can be NULL (the
+ // default), in which case we create own own arena.
+ explicit TemplateDictionary(const TemplateString& name,
+ UnsafeArena* arena=NULL);
+ ~TemplateDictionary();
+
+ // If you want to be explicit, you can use NO_ARENA as a synonym to NULL.
+ static UnsafeArena* const NO_ARENA;
+
+ std::string name() const {
+ return std::string(name_.data(), name_.size());
+ }
+
+ // Returns a recursive copy of this dictionary. This dictionary
+ // *must* be a "top-level" dictionary (that is, not created via
+ // AddSectionDictionary() or AddIncludeDictionary()). Caller owns
+ // the resulting dict, and must delete it. If arena is NULL, we
+ // create our own. Returns NULL if the copy fails (probably because
+ // the "top-level" rule was violated).
+ TemplateDictionary* MakeCopy(const TemplateString& name_of_copy,
+ UnsafeArena* arena=NULL);
+
+ // --- Routines for VARIABLES
+ // These are the five main routines used to set the value of a variable.
+ // As always, wherever you see TemplateString, you can also pass in
+ // either a char* or a C++ string, or a TemplateString(s, slen).
+
+ void SetValue(const TemplateString variable, const TemplateString value);
+ void SetIntValue(const TemplateString variable, long value);
+ void SetFormattedValue(const TemplateString variable, const char* format, ...)
+#if 0
+ __attribute__((__format__ (__printf__, 3, 4)))
+#endif
+ ; // starts at 3 because of implicit 1st arg 'this'
+
+ class SetProxy {
+ public:
+ SetProxy(TemplateDictionary& dict, const TemplateString& variable) :
+ dict_(dict),
+ variable_(variable) {
+ }
+
+ void operator=(str_ref value) {
+ dict_.SetValue(variable_, TemplateString(value.data(), value.size()));
+ }
+
+ void operator=(long value) {
+ dict_.SetIntValue(variable_, value);
+ }
+
+ private:
+ TemplateDictionary& dict_;
+ const TemplateString& variable_;
+ };
+
+ SetProxy operator[](const TemplateString& variable) {
+ return SetProxy(*this, variable);
+ }
+
+ // We also let you set values in the 'global' dictionary which is
+ // referenced when all other dictionaries fail. Note this is a
+ // static method: no TemplateDictionary instance needed. Since
+ // this routine is rarely used, we don't provide variants.
+ static void SetGlobalValue(const TemplateString variable,
+ const TemplateString value);
+
+ // This is used for a value that you want to be 'global', but only
+ // in the scope of a given template, including all its sections and
+ // all its sub-included dictionaries. The main difference between
+ // SetTemplateGlobalValue() and SetValue(), is that
+ // SetTemplateGlobalValue() values persist across template-includes.
+ // This is intended for session-global data; since that should be
+ // fairly rare, we don't provide variants.
+ void SetTemplateGlobalValue(const TemplateString variable,
+ const TemplateString value);
+
+ // Similar SetTemplateGlobalValue above, this method shows a section in this
+ // template, all its sections, and all its template-includes. This is intended
+ // for session-global data, for example allowing you to show variant portions
+ // of your template for certain browsers/languages without having to call
+ // ShowSection on each template you use.
+ void ShowTemplateGlobalSection(const TemplateString variable);
+
+ // These routines are like SetValue and SetTemplateGlobalValue, but
+ // they do not make a copy of the input data. THE CALLER IS
+ // RESPONSIBLE FOR ENSURING THE PASSED-IN STRINGS LIVE FOR AT LEAST
+ // AS LONG AS THIS DICTIONARY! In general, they yield a quite minor
+ // performance increase for significant increased code fragility,
+ // so do not use them unless you really need the speed improvements.
+ void SetValueWithoutCopy(const TemplateString variable,
+ const TemplateString value);
+ void SetTemplateGlobalValueWithoutCopy(const TemplateString variable,
+ const TemplateString value);
+
+
+ // --- Routines for SECTIONS
+ // We show a section once per dictionary that is added with its name.
+ // Recall that lookups are hierarchical: if a section tried to look
+ // up a variable in its sub-dictionary and fails, it will look next
+ // in its parent dictionary (us). So it's perfectly appropriate to
+ // keep the sub-dictionary empty: that will show the section once,
+ // and take all var definitions from us. ShowSection() is a
+ // convenience routine that does exactly that.
+
+ // Creates an empty dictionary whose parent is us, and returns it.
+ // As always, wherever you see TemplateString, you can also pass in
+ // either a char* or a C++ string, or a TemplateString(s, slen).
+ TemplateDictionary* AddSectionDictionary(const TemplateString section_name);
+ void ShowSection(const TemplateString section_name);
+
+ // A convenience method. Often a single variable is surrounded by
+ // some HTML that should not be printed if the variable has no
+ // value. The way to do this is to put that html in a section.
+ // This method makes it so the section is shown exactly once, with a
+ // dictionary that maps the variable to the proper value. If the
+ // value is "", on the other hand, this method does nothing, so the
+ // section remains hidden.
+ void SetValueAndShowSection(const TemplateString variable,
+ const TemplateString value,
+ const TemplateString section_name);
+
+
+ // --- Routines for TEMPLATE-INCLUDES
+ // Included templates are treated like sections, but they require
+ // the name of the include-file to go along with each dictionary.
+
+ TemplateDictionary* AddIncludeDictionary(const TemplateString variable);
+
+ // This is required for include-templates; it specifies what template
+ // to include. But feel free to call this on any dictionary, to
+ // document what template-file the dictionary is intended to go with.
+ void SetFilename(const TemplateString filename);
+
+ // --- DEBUGGING TOOLS
+
+ // Logs the contents of a dictionary and its sub-dictionaries.
+ // Dump goes to stdout/stderr, while DumpToString goes to the given string.
+ // 'indent' is how much to indent each line of the output.
+ void Dump(int indent=0) const;
+ virtual void DumpToString(std::string* out, int indent=0) const;
+
+
+ // --- DEPRECATED ESCAPING FUNCTIONALITY
+
+ // Escaping in the binary has been deprecated in favor of using modifiers
+ // to do the escaping in the template:
+ // "...{{MYVAR:html_escape}}..."
+ void SetEscapedValue(const TemplateString variable, const TemplateString value,
+ const TemplateModifier& escfn);
+ void SetEscapedFormattedValue(const TemplateString variable,
+ const TemplateModifier& escfn,
+ const char* format, ...)
+#if 0
+ __attribute__((__format__ (__printf__, 4, 5)))
+#endif
+ ; // starts at 4 because of implicit 1st arg 'this'
+ void SetEscapedValueAndShowSection(const TemplateString variable,
+ const TemplateString value,
+ const TemplateModifier& escfn,
+ const TemplateString section_name);
+
+
+ private:
+ friend class SectionTemplateNode; // for access to GetSectionValue(), etc.
+ friend class TemplateTemplateNode; // for access to GetSectionValue(), etc.
+ friend class VariableTemplateNode; // for access to GetSectionValue(), etc.
+ // For unittesting code using a TemplateDictionary.
+ friend class TemplateDictionaryPeer;
+
+ class DictionaryPrinter; // nested class
+ friend class DictionaryPrinter;
+
+ // We need this functor to tell small_map how to create a map<> when
+ // it decides to do so: we want it to create that map on the arena.
+ class map_arena_init;
+
+ typedef std::vector<TemplateDictionary*,
+ ArenaAllocator<TemplateDictionary*, UnsafeArena> >
+ DictVector;
+ // The '4' here is the size where small_map switches from vector<> to map<>.
+ typedef small_map<std::map<TemplateId, TemplateString, std::less<TemplateId>,
+ ArenaAllocator<std::pair<const TemplateId, TemplateString>,
+ UnsafeArena> >,
+ 4, std::equal_to<TemplateId>, map_arena_init>
+ VariableDict;
+ typedef small_map<std::map<TemplateId, DictVector*, std::less<TemplateId>,
+ ArenaAllocator<std::pair<const TemplateId, DictVector*>,
+ UnsafeArena> >,
+ 4, std::equal_to<TemplateId>, map_arena_init>
+ SectionDict;
+ typedef small_map<std::map<TemplateId, DictVector*, std::less<TemplateId>,
+ ArenaAllocator<std::pair<const TemplateId, DictVector*>,
+ UnsafeArena> >,
+ 4, std::equal_to<TemplateId>, map_arena_init>
+ IncludeDict;
+ // This is used only for global_dict_, which is just like a VariableDict
+ // but does not bother with an arena (since this memory lives forever).
+ typedef small_map<std::map<TemplateId, TemplateString, std::less<TemplateId> >,
+ 4, std::equal_to<TemplateId>,
+ small_map_default_init<
+ std::map<TemplateId, TemplateString,
+ std::less<TemplateId> > > >
+ GlobalDict;
+
+
+ // These are helper functions to allocate the parts of the dictionary
+ // on the arena.
+ template<typename T> inline void LazilyCreateDict(T** dict);
+ inline void LazyCreateTemplateGlobalDict();
+ inline DictVector* CreateDictVector();
+ inline TemplateDictionary* CreateTemplateSubdict(
+ const TemplateString& name,
+ UnsafeArena* arena,
+ TemplateDictionary* parent_dict,
+ TemplateDictionary* template_global_dict_owner);
+
+ // This is a helper function to insert <key,value> into m.
+ // Normally, we'd just use m[key] = value, but map rules
+ // require default constructor to be public for that to compile, and
+ // for some types we'd rather not allow that. HashInsert also inserts
+ // the key into an id(key)->key map, to allow for id-lookups later.
+ template<typename MapType, typename ValueType>
+ static void HashInsert(MapType* m, TemplateString key, ValueType value);
+
+ // Constructor created for all children dictionaries. This includes
+ // both a pointer to the parent dictionary and also the the
+ // template-global dictionary from which all children (both
+ // IncludeDictionary and SectionDictionary) inherit. Values are
+ // filled into global_template_dict via SetTemplateGlobalValue.
+ explicit TemplateDictionary(const TemplateString& name,
+ class UnsafeArena* arena,
+ TemplateDictionary* parent_dict,
+ TemplateDictionary* template_global_dict_owner);
+
+ // Helps set up the static stuff. Must be called exactly once before
+ // accessing global_dict_. GoogleOnceInit() is used to manage that
+ // initialization in a thread-safe way.
+ static void SetupGlobalDict();
+
+ // Utility functions for copying a string into the arena.
+ // Memdup also copies in a trailing NUL, which is why we have the
+ // trailing-NUL check in the TemplateString version of Memdup.
+ TemplateString Memdup(const char* s, size_t slen);
+ TemplateString Memdup(const TemplateString& s) {
+ if (s.is_immutable() && s.data()[s.size()] == '\0') {
+ return s;
+ }
+ return Memdup(s.data(), s.size());
+ }
+
+ // Used for recursive MakeCopy calls.
+ TemplateDictionary* InternalMakeCopy(
+ const TemplateString& name_of_copy,
+ UnsafeArena* arena,
+ TemplateDictionary* parent_dict,
+ TemplateDictionary* template_global_dict_owner);
+
+ // A helper for creating section and include dicts.
+ static std::string CreateSubdictName(
+ const TemplateString& dict_name, const TemplateString& sub_name,
+ size_t index, const char* suffix);
+
+ // Must be called whenever we add a value to one of the dictionaries above,
+ // to ensure that we can reconstruct the id -> string mapping.
+ static void AddToIdToNameMap(TemplateId id, const TemplateString& str);
+
+ // Used to do the formatting for the SetFormatted*() functions
+ static int StringAppendV(char* space, char** out,
+ const char* format, va_list ap);
+
+ // How Template::Expand() and its children access the template-dictionary.
+ // These fill the API required by TemplateDictionaryInterface.
+ virtual TemplateString GetValue(const TemplateString& variable) const;
+ virtual bool IsHiddenSection(const TemplateString& name) const;
+ virtual bool IsUnhiddenSection(const TemplateString& name) const {
+ return !IsHiddenSection(name);
+ }
+ virtual bool IsHiddenTemplate(const TemplateString& name) const;
+ virtual const char* GetIncludeTemplateName(
+ const TemplateString& variable, int dictnum) const;
+
+ // Determine whether there's anything set in this dictionary
+ bool Empty() const;
+
+ // This is needed by DictionaryPrinter because it's not a friend
+ // of TemplateString, but we are
+ static std::string PrintableTemplateString(
+ const TemplateString& ts) {
+ return std::string(ts.data(), ts.size());
+ }
+ static bool InvalidTemplateString(const TemplateString& ts) {
+ return ts.data() == NULL;
+ }
+ // Compilers differ about whether nested classes inherit our friendship.
+ // The only thing DictionaryPrinter needs is IdToString, so just re-export.
+ static TemplateString IdToString(TemplateId id) { // for DictionaryPrinter
+ return TemplateString::IdToString(id);
+ }
+
+ // CreateTemplateIterator
+ // This is SectionIterator exactly, just with a different name to
+ // self-document the fact the value applies to a template include.
+ // Caller frees return value.
+ virtual TemplateDictionaryInterface::Iterator* CreateTemplateIterator(
+ const TemplateString& section_name) const;
+
+ // CreateSectionIterator
+ // Factory method implementation that constructs a iterator representing the
+ // set of dictionaries associated with a section name, if any. This
+ // implementation checks the local dictionary itself, not the template-wide
+ // dictionary or the global dictionary.
+ // Caller frees return value.
+ virtual TemplateDictionaryInterface::Iterator* CreateSectionIterator(
+ const TemplateString& section_name) const;
+
+ // TemplateDictionary-specific implementation of dictionary iterators.
+ template <typename T> // T is *TemplateDictionary::const_iterator
+ class Iterator : public TemplateDictionaryInterface::Iterator {
+ protected:
+ friend class TemplateDictionary;
+ Iterator(T begin, T end) : begin_(begin), end_(end) { }
+ public:
+ virtual ~Iterator() { }
+ virtual bool HasNext() const;
+ virtual const TemplateDictionaryInterface& Next();
+ private:
+ T begin_;
+ const T end_;
+ };
+
+ // A small helper factory function for Iterator
+ template <typename T>
+ static Iterator<typename T::const_iterator>* MakeIterator(const T& dv) {
+ return new Iterator<typename T::const_iterator>(dv.begin(), dv.end());
+ }
+
+
+ // The "name" of the dictionary for debugging output (Dump, etc.)
+ // The arena, also set at construction time.
+ class UnsafeArena* const arena_;
+ bool should_delete_arena_; // only true if we 'new arena' in constructor
+ TemplateString name_; // points into the arena, or to static memory
+
+ // The three dictionaries that I own -- for vars, sections, and template-incs
+ VariableDict* variable_dict_;
+ SectionDict* section_dict_;
+ IncludeDict* include_dict_;
+
+
+ // The template_global_dict is consulted if a lookup in the variable, section,
+ // or include dicts named above fails. It forms a convenient place to store
+ // session-specific data that's applicable to all templates in the dictionary
+ // tree.
+ // For the parent-template, template_global_dict_ is not NULL, and
+ // template_global_dict_owner_ is this. For all of its children,
+ // template_global_dict_ is NULL, and template_global_dict_owner_ points to
+ // the root parent-template (the one with the non-NULL template_global_dict_).
+ TemplateDictionary* template_global_dict_;
+ TemplateDictionary* template_global_dict_owner_;
+
+ // My parent dictionary, used when variable lookups at this level fail.
+ // Note this is only for *variables* and *sections*, not templates.
+ TemplateDictionary* parent_dict_;
+ // The static, global dictionary, at the top of the parent-dictionary chain
+ static GlobalDict* global_dict_;
+ static TemplateString* empty_string_; // what is returned on lookup misses
+
+ // The filename associated with this dictionary. If set, this declares
+ // what template the dictionary is supposed to be expanded with. Required
+ // for template-includes, optional (but useful) for 'normal' dicts.
+ const char* filename_;
+
+ private:
+ // Can't invoke copy constructor or assignment operator
+ TemplateDictionary(const TemplateDictionary&);
+ void operator=(const TemplateDictionary&);
+};
+
+}
+
+
+#endif // TEMPLATE_TEMPLATE_DICTIONARY_H_
diff --git a/src/windows/ctemplate/template_dictionary_interface.h b/src/windows/ctemplate/template_dictionary_interface.h
new file mode 100644
index 0000000..03bae41
--- /dev/null
+++ b/src/windows/ctemplate/template_dictionary_interface.h
@@ -0,0 +1,149 @@
+// Copyright (c) 2008, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+// Author: williasr@google.com (Scott Williams)
+//
+// This file implements the TemplateDictionaryInterface class. This interface
+// forms the root of the TemplateDictionary class tree, but the interface is
+// minimal enough to allow other sources of template data. Note that the
+// TemplateDictionaryInterface class enumerates the properties expected by
+// Template: it doesn't constrain how data gets into the
+// TemplateDictionaryInterface class to begin with. For these methods, see
+// TemplateDictionary.
+//
+
+#ifndef TEMPLATE_TEMPLATE_DICTIONARY_INTERFACE_H_
+#define TEMPLATE_TEMPLATE_DICTIONARY_INTERFACE_H_
+
+#include <stdlib.h>
+#include <string>
+#include <ctemplate/template_string.h>
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+
+const int kIndent = 2; // num spaces to indent each level -- used with dump
+
+// TemplateDictionaryInterface
+// The template data contains the associated values for
+// variables, the hidden/visible state for sections and included
+// templates, the associated set of dictionaries for sections and
+// included templates, and the template filenames to be expanded in
+// place of template-include nodes.
+class CTEMPLATE_DLL_DECL TemplateDictionaryInterface {
+ public:
+ // TemplateDictionaryInterface destructor
+ virtual ~TemplateDictionaryInterface() {}
+
+ protected:
+ // The interface as follows is used at expand-time by Expand.
+ friend class VariableTemplateNode;
+ friend class SectionTemplateNode;
+ friend class TemplateTemplateNode;
+ // This class reaches into our internals for testing.
+ friend class TemplateDictionaryPeer;
+ friend class TemplateDictionaryPeerIterator;
+
+ // GetSectionValue
+ // Returns the value of a variable.
+ virtual TemplateString GetValue(const TemplateString& variable) const = 0;
+
+ // IsHiddenSection
+ // A predicate to indicate the current hidden/visible state of a section
+ // whose name is passed to it.
+ virtual bool IsHiddenSection(const TemplateString& name) const = 0;
+
+ // Dump a string representation of this dictionary to the supplied string.
+ virtual void DumpToString(std::string* out, int level) const = 0;
+
+ // TemplateDictionaryInterface is an abstract class, so its constructor is
+ // only visible to its subclasses.
+ TemplateDictionaryInterface() {}
+
+ class Iterator {
+ protected:
+ Iterator() { }
+ public:
+ virtual ~Iterator() { }
+
+ // Returns false if the iterator is exhausted.
+ virtual bool HasNext() const = 0;
+
+ // Returns the current referent and increments the iterator to the next.
+ virtual const TemplateDictionaryInterface& Next() = 0;
+ };
+
+ // IsHiddenTemplate
+ // Returns true if the template include is hidden. This is analogous to
+ // IsHiddenSection, but for template nodes.
+ virtual bool IsHiddenTemplate(const TemplateString& name) const = 0;
+
+ // GetIncludeTemplateName
+ // Returns the name of the template associated with the given template
+ // include variable. If more than one dictionary is attached to the include
+ // symbol, dictnum can be used to disambiguate which include name you mean.
+ virtual const char* GetIncludeTemplateName(
+ const TemplateString& variable, int dictnum) const = 0;
+
+ // CreateTemplateIterator
+ // A factory method for constructing an iterator representing the
+ // subdictionaries of the given include node. The caller is
+ // responsible for deleting the return value when it's done with it.
+ virtual Iterator* CreateTemplateIterator(
+ const TemplateString& section) const = 0;
+
+ // CreateSectionIterator
+ // A factory method for constructing an iterator representing the
+ // subdictionaries of the given section node. The caller is
+ // responsible for deleting the return value when it's done with it.
+ virtual Iterator* CreateSectionIterator(
+ const TemplateString& section) const = 0;
+
+ // IsUnhiddenSection
+ // Returns true if the section has been marked visible and false otherwise.
+ virtual bool IsUnhiddenSection(
+ const TemplateString& name) const = 0;
+
+ private:
+ // Disallow copy and assign.
+ TemplateDictionaryInterface(const TemplateDictionaryInterface&);
+ void operator=(const TemplateDictionaryInterface&);
+};
+
+}
+
+
+#endif // TEMPLATE_TEMPLATE_DICTIONARY_INTERFACE_H_
diff --git a/src/windows/ctemplate/template_emitter.h b/src/windows/ctemplate/template_emitter.h
new file mode 100644
index 0000000..58d038a
--- /dev/null
+++ b/src/windows/ctemplate/template_emitter.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2007, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+// Author: csilvers@google.com (Craig Silverstein)
+//
+// When we expand a template, we expand into an abstract "emitter".
+// This is typically a string, but could be a file-wrapper, or any
+// other data structure that supports this very simple "append" API.
+
+#ifndef TEMPLATE_TEMPLATE_EMITTER_H_
+#define TEMPLATE_TEMPLATE_EMITTER_H_
+
+#include <sys/types.h> // for size_t
+#include <string>
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+
+class CTEMPLATE_DLL_DECL ExpandEmitter {
+ public:
+ ExpandEmitter() {}
+ virtual ~ExpandEmitter() {}
+ virtual void Emit(char c) = 0;
+ virtual void Emit(const std::string& s) = 0;
+ virtual void Emit(const char* s) = 0;
+ virtual void Emit(const char* s, size_t slen) = 0;
+};
+
+
+class CTEMPLATE_DLL_DECL StringEmitter : public ExpandEmitter {
+ std::string* const outbuf_;
+ public:
+ StringEmitter(std::string* outbuf) : outbuf_(outbuf) {}
+ virtual void Emit(char c) { *outbuf_ += c; }
+ virtual void Emit(const std::string& s) { *outbuf_ += s; }
+ virtual void Emit(const char* s) { *outbuf_ += s; }
+ virtual void Emit(const char* s, size_t slen) { outbuf_->append(s, slen); }
+};
+
+}
+
+
+#endif // TEMPLATE_TEMPLATE_EMITTER_H_
diff --git a/src/windows/ctemplate/template_enums.h b/src/windows/ctemplate/template_enums.h
new file mode 100644
index 0000000..a240e75
--- /dev/null
+++ b/src/windows/ctemplate/template_enums.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2006, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+//
+// Alas that we can't forward-declare enums! These are the ones
+// used by multiple files
+
+#ifndef TEMPLATE_TEMPLATE_ENUMS_H_
+#define TEMPLATE_TEMPLATE_ENUMS_H_
+
+namespace ctemplate {
+
+// Enums for GetTemplate flag values
+enum Strip { DO_NOT_STRIP, STRIP_BLANK_LINES, STRIP_WHITESPACE,
+ NUM_STRIPS }; // sentinel value
+
+}
+
+
+#endif // TEMPLATE_TEMPLATE_ENUMS_H_
diff --git a/src/windows/ctemplate/template_modifiers.h b/src/windows/ctemplate/template_modifiers.h
new file mode 100644
index 0000000..b981a60
--- /dev/null
+++ b/src/windows/ctemplate/template_modifiers.h
@@ -0,0 +1,357 @@
+// Copyright (c) 2007, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+// Author: csilvers@google.com (Craig Silverstein)
+//
+// We allow template variables to have modifiers, each possibly with a
+// value associated with it. Format is
+// {{VARNAME:modname[=modifier-value]:modname[=modifier-value]:...}}
+// Modname refers to a functor that takes the variable's value
+// and modifier-value (empty-string if no modifier-value was
+// specified), and returns a munged value. Modifiers are applied
+// left-to-right. We define the legal modnames here, and the
+// functors they refer to.
+//
+// Modifiers have a long-name, an optional short-name (one char;
+// may be \0 if you don't want a shortname), and a functor that's
+// applied to the variable.
+//
+// In addition to the list of modifiers hard-coded in the source code
+// here, it is possible to dynamicly register modifiers using a long
+// name starting with "x-". If you wish to define your own modifier
+// class, in your own source code, just subclass TemplateModifier --
+// see template_modifiers.cc for details of how to do that.
+//
+// Adding a new built-in modifier, to this file, takes several steps,
+// both in this .h file and in the corresponding .cc file:
+// 1) .h file: Define a struct for the modifier. It must subclass
+// TemplateModifier.
+// 2) .h file: declare a variable that's an instance of the struct.
+// This is used for people who want to modify the string themselves,
+// via TemplateDictionary::SetEscapedValue.
+// 5) .cc file: define the new modifier's Modify method.
+// 6) .cc file: give storage for the variable declared in the .h file (in 2).
+// 7) .cc file: add the modifier to the g_modifiers array.
+
+#ifndef TEMPLATE_TEMPLATE_MODIFIERS_H_
+#define TEMPLATE_TEMPLATE_MODIFIERS_H_
+
+#include <sys/types.h> // for size_t
+#include <string>
+#include <ctemplate/template_emitter.h> // so we can inline operator()
+#include <ctemplate/per_expand_data.h> // could probably just forward-declare
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+
+class Template;
+
+#define MODIFY_SIGNATURE_ \
+ public: \
+ virtual void Modify(const char* in, size_t inlen, \
+ const PerExpandData*, ExpandEmitter* outbuf, \
+ const std::string& arg) const
+
+// If you wish to write your own modifier, it should subclass this
+// method. Your subclass should only define Modify(); for efficiency,
+// we do not make operator() virtual.
+class CTEMPLATE_DLL_DECL TemplateModifier {
+ public:
+ // This function takes a string as input, a char*/size_t pair, and
+ // appends the modified version to the end of outbuf. In addition
+ // to the variable-value to modify (specified via in/inlen), each
+ // Modify passes in two pieces of user-supplied data:
+ // 1) arg: this is the modifier-value, for modifiers that take a
+ // value (e.g. "{{VAR:modifier=value}}"). This value
+ // comes from the template file. For modifiers that take
+ // no modval argument, arg will always be "". For modifiers
+ // that do take such an argument, arg will always start with "=".
+ // 2) per_expand_data: this is a set of data that the application can
+ // associate with a TemplateDictionary, and is passed in to
+ // every variable expanded using that dictionary. This value
+ // comes from the source code.
+ virtual void Modify(const char* in, size_t inlen,
+ const PerExpandData* per_expand_data,
+ ExpandEmitter* outbuf,
+ const std::string& arg) const = 0;
+
+ // This function can be used to speed up modification. If Modify()
+ // is often a noop, you can implement MightModify() to indicate
+ // situations where it's safe to avoid the call to Modify(), because
+ // Modify() won't do any modifications in this case. Note it's
+ // always safe to return true here; you should just return false if
+ // you're certain Modify() can be ignored. This function is
+ // advisory; the template system is not required to call
+ // MightModify() before Modify().
+ virtual bool MightModify(const PerExpandData* /*per_expand_data*/,
+ const std::string& /*arg*/) const {
+ return true;
+ }
+
+ // We support both modifiers that take an argument, and those that don't.
+ // We also support passing in a string, or a char*/int pair.
+ std::string operator()(const char* in, size_t inlen, const std::string& arg="") const {
+ std::string out;
+ // we'll reserve some space to account for minimal escaping: say 12%
+ out.reserve(inlen + inlen/8 + 16);
+ StringEmitter outbuf(&out);
+ Modify(in, inlen, NULL, &outbuf, arg);
+ return out;
+ }
+ std::string operator()(const std::string& in, const std::string& arg="") const {
+ return operator()(in.data(), in.size(), arg);
+ }
+
+ virtual ~TemplateModifier(); // always need a virtual destructor!
+};
+
+
+// Returns the input verbatim (for testing)
+class CTEMPLATE_DLL_DECL NullModifier : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL NullModifier null_modifier;
+
+// Escapes < > " ' & <non-space whitespace> to < > "
+// ' & <space>
+class CTEMPLATE_DLL_DECL HtmlEscape : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL HtmlEscape html_escape;
+
+// Same as HtmlEscape but leaves all whitespace alone. Eg. for <pre>..</pre>
+class CTEMPLATE_DLL_DECL PreEscape : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL PreEscape pre_escape;
+
+// Like HtmlEscape but allows HTML entities, <br> tags, <wbr> tags,
+// matched <b> and </b> tags, matched <i> and </i> tags, matched <em> and </em>
+// tags, and matched <span dir=(rtl|ltr)> tags.
+class CTEMPLATE_DLL_DECL SnippetEscape : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL SnippetEscape snippet_escape;
+
+// Replaces characters not safe for an unquoted attribute with underscore.
+// Safe characters are alphanumeric, underscore, dash, period, and colon.
+// The equal sign is also considered safe unless it is at the start
+// or end of the input in which case it is replaced with underscore.
+//
+// We added the equal sign to the safe characters to allow this modifier
+// to be used on attribute name/value pairs in HTML tags such as
+// <div {{CLASS:H=attribute}}>
+// where CLASS is expanded to "class=bla".
+//
+// Note: The equal sign is replaced when found at either boundaries of the
+// string due to the concern it may be lead to XSS under some special
+// circumstances: Say, if this string is the value of an attribute in an
+// HTML tag and ends with an equal sign, a browser may possibly end up
+// interpreting the next token as the value of this string rather than
+// a new attribute (esoteric).
+class CTEMPLATE_DLL_DECL CleanseAttribute : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL CleanseAttribute cleanse_attribute;
+
+// Removes characters not safe for a CSS value. Safe characters are
+// alphanumeric, space, underscore, period, coma, exclamation mark,
+// pound, percent, and dash.
+class CTEMPLATE_DLL_DECL CleanseCss : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL CleanseCss cleanse_css;
+
+// Checks that a url is either an absolute http(s) URL or a relative
+// url that doesn't have a protocol hidden in it (ie [foo.html] is
+// fine, but not [javascript:foo]) and then performs another type of
+// escaping. Returns the url escaped with the specified modifier if
+// good, otherwise returns a safe replacement URL.
+// This is normally "#", but for <img> tags, it is not safe to set
+// the src attribute to "#". This is because this causes some browsers
+// to reload the page, which can cause a DoS.
+class CTEMPLATE_DLL_DECL ValidateUrl : public TemplateModifier {
+ public:
+ explicit ValidateUrl(const TemplateModifier& chained_modifier,
+ const char* unsafe_url_replacement)
+ : chained_modifier_(chained_modifier),
+ unsafe_url_replacement_(unsafe_url_replacement),
+ unsafe_url_replacement_length_(strlen(unsafe_url_replacement)) { }
+ MODIFY_SIGNATURE_;
+ static const char* const kUnsafeUrlReplacement;
+ static const char* const kUnsafeImgSrcUrlReplacement;
+ private:
+ const TemplateModifier& chained_modifier_;
+ const char* unsafe_url_replacement_;
+ int unsafe_url_replacement_length_;
+};
+extern CTEMPLATE_DLL_DECL ValidateUrl validate_url_and_html_escape;
+extern CTEMPLATE_DLL_DECL ValidateUrl validate_url_and_javascript_escape;
+extern CTEMPLATE_DLL_DECL ValidateUrl validate_url_and_css_escape;
+extern CTEMPLATE_DLL_DECL ValidateUrl validate_img_src_url_and_html_escape;
+extern CTEMPLATE_DLL_DECL ValidateUrl validate_img_src_url_and_javascript_escape;
+extern CTEMPLATE_DLL_DECL ValidateUrl validate_img_src_url_and_css_escape;
+
+// Escapes < > & " ' to < > & " ' (same as in HtmlEscape).
+// If you use it within a CDATA section, you may be escaping more characters
+// than strictly necessary. If this turns out to be an issue, we will need
+// to add a variant just for CDATA.
+class CTEMPLATE_DLL_DECL XmlEscape : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL XmlEscape xml_escape;
+
+// Escapes characters that cannot appear unescaped in a javascript string
+// assuming UTF-8 encoded input.
+// This does NOT escape all characters that cannot appear unescaped in a
+// javascript regular expression literal.
+class CTEMPLATE_DLL_DECL JavascriptEscape : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL JavascriptEscape javascript_escape;
+
+// Checks that the input is a valid javascript non-string literal
+// meaning a boolean (true, false) or a numeric value (decimal, hex or octal).
+// If valid, we output the input as is, otherwise we output null instead.
+// Input of zero length is considered valid and nothing is output.
+//
+// The emphasis is on safety against injection of javascript code rather
+// than perfect validation, as such it is possible for non-valid literals to
+// pass through.
+//
+// You would use this modifier for javascript variables that are not
+// enclosed in quotes such as:
+// <script>var a = {{VALUE}};</script> OR
+// <a href="url" onclick="doSubmit({{ID}})">
+// For variables that are quoted (i.e. string literals) use javascript_escape.
+//
+// Limitations:
+// . NaN, +/-Infinity and null are not recognized.
+// . Output is not guaranteed to be a valid literal,
+// e.g: +55+-e34 will output as is.
+// e.g: trueeee will output nothing as it is not a valid boolean.
+//
+// Details:
+// . For Hex numbers, it checks for case-insensitive 0x[0-9A-F]+
+// that should be a proper check.
+// . For other numbers, it checks for case-insensitive [0-9eE+-.]*
+// so can also accept invalid numbers such as the number 5..45--10.
+// . "true" and "false" (without quotes) are also accepted and that's it.
+//
+class CTEMPLATE_DLL_DECL JavascriptNumber : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL JavascriptNumber javascript_number;
+
+// Escapes characters not in [0-9a-zA-Z.,_:*/~!()-] as %-prefixed hex.
+// Space is encoded as a +.
+class CTEMPLATE_DLL_DECL UrlQueryEscape : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL UrlQueryEscape url_query_escape;
+
+// Escapes " \ / <FF> <CR> <LF> <BS> <TAB> to \" \\ \/ \f \r \n \b \t
+// Also escapes < > & to their corresponding \uXXXX representation
+// (\u003C, \u003E, \u0026 respectively).
+class CTEMPLATE_DLL_DECL JsonEscape : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL JsonEscape json_escape;
+
+// Inserts the given prefix (given as the argument to this modifier)
+// after every newline in the text. Note that it does *not* insert
+// prefix at the very beginning of the text -- in its expected use,
+// that prefix will already be present before this text, in the
+// template. This is meant to be used internally, and is not exported
+// via the g_modifiers list.
+class CTEMPLATE_DLL_DECL PrefixLine : public TemplateModifier {
+ MODIFY_SIGNATURE_;
+};
+extern CTEMPLATE_DLL_DECL PrefixLine prefix_line;
+
+
+#undef MODIFY_SIGNATURE_
+
+
+// Registers a new template modifier.
+// long_name must start with "x-".
+// If the modifier takes a value (eg "{{VAR:x-name=value}}"), then
+// long_name should end with "=". This is similar to getopt(3) syntax.
+// We also allow value-specializations, with specific values specified
+// as part of long-name. For instance:
+// AddModifier("x-mod=", &my_modifierA);
+// AddModifier("x-mod=bar", &my_modifierB);
+// AddModifier("x-mod2", &my_modifierC);
+// For the template
+// {{VAR1:x-mod=foo}} {{VAR2:x-mod=bar}} {{VAR3:x-mod=baz}} {{VAR4:x-mod2}}
+// VAR1 and VAR3 would get modified by my_modifierA, VAR2 by my_modifierB,
+// and VAR4 by my_modifierC. The order of the AddModifier calls is not
+// significant.
+extern CTEMPLATE_DLL_DECL
+bool AddModifier(const char* long_name, const TemplateModifier* modifier);
+
+// Same as AddModifier() above except that the modifier is considered
+// to produce safe output that can be inserted in any context without
+// the need for additional escaping. This difference only impacts
+// the Auto-Escape mode: In that mode, when a variable (or template-include)
+// has a modifier added via AddXssSafeModifier(), it is excluded from
+// further escaping, effectively treated as though it had the :none modifier.
+// Because Auto-Escape is disabled for any variable and template-include
+// that includes such a modifier, use this function with care and ensure
+// that it may not emit harmful output that could lead to XSS.
+//
+// Some valid uses of AddXssSafeModifier:
+// . A modifier that converts a string to an integer since
+// an integer is generally safe in any context.
+// . A modifier that returns one of a fixed number of safe values
+// depending on properties of the input.
+//
+// Some not recommended uses of AddXssSafeModifier:
+// . A modifier that applies some extra formatting to the input
+// before returning it since the output will still contain
+// harmful content if the input does.
+// . A modifier that applies one type of escaping to the input
+// (say HTML-escape). This may be dangerous when the modifier
+// is used in a different context (say Javascript) where this
+// escaping may be inadequate.
+extern CTEMPLATE_DLL_DECL
+bool AddXssSafeModifier(const char* long_name,
+ const TemplateModifier* modifier);
+
+}
+
+
+#endif // TEMPLATE_TEMPLATE_MODIFIERS_H_
diff --git a/src/windows/ctemplate/template_namelist.h b/src/windows/ctemplate/template_namelist.h
new file mode 100644
index 0000000..26bd03a
--- /dev/null
+++ b/src/windows/ctemplate/template_namelist.h
@@ -0,0 +1,169 @@
+// Copyright (c) 2006, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+//
+// This class implements some template helper classes, that manage
+// template files and make it easier to monitor them.
+//
+// For information about how to use these classes and macros, and to
+// write the templates it takes as input,
+// see the doc/ directory.
+
+#ifndef TEMPLATE_TEMPLATE_NAMELIST_H_
+#define TEMPLATE_TEMPLATE_NAMELIST_H_
+
+#include <time.h> // for time_t
+#include <hash_set>
+#include <string>
+#include <vector>
+#include <ctemplate/template_enums.h> // for Strip
+#include <ctemplate/template_string.h> // for StringHash
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+
+// RegisterTemplateFilename
+// Used to define a reference variable for the name of a template file. E.g:
+// RegisterTemplateFilename(EXAMPLE_FN, "example.tpl");
+// This should be used rather than the seemingly equivalent:
+// #define EXAMPLE_FN "example.tpl"
+// As in the latter, any call to GetTemplate may then reference the name
+// via the first argument. In the example, that would be:
+// Template::GetTemplate(EXAMPLE_FN, DO_NOT_STRIP);
+// By using this macro, rather than the #define, all templates can
+// later be tested for either existence or correct syntax after program
+// start-up.
+// TODO (we wish): Make this macro produce the #include for the auto-generated
+// header files, when and if the macro pre-processor supports that
+#define RegisterTemplateFilename(var, name) \
+ const char* const var = ctemplate::TemplateNamelist::RegisterTemplate(name);
+
+// Class: TemplateNamelist
+// Each time this class is instantiated, the name passed to
+// the constructor is added to the class's static list of names. The
+// entire list may be retrieved later by calling the GetList accessor
+// method. Or they may all be checked for existence or for correct
+// syntax via the other methods. We use this in our
+// sanity-checking code to make sure all the templates used by a program
+// exist and are syntactically correct.
+
+class CTEMPLATE_DLL_DECL TemplateNamelist {
+ friend class TemporaryRegisterTemplate;
+ public:
+ // These types should be taken as 'generic' containers. The only
+ // thing you should do with them is call size() and/or iterate
+ // between begin() and end(), and the only operations we promise
+ // the iterators will support are operator* and operator++.
+ typedef stdext::hash_set<std::string, StringHash> NameListType;
+ typedef std::vector<std::string> MissingListType;
+ typedef std::vector<std::string> SyntaxListType;
+
+ public:
+ // Takes a name and pushes it onto the static namelist
+ // Returns: a pointer to the entry in namelist which holds the name
+ static const char* RegisterTemplate(const char* name);
+
+ // GetList
+ // Description: Returns the collected list of names.
+ static const NameListType& GetList();
+
+ // GetMissingList
+ // If refresh is true or if it is the first time the function is called
+ // in the execution of the program, it creates (or clears) the missing
+ // list and then fills it with the list of
+ // templates that the program knows about but are missing from
+ // the template directory.
+ // If refresh is false and it is not the first time the function is
+ // called, it merely returns the list created in the
+ // call when the last refresh was done.
+ // NOTE: The templates are NOT read, parsed, or cached
+ // by this function.
+ static const MissingListType& GetMissingList(bool refresh);
+
+ // GetBadSyntaxList
+ // If refresh is true or if it is the first time the function is called
+ // in the execution of the program, it creates (or clears) the "bad
+ // syntax" list and then fills it with the list of
+ // templates that the program knows about but contain syntax errors.
+ // A missing file is not considered a syntax error, and thus is
+ // not included in this list.
+ // If refresh is false and it is not the first time the function is
+ // called, it merely returns the list created in the
+ // call when the last refresh was done.
+ // NOTE: The side effect of calling this the first time or
+ // with refresh equal true is that all templates are parsed and cached.
+ // Hence they need to be retrieved with the flags that
+ // the program needs them loaded with (i.e, the strip parameter
+ // passed to Template::GetTemplate.)
+ static const SyntaxListType& GetBadSyntaxList(bool refresh, Strip strip);
+
+ // GetLastmodTime
+ // Iterates through all non-missing templates, and returns the latest
+ // last-modification time for the template files, as returned by stat().
+ // This can be used to make sure template files are getting refreshed.
+ static time_t GetLastmodTime();
+
+ // AllDoExist
+ // Retrieves the missing list (always refreshing the list)
+ // and returns true if it contains any names.
+ // Else, returns false.
+ static bool AllDoExist();
+
+ // IsAllSyntaxOkay
+ // Retrieves the "bad syntax" list (always refreshing the list)
+ // and returns true if it contains any names.
+ // Else, returns false.
+ // NOTE: The side effect of calling this is that all templates are parsed
+ // and cached, hence they need to be retrieved with the flags that
+ // the program needs them loaded with. (I.e, the strip parameter
+ // ultimately passed to Template::GetTemplate.)
+ static bool IsAllSyntaxOkay(Strip strip);
+
+ protected:
+ // The static list of names
+ static NameListType *namelist_;
+ static MissingListType *missing_list_;
+ static SyntaxListType *bad_syntax_list_;
+
+ private:
+ TemplateNamelist(const TemplateNamelist&); // disallow copying
+ void operator=(const TemplateNamelist&);
+};
+
+}
+
+
+#endif // TEMPLATE_TEMPLATE_NAMELIST_H_
diff --git a/src/windows/ctemplate/template_pathops.h b/src/windows/ctemplate/template_pathops.h
new file mode 100644
index 0000000..79f7bf7
--- /dev/null
+++ b/src/windows/ctemplate/template_pathops.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2007, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+
+// ---
+// Author: csilvers@google.com (Craig Silverstein)
+
+#ifndef TEMPLATE_TEMPLATE_PATHOPS_H_
+#define TEMPLATE_TEMPLATE_PATHOPS_H_
+
+#include <string>
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+
+extern CTEMPLATE_DLL_DECL
+const char kCWD[]; // a string that's equivalent to "./"
+extern CTEMPLATE_DLL_DECL
+const char kRootdir[]; // a string that's equivalent to "/"
+
+extern CTEMPLATE_DLL_DECL
+std::string PathJoin(const std::string& a, const std::string& b);
+
+extern CTEMPLATE_DLL_DECL
+bool IsAbspath(const std::string& path);
+
+extern CTEMPLATE_DLL_DECL
+bool IsDirectory(const std::string& path); // checks if path ends with /
+
+extern CTEMPLATE_DLL_DECL
+void NormalizeDirectory(std::string* dir); // adds trailing / if needed
+
+extern CTEMPLATE_DLL_DECL
+std::string Basename(const std::string& path); // everything after last /
+
+// Returns true iff text contains the word as a full word, i.e. delimited by one
+// of [.,_-#*?:] on both the sides.
+// This is used while loading a template, to check that the file's name matches
+// the auto-escape mode specified by it.
+// NOTE: This assumes that the word doesn't contain any of the delimiter
+// characters.
+extern CTEMPLATE_DLL_DECL
+bool ContainsFullWord(const std::string& text, const std::string& word);
+
+}
+
+#endif // TEMPLATE_TEMPLATE_PATHOPS_H_
diff --git a/src/windows/ctemplate/template_string.h b/src/windows/ctemplate/template_string.h
new file mode 100644
index 0000000..f1bd38b
--- /dev/null
+++ b/src/windows/ctemplate/template_string.h
@@ -0,0 +1,363 @@
+// Copyright (c) 2008, Google Inc.
+// 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 Google Inc. 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
+// OWNER 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.
+//
+// ---
+// Author: csilvers@google.com (Craig Silerstein)
+
+#ifndef TEMPLATE_TEMPLATE_STRING_H_
+#define TEMPLATE_TEMPLATE_STRING_H_
+
+#include <string.h> // for memcmp() and size_t
+#include <hash_map>
+#include <string>
+#include <vector>
+
+#include <assert.h>
+#if 0
+#include <stdint.h> // one place @ac_cv_unit64@ might live
+#endif
+#if 0
+#include <inttypes.h> // another place @ac_cv_unit64@ might live
+#endif
+#include <sys/types.h> // final place @ac_cv_unit64@ might live
+
+class TemplateStringTest; // needed for friendship declaration
+class StaticTemplateStringTest;
+
+#if 0
+extern char _start[] __attribute__((weak)); // linker emits: start of .text
+extern char data_start[] __attribute__((weak)); // start of .data
+#endif
+
+// NOTE: if you are statically linking the template library into your binary
+// (rather than using the template .dll), set '/D CTEMPLATE_DLL_DECL='
+// as a compiler flag in your project file to turn off the dllimports.
+#ifndef CTEMPLATE_DLL_DECL
+# define CTEMPLATE_DLL_DECL __declspec(dllimport)
+#endif
+
+namespace ctemplate {
+
+// Most methods of TemplateDictionary take a TemplateString rather than a
+// C++ string. This is for efficiency: it can avoid extra string copies.
+// For any argument that takes a TemplateString, you can pass in any of:
+// * A C++ string
+// * A char*
+// * A StringPiece
+// * TemplateString(char*, length)
+// The last of these is the most efficient, though it requires more work
+// on the call site (you have to create the TemplateString explicitly).
+class TemplateString;
+
+// If you have a string constant (e.g. the string literal "foo") that
+// you need to pass into template routines repeatedly, it is more
+// efficient if you convert it into a TemplateString only once. The
+// way to do this is to use a global StaticTemplateString via STS_INIT
+// (note: do this at global scope *only*!):
+// static const StaticTemplateString kMyVar = STS_INIT(kMyVar, "MY_VALUE");
+struct StaticTemplateString;
+
+#define STS_INIT(name, str) STS_INIT_WITH_HASH(name, str, 0)
+
+// Let's define a convenient hash_compare function for hashing 'normal'
+// strings: char* and string. We'll use MurmurHash, which is probably
+// better than the STL default. We don't include TemplateString or
+// StaticTemplateString here, since they are hashed more efficiently
+// based on their id.
+struct CTEMPLATE_DLL_DECL StringHash {
+ inline size_t operator()(const char* s) const {
+ return Hash(s, strlen(s));
+ };
+
+ inline size_t operator()(const std::string& s) const {
+ return Hash(s.data(), s.size());
+ }
+
+ inline bool operator()(const char* a, const char* b) const {
+ return (a != b) && (strcmp(a, b) < 0); // <, for MSVC
+ }
+
+ inline bool operator()(const std::string& a, const std::string& b) const {
+ return a < b;
+ }
+
+ static const size_t bucket_size = 4; // These are required by MSVC
+ static const size_t min_buckets = 8; // 4 and 8 are the defaults
+ private:
+ size_t Hash(const char* s, size_t slen) const;
+};
+
+// ----------------------- THE CLASSES -------------------------------
+
+typedef unsigned __int64 TemplateId;
+
+const TemplateId kIllegalTemplateId = 0;
+
+struct CTEMPLATE_DLL_DECL StaticTemplateString {
+ // Do not define a constructor! We use only brace-initialization,
+ // so the data is constructed at static-initialization time.
+ // Anything you want to put in a constructor, put in
+ // StaticTemplateStringInitializer instead.
+
+ // These members shouldn't be accessed directly, except in the
+ // internals of the template code. They are public because that is
+ // the only way we can brace-initialize them. NOTE: MSVC (at least
+ // up to 8.0) has a bug where it ignores 'mutable' when it's buried
+ // in an internal struct. To fix that, we have to make this whole
+ // internal struct mutable. We only do this on MSVC, so on other
+ // compilers we get the full constness we want.
+#ifdef _MSC_VER
+ mutable
+#endif
+ struct {
+ const char* ptr_;
+ size_t length_;
+ mutable TemplateId id_; // sometimes lazily-initialized.
+ } do_not_use_directly_;
+
+ // This class is a good hash_compare functor to pass in as the third
+ // argument to stdext::hash_map<>, when creating a map whose keys are
+ // StaticTemplateString. NOTE: This class isn't that safe to use,
+ // because it requires that StaticTemplateStringInitializer has done
+ // its job. Unfortunately, even when you use the STS_INIT macro
+ // (which is always, right??), dynamic initialiation does not happen
+ // in a particular order, and objects in different .cc files may
+ // reference a StaticTemplateString before the corresponding
+ // StaticTemplateStringInitializer sets the id.
+ struct Hasher {
+ inline size_t operator()(const StaticTemplateString& sts) const;
+ inline bool operator()(const StaticTemplateString& a, // <, for MSVC
+ const StaticTemplateString& b) const;
+ static const size_t bucket_size = 4; // These are required by MSVC
+ static const size_t min_buckets = 8; // 4 and 8 are the defaults
+ };
+
+ inline bool empty() const {
+ return do_not_use_directly_.length_ == 0;
+ }
+
+ // Allows comparisons of StaticTemplateString objects as if they were
+ // strings. This is useful for STL.
+ inline bool operator==(const StaticTemplateString& x) const;
+};
+
+class CTEMPLATE_DLL_DECL TemplateString {
+ public:
+ TemplateString(const char* s)
+ : ptr_(s ? s : ""), length_(strlen(ptr_)),
+ is_immutable_(InTextSegment(ptr_)), id_(kIllegalTemplateId) {
+ }
+ TemplateString(const std::string& s)
+ : ptr_(s.data()), length_(s.size()),
+ is_immutable_(false), id_(kIllegalTemplateId) {
+ }
+ TemplateString(const char* s, size_t slen)
+ : ptr_(s), length_(slen),
+ is_immutable_(InTextSegment(s)), id_(kIllegalTemplateId) {
+ }
+ TemplateString(const StaticTemplateString& s)
+ : ptr_(s.do_not_use_directly_.ptr_),
+ length_(s.do_not_use_directly_.length_),
+ is_immutable_(true), id_(s.do_not_use_directly_.id_) {
+ }
+
+ const char* begin() const {
+ return ptr_;
+ }
+
+ const char* end() const {
+ return ptr_ + length_;
+ }
+
+ const char* data() const {
+ return ptr_;
+ }
+
+ size_t size() const {
+ return length_;
+ }
+
+ inline bool empty() const {
+ return length_ == 0;
+ };
+
+ inline bool is_immutable() const {
+ return is_immutable_;
+ }
+
+ // STL requires this to be public for hash_map, though I'd rather not.
+ inline bool operator==(const TemplateString& x) const {
+ return GetGlobalId() == x.GetGlobalId();
+ }
+
+ private:
+ // Only TemplateDictionaries and template expansion code can read these.
+ friend class TemplateDictionary;
+ friend class TemplateCache; // for GetGlobalId
+ friend class StaticTemplateStringInitializer; // for AddToGlo...
+ friend struct TemplateStringHasher; // for GetGlobalId
+ friend TemplateId GlobalIdForTest(const char* ptr, int len);
+ friend TemplateId GlobalIdForSTS_INIT(const TemplateString& s);
+
+ TemplateString(const char* s, size_t slen, bool is_immutable, TemplateId id)
+ : ptr_(s), length_(slen), is_immutable_(is_immutable), id_(id) {
+ }
+
+ // This returns true if s is in the .text segment of the binary.
+ // (Note this only checks .text of the main executable, not of
+ // shared libraries. So it may not be all that useful.)
+ // This requires the gnu linker (and probably elf), to define
+ // _start and data_start.
+ static bool InTextSegment(const char* s) {
+#if 0
+ return (s >= _start && s < data_start); // in .text
+#else
+ return false; // the conservative choice: assume it's not static memory
+#endif
+ }
+
+ protected:
+ inline void CacheGlobalId() { // used by HashedTemplateString
+ id_ = GetGlobalId();
+ };
+
+ private:
+ // Returns the global id, computing it for the first time if
+ // necessary. Note that since this is a const method, we don't
+ // store the computed value in id_, even if id_ is 0.
+ TemplateId GetGlobalId() const;
+ // Adds this TemplateString to the map from global-id to name.
+ void AddToGlobalIdToNameMap();
+
+ // Use sparingly. Converting to a string loses information about the
+ // id of the template string, making operations require extra hash_compare
+ // computations.
+ std::string ToString() const { return std::string(ptr_, length_); }
+
+ // Does the reverse map from TemplateId to TemplateString contents.
+ // Returns a TemplateString(kStsEmpty) if id isn't found. Note that
+ // the TemplateString returned is not necessarily NUL terminated.
+ static TemplateString IdToString(TemplateId id);
+
+ const char* ptr_;
+ size_t length_;
+ // Do we need to manage memory for this string?
+ bool is_immutable_;
+ // Id for hash_compare lookups. If 0, we don't have one and it should be
+ // computed as-needed.
+ TemplateId id_;
+};
+
+// ----------------------- THE CODE -------------------------------
+
+// Use the low-bit from TemplateId as the "initialized" flag. Note
+// that since all initialized TemplateId have the lower bit set, it's
+// safe to have used 0 for kIllegalTemplateId, as we did above.
+const TemplateId kTemplateStringInitializedFlag = 1;
+
+inline bool IsTemplateIdInitialized(TemplateId id) {
+ return id & kTemplateStringInitializedFlag;
+}
+
+// This is a helper struct used in TemplateString::Hasher/TemplateStringHasher
+struct TemplateIdHasher {
+ size_t operator()(TemplateId id) const {
+ // The shift has two effects: it randomizes the "initialized" flag,
+ // and slightly improves the randomness of the low bits. This is
+ // slightly useful when size_t is 32 bits, or when using a small
+ // hash_compare tables with power-of-2 sizes.
+ return static_cast<size_t>(id ^ (id >> 33));
+ }
+ bool operator()(TemplateId a, TemplateId b) const { // <, for MSVC
+ return a < b;
+ }
+ static const size_t bucket_size = 4; // These are required by MSVC
+ static const size_t min_buckets = 8; // 4 and 8 are the defaults
+};
+
+
+inline size_t StaticTemplateString::Hasher::operator()(
+ const StaticTemplateString& sts) const {
+ TemplateId id = sts.do_not_use_directly_.id_;
+ assert(IsTemplateIdInitialized(id));
+ return TemplateIdHasher()(id);
+}
+
+inline bool StaticTemplateString::Hasher::operator()(
+ const StaticTemplateString& a, const StaticTemplateString& b) const {
+ TemplateId id_a = a.do_not_use_directly_.id_;
+ TemplateId id_b = b.do_not_use_directly_.id_;
+ assert(IsTemplateIdInitialized(id_a));
+ assert(IsTemplateIdInitialized(id_b));
+ return TemplateIdHasher()(id_a, id_b);
+}
+
+inline bool StaticTemplateString::operator==(
+ const StaticTemplateString& x) const {
+ return (do_not_use_directly_.length_ == x.do_not_use_directly_.length_ &&
+ (do_not_use_directly_.ptr_ == x.do_not_use_directly_.ptr_ ||
+ memcmp(do_not_use_directly_.ptr_, x.do_not_use_directly_.ptr_,
+ do_not_use_directly_.length_) == 0));
+}
+
+// We set up as much of StaticTemplateString as we can at
+// static-initialization time (using brace-initialization), but some
+// things can't be set up then. This class is for those things; it
+// runs at dynamic-initialization time. If you add logic here, only
+// do so as an optimization: this may be called rather late (though
+// before main), so other code should not depend on this being called
+// before them.
+class CTEMPLATE_DLL_DECL StaticTemplateStringInitializer {
+ public:
+ // This constructor operates on a const StaticTemplateString - we should
+ // only change those things that are mutable.
+ explicit StaticTemplateStringInitializer(const StaticTemplateString* sts);
+};
+
+// Don't use this. This is used only in auto-generated .varnames.h files.
+#define STS_INIT_WITH_HASH(name, str, hash_compare) \
+ { { str, sizeof(""str"")-1, hash_compare } }; \
+ namespace ctemplate_sts_init { \
+ static const ctemplate::StaticTemplateStringInitializer name##_init(&name); \
+ }
+
+// We computed this hash_compare value for the empty string online. In debug
+// mode, we verify it's correct during runtime (that is, that we
+// verify the hash_compare function used by make_tpl_varnames_h hasn't changed
+// since we computed this number). Note this struct is logically
+// static, but since it's in a .h file, we don't say 'static' but
+// instead rely on the linker to provide the POD-with-internal-linkage
+// magic.
+const StaticTemplateString kStsEmpty =
+ STS_INIT_WITH_HASH(kStsEmpty, "", 1457976849674613049ULL);
+
+}
+
+
+#endif // TEMPLATE_TEMPLATE_STRING_H_
diff --git a/src/windows/port.cc b/src/windows/port.cc
new file mode 100644
index 0000000..73bb580
--- /dev/null
+++ b/src/windows/port.cc
@@ -0,0 +1,117 @@
+/* Copyright (c) 2007, Google Inc.
+ * 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 Google Inc. 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
+ * OWNER 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.
+ *
+ * ---
+ * Author: Craig Silverstein
+ */
+
+#include "windows/config.h"
+#ifndef _WIN32
+# error You should only be including windows/port.cc in a windows environment!
+#endif
+
+#include <stdarg.h> // for va_list, va_start, va_end
+#include <string.h> // for strstr()
+#include <assert.h>
+#include "port.h"
+
+// These call the windows _vsnprintf, but always NUL-terminate.
+#if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */
+int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
+ if (size == 0) // not even room for a \0?
+ return -1; // not what C99 says to do, but what windows does
+ str[size-1] = '\0';
+ return _vsnprintf(str, size-1, format, ap);
+}
+
+int snprintf(char *str, size_t size, const char *format, ...) {
+ int r;
+ va_list ap;
+ va_start(ap, format);
+ r = vsnprintf(str, size, format, ap);
+ va_end(ap);
+ return r;
+}
+#endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
+
+#ifdef __cplusplus
+#include <string>
+#include <vector>
+#include <ctemplate/template_pathops.h>
+
+using std::string;
+using std::vector;
+
+namespace ctemplate {
+
+// defined (for unix) in template_test_utils.cc
+string TmpFile(const char* basename) {
+ char tmppath_buffer[1024];
+ int tmppath_len = GetTempPathA(sizeof(tmppath_buffer), tmppath_buffer);
+ if (tmppath_len <= 0 || tmppath_len >= sizeof(tmppath_buffer)) {
+ return basename; // an error, so just bail on tmppath
+ }
+ assert(tmppath_buffer[tmppath_len - 1] == '\\'); // API guarantees it
+ return string(tmppath_buffer) + basename;
+}
+
+// A replacement for template_unittest.cc:CleanTestDir()
+void CreateOrCleanTestDir(const string& dirname) {
+ string glob(PathJoin(dirname, "*"));
+ WIN32_FIND_DATAA found; // that final A is for Ansi (as opposed to Unicode)
+ HANDLE hFind = FindFirstFileA(glob.c_str(), &found); // A is for Ansi
+ if (hFind == INVALID_HANDLE_VALUE) { // directory doesn't exist or some such
+ _mkdir(dirname.c_str());
+ hFind = FindFirstFileA(glob.c_str(), &found); // Try again...
+ }
+ if (hFind != INVALID_HANDLE_VALUE) {
+ do {
+ if (strstr(found.cFileName, "template"))
+ _unlink(PathJoin(dirname, found.cFileName).c_str());
+ } while (FindNextFileA(hFind, &found) != FALSE); // A is for Ansi
+ FindClose(hFind);
+ }
+}
+
+}
+
+void GetNamelist(const char* testdata_dir, vector<string>* namelist) {
+ string glob(GOOGLE_NAMESPACE::PathJoin(testdata_dir,
+ "template_unittest_test*"));
+ WIN32_FIND_DATAA found; // that final A is for Ansi (as opposed to Unicode)
+ HANDLE hFind = FindFirstFileA(glob.c_str(), &found);
+ if (hFind == INVALID_HANDLE_VALUE) // no files matching the glob, probably
+ return; // if we don't find any files, nothing to add to namelist
+ do {
+ namelist->push_back(found.cFileName);
+ } while (FindNextFileA(hFind, &found) != FALSE); // A is for Ansi
+ FindClose(hFind);
+}
+
+#endif /* __cplusplus */
diff --git a/src/windows/port.h b/src/windows/port.h
new file mode 100644
index 0000000..7edc6f0
--- /dev/null
+++ b/src/windows/port.h
@@ -0,0 +1,140 @@
+/* Copyright (c) 2007, Google Inc.
+ * 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 Google Inc. 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
+ * OWNER 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.
+ *
+ * ---
+ * Author: Craig Silverstein
+ *
+ * These are some portability typedefs and defines to make it a bit
+ * easier to compile this code under VC++.
+ *
+ * Several of these are taken from glib:
+ * http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
+ */
+
+#ifndef CTEMPLATE_WINDOWS_PORT_H_
+#define CTEMPLATE_WINDOWS_PORT_H_
+
+#include "windows/config.h"
+#ifdef _WIN32
+
+#define USING_PORT_CC
+
+#define WIN32_LEAN_AND_MEAN /* We always want minimal includes */
+#include <windows.h>
+#include <io.h> /* because we so often use open/close/etc */
+#include <direct.h> /* for _getcwd() */
+#include <sys/utime.h> /* for _utime() */
+#include <stdio.h> /* read in vsnprintf decl. before redifining it */
+#include <stdarg.h> /* template_dictionary.cc uses va_copy */
+#include <string.h> /* for _strnicmp */
+/* Note: the C++ #includes are all together at the bottom. This file is
+ * used by both C and C++ code, so we put all the C++ together.
+ */
+
+/* 4244: otherwise we get problems when substracting two size_t's to an int
+ * 4251: it's complaining about a private struct I've chosen not to dllexport
+ * 4355: we use this in a constructor, but we do it safely
+ * 4715: for some reason VC++ stopped realizing you can't return after abort()
+ * 4800: we know we're casting ints/char*'s to bools, and we're ok with that
+ * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror()
+ */
+#ifdef _MSC_VER
+#pragma warning(disable:4244 4251 4355 4715 4800 4996)
+#endif
+
+/* file I/O */
+#define PATH_MAX 1024
+#define access _access
+#define getcwd _getcwd
+#define open _open
+#define read _read
+#define write _write
+#define lseek _lseek
+#define close _close
+#define popen _popen
+#define pclose _pclose
+#ifndef R_OK /* mingw defines this, for instance */
+#define R_OK 04 /* read-only (for access()) */
+#endif
+#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
+
+#define utime _utime
+#define utimbuf _utimbuf
+
+/* Not quite as lightweight as a hard-link, but more than good enough for us. */
+#define link(oldpath, newpath) (!CopyFileA(oldpath, newpath, false))
+
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
+
+/* Sleep is in ms, on windows */
+#define sleep(secs) Sleep((secs) * 1000)
+
+/* We can't just use _vsnprintf and _snprintf as drop-in-replacements,
+ * because they don't always NUL-terminate. :-( We also can't use the
+ * name vsnprintf, since windows defines that (but not snprintf (!)).
+ */
+#if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */
+extern CTEMPLATE_DLL_DECL int snprintf(char *str, size_t size,
+ const char *format, ...);
+extern int CTEMPLATE_DLL_DECL safe_vsnprintf(char *str, size_t size,
+ const char *format, va_list ap);
+#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap)
+#define va_copy(dst, src) (dst) = (src)
+#endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
+
+/* Windows doesn't support specifying the number of buckets as a
+ * hash_map constructor arg, so we leave this blank.
+ */
+#define CTEMPLATE_SMALL_HASHTABLE
+
+#define DEFAULT_TEMPLATE_ROOTDIR ".."
+
+
+/* These are functions we have to override because they're O/S-specific */
+#ifdef __cplusplus
+#include <string>
+#include <vector>
+
+namespace ctemplate {
+extern CTEMPLATE_DLL_DECL std::string TmpFile(const char* basename);
+void CTEMPLATE_DLL_DECL CreateOrCleanTestDir(const std::string& dirname);
+}
+void CTEMPLATE_DLL_DECL GetNamelist(const char* testdata_dir,
+ std::vector<std::string>* namelist);
+#endif /* __cplusplus */
+
+#ifndef __cplusplus
+/* I don't see how to get inlining for C code in MSVC. Ah well. */
+#define inline
+#endif
+
+#endif /* _WIN32 */
+
+#endif /* CTEMPLATE_WINDOWS_PORT_H_ */
diff --git a/src/windows/preprocess.sh b/src/windows/preprocess.sh
new file mode 100755
index 0000000..b089180
--- /dev/null
+++ b/src/windows/preprocess.sh
@@ -0,0 +1,118 @@
+#!/bin/sh
+
+# Copyright (c) 2007, Google Inc.
+# 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 Google Inc. 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
+# OWNER 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.
+
+# ---
+# Author: Craig Silverstein
+#
+# This script is meant to be run at distribution-generation time, for
+# instance by autogen.sh. It does some of the work configure would
+# normally do, for windows systems. In particular, it expands all the
+# @...@ variables found in .in files, and puts them here, in the windows
+# directory.
+#
+# This script should be run before any new release.
+
+if [ -z "$1" ]; then
+ echo "USAGE: $0 <src/ directory>"
+ exit 1
+fi
+
+DLLDEF_MACRO_NAME="CTEMPLATE_DLL_DECL"
+
+# The text we put in every .h files we create. As a courtesy, we'll
+# include a helpful comment for windows users as to how to use
+# CTEMPLATE_DLL_DECL. Apparently sed expands \n into a newline. Good!
+DLLDEF_DEFINES="\
+// NOTE: if you are statically linking the template library into your binary\n\
+// (rather than using the template .dll), set '/D $DLLDEF_MACRO_NAME='\n\
+// as a compiler flag in your project file to turn off the dllimports.\n\
+#ifndef $DLLDEF_MACRO_NAME\n\
+# define $DLLDEF_MACRO_NAME __declspec(dllimport)\n\
+#endif"
+
+# template_cache.h gets a special DEFINE to work around the
+# difficulties in dll-exporting stl containers. Ugh.
+TEMPLATE_CACHE_DLLDEF_DEFINES="\
+// NOTE: if you are statically linking the template library into your binary\n\
+// (rather than using the template .dll), set '/D $DLLDEF_MACRO_NAME='\n\
+// as a compiler flag in your project file to turn off the dllimports.\n\
+#ifndef $DLLDEF_MACRO_NAME\n\
+# define $DLLDEF_MACRO_NAME __declspec(dllimport)\n\
+extern template class __declspec(dllimport) std::allocator<std::string>;\n\
+extern template class __declspec(dllimport) std::vector<std::string>;\n\
+#else\n\
+template class __declspec(dllexport) std::allocator<std::string>;\n\
+template class __declspec(dllexport) std::vector<std::string>;\n\
+#endif"
+
+# Read all the windows config info into variables
+# In order for the 'set' to take, this requires putting all in a subshell.
+(
+ while read define varname value; do
+ [ "$define" != "#define" ] && continue
+ eval "$varname='$value'"
+ done
+
+ # Process all the .in files in the "ctemplate" subdirectory
+ mkdir -p "$1/windows/ctemplate"
+ for file in "$1"/ctemplate/*.in; do
+ echo "Processing $file"
+ outfile="$1/windows/ctemplate/`basename $file .in`"
+
+ if test "`basename $file`" = template_cache.h.in; then
+ MY_DLLDEF_DEFINES=$TEMPLATE_CACHE_DLLDEF_DEFINES
+ else
+ MY_DLLDEF_DEFINES=$DLLDEF_DEFINES
+ fi
+
+ # Besides replacing @...@, we also need to turn on dllimport
+ # We also need to replace hash by hash_compare (annoying we hard-code :-( )
+ sed -e "s!@ac_windows_dllexport@!$DLLDEF_MACRO_NAME!g" \
+ -e "s!@ac_windows_dllexport_defines@!$MY_DLLDEF_DEFINES!g" \
+ -e "s!@ac_cv_cxx_hash_map@!$HASH_MAP_H!g" \
+ -e "s!@ac_cv_cxx_hash_set@!$HASH_SET_H!g" \
+ -e "s!@ac_cv_cxx_hash_map_class@!$HASH_NAMESPACE::hash_map!g" \
+ -e "s!@ac_cv_cxx_hash_set_class@!$HASH_NAMESPACE::hash_set!g" \
+ -e "s!@ac_google_attribute@!${HAVE___ATTRIBUTE__:-0}!g" \
+ -e "s!@ac_google_end_namespace@!$_END_GOOGLE_NAMESPACE_!g" \
+ -e "s!@ac_google_namespace@!$GOOGLE_NAMESPACE!g" \
+ -e "s!@ac_google_start_namespace@!$_START_GOOGLE_NAMESPACE_!g" \
+ -e "s!@ac_htmlparser_namespace@!$HTMLPARSER_NAMESPACE!g" \
+ -e "s!@ac_cv_uint64@!unsigned __int64!g" \
+ -e "s!@ac_cv_have_stdint_h@!0!g" \
+ -e "s!@ac_cv_have_inttypes_h@!0!g" \
+ -e "s!@ac_have_attribute_weak@!0!g" \
+ -e "s!\\bhash\\b!hash_compare!g" \
+ "$file" > "$outfile"
+ done
+) < "$1/windows/config.h"
+
+echo "DONE"