You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by da...@apache.org on 2017/01/13 18:42:24 UTC

[04/10] incubator-trafficcontrol git commit: Removed ATS patches.

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/0d874bf1/traffic_server/patches/trafficserver-5.3.2-f914e70.diff
----------------------------------------------------------------------
diff --git a/traffic_server/patches/trafficserver-5.3.2-f914e70.diff b/traffic_server/patches/trafficserver-5.3.2-f914e70.diff
deleted file mode 100644
index 2eaf073..0000000
--- a/traffic_server/patches/trafficserver-5.3.2-f914e70.diff
+++ /dev/null
@@ -1,7230 +0,0 @@
-diff --git a/build/ax_cxx_compile_stdcxx_11.m4 b/build/ax_cxx_compile_stdcxx_11.m4
-index e4ba5f5..a8b7d52 100644
---- a/build/ax_cxx_compile_stdcxx_11.m4
-+++ b/build/ax_cxx_compile_stdcxx_11.m4
-@@ -4,69 +4,57 @@
- #
- # SYNOPSIS
- #
--#   AX_CXX_COMPILE_STDCXX_11([ext|noext],[action-if-success],[action-if-failure])
-+#   AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
- #
- # DESCRIPTION
- #
- #   Check for baseline language coverage in the compiler for the C++11
- #   standard; if necessary, add switches to CXXFLAGS to enable support.
--#   Errors out if no mode that supports C++11 baseline syntax can be found.
--#   The argument, if specified, indicates whether you insist on an extended
--#   mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. -std=c++11).
--#   If neither is specified, you get whatever works, with preference for an
--#   extended mode.
-+#
-+#   The first argument, if specified, indicates whether you insist on an
-+#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
-+#   -std=c++11).  If neither is specified, you get whatever works, with
-+#   preference for an extended mode.
-+#
-+#   The second argument, if specified 'mandatory' or if left unspecified,
-+#   indicates that baseline C++11 support is required and that the macro
-+#   should error out if no mode with that support is found.  If specified
-+#   'optional', then configuration proceeds regardless, after defining
-+#   HAVE_CXX11 if and only if a supporting mode is found.
- #
- # LICENSE
- #
- #   Copyright (c) 2008 Benjamin Kosnik <bk...@redhat.com>
- #   Copyright (c) 2012 Zack Weinberg <za...@panix.com>
-+#   Copyright (c) 2013 Roy Stogner <ro...@ices.utexas.edu>
-+#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <so...@google.com>
- #
- #   Copying and distribution of this file, with or without modification, are
- #   permitted in any medium without royalty provided the copyright notice
- #   and this notice are preserved. This file is offered as-is, without any
- #   warranty.
- 
--#serial 1
--
--m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
--  template <typename T>
--    struct check
--    {
--      static_assert(sizeof(int) <= sizeof(T), "not big enough");
--    };
--
--
--    struct in_class_initialization {
--      int i = 0;
--    };
--
--    typedef check<check<bool>> right_angle_brackets;
--
--    int a;
--    decltype(a) b;
-+#serial 11
- 
--    typedef check<int> check_type;
--    check_type c;
--    check_type&& cr = static_cast<check_type&&>(c);
--
--    void * null_pointer_keyword = nullptr;
--])
-+# ATS: Modified to simply check for unordered map, which is the main
-+# feature we need right now from C++0x
-+m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
-+    #include <unordered_map>
-+]])
- 
- AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
-   m4_if([$1], [], [],
-         [$1], [ext], [],
-         [$1], [noext], [],
-         [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
--  AC_LANG_ASSERT([C++])dnl
-+  m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
-+        [$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
-+        [$2], [optional], [ax_cxx_compile_cxx11_required=false],
-+        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])
-+  AC_LANG_PUSH([C++])dnl
-+
-+# We now require either -std=c++11 or -std=c++0x, so don't test without either
-   ac_success=no
--  AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
--  ax_cv_cxx_compile_cxx11,
--  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
--    [ax_cv_cxx_compile_cxx11=yes],
--    [ax_cv_cxx_compile_cxx11=no])])
--  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
--    ac_success=yes
--  fi
- 
-   m4_if([$1], [noext], [], [dnl
-   if test x$ac_success = xno; then
-@@ -90,7 +78,9 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
- 
-   m4_if([$1], [ext], [], [dnl
-   if test x$ac_success = xno; then
--    for switch in -std=c++11 -std=c++0x; do
-+    dnl HP's aCC needs +std=c++11 according to:
-+    dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
-+    for switch in -std=c++11 -std=c++0x +std=c++11; do
-       cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
-       AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
-                      $cachevar,
-@@ -107,10 +97,21 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
-       fi
-     done
-   fi])
--
--  if test x$ac_success = xno ; then
--    m4_if([$3], [], [true], [$3])
-+  AC_LANG_POP([C++])
-+  if test x$ax_cxx_compile_cxx11_required = xtrue; then
-+    if test x$ac_success = xno; then
-+      AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
-+    fi
-   else
--    m4_if([$2], [], [true], [$2])
-+    if test x$ac_success = xno; then
-+      HAVE_CXX11=0
-+      AC_MSG_NOTICE([No compiler with C++11 support was found])
-+    else
-+      HAVE_CXX11=1
-+      AC_DEFINE(HAVE_CXX11,1,
-+                [define if the compiler supports basic C++11 syntax])
-+    fi
-+
-+    AC_SUBST(HAVE_CXX11)
-   fi
- ])
-diff --git a/cmd/traffic_top/stats.h b/cmd/traffic_top/stats.h
-index 4b48bde..9fc8ac8 100644
---- a/cmd/traffic_top/stats.h
-+++ b/cmd/traffic_top/stats.h
-@@ -385,8 +385,8 @@ public:
-         value = (value - old) / _time_diff;
-       }
-     } else if (type == 3 || type == 4) {
--      double numerator;
--      double denominator;
-+      double numerator = 0;
-+      double denominator = 0;
-       getStat(item.numerator, numerator);
-       getStat(item.denominator, denominator);
-       if (denominator == 0)
-diff --git a/configure.ac b/configure.ac
-index 45c47fe..2c79ca4 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -578,10 +578,7 @@ CXXFLAGS="${_ts_saved_CXXFLAGS}"
- # AX_CXX_COMPILE_STDCXX_11 requires the current language to be C++.
- AC_LANG_PUSH([C++])
- 
--AX_CXX_COMPILE_STDCXX_11( [noext], [enable_cxx_11_support=yes], [
--  enable_cxx_11_support=no
--  AC_MSG_NOTICE([disabling features that depend on C++11 support])
--])
-+AX_CXX_COMPILE_STDCXX_11( [noext], [mandatory])
- 
- AM_CONDITIONAL([BUILD_HAVE_CXX_11], [ test "x${enable_cxx_11_support}" = "xyes" ])
- if test "x${enable_cxx_11_support}" = "xyes" ; then
-@@ -1948,6 +1945,7 @@ AS_IF([test "x$enable_experimental_plugins" = xyes], [
-     plugins/experimental/background_fetch/Makefile
-     plugins/experimental/balancer/Makefile
-     plugins/experimental/buffer_upload/Makefile
-+    plugins/experimental/cache_promote/Makefile
-     plugins/experimental/cache_range_requests/Makefile
-     plugins/experimental/channel_stats/Makefile
-     plugins/experimental/collapsed_connection/Makefile
-@@ -1968,6 +1966,7 @@ AS_IF([test "x$enable_experimental_plugins" = xyes], [
-     plugins/experimental/ssl_cert_loader/Makefile
-     plugins/experimental/sslheaders/Makefile
-     plugins/experimental/stale_while_revalidate/Makefile
-+    plugins/experimental/stream_editor/Makefile
-     plugins/experimental/ts_lua/Makefile
-     plugins/experimental/url_sig/Makefile
-     plugins/experimental/xdebug/Makefile
-diff --git a/doc/reference/configuration/parent.config.en.rst b/doc/reference/configuration/parent.config.en.rst
-index f025a7a..88166c9 100644
---- a/doc/reference/configuration/parent.config.en.rst
-+++ b/doc/reference/configuration/parent.config.en.rst
-@@ -21,11 +21,12 @@ parent.config
- 
- .. configfile:: parent.config
- 
--The :file:`parent.config` file identifies the parent proxies used in an
--cache hierarchy. Use this file to perform the following configuration:
-+The :file:`parent.config` file identifies the parent proxies or origins 
-+used in an cache hierarchy. Use this file to perform the following configuration:
- 
- -  Set up parent cache hierarchies, with multiple parents and parent
-    failover
-+-  Configure multiple parent origin servers.
- -  Configure selected URL requests to bypass parent proxies
- 
- Traffic Server uses the :file:`parent.config` file only when the parent
-@@ -122,6 +123,17 @@ The following list shows the possible actions and their allowed values.
-     origin server. You can specify either a hostname or an IP address,
-     but; you must specify the port number.
- 
-+.. _parent-config-format-secondary_parent-parent:
-+
-+``secondary_parent``
-+    An optional ordered list of secondary parent servers using the same format
-+    as the ``parent`` list.  A ``secondary_parent`` list only applies
-+    when ``round_robin`` is set to ``consistent_hash``.  When using
-+    ``consistent_hash``, if the server chosen from the primary list fails,
-+    a parent is selected from a secondary consistent hash ring. This feature
-+    works best in a multi-tiered cache hierarchy where one might take advantage
-+    of the content affinint built up on a secondary list of parents.
-+
- .. _parent-config-format-round-robin:
- 
- ``round_robin``
-@@ -135,6 +147,21 @@ The following list shows the possible actions and their allowed values.
-     -  ``false`` - Round robin selection does not occur.
-     -  ``consistent_hash`` - consistent hash.
- 
-+.. _parent-config-format-parent_is_proxy:
-+
-+``parent_is_proxy``
-+    One of the following values:
-+
-+    - ``true`` - Specifies that the parents are ATS cache proxies, within
-+                 a hierarchy.  This is the default value, if ``parent_is_proxy``
-+                 is not specified in the configuration.
-+
-+    - ``false`` - Specifies that the parents are origin servers. The request
-+                  url's are modified so they are appropriate for origin
-+                  requests.  Normal Parent Selection behaviour applies to
-+                  the origins listed.  Since these would be a list of origin
-+                  servers, set go_direct described below to ``false``.
-+
- .. _parent-config-format-go-direct:
- 
- ``go_direct``
-diff --git a/doc/reference/configuration/records.config.en.rst b/doc/reference/configuration/records.config.en.rst
-index d23b864..e7ea6ba 100644
---- a/doc/reference/configuration/records.config.en.rst
-+++ b/doc/reference/configuration/records.config.en.rst
-@@ -929,6 +929,26 @@ Parent Proxy Configuration
- 
-    Don't try to resolve DNS, forward all DNS requests to the parent. This is off (``0``) by default.
- 
-+.. ts:cv:: CONFIG proxy.config.http.parent_origin.simple_retry_enabled INT 0
-+
-+   Enable the simple retry feature, This is off (``0``) by default.  simple retry is only used for 
-+   parent origin servers, see configuration information for parent.config. 
-+
-+.. ts:cv:: CONFIG proxy.config.http.parent_origin.simple_retry_response_codes STRING 0
-+
-+   This is a comma separated list of response codes that will trigger a simple retry on a parent
-+   origin server if ``simple_retry`` above is enabled.  This is a ``404`` by default.
-+
-+.. ts:cv:: CONFIG proxy.config.http.parent_origin.dead_server_retry_enabled INT 0
-+
-+   Enable the dead_server retry feature, This is off (``0``) by default.  dead server retry 
-+   is only used for parent origin servers, see configuration information for parent.config. 
-+
-+.. ts:cv:: CONFIG proxy.config.http.parent_origin.dead_server_retry_response_codes STRING 0
-+
-+   This is a comma separated list of response codes that will trigger a dead server retry on 
-+   a parent origin server if ``dead_server_retry`` above is enabled.  This is a ``503`` by default.
-+
- HTTP Connection Timeouts
- ========================
- 
-diff --git a/iocore/cache/CacheDir.cc b/iocore/cache/CacheDir.cc
-index e54fbfb..30f46cd 100644
---- a/iocore/cache/CacheDir.cc
-+++ b/iocore/cache/CacheDir.cc
-@@ -1140,6 +1140,15 @@ CacheSync::mainEvent(int event, Event *e)
- Lrestart:
-   if (vol_idx >= gnvol) {
-     vol_idx = 0;
-+    if (buf) {
-+      if (buf_huge)
-+        ats_free_hugepage(buf, buflen);
-+      else
-+        ats_memalign_free(buf);
-+      buflen = 0;
-+      buf = NULL;
-+      buf_huge = false;
-+    }
-     Debug("cache_dir_sync", "sync done");
-     if (event == EVENT_INTERVAL)
-       trigger = e->ethread->schedule_in(this, HRTIME_SECONDS(cache_config_dir_sync_frequency));
-diff --git a/iocore/eventsystem/UnixEventProcessor.cc b/iocore/eventsystem/UnixEventProcessor.cc
-index 54fec71..c3180fa 100644
---- a/iocore/eventsystem/UnixEventProcessor.cc
-+++ b/iocore/eventsystem/UnixEventProcessor.cc
-@@ -135,10 +135,14 @@ EventProcessor::start(int n_event_threads, size_t stacksize)
-   Debug("iocore_thread", "Affinity: %d %ss: %d PU: %d", affinity, obj_name, obj_count, ink_number_of_processors());
- 
- #endif
--  for (i = first_thread; i < n_ethreads; i++) {
--    snprintf(thr_name, MAX_THREAD_NAME_LENGTH, "[ET_NET %d]", i);
--    ink_thread tid = all_ethreads[i]->start(thr_name, stacksize);
--    (void)tid;
-+  for (i = 0; i < n_ethreads; i++) {
-+    ink_thread tid;
-+    if (i >= first_thread) {
-+      snprintf(thr_name, MAX_THREAD_NAME_LENGTH, "[ET_NET %d]", i);
-+      tid = all_ethreads[i]->start(thr_name, stacksize);
-+    } else {
-+      tid = ink_thread_self();
-+    }
- #if TS_USE_HWLOC
-     if (obj_count > 0) {
-       obj = hwloc_get_obj_by_type(ink_get_topology(), obj_type, i % obj_count);
-@@ -154,6 +158,8 @@ EventProcessor::start(int n_event_threads, size_t stacksize)
-     } else {
-       Warning("hwloc returned an unexpected value -- CPU affinity disabled");
-     }
-+#else
-+    (void)tid;
- #endif // TS_USE_HWLOC
-   }
- 
-diff --git a/iocore/net/SSLSessionCache.cc b/iocore/net/SSLSessionCache.cc
-index 740b14f..67513a1 100644
---- a/iocore/net/SSLSessionCache.cc
-+++ b/iocore/net/SSLSessionCache.cc
-@@ -22,7 +22,6 @@
- #include "P_SSLConfig.h"
- #include "SSLSessionCache.h"
- #include <cstring>
--#include <memory>
- 
- #define SSLSESSIONCACHE_STRINGIFY0(x) #x
- #define SSLSESSIONCACHE_STRINGIFY(x) SSLSESSIONCACHE_STRINGIFY0(x)
-@@ -132,7 +131,7 @@ SSLSessionBucket::insertSession(const SSLSessionID &id, SSL_SESSION *sess)
-   unsigned char *loc = reinterpret_cast<unsigned char *>(buf->data());
-   i2d_SSL_SESSION(sess, &loc);
- 
--  std::auto_ptr<SSLSession> ssl_session(new SSLSession(id, buf, len));
-+  ats_scoped_obj<SSLSession> ssl_session(new SSLSession(id, buf, len));
- 
-   MUTEX_TRY_LOCK(lock, mutex, this_ethread());
-   if (!lock.is_locked()) {
-diff --git a/iocore/net/Socks.cc b/iocore/net/Socks.cc
-index a0350f6..7af322f 100644
---- a/iocore/net/Socks.cc
-+++ b/iocore/net/Socks.cc
-@@ -146,7 +146,7 @@ SocksEntry::free()
- 
- #ifdef SOCKS_WITH_TS
-   if (!lerrno && netVConnection && server_result.retry)
--    server_params->recordRetrySuccess(&server_result);
-+    server_params->markParentUp(&server_result);
- #endif
- 
-   if ((action_.cancelled || lerrno) && netVConnection)
-diff --git a/lib/records/RecProcess.cc b/lib/records/RecProcess.cc
-index 9a44ee6..1b69b0c 100644
---- a/lib/records/RecProcess.cc
-+++ b/lib/records/RecProcess.cc
-@@ -562,11 +562,6 @@ _RecRegisterRawStat(RecRawStatBlock *rsb, RecT rec_type, const char *name, RecDa
-     err = REC_ERR_FAIL;
-     goto Ldone;
-   }
--  if (r->rsb_id > 0 && r->rsb_id != id) {
--    Warning("_RecRegisterRawStat(): Created and reusing a stat with id = %d for new stat named %s", r->rsb_id, name);
--  } else {
--    Warning("_RecRegisterStat(): Stat created, name: %s, id: %d", name, id);
--  }
-   r->rsb_id = id; // This is the index within the RSB raw block for this stat, used for lookups by name.
-   if (i_am_the_record_owner(r->rec_type)) {
-     r->sync_required = r->sync_required | REC_PEER_SYNC_REQUIRED;
-@@ -581,7 +576,6 @@ _RecRegisterRawStat(RecRawStatBlock *rsb, RecT rec_type, const char *name, RecDa
- 
-   // setup the periodic sync callback
-   RecRegisterRawStatSyncCb(name, sync_cb, rsb, id);
--  Warning("_RecRegisterRawStat(): Stat created, id:%d name:%s, data address:%p", id, name, &r->stat_meta.data_raw);
- 
- Ldone:
-   return err;
-diff --git a/lib/ts/ConsistentHash.cc b/lib/ts/ConsistentHash.cc
-index 912bc74..22f12c0 100644
---- a/lib/ts/ConsistentHash.cc
-+++ b/lib/ts/ConsistentHash.cc
-@@ -67,19 +67,13 @@ ATSConsistentHash::insert(ATSConsistentHashNode *node, float weight, ATSHash64 *
- }
- 
- ATSConsistentHashNode *
--ATSConsistentHash::lookup(const char *url, size_t url_len, ATSConsistentHashIter *i, bool *w, ATSHash64 *h)
-+ATSConsistentHash::lookup(const char *url, ATSConsistentHashIter *i, bool *w, ATSHash64 *h)
- {
-   uint64_t url_hash;
-   ATSConsistentHashIter NodeMapIterUp, *iter;
-   ATSHash64 *thash;
-   bool *wptr, wrapped = false;
- 
--  if (url_len <= 0 && url) {
--    url_len = strlen(url);
--  } else {
--    url_len = 0;
--  }
--
-   if (h) {
-     thash = h;
-   } else if (hash) {
-@@ -101,7 +95,7 @@ ATSConsistentHash::lookup(const char *url, size_t url_len, ATSConsistentHashIter
-   }
- 
-   if (url) {
--    thash->update(url, url_len);
-+    thash->update(url, strlen(url));
-     thash->final();
-     url_hash = thash->get();
-     thash->clear();
-@@ -130,19 +124,13 @@ ATSConsistentHash::lookup(const char *url, size_t url_len, ATSConsistentHashIter
- }
- 
- ATSConsistentHashNode *
--ATSConsistentHash::lookup_available(const char *url, size_t url_len, ATSConsistentHashIter *i, bool *w, ATSHash64 *h)
-+ATSConsistentHash::lookup_available(const char *url, ATSConsistentHashIter *i, bool *w, ATSHash64 *h)
- {
-   uint64_t url_hash;
-   ATSConsistentHashIter NodeMapIterUp, *iter;
-   ATSHash64 *thash;
-   bool *wptr, wrapped = false;
- 
--  if (url_len <= 0 && url) {
--    url_len = strlen(url);
--  } else {
--    url_len = 0;
--  }
--
-   if (h) {
-     thash = h;
-   } else if (hash) {
-@@ -164,7 +152,7 @@ ATSConsistentHash::lookup_available(const char *url, size_t url_len, ATSConsiste
-   }
- 
-   if (url) {
--    thash->update(url, url_len);
-+    thash->update(url, strlen(url));
-     thash->final();
-     url_hash = thash->get();
-     thash->clear();
-diff --git a/lib/ts/ConsistentHash.h b/lib/ts/ConsistentHash.h
-index 49822ad..dbfd6c3 100644
---- a/lib/ts/ConsistentHash.h
-+++ b/lib/ts/ConsistentHash.h
-@@ -49,10 +49,9 @@ typedef std::map<uint64_t, ATSConsistentHashNode *>::iterator ATSConsistentHashI
- struct ATSConsistentHash {
-   ATSConsistentHash(int r = 1024, ATSHash64 *h = NULL);
-   void insert(ATSConsistentHashNode *node, float weight = 1.0, ATSHash64 *h = NULL);
--  ATSConsistentHashNode *lookup(const char *url = NULL, size_t url_len = 0, ATSConsistentHashIter *i = NULL, bool *w = NULL,
--                                ATSHash64 *h = NULL);
--  ATSConsistentHashNode *lookup_available(const char *url = NULL, size_t url_len = 0, ATSConsistentHashIter *i = NULL,
--                                          bool *w = NULL, ATSHash64 *h = NULL);
-+  ATSConsistentHashNode *lookup(const char *url = NULL, ATSConsistentHashIter *i = NULL, bool *w = NULL, ATSHash64 *h = NULL);
-+  ATSConsistentHashNode *lookup_available(const char *url = NULL, ATSConsistentHashIter *i = NULL, bool *w = NULL,
-+                                          ATSHash64 *h = NULL);
-   ATSConsistentHashNode *lookup_by_hashval(uint64_t hashval, ATSConsistentHashIter *i = NULL, bool *w = NULL);
-   ~ATSConsistentHash();
- 
-diff --git a/lib/ts/ink_memory.cc b/lib/ts/ink_memory.cc
-index 4c18c43..aba2104 100644
---- a/lib/ts/ink_memory.cc
-+++ b/lib/ts/ink_memory.cc
-@@ -187,22 +187,10 @@ ats_msync(caddr_t addr, size_t len, caddr_t end, int flags)
- int
- ats_madvise(caddr_t addr, size_t len, int flags)
- {
--#if defined(linux)
--  (void)addr;
--  (void)len;
--  (void)flags;
--  return 0;
--#else
--  size_t pagesize = ats_pagesize();
--  caddr_t a = (caddr_t)(((uintptr_t)addr) & ~(pagesize - 1));
--  size_t l = (len + (addr - a) + pagesize - 1) & ~(pagesize - 1);
--  int res = 0;
- #if HAVE_POSIX_MADVISE
--  res = posix_madvise(a, l, flags);
-+  return posix_madvise(addr, len, flags);
- #else
--  res = madvise(a, l, flags);
--#endif
--  return res;
-+  return madvise(addr, len, flags);
- #endif
- }
- 
-diff --git a/lib/ts/ink_queue.cc b/lib/ts/ink_queue.cc
-index 0f14b68..da2a93d 100644
---- a/lib/ts/ink_queue.cc
-+++ b/lib/ts/ink_queue.cc
-@@ -106,7 +106,7 @@ ink_freelist_init(InkFreeList **fl, const char *name, uint32_t type_size, uint32
-   if (ats_hugepage_enabled()) {
-     f->chunk_size = INK_ALIGN(chunk_size * f->type_size, ats_hugepage_size()) / f->type_size;
-   } else {
--    f->chunk_size = chunk_size;
-+    f->chunk_size = INK_ALIGN(chunk_size * f->type_size, ats_pagesize()) / f->type_size;
-   }
-   SET_FREELIST_POINTER_VERSION(f->head, FROM_PTR(0), 0);
- 
-@@ -163,6 +163,7 @@ ink_freelist_new(InkFreeList *f)
-     if (TO_PTR(FREELIST_POINTER(item)) == NULL) {
-       uint32_t type_size = f->type_size;
-       uint32_t i;
-+      size_t alloc_size = 0;
- 
- #ifdef MEMPROTECT
-       if (type_size >= MEMPROTECT_SIZE) {
-@@ -176,16 +177,17 @@ ink_freelist_new(InkFreeList *f)
- #ifdef DEBUG
-       char *oldsbrk = (char *)sbrk(0), *newsbrk = NULL;
- #endif
--      if (ats_hugepage_enabled())
--        newp = ats_alloc_hugepage(f->chunk_size * type_size);
-+      if (ats_hugepage_enabled()) {
-+        alloc_size = INK_ALIGN(f->chunk_size * f->type_size, ats_hugepage_size());
-+        newp = ats_alloc_hugepage(alloc_size);
-+      }
- 
-       if (newp == NULL) {
--        if (f->alignment)
--          newp = ats_memalign(f->alignment, f->chunk_size * type_size);
--        else
--          newp = ats_malloc(f->chunk_size * type_size);
-+        alloc_size = INK_ALIGN(f->chunk_size * f->type_size, ats_pagesize());
-+        newp = ats_memalign(ats_pagesize(), alloc_size);
-       }
--      ats_madvise((caddr_t)newp, f->chunk_size * type_size, f->advice);
-+
-+      ats_madvise((caddr_t)newp, alloc_size, f->advice);
-       fl_memadd(f->chunk_size * type_size);
- #ifdef DEBUG
-       newsbrk = (char *)sbrk(0);
-@@ -238,7 +240,6 @@ ink_freelist_new(InkFreeList *f)
- #endif /* SANITY */
-     }
-   } while (result == 0);
--  ink_assert(!((uintptr_t)TO_PTR(FREELIST_POINTER(item)) & (((uintptr_t)f->alignment) - 1)));
- 
-   ink_atomic_increment((int *)&f->used, 1);
-   ink_atomic_increment(&fastalloc_mem_in_use, (int64_t)f->type_size);
-@@ -252,7 +253,7 @@ ink_freelist_new(InkFreeList *f)
-     newp = ats_memalign(f->alignment, f->type_size);
-   else
-     newp = ats_malloc(f->type_size);
--  ats_madvise((caddr_t)newp, f->type_size, f->advice);
-+
-   return newp;
- #endif
- }
-diff --git a/lib/tsconfig/TsConfigGrammar.c b/lib/tsconfig/TsConfigGrammar.c
-index c63b4d8..042a146 100644
---- a/lib/tsconfig/TsConfigGrammar.c
-+++ b/lib/tsconfig/TsConfigGrammar.c
-@@ -1,19 +1,21 @@
--/* A Bison parser, made by GNU Bison 2.7.  */
- 
--/* Bison implementation for Yacc-like parsers in C
--
--      Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
-+/* A Bison parser, made by GNU Bison 2.4.1.  */
- 
-+/* Skeleton implementation for Bison's Yacc-like parsers in C
-+   
-+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-+   Free Software Foundation, Inc.
-+   
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
--
-+   
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
--
-+   
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
- 
-@@ -26,7 +28,7 @@
-    special exception, which will cause the skeleton and the resulting
-    Bison output files to be licensed under the GNU General Public
-    License without this special exception.
--
-+   
-    This special exception was added by the Free Software Foundation in
-    version 2.2 of Bison.  */
- 
-@@ -44,7 +46,7 @@
- #define YYBISON 1
- 
- /* Bison version.  */
--#define YYBISON_VERSION "2.7"
-+#define YYBISON_VERSION "2.4.1"
- 
- /* Skeleton name.  */
- #define YYSKELETON_NAME "yacc.c"
-@@ -58,8 +60,12 @@
- /* Pull parsers.  */
- #define YYPULL 1
- 
-+/* Using locations.  */
-+#define YYLSP_NEEDED 0
-+
- /* "%code top" blocks.  */
--/* Line 349 of yacc.c  */
-+
-+/* Line 171 of yacc.c  */
- #line 26 "TsConfigGrammar.y"
- 
- # if ! (defined(__clang_analyzer__) || defined(__COVERITY__))
-@@ -79,9 +85,9 @@ extern int tsconfiglex(YYSTYPE* yylval, yyscan_t lexer);
- 
- 
- 
--/* Line 349 of yacc.c  */
--#line 84 "TsConfigGrammar.c"
- 
-+/* Line 171 of yacc.c  */
-+#line 91 "TsConfigGrammar.c"
- /* Substitute the variable and function names.  */
- #define yyparse         tsconfigparse
- #define yylex           tsconfiglex
-@@ -91,18 +97,17 @@ extern int tsconfiglex(YYSTYPE* yylval, yyscan_t lexer);
- #define yydebug         tsconfigdebug
- #define yynerrs         tsconfignerrs
- 
-+
- /* Copy the first part of user declarations.  */
- 
--/* Line 371 of yacc.c  */
--#line 98 "TsConfigGrammar.c"
- 
--# ifndef YY_NULL
--#  if defined __cplusplus && 201103L <= __cplusplus
--#   define YY_NULL nullptr
--#  else
--#   define YY_NULL 0
--#  endif
--# endif
-+/* Line 189 of yacc.c  */
-+#line 106 "TsConfigGrammar.c"
-+
-+/* Enabling traces.  */
-+#ifndef YYDEBUG
-+# define YYDEBUG 0
-+#endif
- 
- /* Enabling verbose error messages.  */
- #ifdef YYERROR_VERBOSE
-@@ -112,19 +117,14 @@ extern int tsconfiglex(YYSTYPE* yylval, yyscan_t lexer);
- # define YYERROR_VERBOSE 1
- #endif
- 
--/* In a future release of Bison, this section will be replaced
--   by #include "y.tab.h".  */
--#ifndef YY_TSCONFIG_TSCONFIGGRAMMAR_H_INCLUDED
--# define YY_TSCONFIG_TSCONFIGGRAMMAR_H_INCLUDED
--/* Enabling traces.  */
--#ifndef YYDEBUG
--# define YYDEBUG 0
--#endif
--#if YYDEBUG
--extern int tsconfigdebug;
-+/* Enabling the token table.  */
-+#ifndef YYTOKEN_TABLE
-+# define YYTOKEN_TABLE 0
- #endif
-+
- /* "%code requires" blocks.  */
--/* Line 387 of yacc.c  */
-+
-+/* Line 209 of yacc.c  */
- #line 1 "TsConfigGrammar.y"
- 
- /** @file
-@@ -151,8 +151,9 @@ extern int tsconfigdebug;
-  */
- 
- 
--/* Line 387 of yacc.c  */
--#line 156 "TsConfigGrammar.c"
-+
-+/* Line 209 of yacc.c  */
-+#line 157 "TsConfigGrammar.c"
- 
- /* Tokens.  */
- #ifndef YYTOKENTYPE
-@@ -190,6 +191,7 @@ extern int tsconfigdebug;
- 
- 
- 
-+
- #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
- typedef int YYSTYPE;
- # define YYSTYPE_IS_TRIVIAL 1
-@@ -198,28 +200,14 @@ typedef int YYSTYPE;
- #endif
- 
- 
--#ifdef YYPARSE_PARAM
--#if defined __STDC__ || defined __cplusplus
--int tsconfigparse (void *YYPARSE_PARAM);
--#else
--int tsconfigparse ();
--#endif
--#else /* ! YYPARSE_PARAM */
--#if defined __STDC__ || defined __cplusplus
--int tsconfigparse (yyscan_t lexer, struct TsConfigHandlers* handlers);
--#else
--int tsconfigparse ();
--#endif
--#endif /* ! YYPARSE_PARAM */
--
--#endif /* !YY_TSCONFIG_TSCONFIGGRAMMAR_H_INCLUDED  */
--
- /* Copy the second part of user declarations.  */
- 
--/* Line 390 of yacc.c  */
--#line 221 "TsConfigGrammar.c"
-+
-+/* Line 264 of yacc.c  */
-+#line 208 "TsConfigGrammar.c"
- /* Unqualified %code blocks.  */
--/* Line 391 of yacc.c  */
-+
-+/* Line 265 of yacc.c  */
- #line 44 "TsConfigGrammar.y"
- 
- 
-@@ -242,8 +230,9 @@ int tsconfigerror(
- 
- 
- 
--/* Line 391 of yacc.c  */
--#line 247 "TsConfigGrammar.c"
-+
-+/* Line 265 of yacc.c  */
-+#line 236 "TsConfigGrammar.c"
- 
- #ifdef short
- # undef short
-@@ -293,27 +282,27 @@ typedef short int yytype_int16;
- #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
- 
- #ifndef YY_
--# if defined YYENABLE_NLS && YYENABLE_NLS
-+# if YYENABLE_NLS
- #  if ENABLE_NLS
- #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
--#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
-+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
- #  endif
- # endif
- # ifndef YY_
--#  define YY_(Msgid) Msgid
-+#  define YY_(msgid) msgid
- # endif
- #endif
- 
- /* Suppress unused-variable warnings by "using" E.  */
- #if ! defined lint || defined __GNUC__
--# define YYUSE(E) ((void) (E))
-+# define YYUSE(e) ((void) (e))
- #else
--# define YYUSE(E) /* empty */
-+# define YYUSE(e) /* empty */
- #endif
- 
- /* Identity function, used to suppress warnings about constant conditions.  */
- #ifndef lint
--# define YYID(N) (N)
-+# define YYID(n) (n)
- #else
- #if (defined __STDC__ || defined __C99__FUNC__ \
-      || defined __cplusplus || defined _MSC_VER)
-@@ -346,12 +335,11 @@ YYID (yyi)
- #    define alloca _alloca
- #   else
- #    define YYSTACK_ALLOC alloca
--#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
-+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-      || defined __cplusplus || defined _MSC_VER)
- #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
--      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
--#     ifndef EXIT_SUCCESS
--#      define EXIT_SUCCESS 0
-+#     ifndef _STDLIB_H
-+#      define _STDLIB_H 1
- #     endif
- #    endif
- #   endif
-@@ -374,24 +362,24 @@ YYID (yyi)
- #  ifndef YYSTACK_ALLOC_MAXIMUM
- #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
- #  endif
--#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
-+#  if (defined __cplusplus && ! defined _STDLIB_H \
-        && ! ((defined YYMALLOC || defined malloc) \
- 	     && (defined YYFREE || defined free)))
- #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
--#   ifndef EXIT_SUCCESS
--#    define EXIT_SUCCESS 0
-+#   ifndef _STDLIB_H
-+#    define _STDLIB_H 1
- #   endif
- #  endif
- #  ifndef YYMALLOC
- #   define YYMALLOC malloc
--#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
-+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-      || defined __cplusplus || defined _MSC_VER)
- void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
- #   endif
- #  endif
- #  ifndef YYFREE
- #   define YYFREE free
--#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
-+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-      || defined __cplusplus || defined _MSC_VER)
- void free (void *); /* INFRINGES ON USER NAME SPACE */
- #   endif
-@@ -420,7 +408,23 @@ union yyalloc
-      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
-       + YYSTACK_GAP_MAXIMUM)
- 
--# define YYCOPY_NEEDED 1
-+/* Copy COUNT objects from FROM to TO.  The source and destination do
-+   not overlap.  */
-+# ifndef YYCOPY
-+#  if defined __GNUC__ && 1 < __GNUC__
-+#   define YYCOPY(To, From, Count) \
-+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-+#  else
-+#   define YYCOPY(To, From, Count)		\
-+      do					\
-+	{					\
-+	  YYSIZE_T yyi;				\
-+	  for (yyi = 0; yyi < (Count); yyi++)	\
-+	    (To)[yyi] = (From)[yyi];		\
-+	}					\
-+      while (YYID (0))
-+#  endif
-+# endif
- 
- /* Relocate STACK from its old location to the new one.  The
-    local variables YYSIZE and YYSTACKSIZE give the old and new number of
-@@ -440,26 +444,6 @@ union yyalloc
- 
- #endif
- 
--#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
--/* Copy COUNT objects from SRC to DST.  The source and destination do
--   not overlap.  */
--# ifndef YYCOPY
--#  if defined __GNUC__ && 1 < __GNUC__
--#   define YYCOPY(Dst, Src, Count) \
--      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
--#  else
--#   define YYCOPY(Dst, Src, Count)              \
--      do                                        \
--        {                                       \
--          YYSIZE_T yyi;                         \
--          for (yyi = 0; yyi < (Count); yyi++)   \
--            (Dst)[yyi] = (Src)[yyi];            \
--        }                                       \
--      while (YYID (0))
--#  endif
--# endif
--#endif /* !YYCOPY_NEEDED */
--
- /* YYFINAL -- State number of the termination state.  */
- #define YYFINAL  3
- /* YYLAST -- Last index in YYTABLE.  */
-@@ -547,7 +531,7 @@ static const yytype_uint8 yyrline[] =
- };
- #endif
- 
--#if YYDEBUG || YYERROR_VERBOSE || 1
-+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
- /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
- static const char *const yytname[] =
-@@ -558,7 +542,7 @@ static const char *const yytname[] =
-   "config", "group", "group_open", "group_close", "group_items", "assign",
-   "$@1", "list", "list_open", "list_close", "list_items", "value",
-   "literal", "separator", "path", "path_open", "path_close", "path_item",
--  "path_tag", YY_NULL
-+  "path_tag", 0
- };
- #endif
- 
-@@ -590,8 +574,8 @@ static const yytype_uint8 yyr2[] =
-        3,     1,     1
- };
- 
--/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
--   Performed when YYTABLE doesn't specify something else to do.  Zero
-+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
-    means the default is an error.  */
- static const yytype_uint8 yydefact[] =
- {
-@@ -630,7 +614,8 @@ static const yytype_int8 yypgoto[] =
- 
- /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
-    positive, shift that token.  If negative, reduce the rule which
--   number is the opposite.  If YYTABLE_NINF, syntax error.  */
-+   number is the opposite.  If zero, do what YYDEFACT says.
-+   If YYTABLE_NINF, syntax error.  */
- #define YYTABLE_NINF -3
- static const yytype_int8 yytable[] =
- {
-@@ -640,12 +625,6 @@ static const yytype_int8 yytable[] =
-       26,    42,     0,    37
- };
- 
--#define yypact_value_is_default(Yystate) \
--  (!!((Yystate) == (-11)))
--
--#define yytable_value_is_error(Yytable_value) \
--  YYID (0)
--
- static const yytype_int8 yycheck[] =
- {
-        6,     1,     0,     3,     4,     5,     6,     7,     8,     1,
-@@ -677,50 +656,78 @@ static const yytype_uint8 yystos[] =
- 
- /* Like YYERROR except do call yyerror.  This remains here temporarily
-    to ease the transition to the new meaning of YYERROR, for GCC.
--   Once GCC version 2 has supplanted version 1, this can go.  However,
--   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
--   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
--   discussed.  */
-+   Once GCC version 2 has supplanted version 1, this can go.  */
- 
- #define YYFAIL		goto yyerrlab
--#if defined YYFAIL
--  /* This is here to suppress warnings from the GCC cpp's
--     -Wunused-macros.  Normally we don't worry about that warning, but
--     some users do, and we want to make it easy for users to remove
--     YYFAIL uses, which will produce warnings from Bison 2.5.  */
--#endif
- 
- #define YYRECOVERING()  (!!yyerrstatus)
- 
--#define YYBACKUP(Token, Value)                                  \
--do                                                              \
--  if (yychar == YYEMPTY)                                        \
--    {                                                           \
--      yychar = (Token);                                         \
--      yylval = (Value);                                         \
--      YYPOPSTACK (yylen);                                       \
--      yystate = *yyssp;                                         \
--      goto yybackup;                                            \
--    }                                                           \
--  else                                                          \
--    {                                                           \
-+#define YYBACKUP(Token, Value)					\
-+do								\
-+  if (yychar == YYEMPTY && yylen == 1)				\
-+    {								\
-+      yychar = (Token);						\
-+      yylval = (Value);						\
-+      yytoken = YYTRANSLATE (yychar);				\
-+      YYPOPSTACK (1);						\
-+      goto yybackup;						\
-+    }								\
-+  else								\
-+    {								\
-       yyerror (lexer, handlers, YY_("syntax error: cannot back up")); \
-       YYERROR;							\
-     }								\
- while (YYID (0))
- 
--/* Error token number */
-+
- #define YYTERROR	1
- #define YYERRCODE	256
- 
- 
--/* This macro is provided for backward compatibility. */
-+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
-+   If N is 0, then set CURRENT to the empty location which ends
-+   the previous symbol: RHS[0] (always defined).  */
-+
-+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-+#ifndef YYLLOC_DEFAULT
-+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
-+    do									\
-+      if (YYID (N))                                                    \
-+	{								\
-+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
-+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
-+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
-+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
-+	}								\
-+      else								\
-+	{								\
-+	  (Current).first_line   = (Current).last_line   =		\
-+	    YYRHSLOC (Rhs, 0).last_line;				\
-+	  (Current).first_column = (Current).last_column =		\
-+	    YYRHSLOC (Rhs, 0).last_column;				\
-+	}								\
-+    while (YYID (0))
-+#endif
-+
-+
-+/* YY_LOCATION_PRINT -- Print the location on the stream.
-+   This macro was not mandated originally: define only if we know
-+   we won't break user code: when these are the locations we know.  */
-+
- #ifndef YY_LOCATION_PRINT
--# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-+# if YYLTYPE_IS_TRIVIAL
-+#  define YY_LOCATION_PRINT(File, Loc)			\
-+     fprintf (File, "%d.%d-%d.%d",			\
-+	      (Loc).first_line, (Loc).first_column,	\
-+	      (Loc).last_line,  (Loc).last_column)
-+# else
-+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-+# endif
- #endif
- 
- 
- /* YYLEX -- calling `yylex' with the right arguments.  */
-+
- #ifdef YYLEX_PARAM
- # define YYLEX yylex (&yylval, YYLEX_PARAM)
- #else
-@@ -772,8 +779,6 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, lexer, handlers)
-     struct TsConfigHandlers* handlers;
- #endif
- {
--  FILE *yyo = yyoutput;
--  YYUSE (yyo);
-   if (!yyvaluep)
-     return;
-   YYUSE (lexer);
-@@ -787,7 +792,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, lexer, handlers)
-   switch (yytype)
-     {
-       default:
--        break;
-+	break;
-     }
- }
- 
-@@ -917,6 +922,7 @@ int yydebug;
- # define YYMAXDEPTH 10000
- #endif
- 
-+
- 
- #if YYERROR_VERBOSE
- 
-@@ -1019,145 +1025,115 @@ yytnamerr (char *yyres, const char *yystr)
- }
- # endif
- 
--/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
--   about the unexpected token YYTOKEN for the state stack whose top is
--   YYSSP.
--
--   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
--   not large enough to hold the message.  In that case, also set
--   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
--   required number of bytes is too large to store.  */
--static int
--yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
--                yytype_int16 *yyssp, int yytoken)
-+/* Copy into YYRESULT an error message about the unexpected token
-+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
-+   including the terminating null byte.  If YYRESULT is null, do not
-+   copy anything; just return the number of bytes that would be
-+   copied.  As a special case, return 0 if an ordinary "syntax error"
-+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
-+   size calculation.  */
-+static YYSIZE_T
-+yysyntax_error (char *yyresult, int yystate, int yychar)
- {
--  YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
--  YYSIZE_T yysize = yysize0;
--  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
--  /* Internationalized format string. */
--  const char *yyformat = YY_NULL;
--  /* Arguments of yyformat. */
--  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
--  /* Number of reported tokens (one for the "unexpected", one per
--     "expected"). */
--  int yycount = 0;
--
--  /* There are many possibilities here to consider:
--     - Assume YYFAIL is not used.  It's too flawed to consider.  See
--       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
--       for details.  YYERROR is fine as it does not invoke this
--       function.
--     - If this state is a consistent state with a default action, then
--       the only way this function was invoked is if the default action
--       is an error action.  In that case, don't check for expected
--       tokens because there are none.
--     - The only way there can be no lookahead present (in yychar) is if
--       this state is a consistent state with a default action.  Thus,
--       detecting the absence of a lookahead is sufficient to determine
--       that there is no unexpected or expected token to report.  In that
--       case, just report a simple "syntax error".
--     - Don't assume there isn't a lookahead just because this state is a
--       consistent state with a default action.  There might have been a
--       previous inconsistent state, consistent state with a non-default
--       action, or user semantic action that manipulated yychar.
--     - Of course, the expected token list depends on states to have
--       correct lookahead information, and it depends on the parser not
--       to perform extra reductions after fetching a lookahead from the
--       scanner and before detecting a syntax error.  Thus, state merging
--       (from LALR or IELR) and default reductions corrupt the expected
--       token list.  However, the list is correct for canonical LR with
--       one exception: it will still contain any token that will not be
--       accepted due to an error action in a later state.
--  */
--  if (yytoken != YYEMPTY)
--    {
--      int yyn = yypact[*yyssp];
--      yyarg[yycount++] = yytname[yytoken];
--      if (!yypact_value_is_default (yyn))
--        {
--          /* Start YYX at -YYN if negative to avoid negative indexes in
--             YYCHECK.  In other words, skip the first -YYN actions for
--             this state because they are default actions.  */
--          int yyxbegin = yyn < 0 ? -yyn : 0;
--          /* Stay within bounds of both yycheck and yytname.  */
--          int yychecklim = YYLAST - yyn + 1;
--          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
--          int yyx;
--
--          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
--            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
--                && !yytable_value_is_error (yytable[yyx + yyn]))
--              {
--                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
--                  {
--                    yycount = 1;
--                    yysize = yysize0;
--                    break;
--                  }
--                yyarg[yycount++] = yytname[yyx];
--                {
--                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
--                  if (! (yysize <= yysize1
--                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
--                    return 2;
--                  yysize = yysize1;
--                }
--              }
--        }
--    }
-+  int yyn = yypact[yystate];
- 
--  switch (yycount)
-+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-+    return 0;
-+  else
-     {
--# define YYCASE_(N, S)                      \
--      case N:                               \
--        yyformat = S;                       \
--      break
--      YYCASE_(0, YY_("syntax error"));
--      YYCASE_(1, YY_("syntax error, unexpected %s"));
--      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
--      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
--      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
--      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
--# undef YYCASE_
--    }
-+      int yytype = YYTRANSLATE (yychar);
-+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
-+      YYSIZE_T yysize = yysize0;
-+      YYSIZE_T yysize1;
-+      int yysize_overflow = 0;
-+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-+      int yyx;
-+
-+# if 0
-+      /* This is so xgettext sees the translatable formats that are
-+	 constructed on the fly.  */
-+      YY_("syntax error, unexpected %s");
-+      YY_("syntax error, unexpected %s, expecting %s");
-+      YY_("syntax error, unexpected %s, expecting %s or %s");
-+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
-+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-+# endif
-+      char *yyfmt;
-+      char const *yyf;
-+      static char const yyunexpected[] = "syntax error, unexpected %s";
-+      static char const yyexpecting[] = ", expecting %s";
-+      static char const yyor[] = " or %s";
-+      char yyformat[sizeof yyunexpected
-+		    + sizeof yyexpecting - 1
-+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
-+		       * (sizeof yyor - 1))];
-+      char const *yyprefix = yyexpecting;
-+
-+      /* Start YYX at -YYN if negative to avoid negative indexes in
-+	 YYCHECK.  */
-+      int yyxbegin = yyn < 0 ? -yyn : 0;
-+
-+      /* Stay within bounds of both yycheck and yytname.  */
-+      int yychecklim = YYLAST - yyn + 1;
-+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-+      int yycount = 1;
-+
-+      yyarg[0] = yytname[yytype];
-+      yyfmt = yystpcpy (yyformat, yyunexpected);
-+
-+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-+	  {
-+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-+	      {
-+		yycount = 1;
-+		yysize = yysize0;
-+		yyformat[sizeof yyunexpected - 1] = '\0';
-+		break;
-+	      }
-+	    yyarg[yycount++] = yytname[yyx];
-+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-+	    yysize_overflow |= (yysize1 < yysize);
-+	    yysize = yysize1;
-+	    yyfmt = yystpcpy (yyfmt, yyprefix);
-+	    yyprefix = yyor;
-+	  }
- 
--  {
--    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
--    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
--      return 2;
--    yysize = yysize1;
--  }
-+      yyf = YY_(yyformat);
-+      yysize1 = yysize + yystrlen (yyf);
-+      yysize_overflow |= (yysize1 < yysize);
-+      yysize = yysize1;
- 
--  if (*yymsg_alloc < yysize)
--    {
--      *yymsg_alloc = 2 * yysize;
--      if (! (yysize <= *yymsg_alloc
--             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
--        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
--      return 1;
--    }
-+      if (yysize_overflow)
-+	return YYSIZE_MAXIMUM;
- 
--  /* Avoid sprintf, as that infringes on the user's name space.
--     Don't have undefined behavior even if the translation
--     produced a string with the wrong number of "%s"s.  */
--  {
--    char *yyp = *yymsg;
--    int yyi = 0;
--    while ((*yyp = *yyformat) != '\0')
--      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
--        {
--          yyp += yytnamerr (yyp, yyarg[yyi++]);
--          yyformat += 2;
--        }
--      else
--        {
--          yyp++;
--          yyformat++;
--        }
--  }
--  return 0;
-+      if (yyresult)
-+	{
-+	  /* Avoid sprintf, as that infringes on the user's name space.
-+	     Don't have undefined behavior even if the translation
-+	     produced a string with the wrong number of "%s"s.  */
-+	  char *yyp = yyresult;
-+	  int yyi = 0;
-+	  while ((*yyp = *yyf) != '\0')
-+	    {
-+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
-+		{
-+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
-+		  yyf += 2;
-+		}
-+	      else
-+		{
-+		  yyp++;
-+		  yyf++;
-+		}
-+	    }
-+	}
-+      return yysize;
-+    }
- }
- #endif /* YYERROR_VERBOSE */
-+
- 
- /*-----------------------------------------------.
- | Release the memory associated to this symbol.  |
-@@ -1190,16 +1166,32 @@ yydestruct (yymsg, yytype, yyvaluep, lexer, handlers)
-     {
- 
-       default:
--        break;
-+	break;
-     }
- }
- 
-+/* Prevent warnings from -Wmissing-prototypes.  */
-+#ifdef YYPARSE_PARAM
-+#if defined __STDC__ || defined __cplusplus
-+int yyparse (void *YYPARSE_PARAM);
-+#else
-+int yyparse ();
-+#endif
-+#else /* ! YYPARSE_PARAM */
-+#if defined __STDC__ || defined __cplusplus
-+int yyparse (yyscan_t lexer, struct TsConfigHandlers* handlers);
-+#else
-+int yyparse ();
-+#endif
-+#endif /* ! YYPARSE_PARAM */
-+
- 
- 
- 
--/*----------.
--| yyparse.  |
--`----------*/
-+
-+/*-------------------------.
-+| yyparse or yypush_parse.  |
-+`-------------------------*/
- 
- #ifdef YYPARSE_PARAM
- #if (defined __STDC__ || defined __C99__FUNC__ \
-@@ -1227,31 +1219,8 @@ yyparse (lexer, handlers)
- /* The lookahead symbol.  */
- int yychar;
- 
--
--#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
--/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
--# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
--    _Pragma ("GCC diagnostic push") \
--    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
--    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
--# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
--    _Pragma ("GCC diagnostic pop")
--#else
--/* Default value used for initialization, for pacifying older GCCs
--   or non-GCC compilers.  */
--static YYSTYPE yyval_default;
--# define YY_INITIAL_VALUE(Value) = Value
--#endif
--#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
--# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
--# define YY_IGNORE_MAYBE_UNINITIALIZED_END
--#endif
--#ifndef YY_INITIAL_VALUE
--# define YY_INITIAL_VALUE(Value) /* Nothing. */
--#endif
--
- /* The semantic value of the lookahead symbol.  */
--YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
-+YYSTYPE yylval;
- 
-     /* Number of syntax errors so far.  */
-     int yynerrs;
-@@ -1264,7 +1233,7 @@ YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
-        `yyss': related to states.
-        `yyvs': related to semantic values.
- 
--       Refer to the stacks through separate pointers, to allow yyoverflow
-+       Refer to the stacks thru separate pointers, to allow yyoverflow
-        to reallocate them elsewhere.  */
- 
-     /* The state stack.  */
-@@ -1282,7 +1251,7 @@ YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
-   int yyn;
-   int yyresult;
-   /* Lookahead token as an internal (translated) token number.  */
--  int yytoken = 0;
-+  int yytoken;
-   /* The variables used to return semantic value and location from the
-      action routines.  */
-   YYSTYPE yyval;
-@@ -1300,8 +1269,9 @@ YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
-      Keep to zero when no symbol should be popped.  */
-   int yylen = 0;
- 
--  yyssp = yyss = yyssa;
--  yyvsp = yyvs = yyvsa;
-+  yytoken = 0;
-+  yyss = yyssa;
-+  yyvs = yyvsa;
-   yystacksize = YYINITDEPTH;
- 
-   YYDPRINTF ((stderr, "Starting parse\n"));
-@@ -1310,6 +1280,14 @@ YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
-   yyerrstatus = 0;
-   yynerrs = 0;
-   yychar = YYEMPTY; /* Cause a token to be read.  */
-+
-+  /* Initialize stack pointers.
-+     Waste one element of value and location stack
-+     so that they stay on the same level as the state stack.
-+     The wasted elements are never initialized.  */
-+  yyssp = yyss;
-+  yyvsp = yyvs;
-+
-   goto yysetstate;
- 
- /*------------------------------------------------------------.
-@@ -1401,7 +1379,7 @@ yybackup:
- 
-   /* First try to decide what to do without reference to lookahead token.  */
-   yyn = yypact[yystate];
--  if (yypact_value_is_default (yyn))
-+  if (yyn == YYPACT_NINF)
-     goto yydefault;
- 
-   /* Not known => get a lookahead token if don't already have one.  */
-@@ -1432,8 +1410,8 @@ yybackup:
-   yyn = yytable[yyn];
-   if (yyn <= 0)
-     {
--      if (yytable_value_is_error (yyn))
--        goto yyerrlab;
-+      if (yyn == 0 || yyn == YYTABLE_NINF)
-+	goto yyerrlab;
-       yyn = -yyn;
-       goto yyreduce;
-     }
-@@ -1450,9 +1428,7 @@ yybackup:
-   yychar = YYEMPTY;
- 
-   yystate = yyn;
--  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-   *++yyvsp = yylval;
--  YY_IGNORE_MAYBE_UNINITIALIZED_END
- 
-   goto yynewstate;
- 
-@@ -1489,81 +1465,81 @@ yyreduce:
-   switch (yyn)
-     {
-         case 4:
--/* Line 1792 of yacc.c  */
-+
-+/* Line 1455 of yacc.c  */
- #line 90 "TsConfigGrammar.y"
-     { HANDLE_EVENT(GroupOpen, (yyvsp[(1) - (1)])); }
-     break;
- 
-   case 5:
--/* Line 1792 of yacc.c  */
-+
-+/* Line 1455 of yacc.c  */
- #line 92 "TsConfigGrammar.y"
-     { HANDLE_EVENT(GroupClose, (yyvsp[(1) - (1)])); }
-     break;
- 
-   case 9:
--/* Line 1792 of yacc.c  */
-+
-+/* Line 1455 of yacc.c  */
- #line 96 "TsConfigGrammar.y"
-     { HANDLE_EVENT(GroupName, (yyvsp[(1) - (2)])); }
-     break;
- 
-   case 12:
--/* Line 1792 of yacc.c  */
-+
-+/* Line 1455 of yacc.c  */
- #line 100 "TsConfigGrammar.y"
-     { HANDLE_EVENT(ListOpen, (yyvsp[(1) - (1)])); }
-     break;
- 
-   case 13:
--/* Line 1792 of yacc.c  */
-+
-+/* Line 1455 of yacc.c  */
- #line 102 "TsConfigGrammar.y"
-     { HANDLE_EVENT(ListClose, (yyvsp[(1) - (1)])); }
-     break;
- 
-   case 17:
--/* Line 1792 of yacc.c  */
-+
-+/* Line 1455 of yacc.c  */
- #line 106 "TsConfigGrammar.y"
-     { HANDLE_EVENT(LiteralValue, (yyvsp[(1) - (1)])); }
-     break;
- 
-   case 27:
--/* Line 1792 of yacc.c  */
-+
-+/* Line 1455 of yacc.c  */
- #line 114 "TsConfigGrammar.y"
-     { HANDLE_EVENT(PathOpen, (yyvsp[(1) - (1)])); }
-     break;
- 
-   case 28:
--/* Line 1792 of yacc.c  */
-+
-+/* Line 1455 of yacc.c  */
- #line 116 "TsConfigGrammar.y"
-     { HANDLE_EVENT(PathClose, (yyvsp[(1) - (1)])); }
-     break;
- 
-   case 31:
--/* Line 1792 of yacc.c  */
-+
-+/* Line 1455 of yacc.c  */
- #line 120 "TsConfigGrammar.y"
-     { HANDLE_EVENT(PathTag, (yyvsp[(1) - (1)])); }
-     break;
- 
-   case 32:
--/* Line 1792 of yacc.c  */
-+
-+/* Line 1455 of yacc.c  */
- #line 120 "TsConfigGrammar.y"
-     { HANDLE_EVENT(PathIndex, (yyvsp[(1) - (1)])); }
-     break;
- 
- 
--/* Line 1792 of yacc.c  */
--#line 1554 "TsConfigGrammar.c"
-+
-+/* Line 1455 of yacc.c  */
-+#line 1541 "TsConfigGrammar.c"
-       default: break;
-     }
--  /* User semantic actions sometimes alter yychar, and that requires
--     that yytoken be updated with the new translation.  We take the
--     approach of translating immediately before every use of yytoken.
--     One alternative is translating here after every semantic action,
--     but that translation would be missed if the semantic action invokes
--     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
--     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
--     incorrect destructor might then be invoked immediately.  In the
--     case of YYERROR or YYBACKUP, subsequent parser actions might lead
--     to an incorrect destructor call or verbose syntax error message
--     before the lookahead is translated.  */
-   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
- 
-   YYPOPSTACK (yylen);
-@@ -1591,10 +1567,6 @@ yyreduce:
- | yyerrlab -- here on detecting error |
- `------------------------------------*/
- yyerrlab:
--  /* Make sure we have latest lookahead translation.  See comments at
--     user semantic actions for why this is necessary.  */
--  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
--
-   /* If not already recovering from an error, report this error.  */
-   if (!yyerrstatus)
-     {
-@@ -1602,36 +1574,37 @@ yyerrlab:
- #if ! YYERROR_VERBOSE
-       yyerror (lexer, handlers, YY_("syntax error"));
- #else
--# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
--                                        yyssp, yytoken)
-       {
--        char const *yymsgp = YY_("syntax error");
--        int yysyntax_error_status;
--        yysyntax_error_status = YYSYNTAX_ERROR;
--        if (yysyntax_error_status == 0)
--          yymsgp = yymsg;
--        else if (yysyntax_error_status == 1)
--          {
--            if (yymsg != yymsgbuf)
--              YYSTACK_FREE (yymsg);
--            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
--            if (!yymsg)
--              {
--                yymsg = yymsgbuf;
--                yymsg_alloc = sizeof yymsgbuf;
--                yysyntax_error_status = 2;
--              }
--            else
--              {
--                yysyntax_error_status = YYSYNTAX_ERROR;
--                yymsgp = yymsg;
--              }
--          }
--        yyerror (lexer, handlers, yymsgp);
--        if (yysyntax_error_status == 2)
--          goto yyexhaustedlab;
-+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
-+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
-+	  {
-+	    YYSIZE_T yyalloc = 2 * yysize;
-+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
-+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
-+	    if (yymsg != yymsgbuf)
-+	      YYSTACK_FREE (yymsg);
-+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
-+	    if (yymsg)
-+	      yymsg_alloc = yyalloc;
-+	    else
-+	      {
-+		yymsg = yymsgbuf;
-+		yymsg_alloc = sizeof yymsgbuf;
-+	      }
-+	  }
-+
-+	if (0 < yysize && yysize <= yymsg_alloc)
-+	  {
-+	    (void) yysyntax_error (yymsg, yystate, yychar);
-+	    yyerror (lexer, handlers, yymsg);
-+	  }
-+	else
-+	  {
-+	    yyerror (lexer, handlers, YY_("syntax error"));
-+	    if (yysize != 0)
-+	      goto yyexhaustedlab;
-+	  }
-       }
--# undef YYSYNTAX_ERROR
- #endif
-     }
- 
-@@ -1690,7 +1663,7 @@ yyerrlab1:
-   for (;;)
-     {
-       yyn = yypact[yystate];
--      if (!yypact_value_is_default (yyn))
-+      if (yyn != YYPACT_NINF)
- 	{
- 	  yyn += YYTERROR;
- 	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
-@@ -1713,9 +1686,7 @@ yyerrlab1:
-       YY_STACK_PRINT (yyss, yyssp);
-     }
- 
--  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-   *++yyvsp = yylval;
--  YY_IGNORE_MAYBE_UNINITIALIZED_END
- 
- 
-   /* Shift the error token.  */
-@@ -1739,7 +1710,7 @@ yyabortlab:
-   yyresult = 1;
-   goto yyreturn;
- 
--#if !defined yyoverflow || YYERROR_VERBOSE
-+#if !defined(yyoverflow) || YYERROR_VERBOSE
- /*-------------------------------------------------.
- | yyexhaustedlab -- memory exhaustion comes here.  |
- `-------------------------------------------------*/
-@@ -1751,13 +1722,8 @@ yyexhaustedlab:
- 
- yyreturn:
-   if (yychar != YYEMPTY)
--    {
--      /* Make sure we have latest lookahead translation.  See comments at
--         user semantic actions for why this is necessary.  */
--      yytoken = YYTRANSLATE (yychar);
--      yydestruct ("Cleanup: discarding lookahead",
--                  yytoken, &yylval, lexer, handlers);
--    }
-+     yydestruct ("Cleanup: discarding lookahead",
-+		 yytoken, &yylval, lexer, handlers);
-   /* Do not reclaim the symbols of the rule which action triggered
-      this YYABORT or YYACCEPT.  */
-   YYPOPSTACK (yylen);
-@@ -1781,8 +1747,10 @@ yyreturn:
- }
- 
- 
--/* Line 2055 of yacc.c  */
-+
-+/* Line 1675 of yacc.c  */
- #line 122 "TsConfigGrammar.y"
- 
- 
- # endif // __clang_analyzer__
-+
-diff --git a/lib/tsconfig/TsConfigGrammar.h b/lib/tsconfig/TsConfigGrammar.h
-index 52f083b..d3581d9 100644
---- a/lib/tsconfig/TsConfigGrammar.h
-+++ b/lib/tsconfig/TsConfigGrammar.h
-@@ -1,19 +1,21 @@
--/* A Bison parser, made by GNU Bison 2.7.  */
- 
--/* Bison interface for Yacc-like parsers in C
--
--      Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
-+/* A Bison parser, made by GNU Bison 2.4.1.  */
- 
-+/* Skeleton interface for Bison's Yacc-like parsers in C
-+   
-+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-+   Free Software Foundation, Inc.
-+   
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
--
-+   
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
--
-+   
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
- 
-@@ -26,21 +28,13 @@
-    special exception, which will cause the skeleton and the resulting
-    Bison output files to be licensed under the GNU General Public
-    License without this special exception.
--
-+   
-    This special exception was added by the Free Software Foundation in
-    version 2.2 of Bison.  */
- 
--#ifndef YY_TSCONFIG_TSCONFIGGRAMMAR_H_INCLUDED
--# define YY_TSCONFIG_TSCONFIGGRAMMAR_H_INCLUDED
--/* Enabling traces.  */
--#ifndef YYDEBUG
--# define YYDEBUG 0
--#endif
--#if YYDEBUG
--extern int tsconfigdebug;
--#endif
- /* "%code requires" blocks.  */
--/* Line 2058 of yacc.c  */
-+
-+/* Line 1676 of yacc.c  */
- #line 1 "TsConfigGrammar.y"
- 
- /** @file
-@@ -67,8 +61,9 @@ extern int tsconfigdebug;
-  */
- 
- 
--/* Line 2058 of yacc.c  */
--#line 72 "TsConfigGrammar.h"
-+
-+/* Line 1676 of yacc.c  */
-+#line 67 "TsConfigGrammar.h"
- 
- /* Tokens.  */
- #ifndef YYTOKENTYPE
-@@ -106,6 +101,7 @@ extern int tsconfigdebug;
- 
- 
- 
-+
- #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
- typedef int YYSTYPE;
- # define YYSTYPE_IS_TRIVIAL 1
-@@ -114,18 +110,5 @@ typedef int YYSTYPE;
- #endif
- 
- 
--#ifdef YYPARSE_PARAM
--#if defined __STDC__ || defined __cplusplus
--int tsconfigparse (void *YYPARSE_PARAM);
--#else
--int tsconfigparse ();
--#endif
--#else /* ! YYPARSE_PARAM */
--#if defined __STDC__ || defined __cplusplus
--int tsconfigparse (yyscan_t lexer, struct TsConfigHandlers* handlers);
--#else
--int tsconfigparse ();
--#endif
--#endif /* ! YYPARSE_PARAM */
- 
--#endif /* !YY_TSCONFIG_TSCONFIGGRAMMAR_H_INCLUDED  */
-+
-diff --git a/plugins/cacheurl/cacheurl.cc b/plugins/cacheurl/cacheurl.cc
-index 52565fc..d17c732 100644
---- a/plugins/cacheurl/cacheurl.cc
-+++ b/plugins/cacheurl/cacheurl.cc
-@@ -28,8 +28,8 @@
- #include "ts/ts.h"
- #include "ts/remap.h"
- #include "ink_defs.h"
-+#include "ink_memory.h"
- 
--#include <memory>
- #include <string>
- #include <vector>
- 
-@@ -205,7 +205,7 @@ load_config_file(const char *config_file)
-   char buffer[1024];
-   std::string path;
-   TSFile fh;
--  std::auto_ptr<pr_list> prl(new pr_list());
-+  ats_scoped_obj<pr_list> prl(new pr_list());
- 
-   /* locations in a config file line, end of line, split start, split end */
-   char *eol, *spstart, *spend;
-diff --git a/plugins/experimental/Makefile.am b/plugins/experimental/Makefile.am
-index 52fef44..adb6da8 100644
---- a/plugins/experimental/Makefile.am
-+++ b/plugins/experimental/Makefile.am
-@@ -19,6 +19,7 @@ SUBDIRS = \
-  background_fetch \
-  balancer \
-  buffer_upload \
-+ cache_promote \
-  cache_range_requests \
-  channel_stats \
-  collapsed_connection \
-@@ -38,6 +39,7 @@ SUBDIRS = \
-  ssl_cert_loader \
-  sslheaders \
-  stale_while_revalidate \
-+ stream_editor \
-  url_sig \
-  xdebug
- 
-diff --git a/plugins/experimental/cache_promote/Makefile.am b/plugins/experimental/cache_promote/Makefile.am
-new file mode 100644
-index 0000000..8170aed
---- /dev/null
-+++ b/plugins/experimental/cache_promote/Makefile.am
-@@ -0,0 +1,21 @@
-+#  Licensed to the Apache Software Foundation (ASF) under one
-+#  or more contributor license agreements.  See the NOTICE file
-+#  distributed with this work for additional information
-+#  regarding copyright ownership.  The ASF licenses this file
-+#  to you under the Apache License, Version 2.0 (the
-+#  "License"); you may not use this file except in compliance
-+#  with the License.  You may obtain a copy of the License at
-+#
-+#      http://www.apache.org/licenses/LICENSE-2.0
-+#
-+#  Unless required by applicable law or agreed to in writing, software
-+#  distributed under the License is distributed on an "AS IS" BASIS,
-+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+#  See the License for the specific language governing permissions and
-+#  limitations under the License.
-+
-+include $(top_srcdir)/build/plugins.mk
-+
-+pkglib_LTLIBRARIES = cache_promote.la
-+cache_promote_la_SOURCES = cache_promote.cc
-+cache_promote_la_LDFLAGS = $(TS_PLUGIN_LDFLAGS)
-diff --git a/plugins/experimental/cache_promote/README b/plugins/experimental/cache_promote/README
-new file mode 100644
-index 0000000..26d4500
---- /dev/null
-+++ b/plugins/experimental/cache_promote/README
-@@ -0,0 +1,30 @@
-+LRU Design
-+==========
-+
-+This got slightly complex, because I tried to be clever. But the concept is easy, a
-+list and an unordered map keeps the LRU state.
-+
-+
-+                                                    +-----------------------+    +----------------------------------+
-+                                                    |        LRUList        |    |              LRUMap              |
-+                                                    |        -------        |    |              ------              |
-+                                                    |+---------------------+|    |+--------------------------------+|
-++---------------------+   +---------------------+   ||      LRUEntry       <+----+| {LRUHash *, LRUList::iterator} ||
-+|       LRUHash       |   |      LRUEntry       |   |+---------------------+|    |+--------------------------------+|
-+|      --------       |<--+      --------       |<--+|      LRUEntry       <+----+| {LRUHash *, LRUList::iterator} ||
-+|  u_char _hash[20]   |   | <LRUHash, unsigned> |   |+---------------------+|    |+--------------------------------+|
-++---------------------+   +---------------------+   ||      LRUEntry       <+----+| {LRUHash *, LRUList::iterator} ||
-+                            +-----------------+     |+---------------------+|    |+--------------------------------+|
-+                            | first = LRUHash |     |                       |    |                                  |
-+                            |second = unsigned|     |           *           |    |                *                 |
-+                            +-----------------+     |           *           |    |                *                 |
-+                                                    |           *           |    |                *                 |
-+                                                    |                       |    |                                  |
-+                                                    |+---------------------+|    |+--------------------------------+|
-+                                                    ||      LRUEntry       ||    || {LRUHash *, LRUList::iterator} ||
-+                                                    |+---------------------+|    |+--------------------------------+|
-+                                                    +-----------------------+    +----------------------------------+
-+                                                                                     +--------------------------+
-+                                                                                     |    first  = LRUHash*     |
-+                                                                                     |second = LRUList::iterator|
-+                                                                                     +--------------------------+
-diff --git a/plugins/experimental/cache_promote/cache_promote.cc b/plugins/experimental/cache_promote/cache_promote.cc
-new file mode 100644
-index 0000000..c601927
---- /dev/null
-+++ b/plugins/experimental/cache_promote/cache_promote.cc
-@@ -0,0 +1,515 @@
-+/*
-+  Licensed to the Apache Software Foundation (ASF) under one
-+  or more contributor license agreements.  See the NOTICE file
-+  distributed with this work for additional information
-+  regarding copyright ownership.  The ASF licenses this file
-+  to you under the Apache License, Version 2.0 (the
-+  "License"); you may not use this file except in compliance
-+  with the License.  You may obtain a copy of the License at
-+
-+  http://www.apache.org/licenses/LICENSE-2.0
-+
-+  Unless required by applicable law or agreed to in writing, software
-+  distributed under the License is distributed on an "AS IS" BASIS,
-+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+  See the License for the specific language governing permissions and
-+  limitations under the License.
-+*/
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include <getopt.h>
-+#include <stdlib.h>
-+#include <time.h>
-+#include <openssl/sha.h>
-+
-+#include <string>
-+#include <unordered_map>
-+#include <list>
-+
-+#include "ts/ts.h"
-+#include "ts/remap.h"
-+#include "ts/ink_config.h"
-+
-+
-+static const char *PLUGIN_NAME = "cache_promote";
-+TSCont gNocacheCont;
-+
-+
-+//////////////////////////////////////////////////////////////////////////////////////////////
-+// Note that all options for all policies has to go here. Not particularly pretty...
-+//
-+static const struct option longopt[] = {{const_cast<char *>("policy"), required_argument, NULL, 'p'},
-+                                        // This is for both Chance and LRU (optional) policy
-+                                        {const_cast<char *>("sample"), required_argument, NULL, 's'},
-+                                        // For the LRU policy
-+                                        {const_cast<char *>("buckets"), required_argument, NULL, 'b'},
-+                                        {const_cast<char *>("hits"), required_argument, NULL, 'h'},
-+                                        // EOF
-+                                        {NULL, no_argument, NULL, '\0'}};
-+
-+
-+//////////////////////////////////////////////////////////////////////////////////////////////
-+// Abstract base class for all policies.
-+//
-+class PromotionPolicy
-+{
-+public:
-+  PromotionPolicy() : _sample(0.0)
-+  {
-+    // This doesn't have to be perfect, since this is just chance sampling.
-+    // coverity[dont_call]
-+    srand48((long)time(NULL));
-+  }
-+
-+  void
-+  setSample(char *s)
-+  {
-+    _sample = strtof(s, NULL) / 100.0;
-+  }
-+
-+  float
-+  getSample() const
-+  {
-+    return _sample;
-+  }
-+
-+  bool
-+  doSample() const
-+  {
-+    if (_sample > 0) {
-+      // coverity[dont_call]
-+      double r = drand48();
-+
-+      if (_sample > r) {
-+        TSDebug(PLUGIN_NAME, "checking sampling, is %f > %f? Yes!", _sample, r);
-+      } else {
-+        TSDebug(PLUGIN_NAME, "checking sampling, is %f > %f? No!", _sample, r);
-+        return false;
-+      }
-+    }
-+    return true;
-+  }
-+
-+  virtual ~PromotionPolicy(){};
-+
-+  virtual bool
-+  parseOption(int opt, char *optarg)
-+  {
-+    return false;
-+  }
-+
-+  // These are pure virtual
-+  virtual bool doPromote(TSHttpTxn txnp) = 0;
-+  virtual const char *policyName() const = 0;
-+  virtual void usage() const = 0;
-+
-+private:
-+  float _sample;
-+};
-+
-+
-+//////////////////////////////////////////////////////////////////////////////////////////////
-+// This is the simplest of all policies, just give each request a (small)
-+// percentage chance to be promoted to cache.
-+//
-+class ChancePolicy : public PromotionPolicy
-+{
-+public:
-+  bool doPromote(TSHttpTxn /* txnp ATS_UNUSED */)
-+  {
-+    TSDebug(PLUGIN_NAME, "ChancePolicy::doPromote(%f)", getSample());
-+    return true;
-+  }
-+
-+  void
-+  usage() const
-+  {
-+    TSError("[%s] Usage: @plugin=%s.so @pparam=--policy=chance @pparam=--sample=<x>%%", PLUGIN_NAME, PLUGIN_NAME);
-+  }
-+
-+  const char *
-+  policyName() const
-+  {
-+    return "chance";
-+  }
-+};
-+
-+
-+//////////////////////////////////////////////////////////////////////////////////////////////
-+// The LRU based policy keeps track of <bucket> number of URLs, with a counter for each slot.
-+// Objects are not promoted unless the counter reaches <hits> before it gets evicted. An
-+// optional <chance> parameter can be used to sample hits, this can reduce contention and
-+// churning in the LRU as well.
-+//
-+class LRUHash
-+{
-+  friend struct LRUHashHasher;
-+
-+public:
-+  LRUHash() { TSDebug(PLUGIN_NAME, "In LRUHash()"); }
-+
-+  ~LRUHash() { TSDebug(PLUGIN_NAME, "In ~LRUHash()"); }
-+
-+  LRUHash &operator=(const LRUHash &h)
-+  {
-+    TSDebug(PLUGIN_NAME, "copying an LRUHash object");
-+    memcpy(_hash, h._hash, sizeof(_hash));
-+    return *this;
-+  }
-+
-+  void
-+  init(char *data, int len)
-+  {
-+    SHA_CTX sha;
-+
-+    SHA1_Init(&sha);
-+    SHA1_Update(&sha, data, len);
-+    SHA1_Final(_hash, &sha);
-+  }
-+
-+private:
-+  u_char _hash[SHA_DIGEST_LENGTH];
-+};
-+
-+struct LRUHashHasher {
-+  bool operator()(const LRUHash *s1, const LRUHash *s2) const { return 0 == memcmp(s1->_hash, s2->_hash, sizeof(s2->_hash)); }
-+
-+  size_t operator()(const LRUHash *s) const { return *((size_t *)s->_hash) ^ *((size_t *)(s->_hash + 9)); }
-+};
-+
-+typedef std::pair<LRUHash, unsigned> LRUEntry;
-+typedef std::list<LRUEntry> LRUList;
-+typedef std::unordered_map<const LRUHash *, LRUList::iterator, LRUHashHasher, LRUHashHasher> LRUMap;
-+
-+static LRUEntry NULL_LRU_ENTRY; // Used to create an "empty" new LRUEntry
-+
-+class LRUPolicy : public PromotionPolicy
-+{
-+public:
-+  LRUPolicy() : PromotionPolicy(), _buckets(1000), _hits(10), _lock(TSMutexCreate()) {}
-+
-+  ~LRUPolicy()
-+  {
-+    TSDebug(PLUGIN_NAME, "deleting LRUPolicy object");
-+    TSMutexLock(_lock);
-+
-+    _map.clear();
-+    _list.clear();
-+    _freelist.clear();
-+
-+    TSMutexUnlock(_lock);
-+    TSMutexDestroy(_lock);
-+  }
-+
-+  bool
-+  parseOption(int opt, char *optarg)
-+  {
-+    switch (opt) {
-+    case 'b':
-+      _buckets = static_cast<unsigned>(strtol(optarg, NULL, 10));
-+      break;
-+    case 'h':
-+      _hits = static_cast<unsigned>(strtol(optarg, NULL, 10));
-+      break;
-+    default:
-+      // All other options are unsupported for this policy
-+      return false;
-+    }
-+
-+    // This doesn't have to be perfect, since this is just chance sampling.
-+    // coverity[dont_call]
-+    srand48((long)time(NULL) ^ (long)getpid() ^ (long)getppid());
-+
-+    return true;
-+  }
-+
-+  bool
-+  doPromote(TSHttpTxn txnp)
-+  {
-+    LRUHash hash;
-+    LRUMap::iterator map_it;
-+    int url_len = 0;
-+    char *url = TSHttpTxnEffectiveUrlStringGet(txnp, &url_len);
-+    bool ret = false;
-+
-+    // Generally shouldn't happen ...
-+    if (!url) {
-+      return false;
-+    }
-+
-+    TSDebug(PLUGIN_NAME, "LRUPolicy::doPromote(%.*s ...)", url_len > 30 ? 30 : url_len, url);
-+    hash.init(url, url_len);
-+    TSfree(url);
-+
-+    // We have to hold the lock across all list and hash access / updates
-+    TSMutexLock(_lock);
-+
-+    map_it = _map.find(&hash);
-+    if (_map.end() != map_it) {
-+      // We have an entry in the LRU
-+      if (++(map_it->second->second) >= _hits) {
-+        // Promoted! Cleanup the LRU, and signal success. Save the promoted entry on the freelist.
-+        TSDebug(PLUGIN_NAME, "saving the LRUEntry to the freelist");
-+        _freelist.splice(_freelist.begin(), _list, map_it->second);
-+        _map.erase(map_it->first);
-+        ret = true;
-+      } else {
-+        // It's still not promoted, make sure it's moved to the front of the list
-+        TSDebug(PLUGIN_NAME, "still not promoted, got %d hits so far", map_it->second->second);
-+        _list.splice(_list.begin(), _list, map_it->second);
-+      }
-+    } else {
-+      // New LRU entry for the URL, try to repurpose the list entry as much as possible
-+      if (_list.size() >= _buckets) {
-+        TSDebug(PLUGIN_NAME, "repurposing last LRUHash entry");
-+        _list.splice(_list.begin(), _list, --_list.end());
-+        _map.erase(&(_list.begin()->first));
-+      } else if (_freelist.size() > 0) {
-+        TSDebug(PLUGIN_NAME, "reusing LRUEntry from freelist");
-+        _list.splice(_list.begin(), _freelist, _freelist.begin());
-+      } else {
-+        TSDebug(PLUGIN_NAME, "creating new LRUEntry");
-+        _list.push_front(NULL_LRU_ENTRY);
-+      }
-+      // Update the "new" LRUEntry and add it to the hash
-+      _list.begin()->first = hash;
-+      _list.begin()->second = 1;
-+      _map[&(_list.begin()->first)] = _list.begin();
-+    }
-+
-+    TSMutexUnlock(_lock);
-+
-+    return ret;
-+  }
-+
-+  void
-+  usage() const
-+  {
-+    TSError("[%s] Usage: @plugin=%s.so @pparam=--policy=lru @pparam=--buckets=<n> --hits=<m> --sample=<x>", PLUGIN_NAME,
-+            PLUGIN_NAME);
-+  }
-+
-+  const char *
-+  policyName() const
-+  {
-+    return "LRU";
-+  }
-+
-+private:
-+  unsigned _buckets;
-+  unsigned _hits;
-+  // For the LRU
-+  TSMutex _lock;
-+  LRUMap _map;
-+  LRUList _list, _freelist;
-+};
-+
-+
-+//////////////////////////////////////////////////////////////////////////////////////////////
-+// This holds the configuration for a remap rule, as well as parses the configurations.
-+//
-+class PromotionConfig
-+{
-+public:
-+  PromotionConfig() : _policy(NULL) {}
-+
-+  ~PromotionConfig() { delete _policy; }
-+
-+  PromotionPolicy *
-+  getPolicy() const
-+  {
-+    return _policy;
-+  }
-+
-+  // Parse the command line arguments to the plugin, and instantiate the appropriate policy
-+  bool
-+  factory(int argc, char *argv[])
-+  {
-+    optind = 0;
-+    while (true) {
-+      int opt = getopt_long(argc, (char *const *)argv, "psbh", longopt, NULL);
-+
-+      if (opt == -1) {
-+        break;
-+      } else if (opt == 'p') {
-+        if (0 == strncasecmp(optarg, "chance", 6)) {
-+          _policy = new ChancePolicy();
-+        } else if (0 == strncasecmp(optarg, "lru", 3)) {
-+          _policy = new LRUPolicy();
-+        } else {
-+          TSError("[%s] Unknown policy --policy=%s", PLUGIN_NAME, optarg);
-+          return false;
-+        }
-+        if (_policy) {
-+          TSDebug(PLUGIN_NAME, "created remap with cache promotion policy = %s", _policy->policyName());
-+        }
-+      } else {
-+        if (_policy) {
-+          // The --sample (-s) option is allowed for all configs, but only after --policy is specified.
-+          if (opt == 's') {
-+            _policy->setSample(optarg);
-+          } else {
-+            if (!_policy->parseOption(opt, optarg)) {
-+              TSError("[%s] The specified policy (%s) does not support the -%c option", PLUGIN_NAME, _policy->policyName(), opt);
-+              delete _policy;
-+              _policy = NULL;
-+              return false;
-+            }
-+          }
-+        } else {
-+          TSError("[%s] The --policy=<n> parameter must come first on the remap configuration", PLUGIN_NAME);
-+          return false;
-+        }
-+      }
-+    }
-+
-+    return true;
-+  }
-+
-+private:
-+  PromotionPolicy *_policy;
-+};
-+
-+
-+//////////////////////////////////////////////////////////////////////////////////////////////
-+// Little helper continuation, to turn off writing to the cache. ToDo: when we have proper
-+// APIs to make requests / responses, we can remove this completely.
-+static int
-+cont_nocache_response(TSCont contp, TSEvent event, void *edata)
-+{
-+  TSHttpTxn txnp = static_cast<TSHttpTxn>(edata);
-+
-+  TSHttpTxnServerRespNoStoreSet(txnp, 1);
-+  // Reenable and continue with the state machine.
-+  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
-+  return 0;
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////////////////////
-+// Main "plugin", a TXN hook in the TS_HTTP_READ_CACHE_HDR_HOOK. Unless the policy allows
-+// caching, we will turn off the cache from here on for the TXN.
-+//
-+// NOTE: This is not optimal, the goal was to handle this before we lock the URL in the
-+// cache. However, that does not work. Hence, for now, we also schedule the continuation
-+// for READ_RESPONSE_HDR such that we can turn off  the actual cache write.
-+//
-+static int
-+cont_handle_policy(TSCont contp, TSEvent event, void *edata)
-+{
-+  TSHttpTxn txnp = static_cast<TSHttpTxn>(edata);
-+  PromotionConfig *config = static_cast<PromotionConfig *>(TSContDataGet(contp));
-+
-+  switch (event) {
-+  // Main HOOK
-+  case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE:
-+    if (TS_SUCCESS != TSHttpIsInternalRequest(txnp)) {
-+      int obj_status;
-+
-+      if (TS_ERROR != TSHttpTxnCacheLookupStatusGet(txnp, &obj_status)) {
-+        switch (obj_status) {
-+        case TS_CACHE_LOOKUP_MISS:
-+        case TS_CACHE_LOOKUP_SKIPPED:
-+          if (config->getPolicy()->doSample() && config->getPolicy()->doPromote(txnp)) {
-+            TSDebug(PLUGIN_NAME, "cache-status is %d, and leaving cache on (promoted)", obj_status);
-+          } else {
-+            TSDebug(PLUGIN_NAME, "cache-status is %d, and turning off the cache (not promoted)", obj_status);
-+            TSHttpTxnHookAdd(txnp, TS_HTTP_READ_RESPONSE_HDR_HOOK, gNocacheCont);
-+          }
-+          break;
-+        default:
-+          // Do nothing, just let it handle the lookup.
-+          TSDebug(PLUGIN_NAME, "cache-status is %d (hit), nothing to do", obj_status);
-+          break;
-+        }
-+      }
-+    } else {
-+      TSDebug(PLUGIN_NAME, "Request is an internal (plugin) request, implicitly promoted");
-+    }
-+    break;
-+
-+  // Should not happen
-+  default:
-+    TSDebug(PLUGIN_NAME, "Unhandled event %d", (int)event);
-+    break;
-+  }
-+
-+  // Reenable and continue with the state machine.
-+  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
-+  return 0;
-+}
-+
-+
-+//////////////////////////////////////////////////////////////////////////////////////////////
-+// Initialize the plugin as a remap plugin.
-+//
-+TSReturnCode
-+TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size)
-+{
-+  if (api_info->size < sizeof(TSRemapInterface)) {
-+    strncpy(errbuf, "[tsremap_init] - Incorrect size of TSRemapInterface structure", errbuf_size - 1);
-+    return TS_ERROR;
-+  }
-+
-+  if (api_info->tsremap_version < TSREMAP_VERSION) {
-+    snprintf(errbuf, errbuf_size - 1, "[tsremap_init] - Incorrect API version %ld.%ld", api_info->tsremap_version >> 16,
-+             (api_info->tsremap_version & 0xffff));
-+    return TS_ERROR;
-+  }
-+
-+  gNocacheCont = TSContCreate(cont_nocache_response, NULL);
-+
-+  TSDebug(PLUGIN_NAME, "remap plugin is successfully initialized");
-+  return TS_SUCCESS; /* success */
-+}
-+
-+
-+TSReturnCode
-+TSRemapNewInstance(int argc, char *argv[], void **ih, char * /* errbuf */, int /* errbuf_size */)
-+{
-+  PromotionConfig *config = new PromotionConfig;
-+
-+  --argc;
-+  ++argv;
-+  if (config->factory(argc, argv)) {
-+    TSCont contp = TSContCreate(cont_handle_policy, NULL);
-+
-+    TSContDataSet(contp, static_cast<void *>(config));
-+    *ih = static_cast<void *>(contp);
-+
-+    return TS_SUCCESS;
-+  } else {
-+    delete config;
-+    return TS_ERROR;
-+  }
-+}
-+
-+void
-+TSRemapDeleteInstance(void *ih)
-+{
-+  TSCont contp = static_cast<TSCont>(ih);
-+  PromotionConfig *config = static_cast<PromotionConfig *>(TSContDataGet(contp));
-+
-+  delete config;
-+  TSContDestroy(contp);
-+}
-+
-+
-+//////////////////////////////////////////////////////////////////////////////////////////////
-+// Schedule the cache-read continuation for this remap rule.
-+//
-+TSRemapStatus
-+TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo * /* ATS_UNUSED rri */)
-+{
-+  if (NULL == ih) {
-+    TSDebug(PLUGIN_NAME, "No promotion rules configured, this is probably a plugin bug");
-+  } else {
-+    TSCont contp = static_cast<TSCont>(ih);
-+
-+    TSDebug(PLUGIN_NAME, "scheduling a TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK hook");
-+    TSHttpTxnHookAdd(rh, TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, contp);
-+  }
-+
-+  return TSREMAP_NO_REMAP;
-+}
-diff --git a/plugins/experimental/money_trace/Makefile.am b/plugins/experimental/money_trace/Makefile.am
-new file mode 100644
-index 0000000..d63485f
---- /dev/null
-+++ b/plugins/experimental/money_trace/Makefile.am
-@@ -0,0 +1,22 @@
-+#  Licensed to the Apache Software Foundation (ASF) under one
-+#  or more contributor license agreements.  See the NOTICE file
-+#  distributed with this work for additional information
-+#  regarding copyright ownership.  The ASF licenses this file
-+#  to you under the Apache License, Version 2.0 (the
-+#  "License"); you may not use this file except in compliance
-+#  with the License.  You may obtain a copy of the License at
-+#
-+#      http://www.apache.org/licenses/LICENSE-2.0
-+#
-+#  Unless required by applicable law or agreed to in writing, software
-+#  distributed under the License is distributed on an "AS IS" BASIS,
-+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+#  See the License for the specific language governing permissions and
-+#  limitations under the License.
-+
-+include $(top_srcdir)/build/plugins.mk
-+
-+pkglib_LTLIBRARIES = money_trace.la
-+money_trace_la_SOURCES = money_trace.cc 
-+money_trace_la_LDFLAGS = $(TS_PLUGIN_LDFLAGS)
-+
-diff --git a/plugins/experimental/money_trace/README b/plugins/experimental/money_trace/README
-new file mode 100644
-index 0000000..a495897
---- /dev/null
-+++ b/plugins/experimental/money_trace/README
-@@ -0,0 +1,8 @@
-+
-+Author: John J. Rushford, John_Rushford@cable.comcast.com
-+
-+Money trace plugin 
-+  This is a remap plugin used to add and update a "X-MoneyTrace" used to trace and monitor http transactions in support system logs.
-+
-+See the documentation on this header at https://github.com/Comcast/money/wiki.
-+
-diff --git a/plugins/experimental/money_trace/money_trace.cc b/plugins/experimental/money_trace/money_trace.cc
-new file mode 100644
-index 0000000..adb8980
---- /dev/null
-+++ b/plugins/experimental/money_trace/money_trace.cc
-@@ -0,0 +1,365 @@
-+/*
-+ * Licensed to the Apache Software Foundation (ASF) under one
-+ * or more contributor license agreements.  See the NOTICE file
-+ * distributed with this work for additional information
-+ * regarding copyright ownership.  The ASF licenses this file
-+ * to you under the Apache License, Version 2.0 (the "License");
-+ * you may not use this file except in compliance with the
-+ * License.  You may obtain a copy of the License at
-+ *
-+ *     http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * Unless required by applicable law or agreed to in writing,
-+ * software distributed under the License is distributed on an
-+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-+ * KIND, either express or implied.  See the License for the
-+ * specific language governing permissions and limitations
-+ * under the License.
-+ */
-+
-+/*
-+ * This plugin looks for range requests and then creates a new
-+ * cache key url so that each individual range requests is written
-+ * to the cache as a individual object so that subsequent range
-+ * requests are read accross different disk drives reducing I/O
-+ * wait and load averages when there are large numbers of range
-+ * requests.
-+ */
-+
-+#include <iostream>
-+#include <sstream>
-+#include <stdio.h>
-+#include <string.h>
-+#include "ts/ts.h"
-+#include "ts/remap.h"
-+
-+#include "money_trace.h"
-+
-+/**
-+ * Allocate transaction data structure.
-+ */
-+static struct txndata *
-+allocTransactionData()
-+{
-+  LOG_DEBUG("allocating transaction state data.");
-+  struct txndata *txn_data = (struct txndata *)TSmalloc(sizeof(struct txndata));
-+  txn_data->client_request_mt_header = NULL;
-+  txn_data->new_span_mt_header = NULL;
-+  return txn_data;
-+}
-+
-+/**
-+ * free any previously allocated transaction data.
-+ */
-+static void
-+freeTransactionData(struct txndata *txn_data)
-+{
-+  LOG_DEBUG("de-allocating transaction state data.");
-+  if (txn_data->client_request_mt_header != NULL) {
-+    LOG_DEBUG("freeing txn_data->client_request_mt_header");
-+    TSfree(txn_data->client_request_mt_header);
-+  }
-+  if (txn_data->new_span_mt_header != NULL) {
-+    LOG_DEBUG("freeing txn_data->new_span_mt_header.");
-+    TSfree(txn_data->new_span_mt_header);
-+  }
-+  if (txn_data != NULL) {
-+    LOG_DEBUG("freeing txn_data.");
-+    TSfree(txn_data);
-+  }
-+}
-+
-+/**
-+ * The TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE event callback.
-+ * 
-+ * If there is a cache hit only schedule a TS_HTTP_SEND_RESPONSE_HDR_HOOK
-+ * continuation to send back the money trace header in the response to the
-+ * client.
-+ *
-+ * If there is a cache miss, a new money trace header is created and a
-+ * TS_HTTP_SEND_REQUES_HDR_HOOK continuation is scheduled to add the
-+ * new mon

<TRUNCATED>