..
.. NB:  This file is machine generated, DO NOT EDIT!
..
.. Edit ./vmod_taskvar.vcc and run make instead
..


:tocdepth: 1

.. _vmod_taskvar(3):

================================================
VMOD taskvar - task variables as objects for VCL
================================================

SYNOPSIS
========

.. parsed-literal::

  import taskvar [as name] [from "path"]
  
  :ref:`taskvar.acl()`
  
      :ref:`xacl.get()`
  
      :ref:`xacl.set()`
  
      :ref:`xacl.undefine()`
  
      :ref:`xacl.defined()`
  
      :ref:`xacl.protect()`
  
      :ref:`xacl.protected()`
  
  :ref:`taskvar.backend()`
  
      :ref:`xbackend.get()`
  
      :ref:`xbackend.set()`
  
      :ref:`xbackend.undefine()`
  
      :ref:`xbackend.defined()`
  
      :ref:`xbackend.protect()`
  
      :ref:`xbackend.protected()`
  
  :ref:`taskvar.blob()`
  
      :ref:`xblob.get()`
  
      :ref:`xblob.set()`
  
      :ref:`xblob.undefine()`
  
      :ref:`xblob.defined()`
  
      :ref:`xblob.protect()`
  
      :ref:`xblob.protected()`
  
  :ref:`taskvar.body()`
  
      :ref:`xbody.get()`
  
      :ref:`xbody.set()`
  
      :ref:`xbody.undefine()`
  
      :ref:`xbody.defined()`
  
      :ref:`xbody.protect()`
  
      :ref:`xbody.protected()`
  
  :ref:`taskvar.bool()`
  
      :ref:`xbool.get()`
  
      :ref:`xbool.set()`
  
      :ref:`xbool.undefine()`
  
      :ref:`xbool.defined()`
  
      :ref:`xbool.protect()`
  
      :ref:`xbool.protected()`
  
  :ref:`taskvar.bytes()`
  
      :ref:`xbytes.get()`
  
      :ref:`xbytes.set()`
  
      :ref:`xbytes.undefine()`
  
      :ref:`xbytes.defined()`
  
      :ref:`xbytes.protect()`
  
      :ref:`xbytes.protected()`
  
  :ref:`taskvar.duration()`
  
      :ref:`xduration.get()`
  
      :ref:`xduration.set()`
  
      :ref:`xduration.undefine()`
  
      :ref:`xduration.defined()`
  
      :ref:`xduration.protect()`
  
      :ref:`xduration.protected()`
  
  :ref:`taskvar.header()`
  
      :ref:`xheader.get()`
  
      :ref:`xheader.set()`
  
      :ref:`xheader.undefine()`
  
      :ref:`xheader.defined()`
  
      :ref:`xheader.protect()`
  
      :ref:`xheader.protected()`
  
  :ref:`taskvar.int()`
  
      :ref:`xint.get()`
  
      :ref:`xint.set()`
  
      :ref:`xint.undefine()`
  
      :ref:`xint.defined()`
  
      :ref:`xint.protect()`
  
      :ref:`xint.protected()`
  
  :ref:`taskvar.ip()`
  
      :ref:`xip.get()`
  
      :ref:`xip.set()`
  
      :ref:`xip.undefine()`
  
      :ref:`xip.defined()`
  
      :ref:`xip.protect()`
  
      :ref:`xip.protected()`
  
  :ref:`taskvar.probe()`
  
      :ref:`xprobe.get()`
  
      :ref:`xprobe.set()`
  
      :ref:`xprobe.undefine()`
  
      :ref:`xprobe.defined()`
  
      :ref:`xprobe.protect()`
  
      :ref:`xprobe.protected()`
  
  :ref:`taskvar.real()`
  
      :ref:`xreal.get()`
  
      :ref:`xreal.set()`
  
      :ref:`xreal.undefine()`
  
      :ref:`xreal.defined()`
  
      :ref:`xreal.protect()`
  
      :ref:`xreal.protected()`
  
  :ref:`taskvar.stevedore()`
  
      :ref:`xstevedore.get()`
  
      :ref:`xstevedore.set()`
  
      :ref:`xstevedore.undefine()`
  
      :ref:`xstevedore.defined()`
  
      :ref:`xstevedore.protect()`
  
      :ref:`xstevedore.protected()`
  
  :ref:`taskvar.string()`
  
      :ref:`xstring.get()`
  
      :ref:`xstring.set()`
  
      :ref:`xstring.undefine()`
  
      :ref:`xstring.defined()`
  
      :ref:`xstring.protect()`
  
      :ref:`xstring.protected()`
  
      :ref:`xstring.foreach()`
  
  :ref:`taskvar.time()`
  
      :ref:`xtime.get()`
  
      :ref:`xtime.set()`
  
      :ref:`xtime.undefine()`
  
      :ref:`xtime.defined()`
  
      :ref:`xtime.protect()`
  
      :ref:`xtime.protected()`
  
  :ref:`taskvar.strands()`
  
      :ref:`xstrands.add()`
  
      :ref:`xstrands.clear()`
  
      :ref:`xstrands.get()`
  

