From b238c9774a3c26a5e1d3b85549dcf549fde632f2 Mon Sep 17 00:00:00 2001 From: csilvers Date: Wed, 10 Mar 2010 00:25:37 +0000 Subject: [PATCH] * Allow ftp:// in ValidateUrl modifier (martone) * Add appropriate header files to template-converter (csilvers) * PORTING: Be more careful about #including stdint.h (csilvers) --- src/base/small_map.h | 59 +++++++++++++++++++----- src/ctemplate/template_modifiers.h.in | 4 +- src/template-converter | 18 +++++--- src/template_modifiers.cc | 14 ++++-- src/tests/template_modifiers_unittest.cc | 5 ++ src/windows/ctemplate/template_string.h | 10 ++-- src/windows/preprocess.sh | 3 +- 7 files changed, 84 insertions(+), 29 deletions(-) diff --git a/src/base/small_map.h b/src/base/small_map.h index bd46c5c..d3cdb5d 100644 --- a/src/base/small_map.h +++ b/src/base/small_map.h @@ -107,14 +107,23 @@ class small_map { small_map(const MapInit& functor) : size_(0), functor_(functor) {} + // Allow copy-constructor and assignment, since STL allows them too. + small_map(const small_map& src) { + // size_ and functor_ are initted in InitFrom() + InitFrom(src); + } + void operator=(const small_map& src) { + if (&src == this) return; + + // This is not optimal. If src and dest are both using the small + // array, we could skip the teardown and reconstruct. One problem + // to be resolved is that the value_type itself is pair, and const K is not assignable. + Destroy(); + InitFrom(src); + } ~small_map() { - if (size_ >= 0) { - for (int i = 0; i < size_; i++) { - array_[i].Destroy(); - } - } else { - map_.Destroy(); - } + Destroy(); } class const_iterator; @@ -137,7 +146,11 @@ class small_map { } return *this; } - + inline iterator operator++(int) { + iterator result(*this); + ++(*this); + return result; + } inline value_type* operator->() const { if (array_iter_ != NULL) { return array_iter_->get(); @@ -193,6 +206,11 @@ class small_map { inline const_iterator(const iterator& other) : array_iter_(other.array_iter_), hash_iter_(other.hash_iter_) {} + inline const_iterator operator++(int) { + const_iterator result(*this); + ++(*this); + return result; + } inline const_iterator& operator++() { if (array_iter_ != NULL) { ++array_iter_; @@ -459,9 +477,28 @@ class small_map { } } - // We don't allow a small_map to be copied. - small_map(const small_map&); - small_map& operator=(const small_map&); + // Helpers for constructors and destructors. + void InitFrom(const small_map& src) { + functor_ = src.functor_; + size_ = src.size_; + if (src.size_ >= 0) { + for (int i = 0; i < size_; i++) { + array_[i].Init(*src.array_[i]); + } + } else { + functor_(&map_); + (*map_.get()) = (*src.map_.get()); + } + } + void Destroy() { + if (size_ >= 0) { + for (int i = 0; i < size_; i++) { + array_[i].Destroy(); + } + } else { + map_.Destroy(); + } + } }; template tags, tags, and -// matched and tags. +// Like HtmlEscape but allows HTML entities,
tags, tags, +// matched and tags, and matched and tags. class @ac_windows_dllexport@ SnippetEscape : public TemplateModifier { MODIFY_SIGNATURE_; }; extern @ac_windows_dllexport@ SnippetEscape snippet_escape; diff --git a/src/template-converter b/src/template-converter index 30d0e28..2226bec 100755 --- a/src/template-converter +++ b/src/template-converter @@ -44,7 +44,10 @@ # as a pathname, and take the basename, strip the # suffix if it's .h, and sanitize the rest of the name to be a legal # C variable name. +# NOTE: See doc/index.html for a general description of Google ctemplate. +# Store the input argv. +my $argv = join(" ", $0, @ARGV); # Open template file (my $template_name = shift) || usage("Need to specify template variable name."); @@ -66,13 +69,16 @@ $base_name =~ s|\.h$||; # Strip out suffix, if it's .h $base_name =~ tr|A-Za-z0-9_|_|c; # Sanitize name to remove non-letters/nums # Print header -print "// This file automatically generated by template-converter\n"; +print "// This file automatically generated by template-converter:\n"; +print "// $argv\n"; +print "//\n"; print "// DO NOT EDIT!\n\n"; -print "#ifndef _" . uc($base_name) . "_H\n"; -print "#define _" . uc($base_name) . "_H\n\n"; +print "#ifndef " . uc($base_name) . "_H_\n"; +print "#define " . uc($base_name) . "_H_\n\n"; +print "#include \n\n"; # Read in template file and print template as a string -print "const string ${base_name} (\n"; +print "const std::string ${base_name} (\n"; while (<>) { chomp; my $escaped_line = escape_line($_); @@ -81,7 +87,7 @@ while (<>) { print ");\n\n"; # Print footer and exit -print "#endif /* _" . uc($base_name) . "_H */\n"; +print "#endif /* " . uc($base_name) . "_H_ */\n"; exit(0); # Prints usage message @@ -100,5 +106,3 @@ sub escape_line { $line =~ s|\"|\\"|g; return $line; } - - diff --git a/src/template_modifiers.cc b/src/template_modifiers.cc index ec55277..7b5b011 100644 --- a/src/template_modifiers.cc +++ b/src/template_modifiers.cc @@ -343,18 +343,22 @@ void ValidateUrl::Modify(const char* in, size_t inlen, const PerExpandData* per_expand_data, ExpandEmitter* out, const string& arg) const { const char* slashpos = (char*)memchr(in, '/', inlen); - if (slashpos == NULL) + if (slashpos == NULL) { slashpos = in + inlen; + } const void* colonpos = memchr(in, ':', slashpos - in); - if (colonpos != NULL) { // colon before first slash, could be a protocol + if (colonpos != NULL) { // colon before first slash, could be a protocol if (inlen > sizeof("http://")-1 && strncasecmp(in, "http://", sizeof("http://")-1) == 0) { - // We're ok, it's an http protocol + // We're ok, it's an http protocol } else if (inlen > sizeof("https://")-1 && strncasecmp(in, "https://", sizeof("https://")-1) == 0) { - // https is ok as well + // https is ok as well + } else if (inlen > sizeof("ftp://")-1 && + strncasecmp(in, "ftp://", sizeof("ftp://")-1) == 0) { + // and ftp } else { - // It's a bad protocol, so return something safe + // It's a bad protocol, so return something safe chained_modifier_.Modify("#", 1, per_expand_data, out, ""); return; } diff --git a/src/tests/template_modifiers_unittest.cc b/src/tests/template_modifiers_unittest.cc index c9d4f71..8537bce 100644 --- a/src/tests/template_modifiers_unittest.cc +++ b/src/tests/template_modifiers_unittest.cc @@ -219,6 +219,9 @@ class TemplateModifiersUnittest { dict.SetEscapedValue("harder relative URL", "/search?q=green flowers&hl=en", validate_url_and_html_escape); + dict.SetEscapedValue("ftp URL", + "ftp://ftp.example.org/pub/file.txt", + validate_url_and_html_escape); TemplateDictionaryPeer peer(&dict); // peer can look inside the dict ASSERT_STREQ(peer.GetSectionValue("easy http URL"), @@ -233,6 +236,8 @@ class TemplateModifiersUnittest { "foobar.html"); ASSERT_STREQ(peer.GetSectionValue("harder relative URL"), "/search?q=green flowers&hl=en"); + ASSERT_STREQ(peer.GetSectionValue("ftp URL"), + "ftp://ftp.example.org/pub/file.txt"); } static void TestValidateUrlJavascriptEscape() { diff --git a/src/windows/ctemplate/template_string.h b/src/windows/ctemplate/template_string.h index 2974a89..d15de22 100644 --- a/src/windows/ctemplate/template_string.h +++ b/src/windows/ctemplate/template_string.h @@ -32,9 +32,13 @@ #include // for memcmp() and size_t #include - - - +#if 0 +#include // one place @ac_cv_unit64@ might live +#endif +#if 0 +#include // another place @ac_cv_unit64@ might live +#endif +#include // final place @ac_cv_unit64@ might live #include #include #include diff --git a/src/windows/preprocess.sh b/src/windows/preprocess.sh index afa0874..af6bf34 100755 --- a/src/windows/preprocess.sh +++ b/src/windows/preprocess.sh @@ -88,8 +88,9 @@ DLLDEF_DEFINES="\ -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_u..t64@ might live.*!!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"