The main class used by the template system is
TemplateDictionary
, which is used to expand a template
file. It is used by the main functions for expanding a template,
found in template.h
.
TemplateCache
is used to hold a collection of
Template
objects. TemplateNamelist
provides
various introspection routines on collections of Template
objects.
TemplateModifier
and PerExpandData
are
used to modify the values of a TemplateDictionary
at
expand time. TemplateAnnotator
does too, but is intended
for debugging purposes. TemplateDictionaryPeer
is used
for testing template code.
ExpandEmitter
provides the ability to emit an expanded
template to an arbitrary output store.
TemplateString
is a string-like class that is built to
be very efficient when used with the template system. For instance,
tools are available to hash constant TemplateString
objects at compile-time, speeding up their use at run-time.
The rest of this document describes these classes and functions in more detail, as well as build tools and other mechanisms for handling templates.
(Note: the code snippets below all assume the default configuration
option is set, which puts template code in namespace
ctemplate
.)
Templates are strings that contain special formatting code called template markers. In the Ctemplate System, template strings are usually read from a file.
Anything found in a template of the form {{...}} is interpreted as a template marker. All other text is considered formatting text and is output verbatim at template expansion time. Outside of the template markers, templates may contain any text whatsoever, including (single) curly braces and NUL characters.
The template language has six types of markers:
{{#FOO}}...{{/FOO}}
{{>FOO}}
{{! comment lives here -- cool, no?}}
{{
and }}
to custom
strings. (The only requirement is that these strings not
contain whitespace or the equals sign.) This is useful for
languages like TeX, where double-braces may occur in the text
and are awkward to use for markup. Set-delimiter markers look
like this: {{=< >=}} <! Now markers are
delimited by braces > <=| |=> |! And now markers are
delimited by bars! |
{{%PRAGMA [name="value"...]}}
. Currently,
AUTOESCAPE is the only pragma defined.These marker types each have their own namespace. For readability, however, it is best to not overuse a single name.
A variable and include-template can have one or more modifiers attached to them, like so:
{{MYVAR:mod1:mod2:mod3=value:mod4=value with spaces:mod5}}
A modifier is a filter that's
applied at template-expand time, that munges the value of the variable
before it's output. See the TemplateModifier
class for
more details.
When expanding a variable (or template-include) with a modifier, the modifiers are applied in order, left to right. For a template-include, first the entire sub-template is expanded, as a single string, and then the modifiers are applied to that string.
In general, using explicit modifiers does not turn off auto-escaping on a variable. The explicit
modifier :none
does suppress auto-escaping.
Some marker names may have a special meaning in the template system. Right now, there's one such name.
If you have a section named FOO, you can define inside
of it a section named FOO_separator, and the template
system will automatically expand that section every time
FOO
is expanded, except for the last. Thus, the
contents of FOO_separator
can be used to separate
repeated values of a section.
Here's an example:
Here are the meeting attendees: {{#ATTENDEES}} {{NAME}} {{#ATTENDEES_separator}}, {{/ATTENDEES_separator}} {{/ATTENDEES}} .
Here is a more convoluted example, to show the date:
{{#DATE}}{{DATE_COMPONENT}}{{#DATE_separator}}{{DATE_SEP}}{{/DATE_separator}}{{/DATE}}
You'd set up a template dictionary to repeat DATE
three times, with DATE_COMPONENT
set to the month, day,
and year (or day, month, and year, depending on your locale...), and
DATE_SEP
set to /
or -
or
whatever date-separator is called for.
SEP_separator
is always evaluated with the current
dictionary. Thus, in the date example, if you wanted a different
separator each time, you could do so by setting DATE_SEP
to a different value for each repetition of DATE
.
While SEP_separator
is automatically expanded by the
template system, it is otherwise a perfectly normal section. You can
even instantiate it yourself by calling
AddSectionDictionary("SEP_separator")
. In that case, the
section will be expanded both via the automatic expansion as a
separator, and as a normal section via the section dictionary you
added. This is more confusing than helpful, and you should probably
never do it.
There can be at most one "separator" sub-section per section. If there are more, only the last is automatically expanded.
In the template system -- in functions like
ExpandTemplate()
-- a template is specified by a pair:
filename + strip-mode. The filename specifies the name of the
template file on disk (but see below for string templates). The strip
mode specifies how this file should be parsed as it's read from disk,
in particular, how whitespace should be handled. It can take the
following values:
ctemplate::DO_NOT_STRIP
: do nothing. This expands
the template file verbatim.
ctemplate::STRIP_BLANK_LINES
: remove all blank
lines. This ignores any blank lines found in the template file
when parsing it. When the template is html, this reduces the
size of the output text without requiring a sacrifice of
readability for the input file.
ctemplate::STRIP_WHITESPACE
: remove not only blank
lines when parsing, but also whitespace at the beginning and
end of each line. It also removes any linefeed (possibly
following whitespace) that follows a closing }}
of
any kind of template marker except a template variable.
(This means a linefeed may be removed anywhere by simply
placing a comment marker as the last element on the line.)
When the template is html, this reduces the size of the output
html without changing the way it renders (except in a few
special cases.) When using this flag, the built-in template
variables BI_NEWLINE
and BI_SPACE
can
be useful to force a space or newline in a particular
situation.
The filename is where the template file lives on disk. It can be either an absolute filename, or relative to a directory in the template search path.
In addition to reading a template from disk, it is possible to read
a template from a string, using StringToTemplateCache()
.
The first argument of StringToTemplateCache()
is a "key"
to use to refer to this string-based template. This key takes the
place of the filename, for any routine that asks for a
filename + strip.
This is the main workhorse function of the template system. It takes the filename of a template, a template dictionary, and a string to emit to, and emits an "expanded" version of the template using the given template dictionary to fill in the template markers.
If the template specified by the given filename is already found in
an internal cache, the cached version of the template is used,
otherwise the template is loaded from disk, parsed, and stored in the
cache before expansion is performed. As always, the "filename" can
also be a key to a string-based template,
inserted directly into the cache via
StringToTemplateCache()
.
There is an overloaded version of Expand()
that takes
an ExpandEmitter
rather
than a string, as the source to expand the template into.
This function returns true if the template was successfully
expanded into the output parameter. It returns false if expansion
failed or was only partially successful. It might fail because the
template file cannot be found on disk, or because the template has
syntax errors and cannot be parsed, or because the template
sub-includes another template, and that sub-template has errors. To
minimize the risk of errors at expand-time, you can call
LoadTemplate()
(below) first to load and parse the
template into the cache. This will catch all errors except for errors
involving sub-templates.
In the case of partial failures -- typically, failures resulting in
an error in a sub-inclued template -- there may be partial data
emitted to the output before the error was detected. If
ExpandTemplate()
returns false, you should be careful to
check for and remove this partial data, if desired.
ExpandWithData()
is like
ExpandTemplate()
, with the addition that it allows you to
pass in per-expand data. It's called
like this:
ctemplate::TemplateDictionary dict(...); ctemplate::PerExpandData per_expand_data; string output; ctemplate::ExpandWithData(filename, strip_mode, &output, &dict, &per_expand_data);
Per-expand data is applied to all templates that are seen while
expanding: not only the template you called Expand()
on,
but also sub-templates that are brought in via template-includes
({{>INCLUDE}}
). See the description of the PerExpandData
class for more
details about how expansion can be modified by per-expand data.
The return value has the same meaning as for
ExpandTemplate()
In fact, if you pass in
NULL
as the per_expand_data
argument, this
function is exactly equivalent to ExpandTemplate()
.
This function takes a filename and a strip-mode, and loads the file
into the default template cache. Future calls to
ExpandTemplate()
or ExpandWithData()
will
get the parsed template from the cache, without needing to go to
disk.
This function returns true if the template was successfully read
from disk, parsed, and inserted into the cache. It will also return
true if the template is already in the cache (even if the file has
changed on disk since the template was inserted into the cache). It
will return false if the file cannot be found on disk, or cannot be
successfully parsed. (Note that LoadTemplate()
cannot
detect errors in sub-included templates, since the identity of
sub-included templates is specified in a
TemplateDictionary
, not in the template itself.)
In addition to reading a template file from disk, it is also
possible to read a template file from a string, using
StringToTemplateCache()
. It takes the content
as a string. It also takes in a key and a strip
mode. The given key and strip mode can be used as the filename/strip
pair in calls to ExpandTemplate()
and similar
functions. The key can also be used as the "filename" in calls to
ctemplate::TemplateDictionary::SetFilename()
, allowing
this template to be included inside other templates.
StringToTemplateCache()
returns true if the string is
successfully inserted into the cache. It returns false otherwise,
probably because there is already a string or filename in the cache
with the same key.
All the above routines -- ExpandTemplate()
,
LoadTemplate()
, and the like -- read and write parsed
templates to the default template cache. This is just a static
instance of the TemplateCache
class. It can
be accessed via these two functions:
default_template_cache()
and, if you need a non-const
version of the cache, mutable_default_template_cache()
.
These can be useful if you need the advanced features of template
caches, such as ReloadAllIfChanged()
or
ClearCache()
.
TemplateDictionary
Class The class TemplateDictionary
is used for all template
dictionary operations. In general, an application will need to call a
TemplateDictionary
method for every marker in the
associated template (the major exception: markers that evaluate to the
empty string can be ignored).
The appropriate function to call for a given template marker depends on its type.
A data dictionary is a map from keys to values. The keys are
always strings, corresponding to the name of the associated template
marker, so a section {{#FOO}}
in the template text is
matched to the key FOO
in the dictionary, if it exists.
Note the case must match as well.
The value associated with a key differs according to key type. The
value associated with a variable is simple: it's the value for
that variable. Both keys and values can be any 8-bit
character-string, and may include internal NULs (\0
).
The value associated with a section is a list of data dictionaries. At template-expansion time, the section is expanded once for each dictionary in the list. The first time, all variables/etc. in the section will be evaluated taking into account the first dictionary. The second time, all variables/etc. will be evaluated taking into account the second dictionary. (See below for a definition of "taking into account.")
The value associated with a template-include is also a list
of data dictionaries. Each data dictionary in this list must also
have one other, mandatory associated piece of associated information:
the filename of the template to include. At expand-time, that
filename is passed as-is to ctemplate::ExpandTemplate()
(or, more exactly, the equivalent of ExpandTemplate()
in
the same TemplateCache
that the parent template comes
from).
The dictionary structure is a tree: there's a 'main' dictionary, and then a list of sub-dictionaries for each section or include-template. When looking up a marker -- be it a variable, section, or include-template marker -- the system looks in the currently applicable dictionary. If it's found there, that value is used. If not, and the parent dictionary is not an include-template, it continues the look in the parent dictionary, and possibly the grandparent, etc. That is, lookup has static scoping: you look in your dictionary and any parent dictionary that is associated with the same template-file. As soon as continuing the lookup would require you to jump to a new template-file (which is what include-template would do), we stop the lookup.
If lookup fails in all dictionaries, the template system does a final lookup in the global variable dictionary.
The system initializes the global dictionary with a few useful
values for your convenience (the user can add more). All system
variables are prefixed with BI
, to emphasize they are
"built in" variables.
BI_SPACE
, which has the value
<space>
. It is used to force a space
at the beginning or end of a line in the template,
where it would normally be suppressed. (See below.) BI_NEWLINE
, which has the value
<newline>
It is used to force a
newline at the end of a line, where it would normally
be suppressed. (See below.) Variable inheritance happens at expand time, not at dictionary-create time. So if you create a section dictionary, and then afterwards set a variable in its parent dictionary (or in the global dictionary), the section will inherit that variable value, if it doesn't define the value itself.
SetValue() is used to set the value for a variable
marker in a dictionary. It takes a string as input -- nominally a TemplateString
, though a C++
string or C char* will be auto-converted -- for the variable name and
its value. The name is the same string as is used for the variable's
template-marker inside the template this dictionary will be expanded
with: if the template reads Hello {{NAME}}
then the
first argument to SetValue()
must be NAME
.
Case matters.
SetIntValue()
takes an integer as the value, rather
than a string. On all platforms, the integer may be up to 64
bits.
SetFormattedValue()
is a convenience routine.
SetFormattedValue(key, arg1, arg2, ...)
is logically
equivalent to
char buffer[A_BIG_ENOUGH_NUMBER]; sprintf(buffer, arg1, arg2, ...); SetValue(key, buffer);
without having to worry about the size of buffer
, or
about stack overflow.
SetValueWithoutCopy()
is provided to give an extra bit
of efficiency when needed. SetValue()
will copy the key
and value into an internal data structure used by the
TemplateDictionary
; this avoids dangling pointers if the
arguments to SetValue()
are temporaries, or otherwise
have shorter lifetime than the TemplateDictionary
. But
if you know that both the key and value strings have lifetime longer
than the TemplateDictionary
-- perhaps because they are
global (static duration) char*
's -- you can call
SetValueWIthoutCopy()
to avoid the copy. This yields a
small time savings at the cost of significant code fragility, so
should only be used when absolutely necessary.
SetGlobalValue()
is like SetValue()
but
works on the global dictionary. Since the global dictionary is shared
across all template dictionaries, this is a static method on
TemplateDictionary
. It is thread-safe. It is also
relatively slow.
SetTemplateGlobalValue()
is like
SetValue()
, but the values are preserved across
template-includes.
This example shows all three forms:
A.tpl: {{NAME}} has won {{>PRIZE}}. It is worth {{AMOUNT}}. B.tpl: {{AMOUNT}} dollars! And it's all yours, {{NAME}} C.tpl: To: {{NAME}}. Amount: {{AMOUNT}}. code: ctemplate::TemplateDictionary dict("set_value_demo"); ctemplate::TemplateDictionary* subdict = dict.AddIncludeDictionary("PRIZE"); subdict->SetFilename("B.tpl"); dict->SetValue("NAME", "Jane McJane"); dict->SetTemplateGlobalValue("AMOUNT", "One Million"); ctemplate::TemplateDictionary::SetGlobalValue("NAME", "John Doe"); ctemplate::TemplateDictionary dict_c("set_value_demo, part 2"); ctemplate::ExpandTemplate("A.tpl", ..., &dict); ctemplate::ExpandTemplate("C.tpl", ..., &dict_c);
The first expand yields this:
Jane McJane has won One Million dollars! And it's all yours, John Doe. It is worth One Million.
The second expand yields this:
To: John Doe. Amount: .
NAME
was set via SetValue()
, so its
value was not propagated across the include-dict boundary; instead,
the subdict (B.tpl) got its value for NAME
from the
global dictionary. AMOUNT
, on the other hand, was set
via SetTemplateGlobalValue()
, so its value was propagated
across the boundary, and the subdict saw it. However, the totally
unrelated template, C.tpl, did not see either value, and only sees the
values in the global dictionary. (Of course, had we filled
dict_c
with some values, C.tpl would have had access to
those.)
AddSectionDictionary(section_name)
returns a
sub-dictionary associated with the given section_name (for instance,
dict.AddSectionDictionary("MYSECT")
for a template like
{{#MYSECT}}...{{/MYSECT}}
). If called multiple times, it
will return a new dictionary each time. During Expand()
,
the section will be expanded once for each time
AddSectionDictionary()
was called; that is, the text
inside the section delimiters will be repeated once for each
AddSectionDictionary()
call, and within a single
repetition, the dictionary returned by
AddSectionDictionary()
will be used to populate the text
inside the section delimiters. (With the current dictionary as that
dictionary's parent, for inheritance purposes.)
This suggests that if AddSectionDictionary()
is never
called on a section, the text inside the section will be omitted
entirely by Expand()
.
ShowSection()
is a convenience method used to show the
text inside the section exactly once. It is equivalent to calling
AddSectionDictionary()
once, and ignoring the returned
sub-dictionary. All variables in the section will depend on
dictionary inheritence to get their values.
SetValueAndShowSection()
is another convenience
method,, used to show a section if and only if a related variable is
set to a non-empty value. SetValueAndShowSection(name, value,
section_name)
is equivalent to this: if value is empty do
nothing, otherwise add a single dictionary to
section_name
and call section_dict->AddValue(name,
value)
.
Example:
ctemplate::TemplateDictionary* dict = new ctemplate::TemplateDictionary("section example"); const char* username = GetUsername(); // returns "" for no user if (username[0] != '\0') { ctemplate::TemplateDictionary* sub_dict = dict->AddSectionDictionary("CHANGE_USER"); sub_dict->SetValue("USERNAME", username); } else { // don't need to do anything; we want a hidden section, which is the default } // Instead of the above 'if' statement, we could have done this: if (username[0] != '\0') { dict->ShowSection("CHANGE_USER"); // adds a single, empty dictionary dict->SetValue("USERNAME", username); // take advantage of inheritance } else { // don't need to do anything; we want a hidden section, which is the default } // Or we could have done this: dict->SetValueAndShowSection("USERNAME", username, "CHANGE_USER"); // Moving on... GetPrevSearches(prev_searches, &num_prev_searches); if (num_prev_searches > 0) { for (int i = 0; i < num_prev_searches; ++i) { TemplateDictionary* sub_dict = dict->AddSectionDictionary("PREV_SEARCHES"); sub_dict->SetValue("PREV_SEARCH", prev_searches[i]); } }
AddIncludeDictionary(section_name)
returns a
sub-dictionary associated with the given include_name (for instance,
dict.AddIncludeDictionary("MYTPL")
for a template like
{{>MYTPL}}
). If called multiple times, it
will return a new dictionary each time. It is the responsibility of
the caller to then call SetFilename()
on the
sub-dictionary returned.
During Expand()
,
each dictionary returned by AddIncludeDictionary
will be
examined in turn. For each dictionary for which
SetFilename()
is called, that filename will be read as a
template (via LoadTemplate()
, with the same
"strip" value as the current template), and expanded using the
dictionary. (Note that the dictionary will not inherit
SetValue()
values from the parent dictionary, though it
will inherit SetTemplateGlobalValue()
values.) This
expanded template will then be emitted to the output.
Note that if AddIncludeDictionary()
is never called,
the template-include will be a no-op during Expand()
.
Likewise, if it is called but SetFilename()
is never
called on the resulting sub-dictionary, the template-include will be a
no-op. On the other hand, if it is called multiple times, multiple
templates -- possibly all from the same file, possibly not -- will be
inserted at the point of the template-include.
If a user has called StringToTemplateCache(key, ...)
,
then the user can call SetFilename(key)
to include the
contents of the string as the sub-template.
These routines dump the contents of a dictionary and its
sub-dictionaries. Dump()
dumps to stdout,
DumpToString()
to a string. They are intended for
debugging.
TemplateCache
Class This class holds a collection of templates. It can be used to give
you a coherent view of the template system: you load all the templates
you are going to use into the cache, and then reload them from disk in
one atomic operation. You can have multiple
TemplateCache
objects in your executable, perhaps one for
each service you provide, or perhaps one per thread (so as to avoid
thread contention when loading templates).
One intended use of the template cache is to make it safe to reload
template files while serving user requests from a webserver. The idea
is that every user request, as it's created, is associated with the
current template cache. When you wish to reload, you
Clone()
the current cache, and then reload inside the
cloned copy. New requests will get the cloned cache, while old
requests will continue to render using the old cache.
TemplateCache
is written to make this use-case efficient:
templates are shared between caches when appropriate, with
reference-counting to keep memory management easy.
The template system creates a default template cache, which is
available via the functions default_template_cache()
and
mutable_default_template_cache()
.
For simple uses of the template system, using the default cache,
via ExpandTemplate()
and the like, may be perfectly
adequate. If you want more sophisticated features, such as the
ability to have different versions of the same template file active at
one time, or to change the template root-directory, you will have to
use an explicit TemplateCache
.
These two routines are how you explicitly insert data into the
cache. LoadTemplate()
reads a template from disk, while
StringToTemplateCache()
takes the data from a
user-specified string. These work exactly the same as the global LoadTemplate()
and StringToTemplateCache()
,
except they insert into the given TemplateCache
, rather
than the global cache.
LoadTemplate()
is not strictly necessary: if the cache
cannot find a template it needs at Expand*()
time, it will
automatically try to fetch it from disk. It is intended mostly for
use with Freeze()
, which disables
this auto-fetch behavior.
Both of these routines take a strip mode specifying how the template system should treat whitespace while parsing.
If the template-cache is frozen,
LoadTemplate()
will only return true if the template is
already stored in the cache, and will return false in every other
case. For a frozen cache, StringToTemplateCache()
will
always return false.
These routines takes a string that represents either a template
filename (for disk-based templates), or a key used in
StringToTemplateCache()
(for string-based templates), a strip mode saying how to parse the template's
whitespace, and per-expand data (which
can be NULL). Overloads are provided to output the expanded template
to either a string or to an arbitrary ExpandEmitter
.
Expand uses the filename + strip pair to fetch the template from
the cache, if it's there. If not, ExpandWithData()
will
fetch the template from disk and insert it into the cache.
ExpandFrozen()
, on the other hand, will just fail to
expand, and return false. This is the only difference in behavior
between the two routines. To reinforce this behavior,
ExpandFrozen()
will return false immediately if Freeze()
has not been called on the
cache.
While expanding, the template system may come across template
sub-includes ({{>SUB_TEMPLATE}}
). It will attempt to
fetch these templates from the cache as well; failing that, it will
try to load the template from disk (for ExpandWithData()
)
or else fail the expand and return false (for
ExpandFrozen()
).
Because ExpandFrozen()
never updates the cache, it is
a const method, unlike ExpandWithData()
.
Note that TemplateCache
does not provide the
convenience ExpandTemplate()
routine, as the analogue of
the global ExpandTemplate()
. If you are
not interested in the per-expand data, just call
ExpandWithData()
with the per-expand data set to NULL.
For every file-based template in the cache (this method ignores
string-based templates), ReloadAllIfChanged()
checks the
filesystem to see if the file has changed since it was loaded into the
cache. If so, the cache loads a new version of the file into the
cache. Note that at this point both the old and new versions of the
file exist in the cache! Only the new version is accessible via new
calls to Expand()
, but any expansions currently in flight
during the ReloadAllIfChanged()
call will continue to use
the old version.
NOTE: ReloadAllIfChanged()
never modifies existing
items in the cache in any way. It only loads new entries into the
cache.
ReloadAllIfChanged()
comes in two flavors, controlled
by the passed-in enum. In "immediate" mode, it synchronously iterates
through the cache and reloads all files that need it. In "lazy" mode,
it waits to reload a given template file until the next time it's
actually used (in a call to Expand*()
). "Immediate" mode
is safer in the case where templates depend on each other and the
files change a lot, since all files are reloaded at about the same
time. "Lazy" mode avoids the latency spike of "immediate" mode, and
is preferable in the (common) case that files on disk change only
rarely.
By default, filenames passed in to Expand*()
are taken
to be relative to the current working directory. These functions
change that behavior. SetTemplateRootDirectory()
resets
the search path to be the single path passed in to this function.
Every time AddAlternateTemplateRootDirectory()
is called,
it adds another directory to the end of the search path. The template
system will follow the search path, in order, when looking for a
filename.
Note that the template search path is only meaningful when the
filename passed to Expand*()
(or specified for a
sub-include) is a relative filename. If the filename is an absolute
filename, starting with /
, the search path is
ignored.
template_root_directory()
returns the first entry in
the search path. There is currently no way to access other entries in
the search path.
FindTemplateFilename()
does the work of finding a
template file in the filesystem, using the current template search
path. It takes a relative pathname as input, and returns an absolute
pathname as output, indicating where the template file lives on the
filesystem. If the template file is not found, this method returns
the empty string.
Freeze()
marks the template cache as immutable. After
this method is called, the cache can no longer be modified by loading
new templates or reloading existing templates. During expansion only
cached included templates will be used; they won't be loaded
on-demand.
Before calling Freeze()
, you should make sure your
cache has all the templates it might need, using
LoadTemplate()
and StringToTemplateCache()
.
Otherwise, ExpandWithData()
and
ExpandFrozen()
may fail.
Once the cache is frozen, calls to
SetTemplateRootDirectory()
,
AddAlternateTemplateRootDirectory()
,
Delete()
, and ReloadAllIfChanged()
will
fail.
After the cache is frozen, the TemplateCache
object is
effectively const.
This method deletes an entry from the cache. If the entry is in the cache multiple times (each with a different "strip" mode), this method deletes all of them.
This method deletes all entries from the cache. It can be called even on a frozen cache.
Note: this method is not typically necessary unless you are testing for memory leaks. It is intended to be called just before exiting the program, and after all template expansions are completed. Using it in that way may prevent unnecessary reporting by the leak checker.
Clone()
makes a shallow copy of the given
TemplateCache
object, and returns the copy. The new copy
and the old share the same template objects; since it's a shallow
copy, they actually share pointers to the exact same object. (Since
the template cache never changes a template object once it's loaded
into the cache, sharing the pointer isn't a risk.)
The intended use of Clone()
, as described above, is to
allow fine control over "epochal" changes in templates. One
TemplateCache
can hold all versions of the template files
before the big update; after the update is done, you can clone the old
cache and then call ReloadAllIfChanged()
on the clone.
This is a low-cost operation, since the two copies share most
resources. Smart pointers take care of most memory management
issues.
The caller is responsible for calling delete
on the
returned TemplateCache
object.
TemplateNamelist
Class This class provides information about registered templates. Or more precisely, all templates corresponding to registered filenames.
All methods in this class are static.
TemplateNamelist::RegisterTemplate()
takes a filename
and adds it to the static namelist used by
TemplateNamelist
. All other methods of
TemplateNamelist
work only on registered filenames.
It's fairly rare to call this method directly. Instead, the more
common use is to use the macro RegisterTemplateFilename
somewhere in the global scope, like so:
RegisterTemplateFilename(EXAMPLE_FN, "example.tpl");
The reason to prefer the macro is it defines a global variable that
you can use instead of the hard-coded template name. This helps catch
typos. The RegisterTemplateFilename()
example is
functionally equivalent to:
#define EXAMPLE_FN "example.tpl"
It can be used like this:
ctemplate::ExpandTemplate(EXAMPLE_FN, ctemplate::DO_NOT_STRIP, ...);
TemplateNamelist::GetMissingList()
returns a list of
all registered templates (or rather, all filenames) where the file
could not be found on disk.
Returns true if and only if the missing-list is empty.
Returns a list of all registered templates where the template contains a syntax error, and thus cannot be used.
True if and only if the bad-syntax list is empty.
Returns the latest last-modified time for any registered template-file.
A modifier is a filter that's applied at template-expand time, that
munges the value of the variable before it's output. For instance,
<html><body>{{NAME:html_escape}}</body></html>
asks the template system to apply the built-in
html_escape
modifier when expanding
{{NAME}}
. If you set NAME
in your
dictionary to be Jim & Bob
, what will actually be
emitted in the template is Jim & Bob
.
You can chain modifiers together. This template first html-escapes
NAME
, and then javascript-escapes that result:
<html><body>{{NAME:html_escape:javascript_escape}}</body></html>
Modifiers typically have a long, descriptive name and also a one-letter abbreviation. So this example is equivalent to the previous one:
<html><body>{{NAME:h:j}}</body></html>
Some modifiers take an argument, specified after an equals sign:
<html><body>{{NAME:html_escape_with_arg=pre}}</body></html>
Here are the modifiers that are built in to the template system. They are all defined in template_modifiers.cc:
| long name | short name | description |
|---|---|---|
:cleanse_css | :c |
Removes characters not safe for a CSS value. Safe characters are alphanumeric, space, underscore, period, coma, exclamation mark, pound, percent, and dash. |
:html_escape | :h |
html-escapes the variable before output
(eg & -> & ) |
:html_escape_with_arg | :H |
special purpose html escaping. See :H Arguments below for details. |
:img_src_url_escape_with_arg | :I |
special purpose image url escaping. See :I and :U Arguments below for details. |
:javascript_escape | :j |
javascript-escapes the variable before output (eg
" -> \x27 and
& -> \x26 ) |
:javascript_escape_with_arg | :J
|
special purpose javascript escaping. See :J Arguments below for details. |
:json_escape | :o |
json-escapes a variable before output as a string in json;
HTML characters are escaped using Unicode escape sequences
(e.g & -> \u0026 ) to comply with
RFC 4627.
|
:none | leaves the variable as is (used to disable auto-escaping) | |
:pre_escape | :p |
pre-escapes the variable before output (same as html_escape but whitespace is preserved; useful for <pre>...</pre>) |
:url_escape_with_arg | :U |
special purpose url escaping. See :I and :U Arguments below for details. |
:url_query_escape | :u |
performs URL escaping on the variable before output.
space is turned into +, and everything other than [0-9a-zA-Z.,_:*/~!()-], is
transformed into %-style escapes. Use this when you are building
URLs with variables as parameters:
<a href="http://google.com/search?q={{QUERY:u}}">{{QUERY:h}}</a> |
:xml_escape | xml-escapes the variable before output
(the five characters <>&"' become
<>&"' )
suitable for content returned in raw XML. It is not intended
for escaping content within CDATA blocks. |
The *_with_arg
modifiers require an argument to
specify the type of escaping to use. The following sections list
the supported arguments for each of these modifiers.
Here are the values that are supported by
the html_escape_with_arg
modifier:
| value | description |
|---|---|
=snippet |
like html_escape , but allows HTML entities and
some tags to pass through unchanged. The allowed tags
are <br> , <wbr> , <b> ,
and </b> . |
=pre |
same as pre_escape |
=url |
same as :U=html below. For backwards compatibility. |
=attribute |
replaces characters not safe for an use in an unquoted attribute with underscore. Safe characters are alphanumeric, underscore, dash, period, and colon. |
Here are the values that are supported by
the img_src_url_escape_with_arg
and
url_escape_with_arg
modifiers:
| value | description |
|---|---|
=html |
Ensures that a variable contains a safe URL. Safe means that
it is either a http or https URL, or else it has no protocol
specified.
:U for image URLs. Use :I
instead. # is not a safe replacement for an image URL.
<img src=#> can cause each browser to request the
entire page again.
|
=javascript |
Same as =html , but using javascript escaping
instead of html escaping. |
=css |
Same as =html but using CSS escaping instead
of html escaping so that the variable can be safely inserted
within a CSS @import statement or a CSS property.
The characters in [\r\n()'"<>*\] are transformed
into %-style escapes. |
=query |
(Supported for :U only) Same as
url_query_escape . |
Here are the values that are supported by
the javascript_escape_with_arg
modifier:
| value | description |
|---|---|
=number |
Ensures that the variable is a valid number or boolean
javascript literal. This includes booleans
true and false , decimal
numbers (e.g. 4.10 or -5.01e+10 )
as well as hex numbers (e.g. 0x5FF ). This modifier
is intended to ensure the variable not enclosed in
quotes cannot contain javascript code that may execute. It does
not guarantee that the variable is syntactically well-formed.
If the variable is safe, it is returned
as-is, otherwise it is replaced with null .
In the future we may add more logic to support objects and
arrays. |
In addition to the built-in modifiers, you can write your own
modifier. Custom modifiers must have a name starting with "x-", and
the name can contain alphanumeric characters plus dashes and
underscores. Custom modifiers can also accept values with any
character except for : and }
. For example
this template could be a valid use of a custom modifier:
{{VAR:x-my_modifier:value1,value2,value3 has spaces,etc}}
See <template_modifiers.h>
for details on how to
write a modifier and how to register it. In short, you write a
modifier by subclassing ctemplate::TemplateModifier
and
overriding the Modify
method, and you register it by
calling ctemplate::AddModifier()
Here is an example of
the code for a custom modifier:
class StarEscape : public ctemplate::TemplateModifier { void Modify(const char* in, size_t inlen, const ctemplate::PerExpandData* per_expand_data, ctemplate::ExpandEmitter* outbuf, const string& arg) const { outbuf->Emit(string("*") + string(in, inlen) + string("*")); } };
The minimum work to create a custom modifier is to subclass
TemplateModifier
and override the Modify()
method. Modify()
takes as input the value of the text to
be modified, as well as the per expand
data associated with this Expand()
call. The method
may use this input, plus any other data it may have, to generate
output, which it should write into the given
ExpandEmitter
.
The subclass can also override MightModify()
. This is
useful for modifiers that are typically a no-op (in which case the
modifier is just doing busy-work, copying its input to the output
ExpandEmitter
). If MightModify()
returns
false, the template system will avoid calling Modify()
at
all on that variable, avoiding the busy-work copy.
AddModifier() is used to register a custom modifier,
so the modifier can be used in templates. The name of the modifier
must start with x-
.
AddXssSafeModifier()
is used to register a custom
modifier that can work well with the auto-escape system. It is used when the
modifier produces output that is "safe" from cross-site scripting
attacks in all contexts in which it might be used. For instance, a
modifier that only emits numbers is xss-safe if it's only used in html
or javascript contexts.
If the auto-escape pragma is used in a document, then all variables will be auto-escaped, even if explicit modifiers are used on the variable. The rules are a little complicated:
PerExpandData
Class ExpandWithData()
and
TemplateModifier::Modify()
both take a
PerExpandData
object. Per-expand data is applied to all
templates that are seen while expanding: not only the template you
called ExpandWithData()
on, but also sub-templates that
are brought in via template-includes ({{>INCLUDE}}
).
There are several types of per-expand data you can set, by calling
the appropriate method on a PerExpandData
object.
This is a debugging function. When expanding this template, it adds marker-strings to the output to indicate what template-substitutions the system made. This takes a string argument which can be used to shorten the filenames printed in the annotations: if the filename contains the string you give, everything before that string is elided from the filename before printing. (It's safe to just always pass in the empty string.)
This overrides the default text-based annotation used by
SetAnnotateOutput()
. If this is set and
SetAnnotateOutput()
is called, the per-expand data will
use this TemplateAnnotator
instance
to do the annotation, rather than the default instance.
InsertForModifiers()
stores an arbitrary key/value
pair in the PerExpandData
structure. This is used with
template modifiers: the
PerExpandData
object passed to
ExpandWithData()
is made available to every template
modifier that is called during expand time (including any custom
modifiers). The intended use of this functionality is to allow a
modifier to work one way when expanding a template with dictionary A,
and another way when expanding a template with dictionary B. For
instance, a modifier might encrypt part of a webpage using a user's
secret-key, which is of course different for every expansion of the
webpage.
LookupForModifiers()
can be used by a
template-modifier to read the key/value pair inserted by
InsertForModifiers()
.
LookupForModifiersAsString()
is the same, but returns the
value as a char* rather than a void*, for convenience.
This is an advanced feature for those who need a custom hook into
template expansion. It will not be used by most programmers. It
takes a template-modifier as its argument, but this template modifier
is treated specially: instead of applying when an appropriate magic
string appears in the text of a template, it applies every time a
template is expanded during a call to ExpandWithData()
.
Note this means that it's called not only after the top-level
template, that ExpandWithData()
is called on, is
expanded, but also on every sub-template that is expanded due to a
template-include.
This unusual functionality has a few unusual properties. Since the
template expansion modifier is not called in normal fashion, the
normal arg
argument to the template modifier does not
make sense. Instead, the arg
is set to the path of the
template which is being expanded. Also, template expansion modifiers
can be expensive, since they are applied pretty indiscriminately, so
it can be worth implementing the MightModifiy()
predicate
for the passed-in TemplateModifier
to avoid unnecessary
work.
TemplateAnnotator
Class The TemplateAnnotator
class is used to pass in to PerExpandData::SetAnnotator()
,
to control how expand-time annotation is done. This is meant to be
used as a debugging routine.
This class is an abstract base class; SetAnnotator()
takes a subclass that implements the various methods of the base
class. These methods control the action taken when various template
markers are seen during template expansion.
template_annotator.h
defines the abstract base class,
and also a concrete subclass that is used by default for annotation if
SetAnnotator()
is not called.
TemplateDictionaryPeer
Class By design, it is not possible to view the contents of a
TemplateDictionary
; we want to make sure the interface
between the logic layer of the application and the presentation layer
of the template goes in only one direction. While generally this
keeps programs as clean as possible, it presents problems in testing
code, which may want to verify that a given
TemplateDictionary
has been filled properly. The
TemplateDictionaryPeer
addresses this need. It lives in
template_test_util.h
.
Some of the methods of TemplateDictionaryPeer
are
useful for internal tests only. Below are some of the methods that
are most useful for user-level tests.
This macro allows use of STS_INIT
for testing, even
when the input pointer is not guaranteed to be allocated for the
entire length of the test (it must, of course, be allocated for the
entire lifetime of the template being tested). Since normally
STS_INIT
requires inputs to have static duration, this
allows for more flexibility in tests, at the cost of worse memory
management and decreased code safety (in that it's possible to
accidentally violate the lifetime requirements).
This returns the value for the named variable. It uses normal template scoping rules to resolve the name.
Checks if a section or sub-template is "hidden" (that is, won't be displayed at all).
Returns all the sub-dictionaries for a given section or template-include, in a vector.>
template_test_util.h has other useful routines for testing, such as ExpandIs(), which tests whether a template + dictionary pair expands into an expected string. See the header file for details.
ExpandEmitter
Class There are two overloads of ExpandTemplate()
: the first
emits the expanded template to a C++ string, and the second emits to
an ExpandEmitter
: an abstract base class that serves as a
data source. It supports just one overloaded method,
Emit()
, that can take a char, a char*, or a C++ string as
input.
Using this class requires subclassing ExpandEmitter
and providing the various definitions for Emit()
. For
instance, a subclass might provide definitions of Emit()
that send the input bytes out to a network socket.
In addition to defining the abstract base class,
template_emitter.h
provides a sample concrete subclass
implementation, for emitting to a string.
TemplateString
and
StaticTemplateString
Classes TemplateString
is a string-like implementation.
Ctemplate uses TemplateString
almost exclusively,
internally. Many of the public API methods, such as
TemplateDictionary::SetValue()
, also take
TemplateString
as input. TemplateString
has implicit constructors for both C++ strings and char*'s, so every
method that takes a TemplateString
will also work if
given a C++ string or a char*. If you have a char* and know its
length, you can save a bit of work by explicitly constructing a
TemplateString
with a char* + length, for instance:
dict->SetValue(ctemplate::TemplateString("MYVAR", 5), value);
Some compile-time tools work with TemplateString
to
offload computation from runtime to compile-time. This is possible
because the Ctemplate code often stores a hash of a string
rather than a string directly. For static, immutable strings,
TemplateString
can store a pre-computed hash value. This
functionality is used by make_tpl_varnames_h
. Thus,
using this tool to create constants to use for SetValue()
keys provides not only protection against typos, but a speed
improvement as well.
For immutable strings in your code, you can create efficient
compile-time template-string objects of your own -- in this case of
type StaticTemplateString
-- by using the
STS_INIT
macro, like so:
static const StaticTemplateString kSectName = STS_INIT(kSectName, "test_SetAddSectionDictionary");
The string variable's name, kSectName
is repeated
twice. The variable's value is specified inside the macro. Note that
this macro should be used at the top level of a file, not inside
functions (even when the variables are made static), and you should
define the StaticTemplateString
exactly as above:
static const StaticTemplateString
. Otherwise, the
undefined constructor/destructor order of C++ may result in surprising
behavior, wherein the StaticTemplateString
is not
initialized when it ought to be.
Template
Class In older version of ctemplate, the Template
class,
which holds parsed templates, was a major part of the template
workflow: the common template use-case would be:
Template* tpl = Template::GetTemplate(filename, strip_mode); TemplateDictionary dict(name); tpl->Expand(&dict, &outstring);
In current use, this model is deprecated in favor of the single
ExpandTemplate()
call; support for Template
methods may be removed entirely in future versions of ctemplate.
However, you may still find older code using this old formulation.
The Guide to using Auto Escape has an overview of Auto Escape as well as discussion of its limitations. To use it, put the following text at the top of the template:
{{%AUTOESCAPE context="CONTEXT" [state="STATE"]}}
Description of the arguments:
HTML
,
JAVASCRIPT
, CSS
,
JSON
or XML
. It must correspond
to the context in which the browser will interpret this
template. Warning: Setting the wrong context will
result in wrong escaping applied to all variables in
the given template. In particular, if the template starts with
a <script>
tag, its context is
HTML
and not JAVASCRIPT
. Auto-Escape
will recognize the <script>
tag and hence
properly Javascript-escape the variables within it. Similarly,
if the template starts with a <style>
tag,
its context is HTML
and not CSS
.
IN_TAG
in the HTML
context
to indicate that the template only contains (one or more)
HTML attribute name and value pairs that are part of an
HTML tag formed in a parent template.
This will auto-escape every variable in the template. To turn off
auto-escaping for a particular variable, you can apply the
none
modifier, like so: {{MYVAR:none}}
.
Here is an example of an autoescaped document:
{{%AUTOESCAPE context="HTML"}} <body> <p>Hello {{USER}}</p> <p><a href="{{URL}}">Your Account</a></p> <p>Your identifier: {{ID:none}}{{! This is dangerous! }}</p> </body>
This package includes several tools to make it easier to use write and use templates.
make_tpl_varnames_h
is a "lint" style syntax checker
and header file generator. It takes the names of template files as
command line arguments and loads each file into a Template object by
retrieving the file via the Template factory method. The loading of
the file does pure syntax checking and reports such errors as
mis-matched section start/end markers, mis-matched open/close
double-curly braces, such as "{{VAR}"
, or invalid
characters in template variables/names/comments.
If the template passes the syntax check, by default the utility then creates a header file for use in the executable code that fills the dictionary for the template. If the developer includes this header file, then constants in the header file may be referenced in the dictionary building function, rather than hard-coding strings as variable and section names. By using these constants, the compiler can notify the developer of spelling errors and mismatched names. Here's an example of how this is used, and how it helps prevent errors:
const char * const kosr_RESULT_NUMBER = "RESULT_NUMBER"; // script output dict.SetValue("RESSULT_NUMBER", "4"); // typo is silently missed dict.SetValue(kosr_RESSULT_NUMBER, "4"); // compiler catches typo
Each constant is named as follows:
one_search_result_post20020815.tpl
are
osr
. As an example, the section name "RESULT_NUMBER" in the file
one_search_result_post20020815.tpl would be given the constant name
kosr_RESULT_NUMBER
and would appear in the header file as
const char * const kosr_RESULT_NUMBER = "RESULT_NUMBER";
-- as in the example above. (The variable is actually a
StaticTemplateString
, not a char*, but the basic idea
holds.)
An alternate output directory may be specified by the command line
flag --header_dir
.
The name of the generated header file is the same as the name of
the template file with an extension added to the name. By default,
that extension is .varnames.h
. In the above example, the
header file containing the constant declarations would be named
one_search_result_post20020815.tpl.varnames.h
. An
alternate extension may be provided via the command line flag
--outputfile_suffix
.
Important command line flags:
--noheader
-- Indicates that a header file
should not be generated; only syntax checking should be done. --header_dir
-- sets the directory where the header
is written. Default: "./" --template_dir
-- sets the template root
directory. Default: ./
which is the correct
specification when it is run from the directory where the templates
are located. This is only used if the input template filenames
are specified as relative paths rather than absolute
paths. --outputfile_suffix
-- the extension added to the
name of the template file to create the name of the generated
header file. Default: .varnames.h
.
For a full list of command line flags, run
make_tpl_varnames_h --help
.
StringToTemplateCache()
lets you load a template
from a string instead of a file. Applications may prefer this option
to reduce the dependencies of the executable, or use it in
environments where data files are not practical. In such cases,
template-converter
can be used as a template "compiler",
letting the developer write a template file as a data file in the
normal way, and then "compiling" it to a C++ string to be included in
the executable.
Usage is template-converter <template filename>
.
C++ code is output is to stdout; it can be stored in a .h file or
included directly into a C++ file. Perl must be installed to use this
script.


IN THE NAME OF THE FATHER A film review by Katherine Wickiser Copyright 1993 Katherine Wickiser
Based on the true story of the Conlon Four
Starring: Daniel Day-Lewis and Emma Thompson Rating: 9.9999999999999999999/10
This movie was INCREDIBLE!!!!!! American Express has been showing previews of movies for their loyal card members and I just happen to know one of them who couldn't go to the show. So, you guessed it, I went in his place. And it is something that I will be eternally grateful for.
As you might be able to tell this is my first try at a written review so please bare with me.
This movie is based on the true story of the CONLON FOUR who were wrongly accused of the bombing of a London pub. The movie starts out in Belfast, Northern Ireland and shows the British military occupying the city. Daniel Day-Lewis plays Gerard (Gerry for short), a young man struggling to live with the military watching his every move (the British vs. the I.R.A.).
I haven't cried so hard and for so long in a movie. The movie is a gut-wrenching tale of innocent people sentenced to prison for a bombing that was done by the I.R.A.
The acting was fantastic. As usual Daniel Day-Lewis submerged into his character so much in fact that I kept on asking my self is that him????
I am sorry that I am so sketch on details but PLEASE go see this movie it is definitely worth seeing more than once.
Since I am so "not gifted" in writing this if you have any other questions you can e-mail me at<EMAIL_ADDRESS>GO SEE THIS MOVIE!!!!!!!!!!!!
Katherine Wickiser Carnegie Mellon University
.
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Oklahoma County marriage, divorce records for Nov. 23, 2019
MARRIAGES
Camryn Trice McPherson and Chandler Tibiletti Stovall
Princess June Albisa and Anthony Martin Brown
Maria A. Kwast and Craig Lynn Kwast
Patricia Michelle Rogers and Stephen Carroll Cargill
Maria Nicole Hawks and Nathan Dean Kinnamon
Michelle Casey Haskins and Kaleb Michael Sanders
Tiffany Dawn Cross and Levi Benjamin Newberry
Fernanda Mildred Jimenez Lopez and Dakota Lee Tucker Criss
Savannah Denise Mitchell and Matthew George Long
Anna Alise Essington and Tylor Jordan Anderson
Lisa Michelle Hinkle and Jarrod Smith Jameson
Ellie Lynn Wiss and Ian Benjamin Clifton
Lavinia Georgiana Stan and David Matthew Solis
Jadyn Michele Quiver and Christopher Allen Nowell
Deanna Lee Scofield and Mohamed Arbi Amdouni
Cynthia Renee Barr and Brandon Scott Lum
Andrea Marie Lasater and Trever Lee Arnold
Aisha Marie Rivera and James Daniel McCoy
Kathryn R. Cassidy and De Vonta O. Prince Sadler
Isabella Azevedo Brandao and Luke Jeremiah Luker
Minh Tuyet Thi Cao and Jayden Thanh Vo
Ana Carina Perez Zarate and Luis Enrique Gasca Garcia
Jamie Danielle Troutt and John N. Culp Jr.
DIVORCES
Stafford, Gara v. Ryan
Obi, Justin Emmanuael v. Marie Jones, Rochelle Barabara
Zepeda, Monica v. Victor Hugo
Gorton, Dennis W. v. Kasha Ann
Thomson, Rayne M. v. Bradley K.
Monrrial, Olibia v. Soto, Gumercindo
Griffin, Ashley-Marie v. Joseph Bradley
Ball, Joquetta Rochelle v. Bobby Dewayne
Balderas, Mayra v. Valdez, Hector
Hunt, Darius v. Jodie
Duck, Nancy Bourne v. Eugene Donald
Minnick, Joshua Michael v. Taylor Nicole
Garcia, Yesica v. Gerardo


Internal Repairs
Construction works
External facade works
Finishing Works
Constructional Works
Internal & External Finishing Works
External Facade & Finishing Works
Internal Repairs for a Private Villa in Rawdah Area made by our team.
Construction works for a Private Villa in Huttin Area made by our team.
External facade works for Factory and Depository in Sadeer Garden made by our team.
Finishing Works for a Private Palace in Huttin Area - Riyadh made by our team.
Finishing Works for a Private Villa in Raed Area - Riyadh made by our team.
Constructional Works for a Private Palace in Huttin Area - Riyadh made by our team.
Internal and External Finishing Works for a Commercial Building in Yarmouk Area made by our team.
External Facade and Finishing Works for a candies shop in Yarmouk Area, Riyadh made by our team.
Finishing Works for a Government buildings in Riyadh made by our team.
+966 539 1222 03


PERLWIN32
Section: Perl Programmers Reference Guide (1)Updated: 2009-08-22
Index Return to Main Contents
NAME
perlwin32 - Perl under WindowsSYNOPSIS
These are instructions for building Perl under Windows 9x/NT/2000/XP on the Intel x86 and Itanium architectures.DESCRIPTION
Before you start, you should glance through the README file found in the top-level directory to which the Perl distribution was extracted. Make sure you read and understand the terms under which this software is being distributed.Also make sure you read ``BUGS AND CAVEATS'' below for the known limitations of this port.
The INSTALL file in the perl top-level has much information that is only relevant to people building Perl on Unix-like systems. In particular, you can safely ignore any information that talks about ``Configure''.
You may also want to look at two other options for building a perl that will work on Windows NT: the README.cygwin and README.os2 files, each of which give a different set of rules to build a Perl that will work on Win32 platforms. Those two methods will probably enable you to build a more Unix-compatible perl, but you will also need to download and use various other build-time and run-time support software described in those files.
This set of instructions is meant to describe a so-called ``native'' port of Perl to Win32 platforms. This includes both 32-bit and 64-bit Windows operating systems. The resulting Perl requires no additional software to run (other than what came with your operating system). Currently, this port is capable of using one of the following compilers on the Intel x86 architecture:
Borland C++ version 5.02 or later Microsoft Visual C++ version 2.0 or later MinGW with gcc gcc version 2.95.2 or later
The last of these is a high quality freeware compiler. Use version 3.2.x or later for the best results with this compiler.
The Borland C++ and Microsoft Visual C++ compilers are also now being given away free. The Borland compiler is available as ``Borland C++ Compiler Free Command Line Tools'' and is the same compiler that ships with the full ``Borland C++ Builder'' product. The Microsoft compiler is available as ``Visual C++ Toolkit 2003'' or ``Visual C++ 2005/2008 Express Edition'' (and also as part of the ``.NET Framework SDK'') and is the same compiler that ships with ``Visual C++ .NET 2003 Professional'' or ``Visual C++ 2005/2008 Professional'' respectively.
This port can also be built on the Intel IA64 using:
Microsoft Platform SDK Nov 2001 (64-bit compiler and tools)
The MS Platform SDK can be downloaded from http://www.microsoft.com/.
This port fully supports MakeMaker (the set of modules that is used to build extensions to perl). Therefore, you should be able to build and install most extensions found in the CPAN sites. See ``Usage Hints for Perl on Win32'' below for general hints about this.
Setting Up Perl on Win32
- Make
-
You need a ``make'' program to build the sources. If you are using
Visual C++ or the Platform SDK tools under Windows NT/2000/XP, nmake
will work. All other builds need dmake.
dmake is a freely available make that has very nice macro features and parallelability.
A port of dmake for Windows is available from:
http://search.cpan.org/dist/dmake/
Fetch and install dmake somewhere on your path.
There exists a minor coexistence problem with dmake and Borland C++ compilers. Namely, if a distribution has C files named with mixed case letters, they will be compiled into appropriate .obj-files named with all lowercase letters, and every time dmake is invoked to bring files up to date, it will try to recompile such files again. For example, Tk distribution has a lot of such files, resulting in needless recompiles every time dmake is invoked. To avoid this, you may use the script ``sync_ext.pl'' after a successful build. It is available in the win32 subdirectory of the Perl source distribution.
- Command Shell
-
Use the default ``cmd'' shell that comes with NT. Some versions of the
popular 4DOS/NT shell have incompatibilities that may cause you trouble.
If the build fails under that shell, try building again with the cmd
shell.
The nmake Makefile also has known incompatibilities with the ``command.com'' shell that comes with Windows 9x. You will need to use dmake and makefile.mk to build under Windows 9x.
The surest way to build it is on Windows NT/2000/XP, using the cmd shell.
Make sure the path to the build directory does not contain spaces. The build usually works in this circumstance, but some tests will fail.
- Borland C++
-
If you are using the Borland compiler, you will need dmake.
(The make that Borland supplies is seriously crippled and will not
work for MakeMaker builds.)
See ``Make'' above.
- Microsoft Visual C++
-
The nmake that comes with Visual C++ will suffice for building.
You will need to run the VCVARS32.BAT file, usually found somewhere
like C:\MSDEV4.2\BIN or C:\Program Files\Microsoft Visual Studio\VC98\Bin.
This will set your build environment.
You can also use dmake to build using Visual C++; provided, however, you set OSRELEASE to ``microsft'' (or whatever the directory name under which the Visual C dmake configuration lives) in your environment and edit win32/config.vc to change ``make=nmake'' into ``make=dmake''. The latter step is only essential if you want to use dmake as your default make for building extensions using MakeMaker.
- Microsoft Visual C++ 2008 Express Edition
-
This free version of Visual C++ 2008 Professional contains the same compiler
and linker that ship with the full version, and also contains everything
necessary to build Perl, rather than requiring a separate download of the
Platform SDK like previous versions did.
This package can be downloaded by searching for ``Visual Studio 2008 Express Edition'' in the Download Center at http://www.microsoft.com/downloads/search.aspx?displaylang=en. (Providing exact links to these packages has proven a pointless task because the links keep on changing so often.)
Install Visual C++ 2008, then setup your environment using
C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat
(assuming the default installation location was chosen).
Perl should now build using the win32/Makefile. You will need to edit that file to set
CCTYPE = MSVC90FREE
first.
- Microsoft Visual C++ 2005 Express Edition
-
This free version of Visual C++ 2005 Professional contains the same compiler
and linker that ship with the full version, but doesn't contain everything
necessary to build Perl.
You will also need to download the ``Platform SDK'' (the ``Core SDK'' and ``MDAC SDK'' components are required) for more header files and libraries.
These packages can both be downloaded by searching in the Download Center at http://www.microsoft.com/downloads/search.aspx?displaylang=en. (Providing exact links to these packages has proven a pointless task because the links keep on changing so often.)
Try to obtain the latest version of the Platform SDK. Sometimes these packages contain a particular Windows OS version in their name, but actually work on other OS versions too. For example, the ``Windows Server 2003 R2 Platform SDK'' also runs on Windows XP SP2 and Windows 2000.
According to the download pages these packages are only supported on Windows 2000/XP/2003, so trying to use these tools on Windows 95/98/ME and even Windows NT probably won't work.
Install Visual C++ 2005 first, then the Platform SDK. Setup your environment as follows (assuming default installation locations were chosen):
SET PlatformSDKDir=C:\Program Files\Microsoft Platform SDK SET PATH=%SystemRoot%\system32;%SystemRoot%;C:\Program Files\Microsoft Visual Studio 8\Common7\IDE;C:\Program Files\Microsoft Visual Studio 8\VC\BIN;C:\Program Files\Microsoft Visual Studio 8\Common7\Tools;C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\bin;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727;C:\Program Files\Microsoft Visual Studio 8\VC\VCPackages;%PlatformSDKDir%\Bin SET INCLUDE=C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE;%PlatformSDKDir%\include SET LIB=C:\Program Files\Microsoft Visual Studio 8\VC\LIB;C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\lib;%PlatformSDKDir%\lib SET LIBPATH=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
(The PlatformSDKDir might need to be set differently depending on which version you are using. Earlier versions installed into ``C:\Program Files\Microsoft SDK'', while the latest versions install into version-specific locations such as ``C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2''.)
Perl should now build using the win32/Makefile. You will need to edit that file to set
CCTYPE = MSVC80FREE
and to set CCHOME, CCINCDIR and CCLIBDIR as per the environment setup above.
- Microsoft Visual C++ Toolkit 2003
-
This free toolkit contains the same compiler and linker that ship with
Visual C++ .NET 2003 Professional, but doesn't contain everything
necessary to build Perl.
You will also need to download the ``Platform SDK'' (the ``Core SDK'' and ``MDAC SDK'' components are required) for header files, libraries and rc.exe, and ``.NET Framework SDK'' for more libraries and nmake.exe. Note that the latter (which also includes the free compiler and linker) requires the ``.NET Framework Redistributable'' to be installed first. This can be downloaded and installed separately, but is included in the ``Visual C++ Toolkit 2003'' anyway.
These packages can all be downloaded by searching in the Download Center at http://www.microsoft.com/downloads/search.aspx?displaylang=en. (Providing exact links to these packages has proven a pointless task because the links keep on changing so often.)
Try to obtain the latest version of the Platform SDK. Sometimes these packages contain a particular Windows OS version in their name, but actually work on other OS versions too. For example, the ``Windows Server 2003 R2 Platform SDK'' also runs on Windows XP SP2 and Windows 2000.
According to the download pages these packages are only supported on Windows 2000/XP/2003, so trying to use these tools on Windows 95/98/ME and even Windows NT probably won't work.
Install the Toolkit first, then the Platform SDK, then the .NET Framework SDK. Setup your environment as follows (assuming default installation locations were chosen):
SET PlatformSDKDir=C:\Program Files\Microsoft Platform SDK SET PATH=%SystemRoot%\system32;%SystemRoot%;C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin;%PlatformSDKDir%\Bin;C:\Program Files\Microsoft.NET\SDK\v1.1\Bin SET INCLUDE=C:\Program Files\Microsoft Visual C++ Toolkit 2003\include;%PlatformSDKDir%\include;C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include SET LIB=C:\Program Files\Microsoft Visual C++ Toolkit 2003\lib;%PlatformSDKDir%\lib;C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\lib
(The PlatformSDKDir might need to be set differently depending on which version you are using. Earlier versions installed into ``C:\Program Files\Microsoft SDK'', while the latest versions install into version-specific locations such as ``C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2''.)
Several required files will still be missing:
-
- *
-
cvtres.exe is required by link.exe when using a .res file. It is actually
installed by the .NET Framework SDK, but into a location such as the
following:
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322
Copy it from there to %PlatformSDKDir%\Bin
- *
-
lib.exe is normally used to build libraries, but link.exe with the /lib
option also works, so change win32/config.vc to use it instead:
Change the line reading:
ar='lib'
to:
ar='link /lib'
It may also be useful to create a batch file called lib.bat in C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin containing:
@echo off link /lib %*
for the benefit of any naughty C extension modules that you might want to build later which explicitly reference ``lib'' rather than taking their value from $Config{ar}.
- *
-
setargv.obj is required to build perlglob.exe (and perl.exe if the USE_SETARGV
option is enabled). The Platform SDK supplies this object file in source form
in %PlatformSDKDir%\src\crt. Copy setargv.c, cruntime.h and
internal.h from there to some temporary location and build setargv.obj using
cl.exe /c /I. /D_CRTBLD setargv.c
Then copy setargv.obj to %PlatformSDKDir%\lib
Alternatively, if you don't need perlglob.exe and don't need to enable the USE_SETARGV option then you can safely just remove all mention of $(GLOBEXE) from win32/Makefile and setargv.obj won't be required anyway.
-
Perl should now build using the win32/Makefile. You will need to edit that file to set
CCTYPE = MSVC70FREE
and to set CCHOME, CCINCDIR and CCLIBDIR as per the environment setup above.
-
- Microsoft Platform SDK 64-bit Compiler
- The nmake that comes with the Platform SDK will suffice for building Perl. Make sure you are building within one of the ``Build Environment'' shells available after you install the Platform SDK from the Start Menu.
- MinGW release 3 with gcc
-
The latest release of MinGW at the time of writing is 3.1.0, which contains
gcc-3.2.3. It can be downloaded here:
http://www.mingw.org/
Perl also compiles with earlier releases of gcc (2.95.2 and up). See below for notes about using earlier versions of MinGW/gcc.
You also need dmake. See ``Make'' above on how to get it.
- MinGW release 1 with gcc
-
The MinGW-1.1 bundle contains gcc-2.95.3.
Make sure you install the binaries that work with MSVCRT.DLL as indicated in the README for the GCC bundle. You may need to set up a few environment variables (usually ran from a batch file).
There are a couple of problems with the version of gcc-2.95.2-msvcrt.exe released 7 November 1999:
-
- *
- It left out a fix for certain command line quotes. To fix this, be sure to download and install the file fixes/quote-fix-msvcrt.exe from the above ftp location.
- *
- The definition of the fpos_t type in stdio.h may be wrong. If your stdio.h has this problem, you will see an exception when running the test t/lib/io_xs.t. To fix this, change the typedef for fpos_t from ``long'' to ``long long'' in the file i386-mingw32msvc/include/stdio.h, and rebuild.
-
A potentially simpler to install (but probably soon-to-be-outdated) bundle of the above package with the mentioned fixes already applied is available here:
http://downloads.ActiveState.com/pub/staff/gsar/gcc-2.95.2-msvcrt.zip ftp://ftp.ActiveState.com/pub/staff/gsar/gcc-2.95.2-msvcrt.zip
-
Building
- *
- Make sure you are in the ``win32'' subdirectory under the perl toplevel. This directory contains a ``Makefile'' that will work with versions of nmake that come with Visual C++ or the Platform SDK, and a dmake ``makefile.mk'' that will work for all supported compilers. The defaults in the dmake makefile are setup to build using MinGW/gcc.
- *
-
Edit the makefile.mk (or Makefile, if you're using nmake) and change
the values of INST_DRV and INST_TOP. You can also enable various
build flags. These are explained in the makefiles.
Note that it is generally not a good idea to try to build a perl with INST_DRV and INST_TOP set to a path that already exists from a previous build. In particular, this may cause problems with the lib/ExtUtils/t/Embed.t test, which attempts to build a test program and may end up building against the installed perl's lib/CORE directory rather than the one being tested.
You will have to make sure that CCTYPE is set correctly and that CCHOME points to wherever you installed your compiler.
The default value for CCHOME in the makefiles for Visual C++ may not be correct for some versions. Make sure the default exists and is valid.
You may also need to comment out the "DELAYLOAD = ..." line in the Makefile if you're using VC++ 6.0 without the latest service pack and the linker reports an internal error.
If you are using VC++ 4.2 or earlier then you'll have to change the /EHsc option in the CXX_FLAG macro to the equivalent /GX option.
If you have either the source or a library that contains des_fcrypt(), enable the appropriate option in the makefile. A ready-to-use version of fcrypt.c, based on the version originally written by Eric Young at ftp://ftp.funet.fi/pub/crypt/mirrors/dsi/libdes/, is bundled with the distribution and CRYPT_SRC is set to use it. Alternatively, if you have built a library that contains des_fcrypt(), you can set CRYPT_LIB to point to the library name. Perl will also build without des_fcrypt(), but the crypt() builtin will fail at run time.
If you want build some core extensions statically into perl's dll, specify them in the STATIC_EXT macro.
Be sure to read the instructions near the top of the makefiles carefully.
- *
-
Type ``dmake'' (or ``nmake'' if you are using that make).
This should build everything. Specifically, it will create perl.exe, perl510.dll at the perl toplevel, and various other extension dll's under the lib\auto directory. If the build fails for any reason, make sure you have done the previous steps correctly.
Testing Perl on Win32
Type ``dmake test'' (or ``nmake test''). This will run most of the tests from the testsuite (many tests will be skipped).There should be no test failures when running under Windows NT/2000/XP. Many tests will fail under Windows 9x due to the inferior command shell.
Some test failures may occur if you use a command shell other than the native ``cmd.exe'', or if you are building from a path that contains spaces. So don't do that.
If you are running the tests from a emacs shell window, you may see failures in op/stat.t. Run ``dmake test-notty'' in that case.
If you're using the Borland compiler, you may see a failure in op/taint.t arising from the inability to find the Borland Runtime DLLs on the system default path. You will need to copy the DLLs reported by the messages from where Borland chose to install it, into the Windows system directory (usually somewhere like C:\WINNT\SYSTEM32) and rerun the test.
If you're using Borland compiler versions 5.2 and below, you may run into problems finding the correct header files when building extensions. For example, building the ``Tk'' extension may fail because both perl and Tk contain a header file called ``patchlevel.h''. The latest Borland compiler (v5.5) is free of this misbehaviour, and it even supports an option -VI- for backward (bugward) compatibility for using the old Borland search algorithm to locate header files.
If you run the tests on a FAT partition, you may see some failures for "link()" related tests (op/write.t, op/stat.t ...). Testing on NTFS avoids these errors.
Furthermore, you should make sure that during "make test" you do not have any GNU tool packages in your path: some toolkits like Unixutils include some tools ("type" for instance) which override the Windows ones and makes tests fail. Remove them from your path while testing to avoid these errors.
Please report any other failures as described under ``BUGS AND CAVEATS''.
Installation of Perl on Win32
Type ``dmake install'' (or ``nmake install''). This will put the newly built perl and the libraries under whatever "INST_TOP" points to in the Makefile. It will also install the pod documentation under "$INST_TOP\$INST_VER\lib\pod" and HTML versions of the same under "$INST_TOP\$INST_VER\lib\pod\html".To use the Perl you just installed you will need to add a new entry to your PATH environment variable: "$INST_TOP\bin", e.g.
set PATH=c:\perl\bin;%PATH%
If you opted to uncomment "INST_VER" and "INST_ARCH" in the makefile then the installation structure is a little more complicated and you will need to add two new PATH components instead: "$INST_TOP\$INST_VER\bin" and "$INST_TOP\$INST_VER\bin\$ARCHNAME", e.g.
set PATH=c:\perl\5.6.0\bin;c:\perl\5.6.0\bin\MSWin32-x86;%PATH%
Usage Hints for Perl on Win32
- Environment Variables
-
The installation paths that you set during the build get compiled
into perl, so you don't have to do anything additional to start
using that perl (except add its location to your PATH variable).
If you put extensions in unusual places, you can set PERL5LIB to a list of paths separated by semicolons where you want perl to look for libraries. Look for descriptions of other environment variables you can set in perlrun.
You can also control the shell that perl uses to run system() and backtick commands via PERL5SHELL. See perlrun.
Perl does not depend on the registry, but it can look up certain default values if you choose to put them there. Perl attempts to read entries from "HKEY_CURRENT_USER\Software\Perl" and "HKEY_LOCAL_MACHINE\Software\Perl". Entries in the former override entries in the latter. One or more of the following entries (of type REG_SZ or REG_EXPAND_SZ) may be set:
lib-$] version-specific standard library path to add to @INC lib standard library path to add to @INC sitelib-$] version-specific site library path to add to @INC sitelib site library path to add to @INC vendorlib-$] version-specific vendor library path to add to @INC vendorlib vendor library path to add to @INC PERL* fallback for all %ENV lookups that begin with "PERL"
Note the $] in the above is not literal. Substitute whatever version of perl you want to honor that entry, e.g. 5.6.0. Paths must be separated with semicolons, as usual on win32.
- File Globbing
-
By default, perl handles file globbing using the File::Glob extension,
which provides portable globbing.
If you want perl to use globbing that emulates the quirks of DOS filename conventions, you might want to consider using File::DosGlob to override the internal glob() implementation. See File::DosGlob for details.
- Using perl from the command line
-
If you are accustomed to using perl from various command-line
shells found in UNIX environments, you will be less than pleased
with what Windows offers by way of a command shell.
The crucial thing to understand about the Windows environment is that the command line you type in is processed twice before Perl sees it. First, your command shell (usually CMD.EXE on Windows NT, and COMMAND.COM on Windows 9x) preprocesses the command line, to handle redirection, environment variable expansion, and location of the executable to run. Then, the perl executable splits the remaining command line into individual arguments, using the C runtime library upon which Perl was built.
It is particularly important to note that neither the shell nor the C runtime do any wildcard expansions of command-line arguments (so wildcards need not be quoted). Also, the quoting behaviours of the shell and the C runtime are rudimentary at best (and may, if you are using a non-standard shell, be inconsistent). The only (useful) quote character is the double quote ("). It can be used to protect spaces and other special characters in arguments.
The Windows NT documentation has almost no description of how the quoting rules are implemented, but here are some general observations based on experiments: The C runtime breaks arguments at spaces and passes them to programs in argc/argv. Double quotes can be used to prevent arguments with spaces in them from being split up. You can put a double quote in an argument by escaping it with a backslash and enclosing the whole argument within double quotes. The backslash and the pair of double quotes surrounding the argument will be stripped by the C runtime.
The file redirection characters ``<'', ``>'', and ``|'' can be quoted by double quotes (although there are suggestions that this may not always be true). Single quotes are not treated as quotes by the shell or the C runtime, they don't get stripped by the shell (just to make this type of quoting completely useless). The caret ``^'' has also been observed to behave as a quoting character, but this appears to be a shell feature, and the caret is not stripped from the command line, so Perl still sees it (and the C runtime phase does not treat the caret as a quote character).
Here are some examples of usage of the ``cmd'' shell:
This prints two doublequotes:
perl -e "print '\"\"' "
This does the same:
perl -e "print \"\\\"\\\"\" "
This prints ``bar'' and writes ``foo'' to the file ``blurch'':
perl -e "print 'foo'; print STDERR 'bar'" > blurch
This prints ``foo'' (``bar'' disappears into nowhereland):
perl -e "print 'foo'; print STDERR 'bar'" 2> nul
This prints ``bar'' and writes ``foo'' into the file ``blurch'':
perl -e "print 'foo'; print STDERR 'bar'" 1> blurch
This pipes ``foo'' to the ``less'' pager and prints ``bar'' on the console:
perl -e "print 'foo'; print STDERR 'bar'" | less
This pipes ``foo\nbar\n'' to the less pager:
perl -le "print 'foo'; print STDERR 'bar'" 2>&1 | less
This pipes ``foo'' to the pager and writes ``bar'' in the file ``blurch'':
perl -e "print 'foo'; print STDERR 'bar'" 2> blurch | less
Discovering the usefulness of the ``command.com'' shell on Windows 9x is left as an exercise to the reader :)
One particularly pernicious problem with the 4NT command shell for Windows NT is that it (nearly) always treats a % character as indicating that environment variable expansion is needed. Under this shell, it is therefore important to always double any % characters which you want Perl to see (for example, for hash variables), even when they are quoted.
- Building Extensions
-
The Comprehensive Perl Archive Network (CPAN) offers a wealth
of extensions, some of which require a C compiler to build.
Look in http://www.cpan.org/ for more information on CPAN.
Note that not all of the extensions available from CPAN may work in the Win32 environment; you should check the information at http://testers.cpan.org/ before investing too much effort into porting modules that don't readily build.
Most extensions (whether they require a C compiler or not) can be built, tested and installed with the standard mantra:
perl Makefile.PL $MAKE $MAKE test $MAKE install
where $MAKE is whatever 'make' program you have configured perl to use. Use ``perl -V:make'' to find out what this is. Some extensions may not provide a testsuite (so ``$MAKE test'' may not do anything or fail), but most serious ones do.
It is important that you use a supported 'make' program, and ensure Config.pm knows about it. If you don't have nmake, you can either get dmake from the location mentioned earlier or get an old version of nmake reportedly available from:
http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/nmake15.exe
Another option is to use the make written in Perl, available from CPAN.
http://www.cpan.org/modules/by-module/Make/
You may also use dmake. See ``Make'' above on how to get it.
Note that MakeMaker actually emits makefiles with different syntax depending on what 'make' it thinks you are using. Therefore, it is important that one of the following values appears in Config.pm:
make='nmake' # MakeMaker emits nmake syntax make='dmake' # MakeMaker emits dmake syntax any other value # MakeMaker emits generic make syntax (e.g GNU make, or Perl make)
If the value doesn't match the 'make' program you want to use, edit Config.pm to fix it.
If a module implements XSUBs, you will need one of the supported C compilers. You must make sure you have set up the environment for the compiler for command-line compilation.
If a module does not build for some reason, look carefully for why it failed, and report problems to the module author. If it looks like the extension building support is at fault, report that with full details of how the build failed using the perlbug utility.
- Command-line Wildcard Expansion
-
The default command shells on DOS descendant operating systems (such
as they are) usually do not expand wildcard arguments supplied to
programs. They consider it the application's job to handle that.
This is commonly achieved by linking the application (in our case,
perl) with startup code that the C runtime libraries usually provide.
However, doing that results in incompatible perl versions (since the
behavior of the argv expansion code differs depending on the
compiler, and it is even buggy on some compilers). Besides, it may
be a source of frustration if you use such a perl binary with an
alternate shell that *does* expand wildcards.
Instead, the following solution works rather well. The nice things about it are 1) you can start using it right away; 2) it is more powerful, because it will do the right thing with a pattern like */*/*.c; 3) you can decide whether you do/don't want to use it; and 4) you can extend the method to add any customizations (or even entirely different kinds of wildcard expansion).
C:\> copy con c:\perl\lib\Wild.pm # Wild.pm - emulate shell @ARGV expansion on shells that don't use File::DosGlob; @ARGV = map { my @g = File::DosGlob::glob($_) if /[*?]/; @g ? @g : $_; } @ARGV; 1; ^Z C:\> set PERL5OPT=-MWild C:\> perl -le "for (@ARGV) { print }" */*/perl*.c p4view/perl/perl.c p4view/perl/perlio.c p4view/perl/perly.c perl5.005/win32/perlglob.c perl5.005/win32/perllib.c perl5.005/win32/perlglob.c perl5.005/win32/perllib.c perl5.005/win32/perlglob.c perl5.005/win32/perllib.c
Note there are two distinct steps there: 1) You'll have to create Wild.pm and put it in your perl lib directory. 2) You'll need to set the PERL5OPT environment variable. If you want argv expansion to be the default, just set PERL5OPT in your default startup environment.
If you are using the Visual C compiler, you can get the C runtime's command line wildcard expansion built into perl binary. The resulting binary will always expand unquoted command lines, which may not be what you want if you use a shell that does that for you. The expansion done is also somewhat less powerful than the approach suggested above.
- Win32 Specific Extensions
-
A number of extensions specific to the Win32 platform are available
from CPAN. You may find that many of these extensions are meant to
be used under the Activeware port of Perl, which used to be the only
native port for the Win32 platform. Since the Activeware port does not
have adequate support for Perl's extension building tools, these
extensions typically do not support those tools either and, therefore,
cannot be built using the generic steps shown in the previous section.
To ensure smooth transitioning of existing code that uses the ActiveState port, there is a bundle of Win32 extensions that contains all of the ActiveState extensions and several other Win32 extensions from CPAN in source form, along with many added bugfixes, and with MakeMaker support. The latest version of this bundle is available at:
http://search.cpan.org/dist/libwin32/
See the README in that distribution for building and installation instructions.
- Notes on 64-bit Windows
-
Windows .NET Server supports the LLP64 data model on the Intel Itanium
architecture.
The LLP64 data model is different from the LP64 data model that is the norm on 64-bit Unix platforms. In the former, "int" and "long" are both 32-bit data types, while pointers are 64 bits wide. In addition, there is a separate 64-bit wide integral type, "__int64". In contrast, the LP64 data model that is pervasive on Unix platforms provides "int" as the 32-bit type, while both the "long" type and pointers are of 64-bit precision. Note that both models provide for 64-bits of addressability.
64-bit Windows running on Itanium is capable of running 32-bit x86 binaries transparently. This means that you could use a 32-bit build of Perl on a 64-bit system. Given this, why would one want to build a 64-bit build of Perl? Here are some reasons why you would bother:
-
- *
- A 64-bit native application will run much more efficiently on Itanium hardware.
- *
- There is no 2GB limit on process size.
- *
- Perl automatically provides large file support when built under 64-bit Windows.
- *
- Embedding Perl inside a 64-bit application.
-
Running Perl Scripts
Perl scripts on UNIX use the ``#!'' (a.k.a ``shebang'') line to indicate to the OS that it should execute the file using perl. Win32 has no comparable means to indicate arbitrary files are executables.Instead, all available methods to execute plain text files on Win32 rely on the file ``extension''. There are three methods to use this to execute perl scripts:
- 1.
- There is a facility called ``file extension associations'' that will work in Windows NT 4.0. This can be manipulated via the two commands ``assoc'' and ``ftype'' that come standard with Windows NT 4.0. Type ``ftype /?'' for a complete example of how to set this up for perl scripts (Say what? You thought Windows NT wasn't perl-ready? :).
- 2.
-
Since file associations don't work everywhere, and there are
reportedly bugs with file associations where it does work, the
old method of wrapping the perl script to make it look like a
regular batch file to the OS, may be used. The install process
makes available the ``pl2bat.bat'' script which can be used to wrap
perl scripts into batch files. For example:
pl2bat foo.pl
will create the file ``FOO.BAT''. Note ``pl2bat'' strips any .pl suffix and adds a .bat suffix to the generated file.
If you use the 4DOS/NT or similar command shell, note that ``pl2bat'' uses the ``%*'' variable in the generated batch file to refer to all the command line arguments, so you may need to make sure that construct works in batch files. As of this writing, 4DOS/NT users will need a ``ParameterChar = *'' statement in their 4NT.INI file or will need to execute ``setdos /p*'' in the 4DOS/NT startup file to enable this to work.
- 3.
-
Using ``pl2bat'' has a few problems: the file name gets changed,
so scripts that rely on $0 to find what they must do may not
run properly; running ``pl2bat'' replicates the contents of the
original script, and so this process can be maintenance intensive
if the originals get updated often. A different approach that
avoids both problems is possible.
A script called ``runperl.bat'' is available that can be copied to any filename (along with the .bat suffix). For example, if you call it ``foo.bat'', it will run the file ``foo'' when it is executed. Since you can run batch files on Win32 platforms simply by typing the name (without the extension), this effectively runs the file ``foo'', when you type either ``foo'' or ``foo.bat''. With this method, ``foo.bat'' can even be in a different location than the file ``foo'', as long as ``foo'' is available somewhere on the PATH. If your scripts are on a filesystem that allows symbolic links, you can even avoid copying ``runperl.bat''.
Here's a diversion: copy ``runperl.bat'' to ``runperl'', and type ``runperl''. Explain the observed behavior, or lack thereof. :) Hint: .gnidnats llits er'uoy fi ,``lrepnur'' eteled :tniH
Miscellaneous Things
A full set of HTML documentation is installed, so you should be able to use it if you have a web browser installed on your system."perldoc" is also a useful tool for browsing information contained in the documentation, especially in conjunction with a pager like "less" (recent versions of which have Win32 support). You may have to set the PAGER environment variable to use a specific pager. ``perldoc -f foo'' will print information about the perl operator ``foo''.
One common mistake when using this port with a GUI library like "Tk" is assuming that Perl's normal behavior of opening a command-line window will go away. This isn't the case. If you want to start a copy of "perl" without opening a command-line window, use the "wperl" executable built during the installation process. Usage is exactly the same as normal "perl" on Win32, except that options like "-h" don't work (since they need a command-line window to print to).
If you find bugs in perl, you can run "perlbug" to create a bug report (you may have to send it manually if "perlbug" cannot find a mailer on your system).
BUGS AND CAVEATS
Norton AntiVirus interferes with the build process, particularly if set to ``AutoProtect, All Files, when Opened''. Unlike large applications the perl build process opens and modifies a lot of files. Having the the AntiVirus scan each and every one slows build the process significantly. Worse, with PERLIO=stdio the build process fails with peculiar messages as the virus checker interacts badly with miniperl.exe writing configure files (it seems to either catch file part written and treat it as suspicious, or virus checker may have it ``locked'' in a way which inhibits miniperl updating it). The build does complete with
set PERLIO=perlio
but that may be just luck. Other AntiVirus software may have similar issues.
Some of the built-in functions do not act exactly as documented in perlfunc, and a few are not implemented at all. To avoid surprises, particularly if you have had prior exposure to Perl in other operating environments or if you intend to write code that will be portable to other environments, see perlport for a reasonably definitive list of these differences.
Not all extensions available from CPAN may build or work properly in the Win32 environment. See ``Building Extensions''.
Most "socket()" related calls are supported, but they may not behave as on Unix platforms. See perlport for the full list. Perl requires Winsock2 to be installed on the system. If you're running Win95, you can download Winsock upgrade from here:
Later OS versions already include Winsock2 support.
Signal handling may not behave as on Unix platforms (where it doesn't exactly ``behave'', either :). For instance, calling "die()" or "exit()" from signal handlers will cause an exception, since most implementations of "signal()" on Win32 are severely crippled. Thus, signals may work only for simple things like setting a flag variable in the handler. Using signals under this port should currently be considered unsupported.
Please send detailed descriptions of any problems and solutions that you may find to<EMAIL_ADDRESS>along with the output produced by "perl -V".
ACKNOWLEDGEMENTS
The use of a camel with the topic of Perl is a trademark of O'Reilly and Associates, Inc. Used with permission.AUTHORS
- Gary Ng<EMAIL_ADDRESS>- Gurusamy Sarathy<EMAIL_ADDRESS>- Nick Ing-Simmons<EMAIL_ADDRESS>- Jan Dubois<EMAIL_ADDRESS>- Steve Hay<EMAIL_ADDRESS>This document is maintained by Jan Dubois.
SEE ALSO
perlHISTORY
This port was originally contributed by Gary Ng around 5.003_24, and borrowed from the Hip Communications port that was available at the time. Various people have made numerous and sundry hacks since then.Borland support was added in 5.004_01 (Gurusamy Sarathy).
GCC/mingw32 support was added in 5.005 (Nick Ing-Simmons).
Support for PERL_OBJECT was added in 5.005 (ActiveState Tool Corp).
Support for fork() emulation was added in 5.6 (ActiveState Tool Corp).
Win9x support was added in 5.6 (Benjamin Stuhl).
Support for 64-bit Windows added in 5.8 (ActiveState Corp).
Last updated: 29 August 2007
Index
This document was created by man2html, using the manual pages.
Time: 05:29:09 GMT, December 24, 2015


This monitor checks {{ site.url }} every 5 minutes. Typically, the website is online. Click here for more info.


sDrawRectROP
sDrawRectROP performs a ROP (Raster Operation) on a rectangle with the specified dwColor.
void sDrawRectROP(long x,long y,long wid,long hei,long dwColor,long dwROP);
Parameters
- x,y,wid,hei
- rectangle position and size
- dwColor
- color to use for drawing
- dwROP
- raster operation to use
Available ROPs
Assume dwOutColor is the destination pixel
- SD_COPY
- dwOutColor = dwColor
- SD_XOR
- dwOutColor ^= dwColor
- SD_ADD
- dwOutColor += dwColor
- SD_SUB
- dwOutColor -= dwColor
- SD_OR
- dwOutColor |= dwColor
- SD_AND
- dwOutColor &= dwColor
- SD_SHR
- dwOutColor >>= dwColor; (here dwColor=0..32)
- SD_MUL
- dwOutColor.Red = (dwOutColor.Red * dwColor.Red)>>8; (same for Blue and Green)
- SD_ADDSAT
- dwOutColor = Add_Saturate(dwOutColor,dwColor);
- SD_SUBSAT
- dwOutColor = Sub_Saturate(dwOutColor,dwColor);
- SD_SHRSAT
- dwOutColor.Red = dwOutColor.Red/2; (same for Blue and Green) (dwColor is not used). Makes the destination rectangle darker
- SD_SHLSAT
- dwOutColor = Add_Saturate(dwOutColor,dwOutColor); (dwColor is not used). Makes the destination rectangle brighter
Return Value
None. [ASM: All registers are preserved.]
Example:
sDrawRect(0,0,400,300,0xFFFFFF,SD_XOR);// invert the 400x300 rectangle at position 0:0
See Also
sDrawRectAlpha,
sDrawRect,
sDrawRectAddFade


Audio-Rate Math
One of the most powerful features of Tone.js is the ability to
perform math and logic on audio-rate signal. Signals
can be ramped and scheduled to control Audio Parameters and
other Signals making it simple to create elaborate,
interconnected automations. Additionally, Signals and Signal maths use no
ScriptProcessorNodes which make them very efficient.


Website I like
The three websites which I like are not very fancy but I liked them because of their simplicity and easiness. I think the very important part of any website would be its simplicity so that it can be reached to more number of peoples around. With a more complexity a website can look elegant but might loose its reachability.Three website which I like are as follows
Amazon.com:
I like Amazon more because of its simplicity. If you are very new in internet world even then you can easily buy anything from here because of the images, easy words, categories and other features they have included in their website so that you don't need to be a very good world to operate it.
I would describe it Simple, Elegant and Basic. This website basically solved the problem of how even using simpler and user friendly terms we can easily make the website look elegant. The idea and purpose of the website is fantastic as now we don't have to depend on transportation and time. Even after a long time you can find a new stuff which does not let you get bored.
Gmail.com:
Like everyone will accept Gmail is the most important website you will definitely be use to if you are or are not spending very long time on internet. Gmail has become the most efficient way of communication in internet world. Some of the best feature I like which Gmail include is spanning and differentiating important mails from others which make your world easier. I will conclude Gmail as elegant and sophisticated. You don't need to spend a long amount of time to find important mail here which makes it more efficient than others.
Facebook.com:
For a social person facebook is like a boon. With its ample features it has become the most famous social site all around. You can easily share your pictures, comments, thoughts etc with others and also like the other's. The feature which I like best in facebook is how it helps you search your friend with all the information you have like where he lives his profile photo and all other information the person has already shared on his profile and also the suggestion feature like if your friend's friend is not in your friend list it will suggest you to add them if you want to. I find facebook.com very bold and Entertaining because it makes you feel that you are always connected to others.