DESCRIPTION
===========

This module implements `task` scoped variables as objects: Each client
or backend request (`task`) has their own view of taskvar variables.

A taskvar can be constructed with a default, which is used as the
initial value at the beginning of each `task`.

The value of a taskvar is the either the default or the last value
assigned to it within a `task`. If neither a default nor previous
value was set, then the value is undefined.

A taskvar can also be undefined using the ``.undefine()`` method.

Attempts to ``.get()`` an undefined value will return the ``.get()``
method`s `fallback` argument. For most types, there is a default
fallback; if there is none, using ``.get()`` on an undefined value
triggers a VCL failure at runtime.

taskvar variables can be protected against write access, in which case
any attempt to ``.set()`` them triggers a VCL failure at runtime.

Example with an initially undefined variable::

 import taskvar;

 sub vcl_init {
  new xint = taskvar.int();
 }

 sub vcl_recv {
  set req.http.def = xint.defined(); # false
  set req.http.fallback = xint.get(5); # 5
  xint.set(42);
 }

 sub vcl_deliver {
  set resp.http.the-answer = xint.get(); # 42
 }

Example with an initially defined variable::

 import taskvar;

 sub vcl_init {
  new xint = taskvar.int(17);
 }

 sub vcl_recv {
  set req.http.def = xint.defined(); # true
  set req.http.fallback = xint.get(5); # 17
  xint.set(42);
  xint.protect();
  if (false) {
   xint.set(3); # would fail
  }
 }

 sub vcl_deliver {
  set resp.http.the-answer = xint.get(); # 42
 }

The implementation of the various classes of this vmod is
auto-generated, and so is the documentation. Thus, the documentation
following this generic description is identical for all types except
for the respective type names and the ``.get()`` fallback.

.. just a newline

.. _taskvar.acl():

new xacl = taskvar.acl([ACL init])
----------------------------------

Construct a(n) ACL taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xacl.get():

ACL xacl.get([ACL fallback])
----------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. Using .get() on an undefined value without a fallback triggers a VCL error.

.. _xacl.set():

VOID xacl.set(ACL)
------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xacl.undefine():

VOID xacl.undefine()
--------------------

Undefine the taskvar.

.. _xacl.defined():

BOOL xacl.defined()
-------------------

Return whether the taskvar is defined.

.. _xacl.protect():

VOID xacl.protect()
-------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xacl.protected():

BOOL xacl.protected()
---------------------

Return whether the taskvar is protected.

.. _taskvar.backend():

new xbackend = taskvar.backend([BACKEND init])
----------------------------------------------

Construct a(n) BACKEND taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xbackend.get():

BACKEND xbackend.get([BACKEND fallback])
----------------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is the ``None`` backend.

.. _xbackend.set():

VOID xbackend.set(BACKEND)
--------------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xbackend.undefine():

VOID xbackend.undefine()
------------------------

Undefine the taskvar.

.. _xbackend.defined():

BOOL xbackend.defined()
-----------------------

Return whether the taskvar is defined.

.. _xbackend.protect():

VOID xbackend.protect()
-----------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xbackend.protected():

BOOL xbackend.protected()
-------------------------

Return whether the taskvar is protected.

.. _taskvar.blob():

new xblob = taskvar.blob([BLOB init])
-------------------------------------

Construct a(n) BLOB taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xblob.get():

BLOB xblob.get([BLOB fallback])
-------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is the null blob.

.. _xblob.set():

VOID xblob.set(BLOB)
--------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xblob.undefine():

VOID xblob.undefine()
---------------------

Undefine the taskvar.

.. _xblob.defined():

BOOL xblob.defined()
--------------------

Return whether the taskvar is defined.

.. _xblob.protect():

VOID xblob.protect()
--------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xblob.protected():

BOOL xblob.protected()
----------------------

Return whether the taskvar is protected.

.. _taskvar.body():

new xbody = taskvar.body([BODY init])
-------------------------------------

Construct a(n) BODY taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xbody.get():

BODY xbody.get([BODY fallback])
-------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. Using .get() on an undefined value without a fallback triggers a VCL error.

.. _xbody.set():

VOID xbody.set(BODY)
--------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xbody.undefine():

VOID xbody.undefine()
---------------------

Undefine the taskvar.

.. _xbody.defined():

BOOL xbody.defined()
--------------------

Return whether the taskvar is defined.

.. _xbody.protect():

VOID xbody.protect()
--------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xbody.protected():

BOOL xbody.protected()
----------------------

Return whether the taskvar is protected.

.. _taskvar.bool():

new xbool = taskvar.bool([BOOL init])
-------------------------------------

Construct a(n) BOOL taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xbool.get():

BOOL xbool.get([BOOL fallback])
-------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is false

.. _xbool.set():

VOID xbool.set(BOOL)
--------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xbool.undefine():

VOID xbool.undefine()
---------------------

Undefine the taskvar.

.. _xbool.defined():

BOOL xbool.defined()
--------------------

Return whether the taskvar is defined.

.. _xbool.protect():

VOID xbool.protect()
--------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xbool.protected():

BOOL xbool.protected()
----------------------

Return whether the taskvar is protected.

.. _taskvar.bytes():

new xbytes = taskvar.bytes([BYTES init])
----------------------------------------

Construct a(n) BYTES taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xbytes.get():

BYTES xbytes.get([BYTES fallback])
----------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is 0 bytes.

.. _xbytes.set():

VOID xbytes.set(BYTES)
----------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xbytes.undefine():

VOID xbytes.undefine()
----------------------

Undefine the taskvar.

.. _xbytes.defined():

BOOL xbytes.defined()
---------------------

Return whether the taskvar is defined.

.. _xbytes.protect():

VOID xbytes.protect()
---------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xbytes.protected():

BOOL xbytes.protected()
-----------------------

Return whether the taskvar is protected.

.. _taskvar.duration():

new xduration = taskvar.duration([DURATION init])
-------------------------------------------------

Construct a(n) DURATION taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xduration.get():

DURATION xduration.get([DURATION fallback])
-------------------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is 0s.

.. _xduration.set():

VOID xduration.set(DURATION)
----------------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xduration.undefine():

VOID xduration.undefine()
-------------------------

Undefine the taskvar.

.. _xduration.defined():

BOOL xduration.defined()
------------------------

Return whether the taskvar is defined.

.. _xduration.protect():

VOID xduration.protect()
------------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xduration.protected():

BOOL xduration.protected()
--------------------------

Return whether the taskvar is protected.

.. _taskvar.header():

new xheader = taskvar.header([HEADER init])
-------------------------------------------

Construct a(n) HEADER taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xheader.get():

HEADER xheader.get([HEADER fallback])
-------------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. Using .get() on an undefined value without a fallback triggers a VCL error.

.. _xheader.set():

VOID xheader.set(HEADER)
------------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xheader.undefine():

VOID xheader.undefine()
-----------------------

Undefine the taskvar.

.. _xheader.defined():

BOOL xheader.defined()
----------------------

Return whether the taskvar is defined.

.. _xheader.protect():

VOID xheader.protect()
----------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xheader.protected():

BOOL xheader.protected()
------------------------

Return whether the taskvar is protected.

.. _taskvar.int():

new xint = taskvar.int([INT init])
----------------------------------

Construct a(n) INT taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xint.get():

INT xint.get([INT fallback])
----------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is 0.

.. _xint.set():

VOID xint.set(INT)
------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xint.undefine():

VOID xint.undefine()
--------------------

Undefine the taskvar.

.. _xint.defined():

BOOL xint.defined()
-------------------

Return whether the taskvar is defined.

.. _xint.protect():

VOID xint.protect()
-------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xint.protected():

BOOL xint.protected()
---------------------

Return whether the taskvar is protected.

.. _taskvar.ip():

new xip = taskvar.ip([IP init])
-------------------------------

Construct a(n) IP taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xip.get():

IP xip.get([IP fallback])
-------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is IPv4 0.0.0.0.

.. _xip.set():

VOID xip.set(IP)
----------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xip.undefine():

VOID xip.undefine()
-------------------

Undefine the taskvar.

.. _xip.defined():

BOOL xip.defined()
------------------

Return whether the taskvar is defined.

.. _xip.protect():

VOID xip.protect()
------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xip.protected():

BOOL xip.protected()
--------------------

Return whether the taskvar is protected.

.. _taskvar.probe():

new xprobe = taskvar.probe([PROBE init])
----------------------------------------

Construct a(n) PROBE taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xprobe.get():

PROBE xprobe.get([PROBE fallback])
----------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is no backend.

.. _xprobe.set():

VOID xprobe.set(PROBE)
----------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xprobe.undefine():

VOID xprobe.undefine()
----------------------

Undefine the taskvar.

.. _xprobe.defined():

BOOL xprobe.defined()
---------------------

Return whether the taskvar is defined.

.. _xprobe.protect():

VOID xprobe.protect()
---------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xprobe.protected():

BOOL xprobe.protected()
-----------------------

Return whether the taskvar is protected.

.. _taskvar.real():

new xreal = taskvar.real([REAL init])
-------------------------------------

Construct a(n) REAL taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xreal.get():

REAL xreal.get([REAL fallback])
-------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is 0.0.

.. _xreal.set():

VOID xreal.set(REAL)
--------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xreal.undefine():

VOID xreal.undefine()
---------------------

Undefine the taskvar.

.. _xreal.defined():

BOOL xreal.defined()
--------------------

Return whether the taskvar is defined.

.. _xreal.protect():

VOID xreal.protect()
--------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xreal.protected():

BOOL xreal.protected()
----------------------

Return whether the taskvar is protected.

.. _taskvar.stevedore():

new xstevedore = taskvar.stevedore([STEVEDORE init])
----------------------------------------------------

Construct a(n) STEVEDORE taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xstevedore.get():

STEVEDORE xstevedore.get([STEVEDORE fallback])
----------------------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is the default storage.

.. _xstevedore.set():

VOID xstevedore.set(STEVEDORE)
------------------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xstevedore.undefine():

VOID xstevedore.undefine()
--------------------------

Undefine the taskvar.

.. _xstevedore.defined():

BOOL xstevedore.defined()
-------------------------

Return whether the taskvar is defined.

.. _xstevedore.protect():

VOID xstevedore.protect()
-------------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xstevedore.protected():

BOOL xstevedore.protected()
---------------------------

Return whether the taskvar is protected.

.. _taskvar.string():

new xstring = taskvar.string([STRING init])
-------------------------------------------

Construct a(n) STRING taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xstring.get():

STRING xstring.get([STRING fallback])
-------------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is the empty string.

.. _xstring.set():

VOID xstring.set(STRING)
------------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xstring.undefine():

VOID xstring.undefine()
-----------------------

Undefine the taskvar.

.. _xstring.defined():

BOOL xstring.defined()
----------------------

Return whether the taskvar is defined.

.. _xstring.protect():

VOID xstring.protect()
----------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xstring.protected():

BOOL xstring.protected()
------------------------

Return whether the taskvar is protected.

.. _xstring.foreach():

VOID xstring.foreach(STRING string, SUB sub, STRING delim)
----------------------------------------------------------

::

      VOID xstring.foreach(STRING string, SUB sub, STRING delim=",")

Breaks ``string`` into a sequence of zero or more nonempty tokens,
seperated by ``delim``, and successively calls ``sub`` with the object
set to each token.

Processing ends for a nonempty ``return()`` from ``sub``.

.. _taskvar.time():

new xtime = taskvar.time([TIME init])
-------------------------------------

Construct a(n) TIME taskvar with the default value `init`,
if provided. If no `init` value is provided, the variable
will be initially undefined.

.. _xtime.get():

TIME xtime.get([TIME fallback])
-------------------------------

Return the value of the taskvar or the `fallback` argument
if it is undefined. The default `fallback` is the epoch (1970/1/1 0:00:00 GMT).

.. _xtime.set():

VOID xtime.set(TIME)
--------------------

Set the value of the taskvar.

Triggers a vcl failure for protected variables.

.. _xtime.undefine():

VOID xtime.undefine()
---------------------

Undefine the taskvar.

.. _xtime.defined():

BOOL xtime.defined()
--------------------

Return whether the taskvar is defined.

.. _xtime.protect():

VOID xtime.protect()
--------------------

Protect the taskvar, so any future .set() calls on it
trigger a vcl failure.

.. _xtime.protected():

BOOL xtime.protected()
----------------------

Return whether the taskvar is protected.

.. _taskvar.strands():

new xstrands = taskvar.strands(INT cap, [STRING joiner], [STRING prefix], [STRING postfix])
-------------------------------------------------------------------------------------------

::

   new xstrands = taskvar.strands(
      INT cap=0,
      [STRING joiner],
      [STRING prefix],
      [STRING postfix]
   )

Construct a STRANDS collector task variable, which provides a more efficient way
of constructing long strings than using the built-in `+=` operator or repeatedly
calling `.set(... + .get() + ...)` on a `taskvar.string()`_ variable.

The *cap* argument is he maximum capacity in terms of `xstrands.add()`_ calls.
If zero, the capacity is dynamic and the collector is allocated on the heap.
Otherwise, memory for the `taskvar.strands()`_ collector is allocated on the
workspace of the respective task. When planning for a good *cap* value, consider
the fact that added elements can themselves be STRANDS which may use up more
than one cap unit.

The optional *joiner* argument specifies a string which is automatically
inserted between added elements. It is equivalent to a *prefix* only added for
the second and all other elements.

The optional *prefix* argument specifies a string which is automatically
prepended to each added element. Likewise, the optional *postfix* argument
specifies a string which is automatically appended to each added element.

If *joiner*, *prefix* or *postfix* are used, the internal capacity is
automatically adjusted.

.. _xstrands.add():

VOID xstrands.add(STRING)
-------------------------

Add the argument to the collector.

.. _xstrands.clear():

VOID xstrands.clear()
---------------------

Clear the collector.

.. _xstrands.get():

STRING xstrands.get()
---------------------

Return the (current) value of the collector.

SEE ALSO
========

vcl\(7),vinyld\(1)

COPYRIGHT
=========

::

  Copyright 2018-2022 UPLEX Nils Goroll Systemoptimierung
  
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the
     distribution.
  
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
