mirror of
https://github.com/OlafvdSpek/ctemplate.git
synced 2025-09-28 19:05:49 +08:00
Thu Jun 21 14:02:32 2007 Google Inc. <opensource@google.com>
* ctemplate: version 0.6.1 release * Bugfix: data corruption bug with >2 template modifiers (jmacgill) * Bugfix: syntax error in template-namelist: configure-bug (csilvers) * Bugfix: improve lock hygenie to avoid potential deadlock (csilvers)
This commit is contained in:
parent
f0a3fceb99
commit
cf4599bd94
|
@ -51,3 +51,10 @@ Sat Jun 9 22:34:52 2007 Google Inc. <opensource@google.com>
|
||||||
* New modifiers for url-escaping, attribute-cleansing, etc (ribrdb)
|
* New modifiers for url-escaping, attribute-cleansing, etc (ribrdb)
|
||||||
* Annotations now include modifier information (csilvers)
|
* Annotations now include modifier information (csilvers)
|
||||||
* Support embedded NULs in template names and values (csilvers)
|
* Support embedded NULs in template names and values (csilvers)
|
||||||
|
|
||||||
|
Thu Jun 21 14:02:32 2007 Google Inc. <opensource@google.com>
|
||||||
|
|
||||||
|
* ctemplate: version 0.6.1 release
|
||||||
|
* Bugfix: data corruption bug with >2 template modifiers (jmacgill)
|
||||||
|
* Bugfix: syntax error in template-namelist: configure-bug (csilvers)
|
||||||
|
* Bugfix: improve lock hygenie to avoid potential deadlock (csilvers)
|
||||||
|
|
70
INSTALL
70
INSTALL
|
@ -1,16 +1,14 @@
|
||||||
Installation Instructions
|
Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||||
*************************
|
Foundation, Inc.
|
||||||
|
|
||||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
|
This file is free documentation; the Free Software Foundation gives
|
||||||
Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is free documentation; the Free Software Foundation gives
|
|
||||||
unlimited permission to copy, distribute and modify it.
|
unlimited permission to copy, distribute and modify it.
|
||||||
|
|
||||||
|
|
||||||
Basic Installation
|
Basic Installation
|
||||||
==================
|
==================
|
||||||
|
|
||||||
These are generic installation instructions.
|
These are generic installation instructions.
|
||||||
|
|
||||||
The `configure' shell script attempts to guess correct values for
|
The `configure' shell script attempts to guess correct values for
|
||||||
various system-dependent variables used during compilation. It uses
|
various system-dependent variables used during compilation. It uses
|
||||||
|
@ -70,9 +68,9 @@ The simplest way to compile this package is:
|
||||||
Compilers and Options
|
Compilers and Options
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Some systems require unusual options for compilation or linking that the
|
Some systems require unusual options for compilation or linking that
|
||||||
`configure' script does not know about. Run `./configure --help' for
|
the `configure' script does not know about. Run `./configure --help'
|
||||||
details on some of the pertinent environment variables.
|
for details on some of the pertinent environment variables.
|
||||||
|
|
||||||
You can give `configure' initial values for configuration parameters
|
You can give `configure' initial values for configuration parameters
|
||||||
by setting variables in the command line or in the environment. Here
|
by setting variables in the command line or in the environment. Here
|
||||||
|
@ -85,7 +83,7 @@ is an example:
|
||||||
Compiling For Multiple Architectures
|
Compiling For Multiple Architectures
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
You can compile the package for more than one kind of computer at the
|
You can compile the package for more than one kind of computer at the
|
||||||
same time, by placing the object files for each architecture in their
|
same time, by placing the object files for each architecture in their
|
||||||
own directory. To do this, you must use a version of `make' that
|
own directory. To do this, you must use a version of `make' that
|
||||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||||
|
@ -102,19 +100,19 @@ for another architecture.
|
||||||
Installation Names
|
Installation Names
|
||||||
==================
|
==================
|
||||||
|
|
||||||
By default, `make install' installs the package's commands under
|
By default, `make install' will install the package's files in
|
||||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||||
can specify an installation prefix other than `/usr/local' by giving
|
installation prefix other than `/usr/local' by giving `configure' the
|
||||||
`configure' the option `--prefix=PREFIX'.
|
option `--prefix=PATH'.
|
||||||
|
|
||||||
You can specify separate installation prefixes for
|
You can specify separate installation prefixes for
|
||||||
architecture-specific files and architecture-independent files. If you
|
architecture-specific files and architecture-independent files. If you
|
||||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||||
PREFIX as the prefix for installing programs and libraries.
|
PATH as the prefix for installing programs and libraries.
|
||||||
Documentation and other data files still use the regular prefix.
|
Documentation and other data files will still use the regular prefix.
|
||||||
|
|
||||||
In addition, if you use an unusual directory layout you can give
|
In addition, if you use an unusual directory layout you can give
|
||||||
options like `--bindir=DIR' to specify different values for particular
|
options like `--bindir=PATH' to specify different values for particular
|
||||||
kinds of files. Run `configure --help' for a list of the directories
|
kinds of files. Run `configure --help' for a list of the directories
|
||||||
you can set and what kinds of files go in them.
|
you can set and what kinds of files go in them.
|
||||||
|
|
||||||
|
@ -125,7 +123,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||||
Optional Features
|
Optional Features
|
||||||
=================
|
=================
|
||||||
|
|
||||||
Some packages pay attention to `--enable-FEATURE' options to
|
Some packages pay attention to `--enable-FEATURE' options to
|
||||||
`configure', where FEATURE indicates an optional part of the package.
|
`configure', where FEATURE indicates an optional part of the package.
|
||||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||||
is something like `gnu-as' or `x' (for the X Window System). The
|
is something like `gnu-as' or `x' (for the X Window System). The
|
||||||
|
@ -140,11 +138,11 @@ you can use the `configure' options `--x-includes=DIR' and
|
||||||
Specifying the System Type
|
Specifying the System Type
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
There may be some features `configure' cannot figure out automatically,
|
There may be some features `configure' cannot figure out
|
||||||
but needs to determine by the type of machine the package will run on.
|
automatically, but needs to determine by the type of machine the package
|
||||||
Usually, assuming the package is built to be run on the _same_
|
will run on. Usually, assuming the package is built to be run on the
|
||||||
architectures, `configure' can figure that out, but if it prints a
|
_same_ architectures, `configure' can figure that out, but if it prints
|
||||||
message saying it cannot guess the machine type, give it the
|
a message saying it cannot guess the machine type, give it the
|
||||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||||
type, such as `sun4', or a canonical name which has the form:
|
type, such as `sun4', or a canonical name which has the form:
|
||||||
|
|
||||||
|
@ -159,7 +157,7 @@ where SYSTEM can have one of these forms:
|
||||||
need to know the machine type.
|
need to know the machine type.
|
||||||
|
|
||||||
If you are _building_ compiler tools for cross-compiling, you should
|
If you are _building_ compiler tools for cross-compiling, you should
|
||||||
use the option `--target=TYPE' to select the type of system they will
|
use the `--target=TYPE' option to select the type of system they will
|
||||||
produce code for.
|
produce code for.
|
||||||
|
|
||||||
If you want to _use_ a cross compiler, that generates code for a
|
If you want to _use_ a cross compiler, that generates code for a
|
||||||
|
@ -170,9 +168,9 @@ eventually be run) with `--host=TYPE'.
|
||||||
Sharing Defaults
|
Sharing Defaults
|
||||||
================
|
================
|
||||||
|
|
||||||
If you want to set default values for `configure' scripts to share, you
|
If you want to set default values for `configure' scripts to share,
|
||||||
can create a site shell script called `config.site' that gives default
|
you can create a site shell script called `config.site' that gives
|
||||||
values for variables like `CC', `cache_file', and `prefix'.
|
default values for variables like `CC', `cache_file', and `prefix'.
|
||||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||||
`CONFIG_SITE' environment variable to the location of the site script.
|
`CONFIG_SITE' environment variable to the location of the site script.
|
||||||
|
@ -181,7 +179,7 @@ A warning: not all `configure' scripts look for a site script.
|
||||||
Defining Variables
|
Defining Variables
|
||||||
==================
|
==================
|
||||||
|
|
||||||
Variables not defined in a site shell script can be set in the
|
Variables not defined in a site shell script can be set in the
|
||||||
environment passed to `configure'. However, some packages may run
|
environment passed to `configure'. However, some packages may run
|
||||||
configure again during the build, and the customized values of these
|
configure again during the build, and the customized values of these
|
||||||
variables may be lost. In order to avoid this problem, you should set
|
variables may be lost. In order to avoid this problem, you should set
|
||||||
|
@ -189,18 +187,14 @@ them in the `configure' command line, using `VAR=value'. For example:
|
||||||
|
|
||||||
./configure CC=/usr/local2/bin/gcc
|
./configure CC=/usr/local2/bin/gcc
|
||||||
|
|
||||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
will cause the specified gcc to be used as the C compiler (unless it is
|
||||||
overridden in the site shell script). Here is a another example:
|
overridden in the site shell script).
|
||||||
|
|
||||||
/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
|
||||||
|
|
||||||
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
|
|
||||||
configuration-related scripts to be executed by `/bin/bash'.
|
|
||||||
|
|
||||||
`configure' Invocation
|
`configure' Invocation
|
||||||
======================
|
======================
|
||||||
|
|
||||||
`configure' recognizes the following options to control how it operates.
|
`configure' recognizes the following options to control how it
|
||||||
|
operates.
|
||||||
|
|
||||||
`--help'
|
`--help'
|
||||||
`-h'
|
`-h'
|
||||||
|
|
|
@ -64,7 +64,7 @@ CTEMPLATE_SYMBOLS = '[^A-Za-z](Template|TemplateDictionary|TemplateNamelist|Temp
|
||||||
|
|
||||||
lib_LTLIBRARIES += libctemplate.la
|
lib_LTLIBRARIES += libctemplate.la
|
||||||
libctemplate_la_SOURCES = $(googleinclude_HEADERS) src/config.h \
|
libctemplate_la_SOURCES = $(googleinclude_HEADERS) src/config.h \
|
||||||
src/base/arena.h src/base/arena.cc src/base/mutex.h src/base/mutex.cc \
|
src/base/arena.h src/base/arena.cc src/base/mutex.h \
|
||||||
src/template.cc src/template_dictionary.cc src/template_modifiers.cc \
|
src/template.cc src/template_dictionary.cc src/template_modifiers.cc \
|
||||||
src/template_namelist.cc src/template_from_string.cc
|
src/template_namelist.cc src/template_from_string.cc
|
||||||
libctemplate_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG
|
libctemplate_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG
|
||||||
|
|
22
Makefile.in
22
Makefile.in
|
@ -90,7 +90,7 @@ am__DEPENDENCIES_1 =
|
||||||
libctemplate_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
|
libctemplate_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
|
||||||
am__objects_1 =
|
am__objects_1 =
|
||||||
am_libctemplate_la_OBJECTS = $(am__objects_1) libctemplate_la-arena.lo \
|
am_libctemplate_la_OBJECTS = $(am__objects_1) libctemplate_la-arena.lo \
|
||||||
libctemplate_la-mutex.lo libctemplate_la-template.lo \
|
libctemplate_la-template.lo \
|
||||||
libctemplate_la-template_dictionary.lo \
|
libctemplate_la-template_dictionary.lo \
|
||||||
libctemplate_la-template_modifiers.lo \
|
libctemplate_la-template_modifiers.lo \
|
||||||
libctemplate_la-template_namelist.lo \
|
libctemplate_la-template_namelist.lo \
|
||||||
|
@ -98,7 +98,6 @@ am_libctemplate_la_OBJECTS = $(am__objects_1) libctemplate_la-arena.lo \
|
||||||
libctemplate_la_OBJECTS = $(am_libctemplate_la_OBJECTS)
|
libctemplate_la_OBJECTS = $(am_libctemplate_la_OBJECTS)
|
||||||
libctemplate_nothreads_la_LIBADD =
|
libctemplate_nothreads_la_LIBADD =
|
||||||
am__objects_2 = $(am__objects_1) libctemplate_nothreads_la-arena.lo \
|
am__objects_2 = $(am__objects_1) libctemplate_nothreads_la-arena.lo \
|
||||||
libctemplate_nothreads_la-mutex.lo \
|
|
||||||
libctemplate_nothreads_la-template.lo \
|
libctemplate_nothreads_la-template.lo \
|
||||||
libctemplate_nothreads_la-template_dictionary.lo \
|
libctemplate_nothreads_la-template_dictionary.lo \
|
||||||
libctemplate_nothreads_la-template_modifiers.lo \
|
libctemplate_nothreads_la-template_modifiers.lo \
|
||||||
|
@ -326,6 +325,7 @@ ac_ct_RANLIB = @ac_ct_RANLIB@
|
||||||
ac_ct_STRIP = @ac_ct_STRIP@
|
ac_ct_STRIP = @ac_ct_STRIP@
|
||||||
ac_cv_cxx_hash_map = @ac_cv_cxx_hash_map@
|
ac_cv_cxx_hash_map = @ac_cv_cxx_hash_map@
|
||||||
ac_cv_cxx_hash_namespace = @ac_cv_cxx_hash_namespace@
|
ac_cv_cxx_hash_namespace = @ac_cv_cxx_hash_namespace@
|
||||||
|
ac_cv_cxx_hash_set = @ac_cv_cxx_hash_set@
|
||||||
ac_google_attribute = @ac_google_attribute@
|
ac_google_attribute = @ac_google_attribute@
|
||||||
ac_google_end_namespace = @ac_google_end_namespace@
|
ac_google_end_namespace = @ac_google_end_namespace@
|
||||||
ac_google_namespace = @ac_google_namespace@
|
ac_google_namespace = @ac_google_namespace@
|
||||||
|
@ -435,7 +435,7 @@ noinst_SCRIPTS = src/tests/make_tpl_varnames_h_unittest.sh
|
||||||
# These are the symbols (classes, mostly) we want to export from our library
|
# These are the symbols (classes, mostly) we want to export from our library
|
||||||
CTEMPLATE_SYMBOLS = '[^A-Za-z](Template|TemplateDictionary|TemplateNamelist|TemplateFromString|TemplateString|TemplateState|Strip)[^A-Za-z]'
|
CTEMPLATE_SYMBOLS = '[^A-Za-z](Template|TemplateDictionary|TemplateNamelist|TemplateFromString|TemplateString|TemplateState|Strip)[^A-Za-z]'
|
||||||
libctemplate_la_SOURCES = $(googleinclude_HEADERS) src/config.h \
|
libctemplate_la_SOURCES = $(googleinclude_HEADERS) src/config.h \
|
||||||
src/base/arena.h src/base/arena.cc src/base/mutex.h src/base/mutex.cc \
|
src/base/arena.h src/base/arena.cc src/base/mutex.h \
|
||||||
src/template.cc src/template_dictionary.cc src/template_modifiers.cc \
|
src/template.cc src/template_dictionary.cc src/template_modifiers.cc \
|
||||||
src/template_namelist.cc src/template_from_string.cc
|
src/template_namelist.cc src/template_from_string.cc
|
||||||
|
|
||||||
|
@ -723,14 +723,12 @@ distclean-compile:
|
||||||
-rm -f *.tab.c
|
-rm -f *.tab.c
|
||||||
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-arena.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-arena.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-mutex.Plo@am__quote@
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-template.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-template.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-template_dictionary.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-template_dictionary.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-template_from_string.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-template_from_string.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-template_modifiers.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-template_modifiers.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-template_namelist.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_la-template_namelist.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_nothreads_la-arena.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_nothreads_la-arena.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_nothreads_la-mutex.Plo@am__quote@
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_nothreads_la-template.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_nothreads_la-template.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_nothreads_la-template_dictionary.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_nothreads_la-template_dictionary.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_nothreads_la-template_from_string.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctemplate_nothreads_la-template_from_string.Plo@am__quote@
|
||||||
|
@ -779,13 +777,6 @@ libctemplate_la-arena.lo: src/base/arena.cc
|
||||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_la_CXXFLAGS) $(CXXFLAGS) -c -o libctemplate_la-arena.lo `test -f 'src/base/arena.cc' || echo '$(srcdir)/'`src/base/arena.cc
|
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_la_CXXFLAGS) $(CXXFLAGS) -c -o libctemplate_la-arena.lo `test -f 'src/base/arena.cc' || echo '$(srcdir)/'`src/base/arena.cc
|
||||||
|
|
||||||
libctemplate_la-mutex.lo: src/base/mutex.cc
|
|
||||||
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_la_CXXFLAGS) $(CXXFLAGS) -MT libctemplate_la-mutex.lo -MD -MP -MF "$(DEPDIR)/libctemplate_la-mutex.Tpo" -c -o libctemplate_la-mutex.lo `test -f 'src/base/mutex.cc' || echo '$(srcdir)/'`src/base/mutex.cc; \
|
|
||||||
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libctemplate_la-mutex.Tpo" "$(DEPDIR)/libctemplate_la-mutex.Plo"; else rm -f "$(DEPDIR)/libctemplate_la-mutex.Tpo"; exit 1; fi
|
|
||||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/base/mutex.cc' object='libctemplate_la-mutex.lo' libtool=yes @AMDEPBACKSLASH@
|
|
||||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
|
||||||
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_la_CXXFLAGS) $(CXXFLAGS) -c -o libctemplate_la-mutex.lo `test -f 'src/base/mutex.cc' || echo '$(srcdir)/'`src/base/mutex.cc
|
|
||||||
|
|
||||||
libctemplate_la-template.lo: src/template.cc
|
libctemplate_la-template.lo: src/template.cc
|
||||||
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_la_CXXFLAGS) $(CXXFLAGS) -MT libctemplate_la-template.lo -MD -MP -MF "$(DEPDIR)/libctemplate_la-template.Tpo" -c -o libctemplate_la-template.lo `test -f 'src/template.cc' || echo '$(srcdir)/'`src/template.cc; \
|
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_la_CXXFLAGS) $(CXXFLAGS) -MT libctemplate_la-template.lo -MD -MP -MF "$(DEPDIR)/libctemplate_la-template.Tpo" -c -o libctemplate_la-template.lo `test -f 'src/template.cc' || echo '$(srcdir)/'`src/template.cc; \
|
||||||
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libctemplate_la-template.Tpo" "$(DEPDIR)/libctemplate_la-template.Plo"; else rm -f "$(DEPDIR)/libctemplate_la-template.Tpo"; exit 1; fi
|
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libctemplate_la-template.Tpo" "$(DEPDIR)/libctemplate_la-template.Plo"; else rm -f "$(DEPDIR)/libctemplate_la-template.Tpo"; exit 1; fi
|
||||||
|
@ -828,13 +819,6 @@ libctemplate_nothreads_la-arena.lo: src/base/arena.cc
|
||||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_nothreads_la_CXXFLAGS) $(CXXFLAGS) -c -o libctemplate_nothreads_la-arena.lo `test -f 'src/base/arena.cc' || echo '$(srcdir)/'`src/base/arena.cc
|
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_nothreads_la_CXXFLAGS) $(CXXFLAGS) -c -o libctemplate_nothreads_la-arena.lo `test -f 'src/base/arena.cc' || echo '$(srcdir)/'`src/base/arena.cc
|
||||||
|
|
||||||
libctemplate_nothreads_la-mutex.lo: src/base/mutex.cc
|
|
||||||
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_nothreads_la_CXXFLAGS) $(CXXFLAGS) -MT libctemplate_nothreads_la-mutex.lo -MD -MP -MF "$(DEPDIR)/libctemplate_nothreads_la-mutex.Tpo" -c -o libctemplate_nothreads_la-mutex.lo `test -f 'src/base/mutex.cc' || echo '$(srcdir)/'`src/base/mutex.cc; \
|
|
||||||
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libctemplate_nothreads_la-mutex.Tpo" "$(DEPDIR)/libctemplate_nothreads_la-mutex.Plo"; else rm -f "$(DEPDIR)/libctemplate_nothreads_la-mutex.Tpo"; exit 1; fi
|
|
||||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/base/mutex.cc' object='libctemplate_nothreads_la-mutex.lo' libtool=yes @AMDEPBACKSLASH@
|
|
||||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
|
||||||
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_nothreads_la_CXXFLAGS) $(CXXFLAGS) -c -o libctemplate_nothreads_la-mutex.lo `test -f 'src/base/mutex.cc' || echo '$(srcdir)/'`src/base/mutex.cc
|
|
||||||
|
|
||||||
libctemplate_nothreads_la-template.lo: src/template.cc
|
libctemplate_nothreads_la-template.lo: src/template.cc
|
||||||
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_nothreads_la_CXXFLAGS) $(CXXFLAGS) -MT libctemplate_nothreads_la-template.lo -MD -MP -MF "$(DEPDIR)/libctemplate_nothreads_la-template.Tpo" -c -o libctemplate_nothreads_la-template.lo `test -f 'src/template.cc' || echo '$(srcdir)/'`src/template.cc; \
|
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libctemplate_nothreads_la_CXXFLAGS) $(CXXFLAGS) -MT libctemplate_nothreads_la-template.lo -MD -MP -MF "$(DEPDIR)/libctemplate_nothreads_la-template.Tpo" -c -o libctemplate_nothreads_la-template.lo `test -f 'src/template.cc' || echo '$(srcdir)/'`src/template.cc; \
|
||||||
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libctemplate_nothreads_la-template.Tpo" "$(DEPDIR)/libctemplate_nothreads_la-template.Plo"; else rm -f "$(DEPDIR)/libctemplate_nothreads_la-template.Tpo"; exit 1; fi
|
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libctemplate_nothreads_la-template.Tpo" "$(DEPDIR)/libctemplate_nothreads_la-template.Plo"; else rm -f "$(DEPDIR)/libctemplate_nothreads_la-template.Tpo"; exit 1; fi
|
||||||
|
|
24
configure
vendored
24
configure
vendored
|
@ -1,6 +1,6 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.59 for ctemplate 0.6.
|
# Generated by GNU Autoconf 2.59 for ctemplate 0.6.1.
|
||||||
#
|
#
|
||||||
# Report bugs to <opensource@google.com>.
|
# Report bugs to <opensource@google.com>.
|
||||||
#
|
#
|
||||||
|
@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='ctemplate'
|
PACKAGE_NAME='ctemplate'
|
||||||
PACKAGE_TARNAME='ctemplate'
|
PACKAGE_TARNAME='ctemplate'
|
||||||
PACKAGE_VERSION='0.6'
|
PACKAGE_VERSION='0.6.1'
|
||||||
PACKAGE_STRING='ctemplate 0.6'
|
PACKAGE_STRING='ctemplate 0.6.1'
|
||||||
PACKAGE_BUGREPORT='opensource@google.com'
|
PACKAGE_BUGREPORT='opensource@google.com'
|
||||||
|
|
||||||
ac_unique_file="README"
|
ac_unique_file="README"
|
||||||
|
@ -465,7 +465,7 @@ ac_includes_default="\
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif"
|
#endif"
|
||||||
|
|
||||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBTOOL_DEPS acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS ac_google_namespace ac_google_start_namespace ac_google_end_namespace ac_cv_cxx_hash_namespace ac_cv_cxx_hash_map ac_google_attribute LIBOBJS LTLIBOBJS'
|
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBTOOL_DEPS acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS ac_google_namespace ac_google_start_namespace ac_google_end_namespace ac_cv_cxx_hash_namespace ac_cv_cxx_hash_map ac_cv_cxx_hash_set ac_google_attribute LIBOBJS LTLIBOBJS'
|
||||||
ac_subst_files=''
|
ac_subst_files=''
|
||||||
|
|
||||||
# Initialize some variables set by options.
|
# Initialize some variables set by options.
|
||||||
|
@ -954,7 +954,7 @@ if test "$ac_init_help" = "long"; then
|
||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures ctemplate 0.6 to adapt to many kinds of systems.
|
\`configure' configures ctemplate 0.6.1 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
|
@ -1020,7 +1020,7 @@ fi
|
||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of ctemplate 0.6:";;
|
short | recursive ) echo "Configuration of ctemplate 0.6.1:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
|
@ -1163,7 +1163,7 @@ fi
|
||||||
test -n "$ac_init_help" && exit 0
|
test -n "$ac_init_help" && exit 0
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
ctemplate configure 0.6
|
ctemplate configure 0.6.1
|
||||||
generated by GNU Autoconf 2.59
|
generated by GNU Autoconf 2.59
|
||||||
|
|
||||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
@ -1177,7 +1177,7 @@ cat >&5 <<_ACEOF
|
||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by ctemplate $as_me 0.6, which was
|
It was created by ctemplate $as_me 0.6.1, which was
|
||||||
generated by GNU Autoconf 2.59. Invocation command line was
|
generated by GNU Autoconf 2.59. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
|
@ -1823,7 +1823,7 @@ fi
|
||||||
|
|
||||||
# Define the identity of the package.
|
# Define the identity of the package.
|
||||||
PACKAGE='ctemplate'
|
PACKAGE='ctemplate'
|
||||||
VERSION='0.6'
|
VERSION='0.6.1'
|
||||||
|
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
@ -20613,6 +20613,7 @@ echo "$as_me: WARNING: could not find an STL hash_map" >&2;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if test "$ac_cv___attribute__" == "yes"; then
|
if test "$ac_cv___attribute__" == "yes"; then
|
||||||
ac_google_attribute=1
|
ac_google_attribute=1
|
||||||
|
|
||||||
|
@ -21007,7 +21008,7 @@ _ASBOX
|
||||||
} >&5
|
} >&5
|
||||||
cat >&5 <<_CSEOF
|
cat >&5 <<_CSEOF
|
||||||
|
|
||||||
This file was extended by ctemplate $as_me 0.6, which was
|
This file was extended by ctemplate $as_me 0.6.1, which was
|
||||||
generated by GNU Autoconf 2.59. Invocation command line was
|
generated by GNU Autoconf 2.59. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
|
@ -21070,7 +21071,7 @@ _ACEOF
|
||||||
|
|
||||||
cat >>$CONFIG_STATUS <<_ACEOF
|
cat >>$CONFIG_STATUS <<_ACEOF
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
ctemplate config.status 0.6
|
ctemplate config.status 0.6.1
|
||||||
configured by $0, generated by GNU Autoconf 2.59,
|
configured by $0, generated by GNU Autoconf 2.59,
|
||||||
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
||||||
|
|
||||||
|
@ -21351,6 +21352,7 @@ s,@ac_google_start_namespace@,$ac_google_start_namespace,;t t
|
||||||
s,@ac_google_end_namespace@,$ac_google_end_namespace,;t t
|
s,@ac_google_end_namespace@,$ac_google_end_namespace,;t t
|
||||||
s,@ac_cv_cxx_hash_namespace@,$ac_cv_cxx_hash_namespace,;t t
|
s,@ac_cv_cxx_hash_namespace@,$ac_cv_cxx_hash_namespace,;t t
|
||||||
s,@ac_cv_cxx_hash_map@,$ac_cv_cxx_hash_map,;t t
|
s,@ac_cv_cxx_hash_map@,$ac_cv_cxx_hash_map,;t t
|
||||||
|
s,@ac_cv_cxx_hash_set@,$ac_cv_cxx_hash_set,;t t
|
||||||
s,@ac_google_attribute@,$ac_google_attribute,;t t
|
s,@ac_google_attribute@,$ac_google_attribute,;t t
|
||||||
s,@LIBOBJS@,$LIBOBJS,;t t
|
s,@LIBOBJS@,$LIBOBJS,;t t
|
||||||
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
|
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
# make sure we're interpreted by some minimal autoconf
|
# make sure we're interpreted by some minimal autoconf
|
||||||
AC_PREREQ(2.57)
|
AC_PREREQ(2.57)
|
||||||
|
|
||||||
AC_INIT(ctemplate, 0.6, opensource@google.com)
|
AC_INIT(ctemplate, 0.6.1, opensource@google.com)
|
||||||
# The argument here is just something that should be in the current directory
|
# The argument here is just something that should be in the current directory
|
||||||
# (for sanity checking)
|
# (for sanity checking)
|
||||||
AC_CONFIG_SRCDIR(README)
|
AC_CONFIG_SRCDIR(README)
|
||||||
|
@ -58,6 +58,7 @@ AC_SUBST(ac_google_start_namespace)
|
||||||
AC_SUBST(ac_google_end_namespace)
|
AC_SUBST(ac_google_end_namespace)
|
||||||
AC_SUBST(ac_cv_cxx_hash_namespace)
|
AC_SUBST(ac_cv_cxx_hash_namespace)
|
||||||
AC_SUBST(ac_cv_cxx_hash_map)
|
AC_SUBST(ac_cv_cxx_hash_map)
|
||||||
|
AC_SUBST(ac_cv_cxx_hash_set)
|
||||||
if test "$ac_cv___attribute__" == "yes"; then
|
if test "$ac_cv___attribute__" == "yes"; then
|
||||||
AC_SUBST(ac_google_attribute, 1)
|
AC_SUBST(ac_google_attribute, 1)
|
||||||
else
|
else
|
||||||
|
|
|
@ -32,6 +32,75 @@
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
<h2> Simple Example </h2>
|
||||||
|
|
||||||
|
<p>One reason this example is so simple is that it doesn't even
|
||||||
|
require a separate template file, but instead uses
|
||||||
|
<code>TemplateFromString</code>. It also doesn't use sections or
|
||||||
|
template-includes.</p>
|
||||||
|
|
||||||
|
<pre class=example>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
static const char template_text[] =
|
||||||
|
"ERROR: {{FUNCTION}}({{ARGS}}) returned {{ERROR_CODE}}: {{ERROR_MESSAGE}}\n";
|
||||||
|
Template* tpl = TemplateFromString::GetTemplate("error_msg_tpl", template_text,
|
||||||
|
DO_NOT_STRIP);
|
||||||
|
FILE* fp = fopen(argv[1], "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
int err_no = errno; // squirrel this away
|
||||||
|
TemplateDictionary dict("error_msg: fopen()");
|
||||||
|
dict.SetValue("FUNCTION", "fopen");
|
||||||
|
dict.SetValue("ARGS", argv[1]);
|
||||||
|
dict.SetIntValue("ERROR_CODE", err_no);
|
||||||
|
dict.SetValue("ERROR_MESSAGE", strerror(err_no));
|
||||||
|
|
||||||
|
string error_text;
|
||||||
|
tpl->Expand(&error_text, &dict);
|
||||||
|
puts(error_text.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>This example is only slightly more complicated: we only print the
|
||||||
|
": <error message>" part when the error message isn't the empty
|
||||||
|
string.</p>
|
||||||
|
|
||||||
|
<pre class=example>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
static const char template_text[] =
|
||||||
|
"ERROR: {{FUNCTION}}({{ARGS}}) returned {{ERROR_CODE}}"
|
||||||
|
"{{#MSG_SECTION}}: {{ERROR_MESSAGE}}{{/MSG_SECTION}}\n";
|
||||||
|
Template* tpl = TemplateFromString::GetTemplate("error_msg", template_text,
|
||||||
|
DO_NOT_STRIP);
|
||||||
|
FILE* fp = fopen(argv[1], "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
int err_no = errno; // squirrel this away
|
||||||
|
TemplateDictionary dict("file_error_message");
|
||||||
|
dict.SetValue("FUNCTION", "fopen");
|
||||||
|
dict.SetValue("ARGS", argv[1]);
|
||||||
|
dict.SetIntValue("ERROR_CODE", err_no);
|
||||||
|
if (err_no > 0)
|
||||||
|
dict.SetValueAndShowSection("ERROR_MESSAGE", strerror(err_no),
|
||||||
|
"MSG_SECTION");
|
||||||
|
|
||||||
|
string error_text;
|
||||||
|
tpl->Expand(&error_text, &dict);
|
||||||
|
puts(error_text.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>This maybe-show-text functionality is one way the template
|
||||||
|
machinery is more powerful than just using <code>printf</code>.
|
||||||
|
Another nice property of templates is you can reuse the same variable
|
||||||
|
multiple times in your template string. You can also define the
|
||||||
|
variable values in any order.</p>
|
||||||
|
|
||||||
|
|
||||||
<h2> Search Results Page </h2>
|
<h2> Search Results Page </h2>
|
||||||
|
|
||||||
<p>Here is an example template that could be used to format a Google
|
<p>Here is an example template that could be used to format a Google
|
||||||
|
|
65
ltmain.sh
65
ltmain.sh
|
@ -1,3 +1,8 @@
|
||||||
|
# NOTE(csilvers): This file (ltmain.sh) is taken from
|
||||||
|
# http://ftp.gnu.org/gnu/libtool/libtool-1.5.22.tar.gz
|
||||||
|
# with the following patch applied:
|
||||||
|
# http://www.marcuscom.com/downloads/patch-ltmain.sh
|
||||||
|
|
||||||
# ltmain.sh - Provide generalized library-building support services.
|
# ltmain.sh - Provide generalized library-building support services.
|
||||||
# NOTE: Changing this file will not affect anything until you rerun configure.
|
# NOTE: Changing this file will not affect anything until you rerun configure.
|
||||||
#
|
#
|
||||||
|
@ -43,7 +48,7 @@ EXIT_FAILURE=1
|
||||||
|
|
||||||
PROGRAM=ltmain.sh
|
PROGRAM=ltmain.sh
|
||||||
PACKAGE=libtool
|
PACKAGE=libtool
|
||||||
VERSION="1.5.22 Debian 1.5.22-2"
|
VERSION=1.5.22
|
||||||
TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
|
TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
|
||||||
|
|
||||||
# See if we are running on zsh, and set the options which allow our
|
# See if we are running on zsh, and set the options which allow our
|
||||||
|
@ -1604,11 +1609,18 @@ EOF
|
||||||
compiler_flags="$compiler_flags $arg"
|
compiler_flags="$compiler_flags $arg"
|
||||||
compile_command="$compile_command $arg"
|
compile_command="$compile_command $arg"
|
||||||
finalize_command="$finalize_command $arg"
|
finalize_command="$finalize_command $arg"
|
||||||
|
deplibs="$deplibs $arg"
|
||||||
continue
|
continue
|
||||||
;;
|
;;
|
||||||
|
|
||||||
-module)
|
-module)
|
||||||
module=yes
|
module=yes
|
||||||
|
case $host in
|
||||||
|
*-*-freebsd*)
|
||||||
|
# Do not build the useless static library
|
||||||
|
build_old_libs=no
|
||||||
|
;;
|
||||||
|
esac
|
||||||
continue
|
continue
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
@ -2082,10 +2094,7 @@ EOF
|
||||||
case $pass in
|
case $pass in
|
||||||
dlopen) libs="$dlfiles" ;;
|
dlopen) libs="$dlfiles" ;;
|
||||||
dlpreopen) libs="$dlprefiles" ;;
|
dlpreopen) libs="$dlprefiles" ;;
|
||||||
link)
|
link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
|
||||||
libs="$deplibs %DEPLIBS%"
|
|
||||||
test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
if test "$pass" = dlopen; then
|
if test "$pass" = dlopen; then
|
||||||
|
@ -2104,6 +2113,29 @@ EOF
|
||||||
else
|
else
|
||||||
compiler_flags="$compiler_flags $deplib"
|
compiler_flags="$compiler_flags $deplib"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
case $linkmode in
|
||||||
|
lib)
|
||||||
|
deplibs="$deplib $deplibs"
|
||||||
|
test "$pass" = conv && continue
|
||||||
|
newdependency_libs="$deplib $newdependency_libs"
|
||||||
|
;;
|
||||||
|
prog)
|
||||||
|
if test "$pass" = conv; then
|
||||||
|
deplibs="$deplib $deplibs"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if test "$pass" = scan; then
|
||||||
|
deplibs="$deplib $deplibs"
|
||||||
|
else
|
||||||
|
compile_deplibs="$deplib $compile_deplibs"
|
||||||
|
finalize_deplibs="$deplib $finalize_deplibs"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac # linkmode
|
||||||
|
|
||||||
continue
|
continue
|
||||||
;;
|
;;
|
||||||
-l*)
|
-l*)
|
||||||
|
@ -3204,11 +3236,6 @@ EOF
|
||||||
age="$number_minor"
|
age="$number_minor"
|
||||||
revision="$number_minor"
|
revision="$number_minor"
|
||||||
;;
|
;;
|
||||||
*)
|
|
||||||
$echo "$modename: unknown library version type \`$version_type'" 1>&2
|
|
||||||
$echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
|
|
||||||
exit $EXIT_FAILURE
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
no)
|
no)
|
||||||
|
@ -4713,6 +4740,9 @@ static const void *lt_preloaded_setup() {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
*-*-freebsd*)
|
||||||
|
# FreeBSD doesn't need this...
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
$echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
|
$echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
|
||||||
exit $EXIT_FAILURE
|
exit $EXIT_FAILURE
|
||||||
|
@ -6003,10 +6033,17 @@ relink_command=\"$relink_command\""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Install the pseudo-library for information purposes.
|
# Install the pseudo-library for information purposes.
|
||||||
name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
|
case $host in
|
||||||
instname="$dir/$name"i
|
*-*-freebsd*)
|
||||||
$show "$install_prog $instname $destdir/$name"
|
# Do not install the useless pseudo-library
|
||||||
$run eval "$install_prog $instname $destdir/$name" || exit $?
|
;;
|
||||||
|
*)
|
||||||
|
name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
|
||||||
|
instname="$dir/$name"i
|
||||||
|
$show "$install_prog $instname $destdir/$name"
|
||||||
|
$run eval "$install_prog $instname $destdir/$name" || exit $?
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# Maybe install the static library, too.
|
# Maybe install the static library, too.
|
||||||
test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
|
test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
ctemplate (0.6.1-1) unstable; urgency=low
|
||||||
|
|
||||||
|
* New upstream release.
|
||||||
|
|
||||||
|
-- Google Inc. <opensource@google.com> Thu, 21 Jun 2007 14:02:32 -0700
|
||||||
|
|
||||||
ctemplate (0.6-1) unstable; urgency=low
|
ctemplate (0.6-1) unstable; urgency=low
|
||||||
|
|
||||||
* New upstream release.
|
* New upstream release.
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
/* 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
|
|
||||||
*
|
|
||||||
* A simple mutex wrapper. Right now, it's implemented in terms of
|
|
||||||
* pthreads, but is meant to be easy to extend to other threads impls.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "mutex.h"
|
|
||||||
|
|
||||||
#if defined(NO_THREADS)
|
|
||||||
|
|
||||||
Mutex::Mutex() {}
|
|
||||||
Mutex::~Mutex() {}
|
|
||||||
void Mutex::Lock() {}
|
|
||||||
void Mutex::Unlock() {}
|
|
||||||
void Mutex::ReaderLock() {}
|
|
||||||
void Mutex::ReaderUnlock() {}
|
|
||||||
|
|
||||||
#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
|
|
||||||
|
|
||||||
#include <stdlib.h> // for abort()
|
|
||||||
#include <pthread.h>
|
|
||||||
#define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0)
|
|
||||||
|
|
||||||
Mutex::Mutex() { SAFE_PTHREAD(pthread_rwlock_init(&mutex_, NULL)); }
|
|
||||||
Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy(&mutex_)); }
|
|
||||||
void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock(&mutex_)); }
|
|
||||||
void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); }
|
|
||||||
void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock(&mutex_)); }
|
|
||||||
void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); }
|
|
||||||
|
|
||||||
#elif defined(HAVE_PTHREAD)
|
|
||||||
|
|
||||||
#include <stdlib.h> // for abort()
|
|
||||||
#include <pthread.h>
|
|
||||||
#define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0)
|
|
||||||
|
|
||||||
Mutex::Mutex() { SAFE_PTHREAD(pthread_mutex_init(&mutex_, NULL)); }
|
|
||||||
Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy(&mutex_)); }
|
|
||||||
void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock(&mutex_)); }
|
|
||||||
void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock(&mutex_)); }
|
|
||||||
void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks
|
|
||||||
void Mutex::ReaderUnlock() { Unlock(); }
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#error Need to implement mutex.h/cc for your architecture, or #define NO_THREADS
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -45,21 +45,25 @@
|
||||||
#ifndef GOOGLE_MUTEX_H__
|
#ifndef GOOGLE_MUTEX_H__
|
||||||
#define GOOGLE_MUTEX_H__
|
#define GOOGLE_MUTEX_H__
|
||||||
|
|
||||||
#include "config.h" // to figure out pthreads support
|
#include "config.h" // to figure out pthreads support
|
||||||
|
|
||||||
#if defined(NO_THREADS)
|
#if defined(NO_THREADS)
|
||||||
typedef int MutexType; // some dummy type; it won't be used
|
typedef int MutexType; // some dummy type; it won't be used
|
||||||
#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
|
#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
|
||||||
// Needed for pthread_rwlock_*. If it causes problems, you could take
|
// Needed for pthread_rwlock_*. If it causes problems, you could take
|
||||||
// it out, but then you'd have to unset HAVE_RWLOCK (at least on linux).
|
// it out, but then you'd have to unset HAVE_RWLOCK (at least on linux).
|
||||||
# define _XOPEN_SOURCE 500 // needed to get the rwlock calls
|
# define _XOPEN_SOURCE 500 // needed to get the rwlock calls
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
typedef pthread_rwlock_t MutexType;
|
typedef pthread_rwlock_t MutexType;
|
||||||
#elif defined(HAVE_PTHREAD)
|
#elif defined(HAVE_PTHREAD)
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
typedef pthread_mutex_t MutexType;
|
typedef pthread_mutex_t MutexType;
|
||||||
|
#elif defined(WIN32)
|
||||||
|
# define WIN32_LEAN_AND_MEAN // We only need minimal includes
|
||||||
|
# include <windows.h>
|
||||||
|
typedef CRITICAL_SECTION MutexType;
|
||||||
#else
|
#else
|
||||||
# error Need to implement mutex.h/cc for your architecture, or #define NO_THREADS
|
# error Need to implement mutex.h for your architecture, or #define NO_THREADS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Mutex {
|
class Mutex {
|
||||||
|
@ -68,22 +72,22 @@ class Mutex {
|
||||||
// typically used for Mutexes allocated on the heap or the stack.
|
// typically used for Mutexes allocated on the heap or the stack.
|
||||||
// See below for a recommendation for constructing global Mutex
|
// See below for a recommendation for constructing global Mutex
|
||||||
// objects.
|
// objects.
|
||||||
Mutex();
|
inline Mutex();
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~Mutex();
|
inline ~Mutex();
|
||||||
|
|
||||||
void Lock(); // Block if necessary until free, then acquire exclusively
|
inline void Lock(); // Block if needed until free then acquire exclusively
|
||||||
void Unlock(); // Release. Caller must hold it exclusively (via Lock())
|
inline void Unlock(); // Release a lock acquired via Lock()
|
||||||
|
|
||||||
// Note that on systems that don't support read-write locks, these may
|
// Note that on systems that don't support read-write locks, these may
|
||||||
// be implemented as synonyms to Lock() and Unlock(). So you can use
|
// be implemented as synonyms to Lock() and Unlock(). So you can use
|
||||||
// these for efficiency, but don't use them anyplace where being able
|
// these for efficiency, but don't use them anyplace where being able
|
||||||
// to do shared reads is necessary to avoid deadlock.
|
// to do shared reads is necessary to avoid deadlock.
|
||||||
void ReaderLock(); // Block until free or shared, then acquire a share
|
inline void ReaderLock(); // Block until free or shared then acquire a share
|
||||||
void ReaderUnlock(); // Release a read share of this Mutex
|
inline void ReaderUnlock(); // Release a read share of this Mutex
|
||||||
void WriterLock() { Lock(); } // Block until free, then acquire exclusively
|
inline void WriterLock() { Lock(); } // Acquire an exclusive lock
|
||||||
void WriterUnlock() { Unlock(); } // Release the exclusive lock of this Mutex
|
inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MutexType mutex_;
|
MutexType mutex_;
|
||||||
|
@ -95,6 +99,56 @@ class Mutex {
|
||||||
void operator=(const Mutex&);
|
void operator=(const Mutex&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Now the implementation of Mutex for various systems
|
||||||
|
#if defined(NO_THREADS)
|
||||||
|
|
||||||
|
Mutex::Mutex() {}
|
||||||
|
Mutex::~Mutex() {}
|
||||||
|
void Mutex::Lock() {}
|
||||||
|
void Mutex::Unlock() {}
|
||||||
|
void Mutex::ReaderLock() {}
|
||||||
|
void Mutex::ReaderUnlock() {}
|
||||||
|
|
||||||
|
#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
|
||||||
|
|
||||||
|
#include <stdlib.h> // for abort()
|
||||||
|
#define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0)
|
||||||
|
|
||||||
|
Mutex::Mutex() { SAFE_PTHREAD(pthread_rwlock_init(&mutex_, NULL)); }
|
||||||
|
Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy(&mutex_)); }
|
||||||
|
void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock(&mutex_)); }
|
||||||
|
void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); }
|
||||||
|
void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock(&mutex_)); }
|
||||||
|
void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); }
|
||||||
|
#undef SAFE_PTHREAD
|
||||||
|
|
||||||
|
#elif defined(HAVE_PTHREAD)
|
||||||
|
|
||||||
|
#include <stdlib.h> // for abort()
|
||||||
|
#define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0)
|
||||||
|
|
||||||
|
Mutex::Mutex() { SAFE_PTHREAD(pthread_mutex_init(&mutex_, NULL)); }
|
||||||
|
Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy(&mutex_)); }
|
||||||
|
void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock(&mutex_)); }
|
||||||
|
void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock(&mutex_)); }
|
||||||
|
void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks
|
||||||
|
void Mutex::ReaderUnlock() { Unlock(); }
|
||||||
|
#undef SAFE_PTHREAD
|
||||||
|
|
||||||
|
#elif defined(WIN32)
|
||||||
|
|
||||||
|
Mutex::Mutex() { InitializeCriticalSection(&mutex_); }
|
||||||
|
Mutex::~Mutex() { DeleteCriticalSection(&mutex_); }
|
||||||
|
void Mutex::Lock() { EnterCriticalSection(&mutex_); }
|
||||||
|
void Mutex::Unlock() { LeaveCriticalSection(&mutex_); }
|
||||||
|
void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks
|
||||||
|
void Mutex::ReaderUnlock() { Unlock(); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Some helper classes
|
||||||
|
|
||||||
// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
|
// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
|
||||||
class MutexLock {
|
class MutexLock {
|
||||||
|
|
|
@ -201,6 +201,10 @@ class Template {
|
||||||
const TemplateDictionary *dictionary,
|
const TemplateDictionary *dictionary,
|
||||||
const TemplateDictionary *force_annotate_dict) const;
|
const TemplateDictionary *force_annotate_dict) const;
|
||||||
|
|
||||||
|
// Internal version of ReloadIfChanged, used when the function already
|
||||||
|
// has a write-lock on mutex_.
|
||||||
|
bool ReloadIfChangedLocked();
|
||||||
|
|
||||||
// set_state
|
// set_state
|
||||||
// Sets the state of the template. Used during BuildTree().
|
// Sets the state of the template. Used during BuildTree().
|
||||||
void set_state(TemplateState new_state);
|
void set_state(TemplateState new_state);
|
||||||
|
|
|
@ -67,28 +67,32 @@ class TemplateFromString : public Template {
|
||||||
/* GetTemplate
|
/* GetTemplate
|
||||||
Parameters:
|
Parameters:
|
||||||
(NOTE: The parameter list is not the same as Template::GetTemplate.)
|
(NOTE: The parameter list is not the same as Template::GetTemplate.)
|
||||||
template_name - a logical name for the template text
|
cache_key - the cache string used for the template text.
|
||||||
template_text - the text of the template containing the template
|
template_text - the text of the template containing the template
|
||||||
code with markers, the very same language that
|
code with markers, the very same language that
|
||||||
would be stored in a file for the parent class
|
would be stored in a file for the parent class
|
||||||
strip - same as the parent class
|
strip - same as the parent class
|
||||||
Description:
|
Description:
|
||||||
Attempts to find an instance of the class with the given template_name
|
Attempts to find an instance of the class with the given cache_key
|
||||||
stored in the cache. If it finds one, it returns it, ignoring the
|
stored in the cache. If it finds one, it returns it, ignoring the
|
||||||
template_text passed to the method.
|
template_text passed to the method.
|
||||||
If it does not find one, it creates a new instance of the class,
|
If it does not find one, it creates a new instance of the class,
|
||||||
stores it in the cache under the template_name, and returns it.
|
stores it in the cache under the template_name, and returns it.
|
||||||
Note: since cache lookup is by name, you can't have two instances
|
Note: since cache lookup is by key, you can't have two instances
|
||||||
with the same name but different text, and expect it to work.
|
with the same key but different text, and expect it to work.
|
||||||
|
However, if cache_key is the empty string, we ignore the cache,
|
||||||
|
and always create a new instance of the class (without storing it
|
||||||
|
in the cache). In this case *only*, you're responsible for
|
||||||
|
deleting the returned TemplateFromString object when done with it.
|
||||||
*/
|
*/
|
||||||
static TemplateFromString *GetTemplate(const std::string& template_name,
|
static TemplateFromString *GetTemplate(const std::string& cache_key,
|
||||||
const std::string& template_text,
|
const std::string& template_text,
|
||||||
Strip strip);
|
Strip strip);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* This templates constuctor is private just like the parent's is.
|
/* This templates constuctor is private just like the parent's is.
|
||||||
New ones are acquired through TemplateFromString::GetTemplate */
|
New ones are acquired through TemplateFromString::GetTemplate */
|
||||||
TemplateFromString(const std::string& template_name,
|
TemplateFromString(const std::string& cache_key,
|
||||||
const std::string& template_text,
|
const std::string& template_text,
|
||||||
Strip strip);
|
Strip strip);
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,9 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
165
src/template.cc
165
src/template.cc
|
@ -40,7 +40,9 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <ctype.h> // for isspace()
|
#include <ctype.h> // for isspace()
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h> // for stat() and open() and getcwd()
|
#include <unistd.h> // for stat() and open() and getcwd()
|
||||||
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream> // for logging
|
#include <iostream> // for logging
|
||||||
#include <iomanip> // for indenting in Dump()
|
#include <iomanip> // for indenting in Dump()
|
||||||
|
@ -78,6 +80,9 @@ namespace {
|
||||||
// Mutexes protecting the globals below. First protects g_use_current_dict
|
// Mutexes protecting the globals below. First protects g_use_current_dict
|
||||||
// and template_root_directory_, second protects g_template_cache.
|
// and template_root_directory_, second protects g_template_cache.
|
||||||
// Third protects vars_seen in WriteOneHeaderEntry, below.
|
// Third protects vars_seen in WriteOneHeaderEntry, below.
|
||||||
|
// Lock priority invariant: you should never acquire a Template::mutex_
|
||||||
|
// while holding one of these mutexes.
|
||||||
|
// TODO(csilvers): assert this in the codebase.
|
||||||
static Mutex g_static_mutex;
|
static Mutex g_static_mutex;
|
||||||
static Mutex g_cache_mutex;
|
static Mutex g_cache_mutex;
|
||||||
static Mutex g_header_mutex;
|
static Mutex g_header_mutex;
|
||||||
|
@ -267,24 +272,28 @@ struct TemplateToken {
|
||||||
static void EmitModifiedString(const ModifierAndNonces& modifiers,
|
static void EmitModifiedString(const ModifierAndNonces& modifiers,
|
||||||
const char* in, int inlen,
|
const char* in, int inlen,
|
||||||
ExpandEmitter* outbuf) {
|
ExpandEmitter* outbuf) {
|
||||||
// If there's more than one modifiers, we need to store the
|
string result;
|
||||||
// intermediate results in a temp-buffer. We use a string.
|
|
||||||
string scratch;
|
|
||||||
if (modifiers.size() > 1) {
|
if (modifiers.size() > 1) {
|
||||||
// We'll assume that each modifier adds about 12% to the input size. We
|
// If there's more than one modifiers, we need to store the
|
||||||
// should exponentiate by |modifiers| but we just multiply, to save time.
|
// intermediate results in a temp-buffer. We use a string.
|
||||||
scratch.reserve((inlen + inlen/8) * (modifiers.size()-1) + 16);
|
// We'll assume that each modifier adds about 12% to the input
|
||||||
StringEmitter scratchbuf(&scratch);
|
// size.
|
||||||
// Each time through, we append the latest version of the string to
|
result.reserve((inlen + inlen/8) + 16);
|
||||||
// scratch, and keep a pointer pointing to the most recent version.
|
StringEmitter scratchbuf(&result);
|
||||||
// Except for (rare!) vars with 3+ modifiers, this loop at most once.
|
modifiers.front().first->Modify(in, inlen, &scratchbuf,
|
||||||
for (ModifierAndNonces::const_iterator it = modifiers.begin();
|
modifiers.front().second);
|
||||||
|
// Only used when modifiers.size() > 2
|
||||||
|
for (ModifierAndNonces::const_iterator it = modifiers.begin()+1;
|
||||||
it != modifiers.end()-1; ++it) {
|
it != modifiers.end()-1; ++it) {
|
||||||
const int startpos = scratch.size(); // where we start appendend
|
string output_of_this_modifier;
|
||||||
it->first->Modify(in, inlen, &scratchbuf, it->second);
|
output_of_this_modifier.reserve(result.size() + result.size()/8 + 16);
|
||||||
in = scratch.data() + startpos; // point to the new "in"
|
StringEmitter scratchbuf2(&output_of_this_modifier);
|
||||||
inlen = scratch.size() - startpos;
|
it->first->Modify(result.c_str(), result.size(),
|
||||||
|
&scratchbuf2, it->second);
|
||||||
|
result.swap(output_of_this_modifier);
|
||||||
}
|
}
|
||||||
|
in = result.data();
|
||||||
|
inlen = result.size();
|
||||||
}
|
}
|
||||||
// For the last modifier, we can write directly into outbuf
|
// For the last modifier, we can write directly into outbuf
|
||||||
assert(!modifiers.empty());
|
assert(!modifiers.empty());
|
||||||
|
@ -626,6 +635,8 @@ class SectionTemplateNode : public TemplateNode {
|
||||||
// section, or template to the list of nodes contained in this
|
// section, or template to the list of nodes contained in this
|
||||||
// section. Returns true iff we really added a node and didn't just
|
// section. Returns true iff we really added a node and didn't just
|
||||||
// end a section or hit a syntax error in the template file.
|
// end a section or hit a syntax error in the template file.
|
||||||
|
// You should hold a write-lock on my_template->mutex_ when calling this.
|
||||||
|
// (unless you're calling it from a constructor).
|
||||||
bool AddSubnode(Template *my_template);
|
bool AddSubnode(Template *my_template);
|
||||||
|
|
||||||
// Expands a section node as follows:
|
// Expands a section node as follows:
|
||||||
|
@ -932,6 +943,8 @@ string *Template::template_root_directory_ = NULL;
|
||||||
// inappropriate characters in a name, not finding the closing curly
|
// inappropriate characters in a name, not finding the closing curly
|
||||||
// braces, etc.) an error message is logged, the error state of the
|
// braces, etc.) an error message is logged, the error state of the
|
||||||
// template is set, and a NULL token is returned. Updates parse_state_.
|
// template is set, and a NULL token is returned. Updates parse_state_.
|
||||||
|
// You should hold a write-lock on my_template->mutex_ when calling this
|
||||||
|
// (unless you're calling it from a constructor).
|
||||||
TemplateToken SectionTemplateNode::GetNextToken(Template *my_template) {
|
TemplateToken SectionTemplateNode::GetNextToken(Template *my_template) {
|
||||||
Template::ParseState* ps = &my_template->parse_state_; // short abbrev.
|
Template::ParseState* ps = &my_template->parse_state_; // short abbrev.
|
||||||
const char* token_start = ps->bufstart;
|
const char* token_start = ps->bufstart;
|
||||||
|
@ -1120,9 +1133,11 @@ TemplateToken SectionTemplateNode::GetNextToken(Template *my_template) {
|
||||||
// Template::~Template()
|
// Template::~Template()
|
||||||
// Template::AssureGlobalsInitialized()
|
// Template::AssureGlobalsInitialized()
|
||||||
// Template::GetTemplate()
|
// Template::GetTemplate()
|
||||||
// Calls ReloadIfChanged to load the template the first time.
|
// Calls ReloadIfChanged to load the template the first time. The
|
||||||
// The constructor is private; GetTemplate() is the factory
|
// constructor is private; GetTemplate() is the factory method
|
||||||
// method used to actually construct a new template if needed.
|
// used to actually construct a new template if needed -- it's the
|
||||||
|
// only thing that calls the template constructor -- and where we
|
||||||
|
// actually call ReloadIfChanged() (based on state_ == TS_EMPTY).
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
Template::Template(const string& filename, Strip strip)
|
Template::Template(const string& filename, Strip strip)
|
||||||
|
@ -1134,10 +1149,7 @@ Template::Template(const string& filename, Strip strip)
|
||||||
// of calling Expand() or other Template classes that access globals.
|
// of calling Expand() or other Template classes that access globals.
|
||||||
AssureGlobalsInitialized();
|
AssureGlobalsInitialized();
|
||||||
|
|
||||||
// phase_ indicates what type of thing we expect next during tokenization.
|
VLOG(2) << "Constructing Template for " << template_file();
|
||||||
// We start off expecting text, hence the initial value is GETTING_TEXT
|
|
||||||
|
|
||||||
VLOG(2) << endl << "Constructing Template for " << template_file() << endl;
|
|
||||||
|
|
||||||
// Preserve whitespace in Javascript files because carriage returns
|
// Preserve whitespace in Javascript files because carriage returns
|
||||||
// can convey meaning for comment termination and closures
|
// can convey meaning for comment termination and closures
|
||||||
|
@ -1145,8 +1157,6 @@ Template::Template(const string& filename, Strip strip)
|
||||||
!strcmp(filename.c_str() + filename.length() - 3, ".js") ) {
|
!strcmp(filename.c_str() + filename.length() - 3, ".js") ) {
|
||||||
strip = STRIP_BLANK_LINES;
|
strip = STRIP_BLANK_LINES;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReloadIfChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Template::~Template() {
|
Template::~Template() {
|
||||||
|
@ -1173,26 +1183,33 @@ Template *Template::GetTemplate(const string& filename, Strip strip) {
|
||||||
// No need to have the cache-mutex acquired for this step
|
// No need to have the cache-mutex acquired for this step
|
||||||
string abspath(PathJoin(template_root_directory(), filename));
|
string abspath(PathJoin(template_root_directory(), filename));
|
||||||
|
|
||||||
MutexLock ml(&g_cache_mutex);
|
Template* tpl = NULL;
|
||||||
if (g_template_cache == NULL)
|
{
|
||||||
g_template_cache = new TemplateCache;
|
MutexLock ml(&g_cache_mutex);
|
||||||
|
if (g_template_cache == NULL)
|
||||||
|
g_template_cache = new TemplateCache;
|
||||||
|
|
||||||
Template *tpl = (*g_template_cache)[pair<string, Strip>(abspath, strip)];
|
tpl = (*g_template_cache)[pair<string, Strip>(abspath, strip)];
|
||||||
if (tpl) {
|
if (!tpl) {
|
||||||
// Note: if the status is TS_ERROR here, we don't attempt
|
tpl = new Template(abspath, strip);
|
||||||
// to reload the template file, but we don't return
|
(*g_template_cache)[pair<string, Strip>(abspath, strip)] = tpl;
|
||||||
// the template object either
|
|
||||||
if (tpl->state() == TS_RELOAD) {
|
|
||||||
tpl->ReloadIfChanged();
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
tpl = new Template(abspath, strip);
|
|
||||||
(*g_template_cache)[pair<string, Strip>(abspath, strip)] = tpl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the statis is not TS_READY, then it is TS_ERROR at this
|
// Even though we only read state() here, not write it, we acquire
|
||||||
// point. If it is TS_ERROR, we leave the state as is, but return
|
// the lock in write-mode in case we have to call ReloadIfChanged.
|
||||||
// NULL. We won't try to load the template file again until the
|
WriterMutexLock ml(tpl->mutex_);
|
||||||
|
|
||||||
|
// Note: if the status is TS_ERROR here, we don't attempt to reload
|
||||||
|
// the template file, but we don't return the template object
|
||||||
|
// either. If the state is TS_EMPTY, it means tpl was just constructed
|
||||||
|
// and doesn't have *any* content yet, so we should certainly reload.
|
||||||
|
if (tpl->state() == TS_RELOAD || tpl->state() == TS_EMPTY) {
|
||||||
|
tpl->ReloadIfChangedLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the state is TS_ERROR, we leave the state as is, but return
|
||||||
|
// NULL. We won't try to load the template file again until the
|
||||||
// state gets changed to TS_RELOAD by another call to
|
// state gets changed to TS_RELOAD by another call to
|
||||||
// ReloadAllIfChanged.
|
// ReloadAllIfChanged.
|
||||||
if (tpl->state() != TS_READY) {
|
if (tpl->state() != TS_READY) {
|
||||||
|
@ -1214,6 +1231,8 @@ Template *Template::GetTemplate(const string& filename, Strip strip) {
|
||||||
|
|
||||||
// NOTE: BuildTree takes over ownership of input_buffer, and will delete it.
|
// NOTE: BuildTree takes over ownership of input_buffer, and will delete it.
|
||||||
// It should have been created via new[].
|
// It should have been created via new[].
|
||||||
|
// You should hold a write-lock on mutex_ before calling this
|
||||||
|
// (unless you're calling it from a constructor).
|
||||||
bool Template::BuildTree(const char* input_buffer,
|
bool Template::BuildTree(const char* input_buffer,
|
||||||
const char* input_buffer_end) {
|
const char* input_buffer_end) {
|
||||||
// Assign an arbitrary name to the top-level node
|
// Assign an arbitrary name to the top-level node
|
||||||
|
@ -1331,6 +1350,7 @@ const char *Template::template_file() const {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Template::ReloadIfChanged()
|
// Template::ReloadIfChanged()
|
||||||
|
// Template::ReloadIfChangedLocked()
|
||||||
// Template::ReloadAllIfChanged()
|
// Template::ReloadAllIfChanged()
|
||||||
// If one template, try immediately to reload it from disk. If
|
// If one template, try immediately to reload it from disk. If
|
||||||
// all templates, just set all their statuses to TS_RELOAD, so
|
// all templates, just set all their statuses to TS_RELOAD, so
|
||||||
|
@ -1341,15 +1361,9 @@ const char *Template::template_file() const {
|
||||||
// and parsed it. It never returns true if filename_ is "".
|
// and parsed it. It never returns true if filename_ is "".
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
bool Template::ReloadIfChanged() {
|
bool Template::ReloadIfChangedLocked() {
|
||||||
if (filename_.empty()) return false;
|
if (filename_.empty()) return false;
|
||||||
|
|
||||||
// This entire routine is protected by mutex_ so when it's called
|
|
||||||
// from different threads, they don't stomp on tree_ and state_.
|
|
||||||
// This is still not perfect, since set_filename() could stomp
|
|
||||||
// on filename_ while we're reading it, but it's good enough.
|
|
||||||
WriterMutexLock ml(mutex_);
|
|
||||||
|
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
if (stat(filename_.c_str(), &statbuf) != 0) {
|
if (stat(filename_.c_str(), &statbuf) != 0) {
|
||||||
LOG(WARNING) << "Unable to stat file " << filename_ << endl;
|
LOG(WARNING) << "Unable to stat file " << filename_ << endl;
|
||||||
|
@ -1403,35 +1417,62 @@ bool Template::ReloadIfChanged() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Template::ReloadIfChanged() {
|
||||||
|
// ReloadIfChanged() is protected by mutex_ so when it's called from
|
||||||
|
// different threads, they don't stomp on tree_ and state_.
|
||||||
|
WriterMutexLock ml(mutex_);
|
||||||
|
return ReloadIfChangedLocked();
|
||||||
|
}
|
||||||
|
|
||||||
void Template::ReloadAllIfChanged() {
|
void Template::ReloadAllIfChanged() {
|
||||||
MutexLock ml(&g_cache_mutex); // this protects the static g_template_cache
|
// This is slightly annoying: we copy all the template-pointers to
|
||||||
if (g_template_cache == NULL) {
|
// a vector, so we don't have to hold g_cache_mutex while messing
|
||||||
return;
|
// with the templates (which would violate our lock invariant).
|
||||||
|
vector<Template*> templates_in_cache;
|
||||||
|
{
|
||||||
|
MutexLock ml(&g_cache_mutex); // this protects the static g_template_cache
|
||||||
|
if (g_template_cache == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (TemplateCache::const_iterator iter = g_template_cache->begin();
|
||||||
|
iter != g_template_cache->end();
|
||||||
|
++iter) {
|
||||||
|
templates_in_cache.push_back(iter->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (TemplateCache::const_iterator iter = g_template_cache->begin();
|
for (vector<Template*>::iterator iter = templates_in_cache.begin();
|
||||||
iter != g_template_cache->end();
|
iter != templates_in_cache.end();
|
||||||
++iter) {
|
++iter) {
|
||||||
(*iter).second->set_state(TS_RELOAD);
|
WriterMutexLock ml((*iter)->mutex_);
|
||||||
|
(*iter)->set_state(TS_RELOAD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Template::ClearCache()
|
// Template::ClearCache()
|
||||||
// Deletes all the objects in the template cache
|
// Deletes all the objects in the template cache. Note: it's
|
||||||
|
// dangerous to clear the cache if other threads are still
|
||||||
|
// referencing the templates that are stored in it!
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
void Template::ClearCache() {
|
void Template::ClearCache() {
|
||||||
MutexLock ml(&g_cache_mutex); // this protects the static g_template_cache
|
// We clear the cache by swapping it with an empty cache. This lets
|
||||||
if (g_template_cache == NULL) {
|
// us delete the items in the cache at our leisure without needing
|
||||||
return;
|
// to hold g_cache_mutex.
|
||||||
|
TemplateCache tmp_cache;
|
||||||
|
{
|
||||||
|
MutexLock ml(&g_cache_mutex); // this protects the static g_template_cache
|
||||||
|
if (g_template_cache == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_template_cache->swap(tmp_cache); // now g_template_cache is empty
|
||||||
}
|
}
|
||||||
for (TemplateCache::const_iterator iter = g_template_cache->begin();
|
// Now delete everything we've removed from the cache.
|
||||||
iter != g_template_cache->end();
|
for (TemplateCache::const_iterator iter = tmp_cache.begin();
|
||||||
|
iter != tmp_cache.end();
|
||||||
++iter) {
|
++iter) {
|
||||||
delete (*iter).second;
|
delete iter->second;
|
||||||
}
|
}
|
||||||
delete g_template_cache;
|
|
||||||
g_template_cache = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
|
@ -41,6 +41,9 @@
|
||||||
|
|
||||||
_START_GOOGLE_NAMESPACE_
|
_START_GOOGLE_NAMESPACE_
|
||||||
|
|
||||||
|
// Lock priority invariant: you should never acquire a
|
||||||
|
// TemplateFromString::mutex_ while holding this mutex.
|
||||||
|
// TODO(csilvers): assert this in the codebase.
|
||||||
static Mutex g_cache_mutex;
|
static Mutex g_cache_mutex;
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
@ -53,11 +56,11 @@ using HASH_NAMESPACE::hash_map;
|
||||||
// the template text is taken from the second parameter. After that, the
|
// the template text is taken from the second parameter. After that, the
|
||||||
// object is identical to a Template object, except that it cannot be
|
// object is identical to a Template object, except that it cannot be
|
||||||
// "reloaded."
|
// "reloaded."
|
||||||
TemplateFromString::TemplateFromString(const string& template_name,
|
TemplateFromString::TemplateFromString(const string& cache_key,
|
||||||
const string& template_text,
|
const string& template_text,
|
||||||
Strip strip)
|
Strip strip)
|
||||||
: Template("", strip) {
|
: Template("", strip) {
|
||||||
filename_ = template_name; // for cache and reporting purposes only
|
filename_ = cache_key; // for cache and reporting purposes only
|
||||||
|
|
||||||
// We know that InsertFile never writes more output than it gets input.
|
// We know that InsertFile never writes more output than it gets input.
|
||||||
// While we allocate buffer here, BuildTree takes ownership and deletes it.
|
// While we allocate buffer here, BuildTree takes ownership and deletes it.
|
||||||
|
@ -94,27 +97,30 @@ static TemplateFromStringCache *g_template_from_string_cache = NULL;
|
||||||
|
|
||||||
// TemplateFromString::GetTemplate
|
// TemplateFromString::GetTemplate
|
||||||
// Makes sure the template cache has been created and then tries to
|
// Makes sure the template cache has been created and then tries to
|
||||||
// retrieve a TemplateFromString object from it via the template_name.
|
// retrieve a TemplateFromString object from it via the cache_key.
|
||||||
TemplateFromString *TemplateFromString::GetTemplate(const string& template_name,
|
TemplateFromString *TemplateFromString::GetTemplate(const string& cache_key,
|
||||||
const string& template_text,
|
const string& template_text,
|
||||||
Strip strip) {
|
Strip strip) {
|
||||||
// Only perform this method when you have the lock so multiple threads
|
TemplateFromString *tpl = NULL;
|
||||||
// don't conflict over inserting and retrieving into the cache
|
if (cache_key.empty()) { // user doesn't want to use the cache
|
||||||
MutexLock ml(&g_cache_mutex);
|
tpl = new TemplateFromString(cache_key, template_text, strip);
|
||||||
if (g_template_from_string_cache == NULL) {
|
} else {
|
||||||
g_template_from_string_cache = new TemplateFromStringCache;
|
MutexLock ml(&g_cache_mutex);
|
||||||
|
if (g_template_from_string_cache == NULL) {
|
||||||
|
g_template_from_string_cache = new TemplateFromStringCache;
|
||||||
|
}
|
||||||
|
// If the object isn't really a TemplateFromString this will be a cache miss
|
||||||
|
tpl = (*g_template_from_string_cache)[pair<string,Strip>(cache_key, strip)];
|
||||||
|
|
||||||
|
// If we didn't find one, then create one and store it in the cache
|
||||||
|
if (!tpl) {
|
||||||
|
tpl = new TemplateFromString(cache_key, template_text, strip);
|
||||||
|
(*g_template_from_string_cache)[pair<string, Strip>(cache_key, strip)] =
|
||||||
|
tpl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the object isn't really a TemplateFromString, this will be a cache miss
|
WriterMutexLock ml(tpl->mutex_); // to access state()
|
||||||
TemplateFromString *tpl =
|
|
||||||
(*g_template_from_string_cache)[pair<string, Strip>(template_name, strip)];
|
|
||||||
|
|
||||||
// If we didn't find one, then create one and store it in the cache
|
|
||||||
if (!tpl) {
|
|
||||||
tpl = new TemplateFromString(template_name, template_text, strip);
|
|
||||||
(*g_template_from_string_cache)[pair<string, Strip>(template_name, strip)] =
|
|
||||||
tpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// state_ can be TS_RELOAD if ReloadAllIfChanged() touched this file.
|
// state_ can be TS_RELOAD if ReloadAllIfChanged() touched this file.
|
||||||
// That's fine; we'll just ignore the reload directive for this guy.
|
// That's fine; we'll just ignore the reload directive for this guy.
|
||||||
|
|
|
@ -33,7 +33,9 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h> // for access()
|
#include <unistd.h> // for access()
|
||||||
|
#endif
|
||||||
#include <time.h> // for time_t
|
#include <time.h> // for time_t
|
||||||
#include <sys/stat.h> // for stat()
|
#include <sys/stat.h> // for stat()
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -39,13 +39,17 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm> // for sort
|
#include <algorithm> // for sort
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_DIRENT_H
|
||||||
#include <dirent.h> // for readdir
|
#include <dirent.h> // for readdir
|
||||||
|
#endif
|
||||||
#include <google/template_from_string.h>
|
#include <google/template_from_string.h>
|
||||||
#include <google/template_dictionary.h>
|
#include <google/template_dictionary.h>
|
||||||
|
|
||||||
|
@ -133,6 +137,8 @@ class TemplateFromStringUnittest {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TestGetTemplate() {
|
static void TestGetTemplate() {
|
||||||
|
TemplateDictionary dict("dict");
|
||||||
|
|
||||||
// Tests the cache
|
// Tests the cache
|
||||||
const char* const tpltext = "{This is perfectly valid} yay!";
|
const char* const tpltext = "{This is perfectly valid} yay!";
|
||||||
const char* const tpltext2 = "This will be ignored";
|
const char* const tpltext2 = "This will be ignored";
|
||||||
|
@ -148,6 +154,22 @@ class TemplateFromStringUnittest {
|
||||||
ASSERT(tpl1 == tpl2);
|
ASSERT(tpl1 == tpl2);
|
||||||
ASSERT(tpl3 == tpl4);
|
ASSERT(tpl3 == tpl4);
|
||||||
ASSERT(tpl1 != tpl3);
|
ASSERT(tpl1 != tpl3);
|
||||||
|
AssertExpandIs(tpl1, &dict, tpltext);
|
||||||
|
AssertExpandIs(tpl2, &dict, tpltext);
|
||||||
|
AssertExpandIs(tpl3, &dict, tpltext);
|
||||||
|
AssertExpandIs(tpl4, &dict, tpltext);
|
||||||
|
|
||||||
|
// Tests our mechanism for ignoring the cache (first arg is empty-string)
|
||||||
|
Template* tpl1b = TemplateFromString::GetTemplate(
|
||||||
|
"", tpltext, DO_NOT_STRIP);
|
||||||
|
Template* tpl2b = TemplateFromString::GetTemplate(
|
||||||
|
"", tpltext2, DO_NOT_STRIP);
|
||||||
|
ASSERT(tpl1b != tpl2b);
|
||||||
|
AssertExpandIs(tpl1b, &dict, tpltext);
|
||||||
|
AssertExpandIs(tpl2b, &dict, tpltext2);
|
||||||
|
// When you don't cache the template, you have to delete it!
|
||||||
|
delete tpl1b;
|
||||||
|
delete tpl2b;
|
||||||
|
|
||||||
// Tests that syntax errors cause us to return NULL
|
// Tests that syntax errors cause us to return NULL
|
||||||
Template* tpl5 = StringToTemplate("{{This has spaces in it}}", DO_NOT_STRIP);
|
Template* tpl5 = StringToTemplate("{{This has spaces in it}}", DO_NOT_STRIP);
|
||||||
|
|
|
@ -289,6 +289,24 @@ class TemplateUnittest {
|
||||||
// Check we don't allow modifiers on sections
|
// Check we don't allow modifiers on sections
|
||||||
tpl = StringToTemplate("hi {{#VAR:h}} lo {{/VAR}}", STRIP_WHITESPACE);
|
tpl = StringToTemplate("hi {{#VAR:h}} lo {{/VAR}}", STRIP_WHITESPACE);
|
||||||
ASSERT(tpl == NULL);
|
ASSERT(tpl == NULL);
|
||||||
|
|
||||||
|
// Test when expanded grows by more than 12% per modifier.
|
||||||
|
dict.SetValue("VAR", "http://a.com?b=c&d=e&f=g&q=a>b");
|
||||||
|
tpl = StringToTemplate("{{VAR:u:j:h}}",
|
||||||
|
STRIP_WHITESPACE);
|
||||||
|
AssertExpandIs(tpl, &dict,
|
||||||
|
"http%3A//a.com%3Fb%3Dc%26d%3De%26f%3Dg%26q%3Da%3Eb",
|
||||||
|
true);
|
||||||
|
|
||||||
|
// As above with 4 modifiers.
|
||||||
|
dict.SetValue("VAR", "http://a.com?b=c&d=e&f=g&q=a>b");
|
||||||
|
tpl = StringToTemplate("{{VAR:u:j:h:h}}",
|
||||||
|
STRIP_WHITESPACE);
|
||||||
|
AssertExpandIs(tpl, &dict,
|
||||||
|
"http%3A//a.com%3Fb%3Dc%26d%3De%26f%3Dg%26q%3Da%3Eb",
|
||||||
|
true);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TestSection() {
|
static void TestSection() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user