You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by rr...@apache.org on 2019/06/13 18:43:10 UTC
[trafficserver] 02/02: Moves Errata to tscore,
removes tsconfig library
This is an automated email from the ASF dual-hosted git repository.
rrm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 5051e29982dda7ae5627bf6408158b9de3462385
Author: Randall Meyer <rr...@apache.org>
AuthorDate: Mon Jun 10 09:38:09 2019 -0700
Moves Errata to tscore, removes tsconfig library
---
CMakeLists.txt | 1 -
README | 1 -
ci/rat-regex.txt | 1 -
configure.ac | 1 -
doc/Doxyfile | 1 -
example/Makefile.am | 3 -
include/tscore/Errata.h | 1020 +++++++++++++++++++++++
{lib/tsconfig => include/tscore}/IntrusivePtr.h | 99 +--
include/tscore/MemArena.h | 2 +-
{lib/tsconfig => include/tscore}/NumericType.h | 0
include/tscore/TsBuffer.h | 3 -
include/wccp/Wccp.h | 5 +-
iocore/cache/Makefile.am | 2 -
iocore/net/Makefile.am | 4 -
iocore/net/YamlSNIConfig.cc | 2 +-
iocore/net/YamlSNIConfig.h | 2 +-
lib/Makefile.am | 2 +-
lib/tsconfig/Errata.h | 929 ---------------------
lib/tsconfig/Makefile.am | 40 -
mgmt/utils/Makefile.am | 1 -
src/traffic_cache_tool/CacheDefs.h | 6 +-
src/traffic_cache_tool/Makefile.inc | 2 +-
src/traffic_manager/Makefile.inc | 1 -
src/traffic_server/Makefile.inc | 1 -
src/traffic_wccp/Makefile.inc | 1 -
src/traffic_wccp/wccp_client.cc | 2 +-
{lib/tsconfig => src/tscore}/Errata.cc | 188 +++--
src/tscore/Makefile.am | 1 +
src/tscore/unit_tests/test_IntrusivePtr.cc | 3 +-
src/wccp/WccpLocal.h | 2 +-
src/wccp/WccpUtil.h | 2 +-
tools/git/pre-commit | 2 +-
32 files changed, 1176 insertions(+), 1154 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 68504fb..49e861b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -110,7 +110,6 @@ CPP_ADD_SOURCES(mgmt mgmt/utils)
CPP_LIB(records lib/records lib/records)
CPP_LIB(logging proxy/logging proxy/logging)
-CPP_LIB(tsconfig lib/tsconfig lib/tsconfig)
CPP_LIB(wccp src/wccp include/wccp)
file(GLOB plugin_files
diff --git a/README b/README
index 707c767..42b18c4 100644
--- a/README
+++ b/README
@@ -32,7 +32,6 @@ plugins to build large scale web applications.
|-- perl/ ............. Perl libraries for e.g. mgmt access and configurations
|-- records/ .......... Library for config files
|-- ts/ ............... Base / core library
- |-- tsconfig/.......... New config parser and library (experimental)
|-- wccp/ ............. WCCP implementation
|-- yamlcpp/ .......... Library for YAML of C++
|-- mgmt/ ................. Management server and tools
diff --git a/ci/rat-regex.txt b/ci/rat-regex.txt
index 2e87adb..32b0f3f 100644
--- a/ci/rat-regex.txt
+++ b/ci/rat-regex.txt
@@ -19,7 +19,6 @@
.*\.json$
.*\.yaml$
.*\.md$
-.*\.tsconfig$
.*\.default$
.*\.default\.in$
.*\.config$
diff --git a/configure.ac b/configure.ac
index 062437b..1267cec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2046,7 +2046,6 @@ AC_CONFIG_FILES([
lib/records/Makefile
include/ts/apidefs.h
include/tscore/ink_config.h
- lib/tsconfig/Makefile
src/wccp/Makefile
lib/yamlcpp/Makefile
mgmt/Makefile
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 526d744..39aca55 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -750,7 +750,6 @@ INPUT = mainpage.doc \
../lib/cppapi/include/atscppapi \
../lib/records \
../lib/ts \
- ../lib/tsconfig \
../proxy
# This tag can be used to specify the character encoding of the source files
diff --git a/example/Makefile.am b/example/Makefile.am
index 875d808..f81b9ef 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -21,7 +21,6 @@ AM_CXXFLAGS += -Wno-unused-variable
AM_LDFLAGS = $(TS_PLUGIN_LD_FLAGS)
libtscppapi = $(top_builddir)/src/tscpp/api/libtscppapi.la
-libtsconfig = $(top_builddir)/lib/tsconfig/libtsconfig.la
if BUILD_EXAMPLE_PLUGINS
@@ -127,9 +126,7 @@ server_push_la_SOURCES = server_push/server_push.c
server_transform_la_SOURCES = server_transform/server_transform.c
ssl_preaccept_la_SOURCES = ssl_preaccept/ssl_preaccept.cc
ssl_sni_la_SOURCES = ssl_sni/ssl_sni.cc
-ssl_sni_la_LIBADD = $(libtsconfig)
ssl_sni_whitelist_la_SOURCES = ssl_sni_whitelist/ssl_sni_whitelist.cc
-ssl_sni_whitelist_la_LIBADD = $(libtsconfig)
disable_http2_la_SOURCES = disable_http2/disable_http2.cc
verify_cert_la_SOURCES = verify_cert/verify_cert.cc
statistic_la_SOURCES = statistic/statistic.cc
diff --git a/include/tscore/Errata.h b/include/tscore/Errata.h
new file mode 100644
index 0000000..6bc5e3a
--- /dev/null
+++ b/include/tscore/Errata.h
@@ -0,0 +1,1020 @@
+/** @file
+ Stacking error message handling.
+
+ The problem addressed by this library is the ability to pass back
+ detailed error messages from failures. It is hard to get good
+ diagnostics because the specific failures and general context are
+ located in very different stack frames. This library allows local
+ functions to pass back local messages which can be easily
+ augmented as the error travels up the stack frame.
+
+ This could be done with exceptions but
+ - That is more effort to implemention
+ - Generally more expensive.
+
+ Each message on a stack contains text and a numeric identifier.
+ The identifier value zero is reserved for messages that are not
+ errors so that information can be passed back even in the success
+ case.
+
+ The implementation takes the position that success is fast and
+ failure is expensive. Therefore it is optimized for the success
+ path, imposing very little overhead. On the other hand, if an
+ error occurs and is handled, that is generally so expensive that
+ optimizations are pointless (although, of course, one should not
+ be gratuitiously expensive).
+
+ The library also provides the @c Rv ("return value") template to
+ make returning values and status easier. This template allows a
+ function to return a value and status pair with minimal changes.
+ The pair acts like the value type in most situations, while
+ providing access to the status.
+
+ Each instance of an erratum is a wrapper class that emulates value
+ semantics (copy on write). This means passing even large message
+ stacks is inexpensive, involving only a pointer copy and reference
+ counter increment and decrement. A success value is represented by
+ an internal @c NULL so it is even cheaper to copy.
+
+ To further ease use, the library has the ability to define @a
+ sinks. A sink is a function that acts on an erratum when it
+ becomes unreferenced. The indended use is to send the messages to
+ an output log. This makes reporting errors to a log from even
+ deeply nested functions easy while preserving the ability of the
+ top level logic to control such logging.
+
+ @section license License
+
+ 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.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include <iosfwd>
+#include <sstream>
+#include <deque>
+#include "NumericType.h"
+#include "IntrusivePtr.h"
+
+namespace ts
+{
+/** Class to hold a stack of error messages (the "errata").
+ This is a smart handle class, which wraps the actual data
+ and can therefore be treated a value type with cheap copy
+ semantics. Default construction is very cheap.
+ */
+class Errata
+{
+protected:
+ /// Implementation class.
+ struct Data;
+ /// Handle for implementation class instance.
+ typedef IntrusivePtr<Data> ImpPtr;
+
+public:
+ typedef Errata self; /// Self reference type.
+
+ /// Message ID.
+ typedef NumericType<unsigned int, struct MsgIdTag> Id;
+
+ /* Tag / level / code severity.
+ This is intended for clients to use to provide additional
+ classification of a message. A severity code, as for syslog,
+ is a common use.
+
+ */
+ typedef NumericType<unsigned int, struct CodeTag> Code;
+ struct Message;
+
+ typedef std::deque<Message> Container; ///< Storage type for messages.
+ // We iterate backwards to look like a stack.
+ // typedef Container::reverse_iterator iterator; ///< Message iteration.
+ /// Message const iteration.
+ // typedef Container::const_reverse_iterator const_iterator;
+ /// Reverse message iteration.
+ // typedef Container::iterator reverse_iterator;
+ /// Reverse constant message iteration.
+ // typedef Container::const_iterator const_reverse_iterator;
+
+ /// Default constructor - empty errata, very fast.
+ Errata();
+ /// Copy constructor, very fast.
+ Errata(self const &that ///< Object to copy
+ );
+ /// Construct from string.
+ /// Message Id and Code are default.
+ explicit Errata(std::string const &text ///< Finalized message text.
+ );
+ /// Construct with @a id and @a text.
+ /// Code is default.
+ Errata(Id id, ///< Message id.
+ std::string const &text ///< Message text.
+ );
+ /// Construct with @a id, @a code, and @a text.
+ Errata(Id id, ///< Message text.
+ Code code, ///< Message code.
+ std::string const &text ///< Message text.
+ );
+ /** Construct from a message instance.
+ This is equivalent to default constructing an @c errata and then
+ invoking @c push with an argument of @a msg.
+ */
+ Errata(Message const &msg ///< Message to push
+ );
+
+ /// Move constructor.
+ Errata(self &&that);
+ /// Move constructor from @c Message.
+ Errata(Message &&msg);
+
+ /// destructor
+ ~Errata();
+
+ /// Self assignment.
+ /// @return A reference to this object.
+ self &operator=(const self &that ///< Source instance.
+ );
+
+ /// Move assignment.
+ self &operator=(self &&that);
+
+ /** Assign message.
+ All other messages are discarded.
+ @return A reference to this object.
+ */
+ self &operator=(Message const &msg ///< Source message.
+ );
+
+ /** Push @a text as a message.
+ The message is constructed from just the @a text.
+ It becomes the top message.
+ @return A reference to this object.
+ */
+ self &push(std::string const &text);
+ /** Push @a text as a message with message @a id.
+ The message is constructed from @a text and @a id.
+ It becomes the top message.
+ @return A reference to this object.
+ */
+ self &push(Id id, std::string const &text);
+ /** Push @a text as a message with message @a id and @a code.
+ The message is constructed from @a text and @a id.
+ It becomes the top message.
+ @return A reference to this object.
+ */
+ self &push(Id id, Code code, std::string const &text);
+ /** Push a message.
+ @a msg becomes the top message.
+ @return A reference to this object.
+ */
+ self &push(Message const &msg);
+ self &push(Message &&msg);
+
+ /** Push a constructed @c Message.
+ The @c Message is set to have the @a id and @a code. The other arguments are converted
+ to strings and concatenated to form the messsage text.
+ @return A reference to this object.
+ */
+ template <typename... Args> self &push(Id id, Code code, Args const &... args);
+
+ /** Push a nested status.
+ @a err becomes the top item.
+ @return A reference to this object.
+ */
+ self &push(self const &err);
+
+ /** Access top message.
+ @return If the errata is empty, a default constructed message
+ otherwise the most recent message.
+ */
+ Message const &top() const;
+
+ /** Move messages from @a that to @c this errata.
+ Messages from @a that are put on the top of the
+ stack in @c this and removed from @a that.
+ */
+ self &pull(self &that);
+
+ /// Remove last message.
+ void pop();
+
+ /// Remove all messages.
+ void clear();
+
+ /** Inhibit logging.
+ @note This only affects @c this as a top level @c errata.
+ It has no effect on this @c this being logged as a nested
+ @c errata.
+ */
+ self &doNotLog();
+
+ friend std::ostream &operator<<(std::ostream &, self const &);
+
+ /// Default glue value (a newline) for text rendering.
+ static std::string const DEFAULT_GLUE;
+
+ /** Test status.
+
+ Equivalent to @c success but more convenient for use in
+ control statements.
+
+ @return @c true if no messages or last message has a zero
+ message ID, @c false otherwise.
+ */
+ operator bool() const;
+
+ /** Test errata for no failure condition.
+
+ Equivalent to @c operator @c bool but easier to invoke.
+
+ @return @c true if no messages or last message has a zero
+ message ID, @c false otherwise.
+ */
+ bool isOK() const;
+
+ /// Number of messages in the errata.
+ size_t size() const;
+
+ /* Forward declares.
+ We have to make our own iterators as the least bad option. The problem
+ is that we have recursive structures so declaration order is difficult.
+ We can't use the container iterators here because the element type is
+ not yet defined. If we define the element type here, it can't contain
+ an Errata and we have to do funky things to get around that. So we
+ have our own iterators, which are just shadowing sublclasses of the
+ container iterators.
+ */
+ class iterator;
+ class const_iterator;
+
+ /// Reference to top item on the stack.
+ iterator begin();
+ /// Reference to top item on the stack.
+ const_iterator begin() const;
+ //! Reference one past bottom item on the stack.
+ iterator end();
+ //! Reference one past bottom item on the stack.
+ const_iterator end() const;
+
+ // Logging support.
+
+ /** Base class for erratum sink.
+ When an errata is abandoned, this will be called on it to perform
+ any client specific logging. It is passed around by handle so that
+ it doesn't have to support copy semantics (and is not destructed
+ until application shutdown). Clients can subclass this class in order
+ to preserve arbitrary data for the sink or retain a handle to the
+ sink for runtime modifications.
+ */
+ class Sink : public IntrusivePtrCounter
+ {
+ public:
+ typedef Sink self; ///< Self reference type.
+ typedef IntrusivePtr<self> Handle; ///< Handle type.
+
+ /// Handle an abandoned errata.
+ virtual void operator()(Errata const &) const = 0;
+ /// Force virtual destructor.
+ virtual ~Sink() {}
+ };
+
+ //! Register a sink for discarded erratum.
+ static void registerSink(Sink::Handle const &s);
+
+ /// Register a function as a sink.
+ typedef void (*SinkHandlerFunction)(Errata const &);
+
+ // Wrapper class to support registering functions as sinks.
+ struct SinkFunctionWrapper : public Sink {
+ /// Constructor.
+ SinkFunctionWrapper(SinkHandlerFunction f) : m_f(f) {}
+ /// Operator to invoke the function.
+ void
+ operator()(Errata const &e) const override
+ {
+ m_f(e);
+ }
+ SinkHandlerFunction m_f; ///< Client supplied handler.
+ };
+
+ /// Register a sink function for abandonded erratum.
+ static void
+ registerSink(SinkHandlerFunction f)
+ {
+ registerSink(Sink::Handle(new SinkFunctionWrapper(f)));
+ }
+
+ /** Simple formatted output.
+
+ Each message is written to a line. All lines are indented with
+ whitespace @a offset characters. Lines are indented an
+ additional @a indent. This value is increased by @a shift for
+ each level of nesting of an @c Errata. if @a lead is not @c
+ NULL the indentation is overwritten by @a lead if @a indent is
+ non-zero. It acts as a "continuation" marker for nested
+ @c Errata.
+
+ */
+ std::ostream &write(std::ostream &out, ///< Output stream.
+ int offset, ///< Lead white space for every line.
+ int indent, ///< Additional indention per line for messages.
+ int shift, ///< Additional @a indent for nested @c Errata.
+ char const *lead ///< Leading text for nested @c Errata.
+ ) const;
+ /// Simple formatted output to fixed sized buffer.
+ /// @return Number of characters written to @a buffer.
+ size_t write(char *buffer, ///< Output buffer.
+ size_t n, ///< Buffer size.
+ int offset, ///< Lead white space for every line.
+ int indent, ///< Additional indention per line for messages.
+ int shift, ///< Additional @a indent for nested @c Errata.
+ char const *lead ///< Leading text for nested @c Errata.
+ ) const;
+
+protected:
+ /// Construct from implementation pointer.
+ /// Used internally by nested classes.
+ Errata(ImpPtr const &ptr);
+ /// Implementation instance.
+ ImpPtr m_data;
+
+ /// Return the implementation instance, allocating and unsharing as needed.
+ Data *pre_write();
+ /// Force and return an implementation instance.
+ /// Does not follow copy on write.
+ Data const *instance();
+
+ /// Used for returns when no data is present.
+ static Message const NIL_MESSAGE;
+
+ friend struct Data;
+ friend class Item;
+};
+
+extern std::ostream &operator<<(std::ostream &os, Errata const &stat);
+
+/// Storage for a single message.
+struct Errata::Message {
+ typedef Message self; ///< Self reference type.
+
+ /// Default constructor.
+ /// The message has Id = 0, default code, and empty text.
+ Message() = default;
+
+ /// Construct from text.
+ /// Id is zero and Code is default.
+ Message(std::string const &text ///< Finalized message text.
+ );
+
+ /// Construct with @a id and @a text.
+ /// Code is default.
+ Message(Id id, ///< ID of message in table.
+ std::string const &text ///< Final text for message.
+ );
+
+ /// Construct with @a id, @a code, and @a text.
+ Message(Id id, ///< Message Id.
+ Code code, ///< Message Code.
+ std::string const &text ///< Final text for message.
+ );
+
+ /// Construct with an @a id, @a code, and a @a message.
+ /// The message contents are created by converting the variable arguments
+ /// to strings using the stream operator and concatenated in order.
+ template <typename... Args>
+ Message(Id id, ///< Message Id.
+ Code code, ///< Message Code.
+ Args const &... text);
+
+ /// Reset to the message to default state.
+ self &clear();
+
+ /// Set the message Id.
+ self &set(Id id ///< New message Id.
+ );
+
+ /// Set the code.
+ self &set(Code code ///< New code for message.
+ );
+
+ /// Set the text.
+ self &set(std::string const &text ///< New message text.
+ );
+
+ /// Set the text.
+ self &set(char const *text ///< New message text.
+ );
+
+ /// Set the errata.
+ self &set(Errata const &err ///< Errata to store.
+ );
+
+ /// Get the text of the message.
+ std::string const &text() const;
+
+ /// Get the code.
+ Code getCode() const;
+ /// Get the nested status.
+ /// @return A status object, which is not @c NULL if there is a
+ /// nested status stored in this item.
+ Errata getErrata() const;
+
+ /** The default message code.
+
+ This value is used as the Code value for constructing and
+ clearing messages. It can be changed to control the value
+ used for empty messages.
+ */
+ static Code Default_Code;
+
+ /// Type for overriding success message test.
+ typedef bool (*SuccessTest)(Message const &m);
+
+ /** Success message test.
+
+ When a message is tested for being "successful", this
+ function is called. It may be overridden by a client.
+ The initial value is @c DEFAULT_SUCCESS_TEST.
+
+ @note This is only called when there are Messages in the
+ Errata. An empty Errata (@c NULL or empty stack) is always
+ a success. Only the @c top Message is checked.
+
+ @return @c true if the message indicates success,
+ @c false otherwise.
+ */
+ static SuccessTest Success_Test;
+
+ /// Indicate success if the message code is zero.
+ /// @note Used as the default success test.
+ static bool isCodeZero(Message const &m);
+
+ static SuccessTest const DEFAULT_SUCCESS_TEST;
+
+ template <typename... Args> static std::string stringify(Args const &... items);
+
+ Id m_id = 0; ///< Message ID.
+ Code m_code = Default_Code; ///< Message code.
+ std::string m_text; ///< Final text.
+ Errata m_errata; ///< Nested errata.
+};
+
+/** This is the implementation class for Errata.
+
+ It holds the actual messages and is treated as a passive data
+ object with nice constructors.
+
+ We implement reference counting semantics by hand for two
+ reasons. One is that we need to do some specialized things, but
+ mainly because the client can't see this class so we can't
+*/
+struct Errata::Data : public IntrusivePtrCounter {
+ typedef Data self; ///< Self reference type.
+
+ //! Default constructor.
+ Data();
+
+ /// Destructor, to do logging.
+ ~Data();
+
+ //! Number of messages.
+ size_t size() const;
+
+ /// Get the top message on the stack.
+ Message const &top() const;
+
+ /// Put a message on top of the stack.
+ void push(Message const &msg);
+ void push(Message &&msg);
+
+ /// Log this when it is deleted.
+ mutable bool m_log_on_delete = true;
+
+ //! The message stack.
+ Container m_items;
+};
+
+/// Forward iterator for @c Messages in an @c Errata.
+class Errata::iterator : public Errata::Container::reverse_iterator
+{
+public:
+ typedef iterator self; ///< Self reference type.
+ typedef Errata::Container::reverse_iterator super; ///< Parent type.
+ iterator(); ///< Default constructor.
+ /// Copy constructor.
+ iterator(self const &that ///< Source instance.
+ );
+ /// Construct from super class.
+ iterator(super const &that ///< Source instance.
+ );
+ /// Assignment.
+ self &operator=(self const &that);
+ /// Assignment from super class.
+ self &operator=(super const &that);
+ /// Prefix increment.
+ self &operator++();
+ /// Prefix decrement.
+ self &operator--();
+};
+
+/// Forward constant iterator for @c Messages in an @c Errata.
+class Errata::const_iterator : public Errata::Container::const_reverse_iterator
+{
+public:
+ typedef const_iterator self; ///< Self reference type.
+ typedef Errata::Container::const_reverse_iterator super; ///< Parent type.
+ const_iterator(); ///< Default constructor.
+ /// Copy constructor.
+ const_iterator(self const &that ///< Source instance.
+ );
+ const_iterator(super const &that ///< Source instance.
+ );
+ /// Assignment.
+ self &operator=(self const &that);
+ /// Assignment from super class.
+ self &operator=(super const &that);
+ /// Prefix increment.
+ self &operator++();
+ /// Prefix decrement.
+ self &operator--();
+};
+
+/** Helper class for @c Rv.
+ This class enables us to move the implementation of non-templated methods
+ and members out of the header file for a cleaner API.
+ */
+struct RvBase {
+ Errata _errata; ///< The status from the function.
+
+ /** Default constructor. */
+ RvBase();
+
+ /** Construct with specific status.
+ */
+ RvBase(Errata const &s ///< Status to copy
+ );
+
+ //! Test the return value for success.
+ bool isOK() const;
+
+ /** Clear any stacked errors.
+ This is useful during shutdown, to silence irrelevant errors caused
+ by the shutdown process.
+ */
+ void clear();
+
+ /// Inhibit logging of the errata.
+ void doNotLog();
+};
+
+/** Return type for returning a value and status (errata). In
+ general, a method wants to return both a result and a status so
+ that errors are logged properly. This structure is used to do that
+ in way that is more usable than just @c std::pair. - Simpler and
+ shorter typography - Force use of @c errata rather than having to
+ remember it (and the order) each time - Enable assignment directly
+ to @a R for ease of use and compatibility so clients can upgrade
+ asynchronously.
+ */
+template <typename R> struct Rv : public RvBase {
+ typedef Rv self; ///< Standard self reference type.
+ typedef RvBase super; ///< Standard super class reference type.
+ typedef R Result; ///< Type of result value.
+
+ Result _result; ///< The actual result of the function.
+
+ /** Default constructor.
+ The default constructor for @a R is used.
+ The status is initialized to SUCCESS.
+ */
+ Rv();
+
+ /** Standard (success) constructor.
+
+ This copies the result and sets the status to SUCCESS.
+
+ @note Not @c explicit so that clients can return just a result
+ and have it be marked as SUCCESS.
+ */
+ Rv(Result const &r ///< The function result
+ );
+
+ /** Construct from a result and a pre-existing status object.
+
+ @internal No constructor from just an Errata to avoid
+ potential ambiguity with constructing from result type.
+ */
+ Rv(Result const &r, ///< The function result
+ Errata const &s ///< A pre-existing status object
+ );
+
+ /** User conversion to the result type.
+
+ This makes it easy to use the function normally or to pass the
+ result only to other functions without having to extract it by
+ hand.
+ */
+ operator Result const &() const;
+
+ /** Assignment from result type.
+
+ This allows the result to be assigned to a pre-declared return
+ value structure. The return value is a reference to the
+ internal result so that this operator can be chained in other
+ assignments to instances of result type. This is most commonly
+ used when the result is computed in to a local variable to be
+ both returned and stored in a member.
+
+ @code
+ Rv<int> zret;
+ int value;
+ // ... complex computations, result in value
+ this->m_value = zret = value;
+ // ...
+ return zret;
+ @endcode
+
+ @return A reference to the copy of @a r stored in this object.
+ */
+ Result &
+ operator=(Result const &r ///< Result to assign
+ )
+ {
+ _result = r;
+ return _result;
+ }
+
+ /** Add the status from another instance to this one.
+ @return A reference to @c this object.
+ */
+ template <typename U>
+ self &push(Rv<U> const &that ///< Source of status messages
+ );
+
+ /** Set the result.
+
+ This differs from assignment of the function result in that the
+ return value is a reference to the @c Rv, not the internal
+ result. This makes it useful for assigning a result local
+ variable and then returning.
+
+ @code
+ Rv<int> zret;
+ int value;
+ // ... complex computation, result in value
+ return zret.set(value);
+ @endcode
+ */
+ self &set(Result const &r ///< Result to store
+ );
+
+ /** Return the result.
+ @return A reference to the result value in this object.
+ */
+ Result &result();
+
+ /** Return the result.
+ @return A reference to the result value in this object.
+ */
+ Result const &result() const;
+
+ /** Return the status.
+ @return A reference to the @c errata in this object.
+ */
+ Errata &errata();
+
+ /** Return the status.
+ @return A reference to the @c errata in this object.
+ */
+ Errata const &errata() const;
+
+ /// Directly set the errata
+ self &operator=(Errata const &status ///< Errata to assign.
+ );
+
+ /// Push a message on to the status.
+ self &push(Errata::Message const &msg);
+};
+
+/** Combine a function result and status in to an @c Rv.
+ This is useful for clients that want to declare the status object
+ and result independently.
+ */
+template <typename R>
+Rv<R>
+MakeRv(R const &r, ///< The function result
+ Errata const &s ///< The pre-existing status object
+)
+{
+ return Rv<R>(r, s);
+}
+/* ----------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
+// Inline methods.
+inline Errata::Message::Message(std::string const &text) : m_text(text) {}
+inline Errata::Message::Message(Id id, std::string const &text) : m_text(text) {}
+inline Errata::Message::Message(Id id, Code code, std::string const &text) : m_text(text) {}
+template <typename... Args>
+Errata::Message::Message(Id id, Code code, Args const &... text) : m_id(id), m_code(code), m_text(stringify(text...))
+{
+}
+
+inline Errata::Message &
+Errata::Message::clear()
+{
+ m_id = 0;
+ m_code = Default_Code;
+ m_text.erase();
+ m_errata.clear();
+ return *this;
+}
+
+inline std::string const &
+Errata::Message::text() const
+{
+ return m_text;
+}
+inline Errata::Code
+Errata::Message::getCode() const
+{
+ return m_code;
+}
+inline Errata
+Errata::Message::getErrata() const
+{
+ return m_errata;
+}
+
+inline Errata::Message &
+Errata::Message::set(Id id)
+{
+ m_id = id;
+ return *this;
+}
+inline Errata::Message &
+Errata::Message::set(Code code)
+{
+ m_code = code;
+ return *this;
+}
+inline Errata::Message &
+Errata::Message::set(std::string const &text)
+{
+ m_text = text;
+ return *this;
+}
+inline Errata::Message &
+Errata::Message::set(char const *text)
+{
+ m_text = text;
+ return *this;
+}
+inline Errata::Message &
+Errata::Message::set(Errata const &err)
+{
+ m_errata = err;
+ m_errata.doNotLog();
+ return *this;
+}
+
+template <typename... Args>
+std::string
+Errata::Message::stringify(Args const &... items)
+{
+ std::ostringstream s;
+ (void)(int[]){0, ((s << items), 0)...};
+ return s.str();
+}
+
+inline Errata::Errata() {}
+inline Errata::Errata(Id id, Code code, std::string const &text)
+{
+ this->push(Message(id, code, text));
+}
+inline Errata::Errata(Message const &msg)
+{
+ this->push(msg);
+}
+inline Errata::Errata(Message &&msg)
+{
+ this->push(std::move(msg));
+}
+
+inline Errata::operator bool() const
+{
+ return this->isOK();
+}
+
+inline size_t
+Errata::size() const
+{
+ return m_data ? m_data->m_items.size() : 0;
+}
+
+inline bool
+Errata::isOK() const
+{
+ return nullptr == m_data || 0 == m_data->size() || Message::Success_Test(this->top());
+}
+
+inline Errata &
+Errata::push(std::string const &text)
+{
+ this->push(Message(text));
+ return *this;
+}
+
+inline Errata &
+Errata::push(Id id, std::string const &text)
+{
+ this->push(Message(id, text));
+ return *this;
+}
+
+inline Errata &
+Errata::push(Id id, Code code, std::string const &text)
+{
+ this->push(Message(id, code, text));
+ return *this;
+}
+
+template <typename... Args>
+auto
+Errata::push(Id id, Code code, Args const &... args) -> self &
+{
+ this->push(Message(id, code, args...));
+ return *this;
+}
+
+inline Errata::Message const &
+Errata::top() const
+{
+ return m_data ? m_data->top() : NIL_MESSAGE;
+}
+inline Errata &
+Errata::doNotLog()
+{
+ this->instance()->m_log_on_delete = false;
+ return *this;
+}
+
+inline Errata::Data::Data() {}
+inline size_t
+Errata::Data::size() const
+{
+ return m_items.size();
+}
+
+inline Errata::iterator::iterator() {}
+inline Errata::iterator::iterator(self const &that) : super(that) {}
+inline Errata::iterator::iterator(super const &that) : super(that) {}
+inline Errata::iterator &
+Errata::iterator::operator=(self const &that)
+{
+ this->super::operator=(that);
+ return *this;
+}
+inline Errata::iterator &
+Errata::iterator::operator=(super const &that)
+{
+ this->super::operator=(that);
+ return *this;
+}
+inline Errata::iterator &
+Errata::iterator::operator++()
+{
+ this->super::operator++();
+ return *this;
+}
+inline Errata::iterator &
+Errata::iterator::operator--()
+{
+ this->super::operator--();
+ return *this;
+}
+
+inline Errata::const_iterator::const_iterator() {}
+inline Errata::const_iterator::const_iterator(self const &that) : super(that) {}
+inline Errata::const_iterator::const_iterator(super const &that) : super(that) {}
+inline Errata::const_iterator &
+Errata::const_iterator::operator=(self const &that)
+{
+ super::operator=(that);
+ return *this;
+}
+inline Errata::const_iterator &
+Errata::const_iterator::operator=(super const &that)
+{
+ super::operator=(that);
+ return *this;
+}
+inline Errata::const_iterator &
+Errata::const_iterator::operator++()
+{
+ this->super::operator++();
+ return *this;
+}
+inline Errata::const_iterator &
+Errata::const_iterator::operator--()
+{
+ this->super::operator--();
+ return *this;
+}
+
+inline RvBase::RvBase() {}
+inline RvBase::RvBase(Errata const &errata) : _errata(errata) {}
+inline bool
+RvBase::isOK() const
+{
+ return _errata;
+}
+inline void
+RvBase::clear()
+{
+ _errata.clear();
+}
+inline void
+RvBase::doNotLog()
+{
+ _errata.doNotLog();
+}
+
+template <typename T> Rv<T>::Rv() : _result() {}
+template <typename T> Rv<T>::Rv(Result const &r) : _result(r) {}
+template <typename T> Rv<T>::Rv(Result const &r, Errata const &errata) : super(errata), _result(r) {}
+template <typename T> Rv<T>::operator Result const &() const
+{
+ return _result;
+}
+template <typename T>
+T const &
+Rv<T>::result() const
+{
+ return _result;
+}
+template <typename T>
+T &
+Rv<T>::result()
+{
+ return _result;
+}
+template <typename T>
+Errata const &
+Rv<T>::errata() const
+{
+ return _errata;
+}
+template <typename T>
+Errata &
+Rv<T>::errata()
+{
+ return _errata;
+}
+template <typename T>
+Rv<T> &
+Rv<T>::set(Result const &r)
+{
+ _result = r;
+ return *this;
+}
+template <typename T>
+Rv<T> &
+Rv<T>::operator=(Errata const &errata)
+{
+ _errata = errata;
+ return *this;
+}
+template <typename T>
+Rv<T> &
+Rv<T>::push(Errata::Message const &msg)
+{
+ _errata.push(msg);
+ return *this;
+}
+template <typename T>
+template <typename U>
+Rv<T> &
+Rv<T>::push(Rv<U> const &that)
+{
+ _errata.push(that.errata());
+ return *this;
+}
+/* ----------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
+} // namespace ts
diff --git a/lib/tsconfig/IntrusivePtr.h b/include/tscore/IntrusivePtr.h
similarity index 86%
rename from lib/tsconfig/IntrusivePtr.h
rename to include/tscore/IntrusivePtr.h
index cb09d0a..dcf54ae 100644
--- a/lib/tsconfig/IntrusivePtr.h
+++ b/include/tscore/IntrusivePtr.h
@@ -39,8 +39,7 @@
namespace ts
{
-
-template < typename T > class IntrusivePtr; // forward declare
+template <typename T> class IntrusivePtr; // forward declare
/* ----------------------------------------------------------------------- */
/** Reference counter mixin.
@@ -62,9 +61,10 @@ template < typename T > class IntrusivePtr; // forward declare
*/
class IntrusivePtrCounter
{
- template < typename T > friend class IntrusivePtr;
+ template <typename T> friend class IntrusivePtr;
using self_type = IntrusivePtrCounter;
+
public:
/** Copy constructor.
@@ -72,9 +72,9 @@ public:
client that uses a default copy constructor will _copy the ref count into the new object_.
That way lies madness.
*/
- IntrusivePtrCounter(self_type const & that);
+ IntrusivePtrCounter(self_type const &that);
/// No move constructor - that won't work for an object that is the target of a shared pointer.
- IntrusivePtrCounter(self_type && that) = delete;
+ IntrusivePtrCounter(self_type &&that) = delete;
/** Assignment operator.
@@ -100,15 +100,15 @@ protected:
*/
class IntrusivePtrAtomicCounter
{
- template < typename T > friend class IntrusivePtr;
+ template <typename T> friend class IntrusivePtr;
using self_type = IntrusivePtrAtomicCounter; ///< Self reference type.
public:
/// Copy constructor - do not copy reference count.
- IntrusivePtrAtomicCounter(self_type const & that);
+ IntrusivePtrAtomicCounter(self_type const &that);
/// No move constructor - that won't work for an object that is the target of a shared pointer.
- IntrusivePtrAtomicCounter(self_type && that) = delete;
+ IntrusivePtrAtomicCounter(self_type &&that) = delete;
/// Self assignment - do not copy reference count.
self_type &operator=(self_type const &that);
@@ -144,9 +144,9 @@ protected:
*/
template <typename T> class IntrusivePtr
{
-private: /* don't pollute client with these typedefs */
- using self_type = IntrusivePtr; ///< Self reference type.
- template < typename U > friend class IntrusivePtr; // Make friends with siblings for cross type casts.
+private: /* don't pollute client with these typedefs */
+ using self_type = IntrusivePtr; ///< Self reference type.
+ template <typename U> friend class IntrusivePtr; // Make friends with siblings for cross type casts.
public:
/// The externally used type for the reference count.
using counter_type = long int;
@@ -160,13 +160,13 @@ public:
~IntrusivePtr();
/// Copy constructor. A new reference to the object is created.
- IntrusivePtr(self_type const& that);
+ IntrusivePtr(self_type const &that);
/// Move constructor. The reference in @a that is moved to @a this.
- IntrusivePtr(self_type && that);
+ IntrusivePtr(self_type &&that);
/// Self assignment. A new reference to the object is created.
- self_type& operator=(self_type const& that);
+ self_type &operator=(self_type const &that);
/// Move assignment. The reference in @a that is moved to @a this.
- self_type& operator=(self_type && that);
+ self_type &operator=(self_type &&that);
/** Assign from instance.
@@ -190,7 +190,7 @@ public:
@return @c true if there are no references upon return,
@c false if the reference count is not zero.
*/
- T* release();
+ T *release();
/// Test for not @c nullptr
explicit operator bool() const;
@@ -213,20 +213,16 @@ public:
/** Cross type construction.
This succeeds if an @a U* can be implicitly converted to a @a T*.
*/
- template <typename U>
- IntrusivePtr(IntrusivePtr<U> const &that);
+ template <typename U> IntrusivePtr(IntrusivePtr<U> const &that);
- template <typename U>
- IntrusivePtr(IntrusivePtr<U> && that);
+ template <typename U> IntrusivePtr(IntrusivePtr<U> &&that);
/** Cross type assignment.
This succeeds if an @a U* can be implicitily converted to a @a T*.
*/
- template <typename U>
- self_type &operator=(IntrusivePtr<U> const &that);
+ template <typename U> self_type &operator=(IntrusivePtr<U> const &that);
- template <typename U>
- self_type &operator=(IntrusivePtr<U> && that);
+ template <typename U> self_type &operator=(IntrusivePtr<U> &&that);
/// Reference count.
/// @return Number of references.
@@ -345,7 +341,8 @@ public:
};
// If no specialization is provided then use the default;
-template < typename T > struct IntrusivePtrPolicy : public IntrusivePtrDefaultPolicy<T> {};
+template <typename T> struct IntrusivePtrPolicy : public IntrusivePtrDefaultPolicy<T> {
+};
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Inline Methods */
@@ -405,60 +402,53 @@ template <typename T> IntrusivePtr<T>::~IntrusivePtr()
this->unset();
}
-template < typename T >
-IntrusivePtr<T>::IntrusivePtr(self_type const &that)
+template <typename T> IntrusivePtr<T>::IntrusivePtr(self_type const &that)
{
this->set(that.m_obj);
}
-template <typename T>
-template <typename U>
-IntrusivePtr<T>::IntrusivePtr(IntrusivePtr<U> const &that)
+template <typename T> template <typename U> IntrusivePtr<T>::IntrusivePtr(IntrusivePtr<U> const &that)
{
- static_assert(std::is_convertible<U*, T*>::value, "The argument type is not implicitly convertible to the return type.");
+ static_assert(std::is_convertible<U *, T *>::value, "The argument type is not implicitly convertible to the return type.");
this->set(that.m_obj);
}
-template < typename T >
-IntrusivePtr<T>::IntrusivePtr(self_type && that)
+template <typename T> IntrusivePtr<T>::IntrusivePtr(self_type &&that)
{
- std::swap<T*>(m_obj, that.m_obj);
+ std::swap<T *>(m_obj, that.m_obj);
}
-template <typename T>
-template <typename U>
-IntrusivePtr<T>::IntrusivePtr(IntrusivePtr<U> && that)
+template <typename T> template <typename U> IntrusivePtr<T>::IntrusivePtr(IntrusivePtr<U> &&that)
{
- static_assert(std::is_convertible<U*, T*>::value, "The argument type is not implicitly convertible to the return type.");
- std::swap<T*>(m_obj, that.get());
+ static_assert(std::is_convertible<U *, T *>::value, "The argument type is not implicitly convertible to the return type.");
+ std::swap<T *>(m_obj, that.get());
}
-template < typename T >
+template <typename T>
IntrusivePtr<T> &
-IntrusivePtr<T>::operator=(self_type const& that)
+IntrusivePtr<T>::operator=(self_type const &that)
{
this->reset(that.get());
return *this;
}
-
template <typename T>
template <typename U>
IntrusivePtr<T> &
-IntrusivePtr<T>::operator=(IntrusivePtr<U> const& that)
+IntrusivePtr<T>::operator=(IntrusivePtr<U> const &that)
{
- static_assert(std::is_convertible<U*, T*>::value, "The argument type is not implicitly convertible to the return type.");
+ static_assert(std::is_convertible<U *, T *>::value, "The argument type is not implicitly convertible to the return type.");
this->reset(that.get());
return *this;
}
-template < typename T >
+template <typename T>
IntrusivePtr<T> &
-IntrusivePtr<T>::operator=(self_type && that)
+IntrusivePtr<T>::operator=(self_type &&that)
{
if (m_obj != that.m_obj) {
this->unset();
- m_obj = that.m_obj;
+ m_obj = that.m_obj;
that.m_obj = nullptr;
} else {
that.unset();
@@ -469,12 +459,12 @@ IntrusivePtr<T>::operator=(self_type && that)
template <typename T>
template <typename U>
IntrusivePtr<T> &
-IntrusivePtr<T>::operator=(IntrusivePtr<U> && that)
+IntrusivePtr<T>::operator=(IntrusivePtr<U> &&that)
{
- static_assert(std::is_convertible<U*, T*>::value, "The argument type is not implicitly convertible to the return type.");
+ static_assert(std::is_convertible<U *, T *>::value, "The argument type is not implicitly convertible to the return type.");
if (m_obj != that.m_obj) {
this->unset();
- m_obj = that.m_obj;
+ m_obj = that.m_obj;
that.m_obj = nullptr;
} else {
that.unset();
@@ -530,7 +520,7 @@ template <typename T>
void
IntrusivePtr<T>::set(T *obj)
{
- m_obj = obj; /* update to new object */
+ m_obj = obj; /* update to new object */
if (nullptr != m_obj) /* if a real object, bump the ref count */
++(m_obj->m_intrusive_pointer_reference_count);
}
@@ -546,10 +536,10 @@ IntrusivePtr<T>::reset(T *obj)
}
template <typename T>
-T*
+T *
IntrusivePtr<T>::release()
{
- T* zret = m_obj;
+ T *zret = m_obj;
if (m_obj) {
auto &cp = m_obj->m_intrusive_pointer_reference_count;
// If the client is using this method, they're doing something funky
@@ -561,8 +551,7 @@ IntrusivePtr<T>::release()
return zret;
}
-template <typename T>
-IntrusivePtr<T>::operator bool() const
+template <typename T> IntrusivePtr<T>::operator bool() const
{
return m_obj != nullptr;
}
diff --git a/include/tscore/MemArena.h b/include/tscore/MemArena.h
index fb98590..0b868c8 100644
--- a/include/tscore/MemArena.h
+++ b/include/tscore/MemArena.h
@@ -29,7 +29,7 @@
#include <utility>
#include "tscpp/util/MemSpan.h"
#include "tscore/Scalar.h"
-#include <tsconfig/IntrusivePtr.h>
+#include "tscore/IntrusivePtr.h"
/// Apache Traffic Server commons.
namespace ts
diff --git a/lib/tsconfig/NumericType.h b/include/tscore/NumericType.h
similarity index 100%
rename from lib/tsconfig/NumericType.h
rename to include/tscore/NumericType.h
diff --git a/include/tscore/TsBuffer.h b/include/tscore/TsBuffer.h
index 7837c64..e2ad2f7 100644
--- a/include/tscore/TsBuffer.h
+++ b/include/tscore/TsBuffer.h
@@ -1,9 +1,6 @@
/** @file
Definitions for a buffer type, to carry a reference to a chunk of memory.
- @internal This is a copy of TsBuffer.h in lib/tsconfig. That should
- eventually be replaced with this promoted file.
-
@section license License
Licensed to the Apache Software Foundation (ASF) under one
diff --git a/include/wccp/Wccp.h b/include/wccp/Wccp.h
index 20e29ea..0e1d265 100644
--- a/include/wccp/Wccp.h
+++ b/include/wccp/Wccp.h
@@ -22,9 +22,10 @@
#pragma once
-#include "tscore/TsBuffer.h"
-#include <tsconfig/Errata.h>
#include <memory.h>
+
+#include "tscore/TsBuffer.h"
+#include "tscore/Errata.h"
#include "tscore/ink_defs.h"
#include "tscore/ink_memory.h"
// Nasty, defining this with no prefix. The value is still available
diff --git a/iocore/cache/Makefile.am b/iocore/cache/Makefile.am
index e9c9df3..3c52888 100644
--- a/iocore/cache/Makefile.am
+++ b/iocore/cache/Makefile.am
@@ -106,7 +106,6 @@ test_LDADD = \
$(top_builddir)/src/tscore/libtscore.la \
$(top_builddir)/lib/records/librecords_p.a \
$(top_builddir)/iocore/eventsystem/libinkevent.a \
- $(top_builddir)/lib/tsconfig/libtsconfig.la \
@HWLOC_LIBS@ \
@LIBPCRE@ \
@LIBRESOLV@ \
@@ -117,7 +116,6 @@ test_LDADD = \
@YAMLCPP_LIBS@ \
-lm
-
check_PROGRAMS = \
test_Cache \
test_RWW \
diff --git a/iocore/net/Makefile.am b/iocore/net/Makefile.am
index 7e27fe5..1c098f6 100644
--- a/iocore/net/Makefile.am
+++ b/iocore/net/Makefile.am
@@ -75,7 +75,6 @@ test_UDPNet_LDADD = \
$(top_builddir)/lib/records/librecords_p.a \
$(top_builddir)/src/tscore/libtscore.la $(top_builddir)/src/tscpp/util/libtscpputil.la \
$(top_builddir)/proxy/ParentSelectionStrategy.o \
- $(top_builddir)/lib/tsconfig/libtsconfig.la \
@HWLOC_LIBS@ @OPENSSL_LIBS@ @LIBPCRE@ @YAMLCPP_LIBS@
test_UDPNet_SOURCES = \
@@ -167,9 +166,6 @@ libinknet_a_SOURCES += \
P_NetVCTest.h
endif
-libinknet_a_LIBADD = \
- $(top_builddir)/lib/tsconfig/libtsconfig.la
-
include $(top_srcdir)/build/tidy.mk
clang-tidy-local: $(DIST_SOURCES)
diff --git a/iocore/net/YamlSNIConfig.cc b/iocore/net/YamlSNIConfig.cc
index 9ff0d62..8a07c11 100644
--- a/iocore/net/YamlSNIConfig.cc
+++ b/iocore/net/YamlSNIConfig.cc
@@ -30,7 +30,7 @@
#include "tscore/Diags.h"
#include "tscore/EnumDescriptor.h"
-#include "tsconfig/Errata.h"
+#include "tscore/Errata.h"
#include "P_SNIActionPerformer.h"
ts::Errata
diff --git a/iocore/net/YamlSNIConfig.h b/iocore/net/YamlSNIConfig.h
index babd016..0e6b8fc 100644
--- a/iocore/net/YamlSNIConfig.h
+++ b/iocore/net/YamlSNIConfig.h
@@ -24,7 +24,7 @@
#include <vector>
#include <string>
-#include "tsconfig/Errata.h"
+#include "tscore/Errata.h"
#define TSDECL(id) constexpr char TS_##id[] = #id
TSDECL(fqdn);
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 3db8fd7..8b3d28e 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -16,7 +16,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-SUBDIRS = . records tsconfig
+SUBDIRS = . records
if BUILD_PERL_LIB
SUBDIRS += perl
diff --git a/lib/tsconfig/Errata.h b/lib/tsconfig/Errata.h
deleted file mode 100644
index 2322f3b..0000000
--- a/lib/tsconfig/Errata.h
+++ /dev/null
@@ -1,929 +0,0 @@
-# if !defined TS_ERRATA_HEADER
-# define TS_ERRATA_HEADER
-
-/** @file
- Stacking error message handling.
-
- The problem addressed by this library is the ability to pass back
- detailed error messages from failures. It is hard to get good
- diagnostics because the specific failures and general context are
- located in very different stack frames. This library allows local
- functions to pass back local messages which can be easily
- augmented as the error travels up the stack frame.
-
- This could be done with exceptions but
- - That is more effort to implemention
- - Generally more expensive.
-
- Each message on a stack contains text and a numeric identifier.
- The identifier value zero is reserved for messages that are not
- errors so that information can be passed back even in the success
- case.
-
- The implementation takes the position that success is fast and
- failure is expensive. Therefore it is optimized for the success
- path, imposing very little overhead. On the other hand, if an
- error occurs and is handled, that is generally so expensive that
- optimizations are pointless (although, of course, one should not
- be gratuitiously expensive).
-
- The library also provides the @c Rv ("return value") template to
- make returning values and status easier. This template allows a
- function to return a value and status pair with minimal changes.
- The pair acts like the value type in most situations, while
- providing access to the status.
-
- Each instance of an erratum is a wrapper class that emulates value
- semantics (copy on write). This means passing even large message
- stacks is inexpensive, involving only a pointer copy and reference
- counter increment and decrement. A success value is represented by
- an internal @c NULL so it is even cheaper to copy.
-
- To further ease use, the library has the ability to define @a
- sinks. A sink is a function that acts on an erratum when it
- becomes unreferenced. The indended use is to send the messages to
- an output log. This makes reporting errors to a log from even
- deeply nested functions easy while preserving the ability of the
- top level logic to control such logging.
-
- @section license License
-
- 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 <memory>
-# include <string>
-# include <iosfwd>
-# include <sstream>
-# include <deque>
-# include "NumericType.h"
-# include "IntrusivePtr.h"
-
-namespace ts {
-
-/** Class to hold a stack of error messages (the "errata").
- This is a smart handle class, which wraps the actual data
- and can therefore be treated a value type with cheap copy
- semantics. Default construction is very cheap.
- */
-class Errata {
-protected:
- /// Implementation class.
- struct Data;
- /// Handle for implementation class instance.
- typedef IntrusivePtr<Data> ImpPtr;
-public:
- typedef Errata self; /// Self reference type.
-
- /// Message ID.
- typedef NumericType<unsigned int, struct MsgIdTag> Id;
-
- /* Tag / level / code severity.
- This is intended for clients to use to provide additional
- classification of a message. A severity code, as for syslog,
- is a common use.
-
- */
- typedef NumericType<unsigned int, struct CodeTag> Code;
- struct Message;
-
- typedef std::deque<Message> Container; ///< Storage type for messages.
- // We iterate backwards to look like a stack.
-// typedef Container::reverse_iterator iterator; ///< Message iteration.
- /// Message const iteration.
-// typedef Container::const_reverse_iterator const_iterator;
- /// Reverse message iteration.
-// typedef Container::iterator reverse_iterator;
- /// Reverse constant message iteration.
-// typedef Container::const_iterator const_reverse_iterator;
-
- /// Default constructor - empty errata, very fast.
- Errata();
- /// Copy constructor, very fast.
- Errata (
- self const& that ///< Object to copy
- );
- /// Construct from string.
- /// Message Id and Code are default.
- explicit Errata(
- std::string const& text ///< Finalized message text.
- );
- /// Construct with @a id and @a text.
- /// Code is default.
- Errata(
- Id id, ///< Message id.
- std::string const& text ///< Message text.
- );
- /// Construct with @a id, @a code, and @a text.
- Errata(
- Id id, ///< Message text.
- Code code, ///< Message code.
- std::string const& text ///< Message text.
- );
- /** Construct from a message instance.
- This is equivalent to default constructing an @c errata and then
- invoking @c push with an argument of @a msg.
- */
- Errata(
- Message const& msg ///< Message to push
- );
-
- /// Move constructor.
- Errata(self && that);
- /// Move constructor from @c Message.
- Errata(Message && msg);
-
- /// destructor
- ~Errata();
-
- /// Self assignment.
- /// @return A reference to this object.
- self& operator = (
- const self& that ///< Source instance.
- );
-
- /// Move assignment.
- self& operator = (self && that);
-
- /** Assign message.
- All other messages are discarded.
- @return A reference to this object.
- */
- self& operator = (
- Message const& msg ///< Source message.
- );
-
- /** Push @a text as a message.
- The message is constructed from just the @a text.
- It becomes the top message.
- @return A reference to this object.
- */
- self& push(std::string const& text);
- /** Push @a text as a message with message @a id.
- The message is constructed from @a text and @a id.
- It becomes the top message.
- @return A reference to this object.
- */
- self& push(Id id, std::string const& text);
- /** Push @a text as a message with message @a id and @a code.
- The message is constructed from @a text and @a id.
- It becomes the top message.
- @return A reference to this object.
- */
- self& push(Id id, Code code, std::string const& text);
- /** Push a message.
- @a msg becomes the top message.
- @return A reference to this object.
- */
- self& push(Message const& msg);
- self& push(Message && msg);
-
- /** Push a constructed @c Message.
- The @c Message is set to have the @a id and @a code. The other arguments are converted
- to strings and concatenated to form the messsage text.
- @return A reference to this object.
- */
- template < typename ... Args >
- self& push(Id id, Code code, Args const& ... args);
-
- /** Push a nested status.
- @a err becomes the top item.
- @return A reference to this object.
- */
- self& push(self const& err);
-
- /** Access top message.
- @return If the errata is empty, a default constructed message
- otherwise the most recent message.
- */
- Message const& top() const;
-
- /** Move messages from @a that to @c this errata.
- Messages from @a that are put on the top of the
- stack in @c this and removed from @a that.
- */
- self& pull(self& that);
-
- /// Remove last message.
- void pop();
-
- /// Remove all messages.
- void clear();
-
- /** Inhibit logging.
- @note This only affects @c this as a top level @c errata.
- It has no effect on this @c this being logged as a nested
- @c errata.
- */
- self& doNotLog();
-
- friend std::ostream& operator<< (std::ostream&, self const&);
-
- /// Default glue value (a newline) for text rendering.
- static std::string const DEFAULT_GLUE;
-
- /** Test status.
-
- Equivalent to @c success but more convenient for use in
- control statements.
-
- @return @c true if no messages or last message has a zero
- message ID, @c false otherwise.
- */
- operator bool() const;
-
- /** Test errata for no failure condition.
-
- Equivalent to @c operator @c bool but easier to invoke.
-
- @return @c true if no messages or last message has a zero
- message ID, @c false otherwise.
- */
- bool isOK() const;
-
- /// Number of messages in the errata.
- size_t size() const;
-
- /* Forward declares.
- We have to make our own iterators as the least bad option. The problem
- is that we have recursive structures so declaration order is difficult.
- We can't use the container iterators here because the element type is
- not yet defined. If we define the element type here, it can't contain
- an Errata and we have to do funky things to get around that. So we
- have our own iterators, which are just shadowing sublclasses of the
- container iterators.
- */
- class iterator;
- class const_iterator;
-
- /// Reference to top item on the stack.
- iterator begin();
- /// Reference to top item on the stack.
- const_iterator begin() const;
- //! Reference one past bottom item on the stack.
- iterator end();
- //! Reference one past bottom item on the stack.
- const_iterator end() const;
-
- // Logging support.
-
- /** Base class for erratum sink.
- When an errata is abandoned, this will be called on it to perform
- any client specific logging. It is passed around by handle so that
- it doesn't have to support copy semantics (and is not destructed
- until application shutdown). Clients can subclass this class in order
- to preserve arbitrary data for the sink or retain a handle to the
- sink for runtime modifications.
- */
- class Sink : public IntrusivePtrCounter {
- public:
- typedef Sink self; ///< Self reference type.
- typedef IntrusivePtr<self> Handle; ///< Handle type.
-
- /// Handle an abandoned errata.
- virtual void operator() (Errata const&) const = 0;
- /// Force virtual destructor.
- virtual ~Sink() {}
- };
-
- //! Register a sink for discarded erratum.
- static void registerSink(Sink::Handle const& s);
-
- /// Register a function as a sink.
- typedef void (*SinkHandlerFunction)(Errata const&);
-
- // Wrapper class to support registering functions as sinks.
- struct SinkFunctionWrapper : public Sink {
- /// Constructor.
- SinkFunctionWrapper(SinkHandlerFunction f) : m_f(f) { }
- /// Operator to invoke the function.
- void operator() (Errata const& e) const override { m_f(e); }
- SinkHandlerFunction m_f; ///< Client supplied handler.
- };
-
- /// Register a sink function for abandonded erratum.
- static void registerSink(SinkHandlerFunction f) {
- registerSink(Sink::Handle(new SinkFunctionWrapper(f)));
- }
-
- /** Simple formatted output.
-
- Each message is written to a line. All lines are indented with
- whitespace @a offset characters. Lines are indented an
- additional @a indent. This value is increased by @a shift for
- each level of nesting of an @c Errata. if @a lead is not @c
- NULL the indentation is overwritten by @a lead if @a indent is
- non-zero. It acts as a "continuation" marker for nested
- @c Errata.
-
- */
- std::ostream& write(
- std::ostream& out, ///< Output stream.
- int offset, ///< Lead white space for every line.
- int indent, ///< Additional indention per line for messages.
- int shift, ///< Additional @a indent for nested @c Errata.
- char const* lead ///< Leading text for nested @c Errata.
- ) const;
- /// Simple formatted output to fixed sized buffer.
- /// @return Number of characters written to @a buffer.
- size_t write(
- char* buffer, ///< Output buffer.
- size_t n, ///< Buffer size.
- int offset, ///< Lead white space for every line.
- int indent, ///< Additional indention per line for messages.
- int shift, ///< Additional @a indent for nested @c Errata.
- char const* lead ///< Leading text for nested @c Errata.
- ) const;
-
-protected:
- /// Construct from implementation pointer.
- /// Used internally by nested classes.
- Errata(ImpPtr const& ptr);
- /// Implementation instance.
- ImpPtr m_data;
-
- /// Return the implementation instance, allocating and unsharing as needed.
- Data* pre_write();
- /// Force and return an implementation instance.
- /// Does not follow copy on write.
- Data const* instance();
-
- /// Used for returns when no data is present.
- static Message const NIL_MESSAGE;
-
- friend struct Data;
- friend class Item;
-
-};
-
-extern std::ostream& operator<< (std::ostream& os, Errata const& stat);
-
-/// Storage for a single message.
-struct Errata::Message {
- typedef Message self; ///< Self reference type.
-
- /// Default constructor.
- /// The message has Id = 0, default code, and empty text.
- Message() = default;
-
- /// Construct from text.
- /// Id is zero and Code is default.
- Message(
- std::string const& text ///< Finalized message text.
- );
-
- /// Construct with @a id and @a text.
- /// Code is default.
- Message(
- Id id, ///< ID of message in table.
- std::string const& text ///< Final text for message.
- );
-
- /// Construct with @a id, @a code, and @a text.
- Message(
- Id id, ///< Message Id.
- Code code, ///< Message Code.
- std::string const& text ///< Final text for message.
- );
-
- /// Construct with an @a id, @a code, and a @a message.
- /// The message contents are created by converting the variable arguments
- /// to strings using the stream operator and concatenated in order.
- template < typename ... Args>
- Message(
- Id id, ///< Message Id.
- Code code, ///< Message Code.
- Args const& ... text
- );
-
- /// Reset to the message to default state.
- self& clear();
-
- /// Set the message Id.
- self& set(
- Id id ///< New message Id.
- );
-
- /// Set the code.
- self& set(
- Code code ///< New code for message.
- );
-
- /// Set the text.
- self& set(
- std::string const& text ///< New message text.
- );
-
- /// Set the text.
- self& set(
- char const* text ///< New message text.
- );
-
- /// Set the errata.
- self& set(
- Errata const& err ///< Errata to store.
- );
-
- /// Get the text of the message.
- std::string const& text() const;
-
- /// Get the code.
- Code getCode() const;
- /// Get the nested status.
- /// @return A status object, which is not @c NULL if there is a
- /// nested status stored in this item.
- Errata getErrata() const;
-
- /** The default message code.
-
- This value is used as the Code value for constructing and
- clearing messages. It can be changed to control the value
- used for empty messages.
- */
- static Code Default_Code;
-
- /// Type for overriding success message test.
- typedef bool (*SuccessTest)(Message const& m);
-
- /** Success message test.
-
- When a message is tested for being "successful", this
- function is called. It may be overridden by a client.
- The initial value is @c DEFAULT_SUCCESS_TEST.
-
- @note This is only called when there are Messages in the
- Errata. An empty Errata (@c NULL or empty stack) is always
- a success. Only the @c top Message is checked.
-
- @return @c true if the message indicates success,
- @c false otherwise.
- */
- static SuccessTest Success_Test;
-
- /// Indicate success if the message code is zero.
- /// @note Used as the default success test.
- static bool isCodeZero(Message const& m);
-
- static SuccessTest const DEFAULT_SUCCESS_TEST;
-
- template < typename ... Args> static std::string stringify(Args const& ... items);
-
- Id m_id = 0; ///< Message ID.
- Code m_code = Default_Code; ///< Message code.
- std::string m_text; ///< Final text.
- Errata m_errata; ///< Nested errata.
-};
-
-/** This is the implementation class for Errata.
-
- It holds the actual messages and is treated as a passive data
- object with nice constructors.
-
- We implement reference counting semantics by hand for two
- reasons. One is that we need to do some specialized things, but
- mainly because the client can't see this class so we can't
-*/
-struct Errata::Data : public IntrusivePtrCounter {
- typedef Data self; ///< Self reference type.
-
- //! Default constructor.
- Data();
-
- /// Destructor, to do logging.
- ~Data();
-
- //! Number of messages.
- size_t size() const;
-
- /// Get the top message on the stack.
- Message const& top() const;
-
- /// Put a message on top of the stack.
- void push(Message const& msg);
- void push(Message && msg);
-
- /// Log this when it is deleted.
- mutable bool m_log_on_delete = true;
-
- //! The message stack.
- Container m_items;
-};
-
-/// Forward iterator for @c Messages in an @c Errata.
-class Errata::iterator : public Errata::Container::reverse_iterator {
-public:
- typedef iterator self; ///< Self reference type.
- typedef Errata::Container::reverse_iterator super; ///< Parent type.
- iterator(); ///< Default constructor.
- /// Copy constructor.
- iterator(
- self const& that ///< Source instance.
- );
- /// Construct from super class.
- iterator(
- super const& that ///< Source instance.
- );
- /// Assignment.
- self& operator = (self const& that);
- /// Assignment from super class.
- self& operator = (super const& that);
- /// Prefix increment.
- self& operator ++ ();
- /// Prefix decrement.
- self& operator -- ();
-};
-
-/// Forward constant iterator for @c Messages in an @c Errata.
-class Errata::const_iterator : public Errata::Container::const_reverse_iterator {
-public:
- typedef const_iterator self; ///< Self reference type.
- typedef Errata::Container::const_reverse_iterator super; ///< Parent type.
- const_iterator(); ///< Default constructor.
- /// Copy constructor.
- const_iterator(
- self const& that ///< Source instance.
- );
- const_iterator(
- super const& that ///< Source instance.
- );
- /// Assignment.
- self& operator = (self const& that);
- /// Assignment from super class.
- self& operator = (super const& that);
- /// Prefix increment.
- self& operator ++ ();
- /// Prefix decrement.
- self& operator -- ();
-};
-
-/** Helper class for @c Rv.
- This class enables us to move the implementation of non-templated methods
- and members out of the header file for a cleaner API.
- */
-struct RvBase {
- Errata _errata; ///< The status from the function.
-
- /** Default constructor. */
- RvBase();
-
- /** Construct with specific status.
- */
- RvBase (
- Errata const& s ///< Status to copy
- );
-
- //! Test the return value for success.
- bool isOK() const;
-
- /** Clear any stacked errors.
- This is useful during shutdown, to silence irrelevant errors caused
- by the shutdown process.
- */
- void clear();
-
- /// Inhibit logging of the errata.
- void doNotLog();
-};
-
-/** Return type for returning a value and status (errata). In
- general, a method wants to return both a result and a status so
- that errors are logged properly. This structure is used to do that
- in way that is more usable than just @c std::pair. - Simpler and
- shorter typography - Force use of @c errata rather than having to
- remember it (and the order) each time - Enable assignment directly
- to @a R for ease of use and compatibility so clients can upgrade
- asynchronously.
- */
-template < typename R >
-struct Rv : public RvBase {
- typedef Rv self; ///< Standard self reference type.
- typedef RvBase super; ///< Standard super class reference type.
- typedef R Result; ///< Type of result value.
-
- Result _result; ///< The actual result of the function.
-
- /** Default constructor.
- The default constructor for @a R is used.
- The status is initialized to SUCCESS.
- */
- Rv();
-
- /** Standard (success) constructor.
-
- This copies the result and sets the status to SUCCESS.
-
- @note Not @c explicit so that clients can return just a result
- and have it be marked as SUCCESS.
- */
- Rv(
- Result const& r ///< The function result
- );
-
- /** Construct from a result and a pre-existing status object.
-
- @internal No constructor from just an Errata to avoid
- potential ambiguity with constructing from result type.
- */
- Rv(
- Result const& r, ///< The function result
- Errata const& s ///< A pre-existing status object
- );
-
- /** User conversion to the result type.
-
- This makes it easy to use the function normally or to pass the
- result only to other functions without having to extract it by
- hand.
- */
- operator Result const& () const;
-
- /** Assignment from result type.
-
- This allows the result to be assigned to a pre-declared return
- value structure. The return value is a reference to the
- internal result so that this operator can be chained in other
- assignments to instances of result type. This is most commonly
- used when the result is computed in to a local variable to be
- both returned and stored in a member.
-
- @code
- Rv<int> zret;
- int value;
- // ... complex computations, result in value
- this->m_value = zret = value;
- // ...
- return zret;
- @endcode
-
- @return A reference to the copy of @a r stored in this object.
- */
- Result& operator = (
- Result const& r ///< Result to assign
- ) {
- _result = r;
- return _result;
- }
-
- /** Add the status from another instance to this one.
- @return A reference to @c this object.
- */
- template < typename U >
- self& push(
- Rv<U> const& that ///< Source of status messages
- );
-
- /** Set the result.
-
- This differs from assignment of the function result in that the
- return value is a reference to the @c Rv, not the internal
- result. This makes it useful for assigning a result local
- variable and then returning.
-
- @code
- Rv<int> zret;
- int value;
- // ... complex computation, result in value
- return zret.set(value);
- @endcode
- */
- self& set(
- Result const& r ///< Result to store
- );
-
- /** Return the result.
- @return A reference to the result value in this object.
- */
- Result& result();
-
- /** Return the result.
- @return A reference to the result value in this object.
- */
- Result const& result() const;
-
- /** Return the status.
- @return A reference to the @c errata in this object.
- */
- Errata& errata();
-
- /** Return the status.
- @return A reference to the @c errata in this object.
- */
- Errata const& errata() const;
-
- /// Directly set the errata
- self& operator = (
- Errata const& status ///< Errata to assign.
- );
-
- /// Push a message on to the status.
- self& push(
- Errata::Message const& msg
- );
-};
-
-/** Combine a function result and status in to an @c Rv.
- This is useful for clients that want to declare the status object
- and result independently.
- */
-template < typename R > Rv<R>
-MakeRv(
- R const& r, ///< The function result
- Errata const& s ///< The pre-existing status object
-) {
- return Rv<R>(r, s);
-}
-/* ----------------------------------------------------------------------- */
-/* ----------------------------------------------------------------------- */
-// Inline methods.
-inline Errata::Message::Message(std::string const& text)
- : m_text(text) {
-}
-inline Errata::Message::Message(Id id, std::string const& text)
- : m_text(text) {
-}
-inline Errata::Message::Message(Id id, Code code, std::string const& text)
- : m_text(text) {
-}
-template < typename ... Args>
-Errata::Message::Message(Id id, Code code, Args const& ... text)
- : m_id(id), m_code(code), m_text(stringify(text ...))
-{
-}
-
-inline Errata::Message& Errata::Message::clear() {
- m_id = 0;
- m_code = Default_Code;
- m_text.erase();
- m_errata.clear();
- return *this;
-}
-
-inline std::string const& Errata::Message::text() const { return m_text; }
-inline Errata::Code Errata::Message::getCode() const { return m_code; }
-inline Errata Errata::Message::getErrata() const { return m_errata; }
-
-inline Errata::Message& Errata::Message::set(Id id) {
- m_id = id;
- return *this;
-}
-inline Errata::Message& Errata::Message::set(Code code) {
- m_code = code;
- return *this;
-}
-inline Errata::Message& Errata::Message::set(std::string const& text) {
- m_text = text;
- return *this;
-}
-inline Errata::Message& Errata::Message::set(char const* text) {
- m_text = text;
- return *this;
-}
-inline Errata::Message& Errata::Message::set(Errata const& err) {
- m_errata = err;
- m_errata.doNotLog();
- return *this;
-}
-
-template < typename ... Args>
-std::string Errata::Message::stringify(Args const& ... items)
-{
- std::ostringstream s;
- (void)(int[]){0, ( (s << items) , 0 ) ... };
- return s.str();
-}
-
-inline Errata::Errata() {}
-inline Errata::Errata(Id id, Code code, std::string const& text) {
- this->push(Message(id, code, text));
-}
-inline Errata::Errata(Message const& msg) {
- this->push(msg);
-}
-inline Errata::Errata(Message && msg) {
- this->push(std::move(msg));
-}
-
-inline Errata::operator bool() const { return this->isOK(); }
-
-inline size_t Errata::size() const {
- return m_data ? m_data->m_items.size() : 0;
-}
-
-inline bool Errata::isOK() const {
- return nullptr == m_data
- || 0 == m_data->size()
- || Message::Success_Test(this->top())
- ;
-}
-
-inline Errata&
-Errata::push(std::string const& text) {
- this->push(Message(text));
- return *this;
-}
-
-inline Errata&
-Errata::push(Id id, std::string const& text) {
- this->push(Message(id, text));
- return *this;
-}
-
-inline Errata&
-Errata::push(Id id, Code code, std::string const& text) {
- this->push(Message(id, code, text));
- return *this;
-}
-
-template < typename ... Args >
-auto Errata::push(Id id, Code code, Args const& ... args) -> self&
-{
- this->push(Message(id, code, args ...));
- return *this;
-}
-
-inline Errata::Message const&
-Errata::top() const {
- return m_data ? m_data->top() : NIL_MESSAGE;
-}
-inline Errata& Errata::doNotLog() {
- this->instance()->m_log_on_delete = false;
- return *this;
-}
-
-inline Errata::Data::Data() {}
-inline size_t Errata::Data::size() const { return m_items.size(); }
-
-inline Errata::iterator::iterator() { }
-inline Errata::iterator::iterator(self const& that) : super(that) { }
-inline Errata::iterator::iterator(super const& that) : super(that) { }
-inline Errata::iterator& Errata::iterator::operator = (self const& that) { this->super::operator = (that); return *this; }
-inline Errata::iterator& Errata::iterator::operator = (super const& that) { this->super::operator = (that); return *this; }
-inline Errata::iterator& Errata::iterator::operator ++ () { this->super::operator ++ (); return *this; }
-inline Errata::iterator& Errata::iterator::operator -- () { this->super::operator -- (); return *this; }
-
-inline Errata::const_iterator::const_iterator() { }
-inline Errata::const_iterator::const_iterator(self const& that) : super(that) { }
-inline Errata::const_iterator::const_iterator(super const& that) : super(that) { }
-inline Errata::const_iterator& Errata::const_iterator::operator = (self const& that) { super::operator = (that); return *this; }
-inline Errata::const_iterator& Errata::const_iterator::operator = (super const& that) { super::operator = (that); return *this; }
-inline Errata::const_iterator& Errata::const_iterator::operator ++ () { this->super::operator ++ (); return *this; }
-inline Errata::const_iterator& Errata::const_iterator::operator -- () { this->super::operator -- (); return *this; }
-
-inline RvBase::RvBase() { }
-inline RvBase::RvBase(Errata const& errata) : _errata(errata) { }
-inline bool RvBase::isOK() const { return _errata; }
-inline void RvBase::clear() { _errata.clear(); }
-inline void RvBase::doNotLog() { _errata.doNotLog(); }
-
-template < typename T > Rv<T>::Rv() : _result() { }
-template < typename T > Rv<T>::Rv(Result const& r) : _result(r) { }
-template < typename T > Rv<T>::Rv(Result const& r, Errata const& errata)
- : super(errata)
- , _result(r) {
-}
-template < typename T > Rv<T>::operator Result const&() const {
- return _result;
-}
-template < typename T > T const& Rv<T>::result() const { return _result; }
-template < typename T > T& Rv<T>::result() { return _result; }
-template < typename T > Errata const& Rv<T>::errata() const { return _errata; }
-template < typename T > Errata& Rv<T>::errata() { return _errata; }
-template < typename T > Rv<T>&
-Rv<T>::set(Result const& r) {
- _result = r;
- return *this;
-}
-template < typename T > Rv<T>&
-Rv<T>::operator = (Errata const& errata) {
- _errata = errata;
- return *this;
-}
-template < typename T > Rv<T>&
-Rv<T>::push(Errata::Message const& msg) {
- _errata.push(msg);
- return *this;
-}
-template < typename T > template < typename U > Rv<T>&
-Rv<T>::push(Rv<U> const& that) {
- _errata.push(that.errata());
- return *this;
-}
-/* ----------------------------------------------------------------------- */
-/* ----------------------------------------------------------------------- */
-} // namespace ts
-
-# endif // TS_ERRATA_HEADER
diff --git a/lib/tsconfig/Makefile.am b/lib/tsconfig/Makefile.am
deleted file mode 100644
index fd47d44..0000000
--- a/lib/tsconfig/Makefile.am
+++ /dev/null
@@ -1,40 +0,0 @@
-# Makefile.am for TS Config module.
-#
-# 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.
-
-lib_LTLIBRARIES = libtsconfig.la
-libtsconfig_la_LDFLAGS = -version-info @TS_LIBTOOL_VERSION@
-
-AM_CFLAGS += @FLEX_CFLAGS@
-
-AM_CPPFLAGS += \
- -I$(abs_top_srcdir)/include \
- -I$(abs_top_srcdir)/lib \
- $(TS_INCLUDES)
-
-CLEANFILES = $(BUILT_SOURCES)
-
-libtsconfig_la_SOURCES = \
- Errata.cc \
- Errata.h \
- IntrusivePtr.h \
- NumericType.h
-
-include $(top_srcdir)/build/tidy.mk
-
-clang-tidy-local: $(DIST_SOURCES)
- $(CXX_Clang_Tidy)
diff --git a/mgmt/utils/Makefile.am b/mgmt/utils/Makefile.am
index 4da8913..8c366b1 100644
--- a/mgmt/utils/Makefile.am
+++ b/mgmt/utils/Makefile.am
@@ -22,7 +22,6 @@ AM_CPPFLAGS += \
-I$(abs_top_srcdir)/mgmt \
-I$(abs_top_srcdir)/mgmt/api \
-I$(abs_top_srcdir)/mgmt/api/include \
- -I$(abs_top_srcdir)/include/tsconfig \
-I$(abs_top_srcdir)/proxy \
-I$(abs_top_srcdir)/include \
-I$(abs_top_srcdir)/lib \
diff --git a/src/traffic_cache_tool/CacheDefs.h b/src/traffic_cache_tool/CacheDefs.h
index 8a1b202..bc22ace 100644
--- a/src/traffic_cache_tool/CacheDefs.h
+++ b/src/traffic_cache_tool/CacheDefs.h
@@ -22,15 +22,17 @@
*/
#pragma once
+
#include <netinet/in.h>
#include <iostream>
+#include <list>
+
#include "tscore/I_Version.h"
#include "tscore/Scalar.h"
#include "tscore/Regex.h"
-#include <tsconfig/Errata.h>
+#include "tscore/Errata.h"
#include "tscpp/util/TextView.h"
#include "tscore/ink_file.h"
-#include <list>
#include "tscore/CryptoHash.h"
#include "tscore/ts_file.h"
diff --git a/src/traffic_cache_tool/Makefile.inc b/src/traffic_cache_tool/Makefile.inc
index 8af4112..623910b 100644
--- a/src/traffic_cache_tool/Makefile.inc
+++ b/src/traffic_cache_tool/Makefile.inc
@@ -43,8 +43,8 @@ traffic_cache_tool_traffic_cache_tool_LDADD = \
$(top_builddir)/src/tscore/.libs/ink_string.o \
$(top_builddir)/src/tscore/.libs/BufferWriterFormat.o \
$(top_builddir)/src/tscore/.libs/ts_file.o \
+ $(top_builddir)/src/tscore/.libs/Errata.o \
$(top_builddir)/src/tscpp/util/.libs/TextView.o \
- $(top_builddir)/lib/tsconfig/.libs/Errata.o \
$(top_builddir)/src/tscore/.libs/Regex.o \
$(top_builddir)/src/tscore/.libs/CryptoHash.o \
$(top_builddir)/src/tscore/.libs/MMH.o \
diff --git a/src/traffic_manager/Makefile.inc b/src/traffic_manager/Makefile.inc
index 19dfb92..db5a955 100644
--- a/src/traffic_manager/Makefile.inc
+++ b/src/traffic_manager/Makefile.inc
@@ -57,6 +57,5 @@ traffic_manager_traffic_manager_LDADD = \
if BUILD_WCCP
traffic_manager_traffic_manager_LDADD += \
wccp/libwccp.a \
- $(top_builddir)/lib/tsconfig/libtsconfig.la \
@OPENSSL_LIBS@
endif
diff --git a/src/traffic_server/Makefile.inc b/src/traffic_server/Makefile.inc
index a18d6ce..9d3d621 100644
--- a/src/traffic_server/Makefile.inc
+++ b/src/traffic_server/Makefile.inc
@@ -79,7 +79,6 @@ traffic_server_traffic_server_LDADD = \
$(top_builddir)/iocore/net/libinknet.a \
$(top_builddir)/lib/records/librecords_p.a \
$(top_builddir)/iocore/eventsystem/libinkevent.a \
- $(top_builddir)/lib/tsconfig/libtsconfig.la \
@HWLOC_LIBS@ \
@LIBPCRE@ \
@LIBRESOLV@ \
diff --git a/src/traffic_wccp/Makefile.inc b/src/traffic_wccp/Makefile.inc
index daa92f4..5b946bb 100644
--- a/src/traffic_wccp/Makefile.inc
+++ b/src/traffic_wccp/Makefile.inc
@@ -35,7 +35,6 @@ traffic_wccp_traffic_wccp_SOURCES = \
traffic_wccp/wccp_client.cc
traffic_wccp_traffic_wccp_LDADD = \
- $(top_builddir)/lib/tsconfig/libtsconfig.la \
$(top_builddir)/src/wccp/libwccp.a \
$(top_builddir)/src/tscore/libtscore.la \
$(top_builddir)/src/tscpp/util/libtscpputil.la \
diff --git a/src/traffic_wccp/wccp_client.cc b/src/traffic_wccp/wccp_client.cc
index b4e140f..3ca292e 100644
--- a/src/traffic_wccp/wccp_client.cc
+++ b/src/traffic_wccp/wccp_client.cc
@@ -40,7 +40,7 @@
#include "wccp/Wccp.h"
#include "../wccp/WccpUtil.h"
#include "tscore/ink_lockfile.h"
-#include "tsconfig/Errata.h"
+#include "tscore/Errata.h"
#define WCCP_LOCK "wccp.pid"
diff --git a/lib/tsconfig/Errata.cc b/src/tscore/Errata.cc
similarity index 60%
rename from lib/tsconfig/Errata.cc
rename to src/tscore/Errata.cc
index f91ca7f..ded3bf5 100644
--- a/lib/tsconfig/Errata.cc
+++ b/src/tscore/Errata.cc
@@ -20,86 +20,89 @@
limitations under the License.
*/
-# include "Errata.h"
-# include <iostream>
-# include <sstream>
-# include <iomanip>
-# include <algorithm>
-# include <memory.h>
+#include "tscore/Errata.h"
-namespace ts {
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <algorithm>
+#include <memory.h>
+namespace ts
+{
/** List of sinks for abandoned erratum.
*/
-namespace {
+namespace
+{
std::deque<Errata::Sink::Handle> Sink_List;
}
std::string const Errata::DEFAULT_GLUE("\n");
Errata::Message const Errata::NIL_MESSAGE;
-Errata::Code Errata::Message::Default_Code = 0;
-Errata::Message::SuccessTest const Errata::Message::DEFAULT_SUCCESS_TEST =
- &Errata::Message::isCodeZero;
-Errata::Message::SuccessTest Errata::Message::Success_Test =
- Errata::Message::DEFAULT_SUCCESS_TEST;
+Errata::Code Errata::Message::Default_Code = 0;
+Errata::Message::SuccessTest const Errata::Message::DEFAULT_SUCCESS_TEST = &Errata::Message::isCodeZero;
+Errata::Message::SuccessTest Errata::Message::Success_Test = Errata::Message::DEFAULT_SUCCESS_TEST;
bool
-Errata::Message::isCodeZero(Message const& msg) {
+Errata::Message::isCodeZero(Message const &msg)
+{
return msg.m_code == 0;
}
void
-Errata::Data::push(Message const& msg) {
+Errata::Data::push(Message const &msg)
+{
m_items.push_back(msg);
}
void
-Errata::Data::push(Message && msg) {
+Errata::Data::push(Message &&msg)
+{
m_items.push_back(std::move(msg));
}
-Errata::Message const&
-Errata::Data::top() const {
- return m_items.size() ? m_items.back() : NIL_MESSAGE ;
+Errata::Message const &
+Errata::Data::top() const
+{
+ return m_items.size() ? m_items.back() : NIL_MESSAGE;
}
-inline Errata::Errata(ImpPtr const& ptr)
- : m_data(ptr) {
-}
+inline Errata::Errata(ImpPtr const &ptr) : m_data(ptr) {}
-Errata::Data::~Data() {
+Errata::Data::~Data()
+{
if (m_log_on_delete) {
Errata tmp(ImpPtr(this)); // because client API requires a wrapper.
- for ( auto& f : Sink_List ) { (*f)(tmp); }
+ for (auto &f : Sink_List) {
+ (*f)(tmp);
+ }
tmp.m_data.release(); // don't delete this again.
}
}
-Errata::Errata(self const& that)
- : m_data(that.m_data) {
-}
+Errata::Errata(self const &that) : m_data(that.m_data) {}
-Errata::Errata(self && that)
- : m_data(that.m_data) {
-}
+Errata::Errata(self &&that) : m_data(that.m_data) {}
-Errata::Errata(std::string const& text) {
+Errata::Errata(std::string const &text)
+{
this->push(text);
}
-Errata::Errata(Id id, std::string const& text) {
+Errata::Errata(Id id, std::string const &text)
+{
this->push(id, text);
}
-Errata::~Errata() {
-}
+Errata::~Errata() {}
/* This forces the errata to have a data object that only it references.
If we're sharing the data, clone. If there's no data, allocate.
This is used just before a write operation to have copy on write semantics.
*/
-Errata::Data*
-Errata::pre_write() {
+Errata::Data *
+Errata::pre_write()
+{
if (m_data) {
if (m_data.use_count() > 1) {
m_data.reset(new Data(*m_data)); // clone current data
@@ -111,33 +114,39 @@ Errata::pre_write() {
}
// Just create an instance if needed.
-Errata::Data const*
-Errata::instance() {
- if (!m_data) { m_data.reset(new Data);
-}
+Errata::Data const *
+Errata::instance()
+{
+ if (!m_data) {
+ m_data.reset(new Data);
+ }
return m_data.get();
}
-Errata&
-Errata::push(Message const& msg) {
+Errata &
+Errata::push(Message const &msg)
+{
this->pre_write()->push(msg);
return *this;
}
-Errata&
-Errata::push(Message && msg) {
+Errata &
+Errata::push(Message &&msg)
+{
this->pre_write()->push(std::move(msg));
return *this;
}
-Errata&
-Errata::operator=(self const& that) {
+Errata &
+Errata::operator=(self const &that)
+{
m_data = that.m_data;
return *this;
}
-Errata&
-Errata::operator = (Message const& msg) {
+Errata &
+Errata::operator=(Message const &msg)
+{
// Avoid copy on write in the case where we discard.
if (!m_data || m_data.use_count() > 1) {
this->clear();
@@ -149,28 +158,27 @@ Errata::operator = (Message const& msg) {
return *this;
}
-Errata&
-Errata::operator = (self && that) {
+Errata &
+Errata::operator=(self &&that)
+{
m_data = that.m_data;
return *this;
}
-Errata&
-Errata::pull(self& that) {
+Errata &
+Errata::pull(self &that)
+{
if (that.m_data) {
this->pre_write();
- m_data->m_items.insert(
- m_data->m_items.end(),
- that.m_data->m_items.begin(),
- that.m_data->m_items.end()
- );
+ m_data->m_items.insert(m_data->m_items.end(), that.m_data->m_items.begin(), that.m_data->m_items.end());
that.m_data->m_items.clear();
}
return *this;
}
void
-Errata::pop() {
+Errata::pop()
+{
if (m_data && m_data->size()) {
this->pre_write()->m_items.pop_front();
}
@@ -178,7 +186,8 @@ Errata::pop() {
}
void
-Errata::clear() {
+Errata::clear()
+{
m_data.reset(nullptr);
}
@@ -195,67 +204,54 @@ Errata::clear() {
static Errata::Container NIL_CONTAINER;
Errata::iterator
-Errata::begin() {
+Errata::begin()
+{
return m_data ? m_data->m_items.rbegin() : NIL_CONTAINER.rbegin();
}
Errata::const_iterator
-Errata::begin() const {
- return m_data ? static_cast<Data const&>(*m_data).m_items.rbegin()
- : static_cast<Container const&>(NIL_CONTAINER).rbegin();
+Errata::begin() const
+{
+ return m_data ? static_cast<Data const &>(*m_data).m_items.rbegin() : static_cast<Container const &>(NIL_CONTAINER).rbegin();
}
Errata::iterator
-Errata::end() {
+Errata::end()
+{
return m_data ? m_data->m_items.rend() : NIL_CONTAINER.rend();
}
Errata::const_iterator
-Errata::end() const {
- return m_data ? static_cast<Data const&>(*m_data).m_items.rend()
- : static_cast<Container const&>(NIL_CONTAINER).rend();
+Errata::end() const
+{
+ return m_data ? static_cast<Data const &>(*m_data).m_items.rend() : static_cast<Container const &>(NIL_CONTAINER).rend();
}
void
-Errata::registerSink(Sink::Handle const& s) {
+Errata::registerSink(Sink::Handle const &s)
+{
Sink_List.push_back(s);
}
-std::ostream&
-Errata::write(
- std::ostream& out,
- int offset,
- int indent,
- int shift,
- char const* lead
-) const {
-
- for ( auto m : *this ) {
+std::ostream &
+Errata::write(std::ostream &out, int offset, int indent, int shift, char const *lead) const
+{
+ for (auto m : *this) {
if ((offset + indent) > 0) {
- out << std::setw(indent + offset) << std::setfill(' ')
- << ((indent > 0 && lead) ? lead : " ");
+ out << std::setw(indent + offset) << std::setfill(' ') << ((indent > 0 && lead) ? lead : " ");
}
- out << m.m_id << " [" << m.m_code << "]: " << m.m_text
- << std::endl
- ;
+ out << m.m_id << " [" << m.m_code << "]: " << m.m_text << std::endl;
if (m.getErrata().size()) {
- m.getErrata().write(out, offset, indent+shift, shift, lead);
-}
-
+ m.getErrata().write(out, offset, indent + shift, shift, lead);
+ }
}
return out;
}
size_t
-Errata::write(
- char *buff,
- size_t n,
- int offset,
- int indent,
- int shift,
- char const* lead
-) const {
+Errata::write(char *buff, size_t n, int offset, int indent, int shift, char const *lead) const
+{
std::ostringstream out;
std::string text;
this->write(out, offset, indent, shift, lead);
@@ -264,7 +260,9 @@ Errata::write(
return text.size();
}
-std::ostream& operator<< (std::ostream& os, Errata const& err) {
+std::ostream &
+operator<<(std::ostream &os, Errata const &err)
+{
return err.write(os, 0, 0, 2, "> ");
}
diff --git a/src/tscore/Makefile.am b/src/tscore/Makefile.am
index bb6fd0c..dd62c06 100644
--- a/src/tscore/Makefile.am
+++ b/src/tscore/Makefile.am
@@ -56,6 +56,7 @@ libtscore_la_SOURCES = \
ContFlags.cc \
CryptoHash.cc \
Diags.cc \
+ Errata.cc \
EventNotify.cc \
Extendible.cc \
fastlz.c \
diff --git a/src/tscore/unit_tests/test_IntrusivePtr.cc b/src/tscore/unit_tests/test_IntrusivePtr.cc
index d4a130a..5f5ff08 100644
--- a/src/tscore/unit_tests/test_IntrusivePtr.cc
+++ b/src/tscore/unit_tests/test_IntrusivePtr.cc
@@ -21,9 +21,10 @@
limitations under the License.
*/
+#include "tscore/IntrusivePtr.h"
+
#include <string>
#include <sstream>
-#include <tsconfig/IntrusivePtr.h>
#include <catch.hpp>
struct Thing : public ts::IntrusivePtrCounter {
diff --git a/src/wccp/WccpLocal.h b/src/wccp/WccpLocal.h
index db1ec24..773ce91 100644
--- a/src/wccp/WccpLocal.h
+++ b/src/wccp/WccpLocal.h
@@ -25,7 +25,7 @@
#include "wccp/Wccp.h"
#include "WccpUtil.h"
#include "ts/apidefs.h"
-#include "tsconfig/Errata.h"
+#include "tscore/Errata.h"
// Needed for template use of byte ordering functions.
#include <netinet/in.h>
#include <memory.h>
diff --git a/src/wccp/WccpUtil.h b/src/wccp/WccpUtil.h
index 3d65913..2c5d5f2 100644
--- a/src/wccp/WccpUtil.h
+++ b/src/wccp/WccpUtil.h
@@ -24,7 +24,7 @@
#include <vector>
-#include "tsconfig/Errata.h"
+#include "tscore/Errata.h"
namespace wccp
{
diff --git a/tools/git/pre-commit b/tools/git/pre-commit
index 748215b..48cfaa1 100755
--- a/tools/git/pre-commit
+++ b/tools/git/pre-commit
@@ -47,7 +47,7 @@ patch_file=$(mktemp -t clang-format.XXXXXXXXXX)
trap "rm -f $patch_file" 0 1 2 3 5 15
# Loop over all files that are changed, and produce a diff file
-git diff-index --cached --diff-filter=ACMR --name-only HEAD | grep -vE "lib/tsconfig|lib/yamlcpp" | while read file; do
+git diff-index --cached --diff-filter=ACMR --name-only HEAD | grep -vE "lib/yamlcpp" | while read file; do
case "$file" in
*.cc | *.c | *.h | *.h.in)
${FORMAT} "$file" | diff -u "$file" - >> "$patch_file"