You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2018/08/13 20:05:26 UTC

[trafficserver] branch 8.0.x updated (40f80dc -> 22b1ff6)

This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a change to branch 8.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git.


    from 40f80dc  make sure len is smaller than MAX_ENTRY before we use it as the index
     new d3ab5b5  BufferWriter: Some minor cleanups. Clean up use of std::literal, add bwf::Errno default constructor, move Date format to explicit default.
     new c25f554  BufferWriter: Add OptionalAffix support for optionally printing strings. Update the documenation.
     new 22b1ff6  TextView: Add constexpr literal constructor for std::string_view.

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../internal-libraries/buffer-writer.en.rst        | 92 ++++++++++++++++++----
 lib/ts/BufferWriter.h                              |  5 +-
 lib/ts/BufferWriterFormat.cc                       |  6 ++
 lib/ts/TextView.h                                  | 10 +++
 lib/ts/bwf_std_format.h                            | 48 ++++++++++-
 5 files changed, 141 insertions(+), 20 deletions(-)


[trafficserver] 02/03: BufferWriter: Add OptionalAffix support for optionally printing strings. Update the documenation.

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 8.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit c25f554a9c1c250305e48bd0fdc16cfd2ce1f22c
Author: Alan M. Carroll <am...@apache.org>
AuthorDate: Mon Jul 2 20:46:56 2018 -0500

    BufferWriter: Add OptionalAffix support for optionally printing strings.
    Update the documenation.
    
    (cherry picked from commit 59d1c368e94c7c3f2c1ccf44b69f65bdc3158f74)
---
 .../internal-libraries/buffer-writer.en.rst        | 92 ++++++++++++++++++----
 lib/ts/BufferWriterFormat.cc                       |  6 ++
 lib/ts/bwf_std_format.h                            | 25 ++++++
 3 files changed, 109 insertions(+), 14 deletions(-)

diff --git a/doc/developer-guide/internal-libraries/buffer-writer.en.rst b/doc/developer-guide/internal-libraries/buffer-writer.en.rst
index 4f7a416..adbf871 100644
--- a/doc/developer-guide/internal-libraries/buffer-writer.en.rst
+++ b/doc/developer-guide/internal-libraries/buffer-writer.en.rst
@@ -638,7 +638,9 @@ uses the :code:`std::string` overload for :func:`bwprint` would look like ::
    }
 
 This gathers the argument (generally references to the arguments) in to a single tuple which is then
-passed by reference, to avoid restacking the arguments for every nested function call.
+passed by reference, to avoid restacking the arguments for every nested function call. In essence the
+arguments are put on the stack (inside the tuple) once and a reference to that stack is passed to
+nested functions.
 
 Specialized Types
 -----------------
@@ -715,46 +717,108 @@ but can be overloaded to produce different (wrapper class based) output. The cla
 such as the descriptive string for the value. To do this the format wrapper class :code:`ts::bwf::Errno`
 is provided. Using it is simple::
 
-    w.print("File not open - {}", ts::bwf::Errno(errno));
+   w.print("File not open - {}", ts::bwf::Errno(errno));
 
 which will produce output that looks like
 
-    "File not open - EACCES: Permission denied [13]"
+   "File not open - EACCES: Permission denied [13]"
 
 For :code:`errno` this is handy in another way as :code:`ts::bwf::Errno` will preserve the value of
 :code:`errno` across other calls that might change it. E.g.::
 
-    ts::bwf::Errno last_err(errno);
-    // some other code generating diagnostics that might tweak errno.
-    w.print("File not open - {}", last_err);
+   ts::bwf::Errno last_err(errno);
+   // some other code generating diagnostics that might tweak errno.
+   w.print("File not open - {}", last_err);
+
+This can also be useful for user defined data types. For instance, in the HostDB the type of the entry
+is printed in multiple places and each time this code is repeated ::
+
+      "%s%s %s", r->round_robin ? "Round-Robin" : "",
+         r->reverse_dns ? "Reverse DNS" : "", r->is_srv ? "SRV" : "DNS"
+
+This could be wrapped in a class, :code:`HostDBType` such as ::
+
+   struct HostDBType {
+      HostDBInfo* _r { nullptr };
+      HostDBType(r) : _r(r) {}
+   };
+
+Then define a formatter for the wrapper ::
+
+   BufferWriter& bwformat(BufferWriter& w, BWFSpec const& spec, HostDBType const& wrap) {
+     return w.print("{}{} {}", wrap._r->round_robin ? "Round-Robin" : "",
+        r->reverse_dns ? "Reverse DNS" : "",
+        r->is_srv ? "SRV" : "DNS");
+   }
+
+Now this can be output elsewhere with just
+
+   w.print("{}", HostDBType(r));
+
+If this is used multiple places, this is cleaner and more robust as it can be updated everywhere with a
+change in a single code location.
 
 These are the existing format classes in header file ``bfw_std_format.h``. All are in the :code:`ts::bwf` namespace.
 
 .. class:: Errno
 
-    Formating for :code:`errno`.
+   Formating for :code:`errno`.
 
-    .. function:: Errno(int errno)
+   .. function:: Errno(int errno)
 
 .. class:: Date
 
-    Date formatting in the :code:`strftime` style.
+   Date formatting in the :code:`strftime` style.
 
-    .. function:: Date(time_t epoch, std::string_view fmt = "%Y %b %d %H:%M:%S")
+   .. function:: Date(time_t epoch, std::string_view fmt = "%Y %b %d %H:%M:%S")
 
-        :arg:`epoch` is the time to print. :arg:`fmt` is the format for printing which is identical to that of `strftime <https://linux.die.net/man/3/strftime>`__. The default format looks like "2018 Jun 08 13:55:37".
+      :arg:`epoch` is the time to print. :arg:`fmt` is the format for printing which is identical to
+      that of `strftime <https://linux.die.net/man/3/strftime>`__. The default format looks like
+      "2018 Jun 08 13:55:37".
 
-    .. function:: Date(std::string_view fmt = "%Y %b %d %H:%M:%S")
+   .. function:: Date(std::string_view fmt = "%Y %b %d %H:%M:%S")
 
-         As previous except the epoch is the current epoch at the time the constructor is invoked. Therefore if the current time is to be printed the default constructor can be used.
+      As previous except the epoch is the current epoch at the time the constructor is invoked.
+      Therefore if the current time is to be printed the default constructor can be used.
 
-   When used the format specification can take an extention of "local" which formats the time as local time. Otherwise it is GMT.
+   When used the format specification can take an extention of "local" which formats the time as
+   local time. Otherwise it is GMT.
    ``w.print("{}", Date("%H:%M"));`` will print the hour and minute as GMT values. ``w.print("{::local}", Date("%H:%M"));`` will
    When used the format specification can take an extention of "local" which formats the time as local time. Otherwise it is GMT.
    ``w.print("{}", Date("%H:%M"));`` will print the hour and minute as GMT values. ``w.print("{::local}", Date("%H:%M"));`` will
    print the hour and minute in the local time zone. ``w.print("{::gmt}"), ...);`` will output in GMT if additional explicitness is
    desired.
 
+.. class:: OptionalAffix
+
+   Affix support for printing optional strings. This enables printing a string such the affixes are printed only if the string is not
+   empty. An empty string (or :code:`nullptr`) yields no output. A common situation in which is this is useful is code like ::
+
+      printf("%s%s", data ? data : "", data ? " " : "");
+
+   or something like ::
+
+      if (data) {
+         printf("%s ", data);
+      }
+
+   Instead :class:`OptionalAffix` can be used in line, which is easier if there are multiple items. E.g.
+
+      w.print("{}", ts::bwf::OptionalAffix(data)); // because default is single trailing space suffix.
+
+   .. function:: OptionalAffix(const char* text, std::string_view suffix = " ", std::string_view prefix = "")
+
+      Create a format wrapper with :arg:`suffix` and :arg:`prefix`. If :arg:`text` is
+      :code:`nullptr` or is empty generate no output. Otherwise print the :arg:`prefix`,
+      :arg:`text`, :arg:`suffix`.
+
+   .. function:: OptionalAffix(std::string_view text, std::string_view suffix = " ", std::string_view prefix = "")
+
+      Create a format wrapper with :arg:`suffix` and :arg:`prefix`. If :arg:`text` is
+      :code:`nullptr` or is empty generate no output. Otherwise print the :arg:`prefix`,
+      :arg:`text`, :arg:`suffix`. Note that passing :code:`std::string` as the first argument will
+      work for this overload.
+
 Global Names
 ++++++++++++
 
diff --git a/lib/ts/BufferWriterFormat.cc b/lib/ts/BufferWriterFormat.cc
index e265276..836c972 100644
--- a/lib/ts/BufferWriterFormat.cc
+++ b/lib/ts/BufferWriterFormat.cc
@@ -951,6 +951,12 @@ bwformat(BufferWriter &w, BWFSpec const &spec, bwf::Date const &date)
   return w;
 }
 
+BufferWriter &
+bwformat(BufferWriter &w, BWFSpec const &spec, bwf::OptionalAffix const &opts)
+{
+  return w.write(opts._prefix).write(opts._text).write(opts._suffix);
+}
+
 } // namespace ts
 
 namespace
diff --git a/lib/ts/bwf_std_format.h b/lib/ts/bwf_std_format.h
index aee70f6..d90da57 100644
--- a/lib/ts/bwf_std_format.h
+++ b/lib/ts/bwf_std_format.h
@@ -66,9 +66,34 @@ namespace bwf
     Date(std::string_view fmt = DEFAULT_FORMAT);
   };
 
+  /** For optional printing strings along with suffixes and prefixes.
+   *  If the wrapped string is null or empty, nothing is printed. Otherwise the prefix, string,
+   *  and suffix are printed. The default are a single space for suffix and nothing for the prefix.
+   */
+  struct OptionalAffix {
+    std::string_view _text;
+    std::string_view _suffix;
+    std::string_view _prefix;
+
+    OptionalAffix(const char *text, std::string_view suffix = " "sv, std::string_view prefix = ""sv)
+      : OptionalAffix(std::string_view(text ? text : ""), suffix, prefix)
+    {
+    }
+
+    OptionalAffix(std::string_view text, std::string_view suffix = " "sv, std::string_view prefix = ""sv)
+    {
+      // If text is null or empty, leave the members empty too.
+      if (!text.empty()) {
+        _text   = text;
+        _prefix = prefix;
+        _suffix = suffix;
+      }
+    }
+  };
 } // namespace bwf
 
 BufferWriter &bwformat(BufferWriter &w, BWFSpec const &spec, bwf::Errno const &e);
 BufferWriter &bwformat(BufferWriter &w, BWFSpec const &spec, bwf::Date const &date);
+BufferWriter &bwformat(BufferWriter &w, BWFSpec const &spec, bwf::OptionalAffix const &opts);
 
 } // namespace ts


[trafficserver] 01/03: BufferWriter: Some minor cleanups. Clean up use of std::literal, add bwf::Errno default constructor, move Date format to explicit default.

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 8.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit d3ab5b50a5d0897459f04b45b1a18aff0deef7fa
Author: Alan M. Carroll <am...@apache.org>
AuthorDate: Mon Jul 2 20:44:17 2018 -0500

    BufferWriter: Some minor cleanups.
    Clean up use of std::literal, add bwf::Errno default constructor, move Date format to explicit default.
    
    (cherry picked from commit b28833b7cce7a77fc03ab80811ae3247b3cf49af)
---
 lib/ts/BufferWriter.h   |  5 +++--
 lib/ts/bwf_std_format.h | 23 +++++++++++++++++++----
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/lib/ts/BufferWriter.h b/lib/ts/BufferWriter.h
index b1c4c9b..b459ee1 100644
--- a/lib/ts/BufferWriter.h
+++ b/lib/ts/BufferWriter.h
@@ -35,8 +35,6 @@
 #include <ts/MemSpan.h>
 #include <ts/BufferWriterForward.h>
 
-using namespace std::literals;
-
 namespace ts
 {
 /** Base (abstract) class for concrete buffer writers.
@@ -611,6 +609,7 @@ template <typename... Args>
 BufferWriter &
 BufferWriter::printv(TextView fmt, std::tuple<Args...> const &args)
 {
+  using namespace std::literals;
   static constexpr int N = sizeof...(Args); // used as loop limit
   static const auto fa   = bw_fmt::Get_Arg_Formatter_Array<decltype(args)>(std::index_sequence_for<Args...>{});
   int arg_idx            = 0; // the next argument index to be processed.
@@ -671,6 +670,7 @@ template <typename... Args>
 BufferWriter &
 BufferWriter::printv(BWFormat const &fmt, std::tuple<Args...> const &args)
 {
+  using namespace std::literals;
   static constexpr int N = sizeof...(Args);
   static const auto fa   = bw_fmt::Get_Arg_Formatter_Array<decltype(args)>(std::index_sequence_for<Args...>{});
 
@@ -795,6 +795,7 @@ bwformat(BufferWriter &w, BWFSpec const &, char c)
 inline BufferWriter &
 bwformat(BufferWriter &w, BWFSpec const &spec, bool f)
 {
+  using namespace std::literals;
   if ('s' == spec._type) {
     w.write(f ? "true"sv : "false"sv);
   } else if ('S' == spec._type) {
diff --git a/lib/ts/bwf_std_format.h b/lib/ts/bwf_std_format.h
index 60776c4..aee70f6 100644
--- a/lib/ts/bwf_std_format.h
+++ b/lib/ts/bwf_std_format.h
@@ -25,12 +25,14 @@
 
 #include <atomic>
 #include <string_view>
+#include <ts/TextView.h>
+#include <ts/BufferWriterForward.h>
 
 namespace std
 {
 template <typename T>
 ts::BufferWriter &
-bwformat(ts::BufferWriter &w, ts::BWFSpec const &spec, std::atomic<T> const &v)
+bwformat(ts::BufferWriter &w, ts::BWFSpec const &spec, atomic<T> const &v)
 {
   return ts::bwformat(w, spec, v.load());
 }
@@ -40,17 +42,30 @@ namespace ts
 {
 namespace bwf
 {
+  using namespace std::literals; // enable ""sv
+
+  /** Format wrapper for @c errno.
+   * This stores a copy of the argument or @c errno if an argument isn't provided. The output
+   * is then formatted with the short, long, and numeric value of @c errno. If the format specifier
+   * is type 'd' then just the numeric value is printed.
+   */
   struct Errno {
     int _e;
-    explicit Errno(int e) : _e(e) {}
+    explicit Errno(int e = errno) : _e(e) {}
   };
 
+  /** Format wrapper for time stamps.
+   * If the time isn't provided, the current epoch time is used. If the format string isn't
+   * provided a format like "2017 Jun 29 14:11:29" is used.
+   */
   struct Date {
+    static constexpr std::string_view DEFAULT_FORMAT{"%Y %b %d %H:%M:%S"_sv};
     time_t _epoch;
     std::string_view _fmt;
-    Date(time_t t, std::string_view fmt = "%Y %b %d %H:%M:%S"sv) : _epoch(t), _fmt(fmt) {}
-    Date(std::string_view fmt = "%Y %b %d %H:%M:%S"sv);
+    Date(time_t t, std::string_view fmt = DEFAULT_FORMAT) : _epoch(t), _fmt(fmt) {}
+    Date(std::string_view fmt = DEFAULT_FORMAT);
   };
+
 } // namespace bwf
 
 BufferWriter &bwformat(BufferWriter &w, BWFSpec const &spec, bwf::Errno const &e);


[trafficserver] 03/03: TextView: Add constexpr literal constructor for std::string_view.

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 8.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 22b1ff6c17e98e5cb9f447685730b8618e9fc007
Author: Alan M. Carroll <am...@apache.org>
AuthorDate: Mon Jul 2 20:34:08 2018 -0500

    TextView: Add constexpr literal constructor for std::string_view.
    
    (cherry picked from commit 0225210345ec575c4ddbe37ed011e16f6e61738e)
---
 lib/ts/TextView.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lib/ts/TextView.h b/lib/ts/TextView.h
index a1a688f..d4494cd 100644
--- a/lib/ts/TextView.h
+++ b/lib/ts/TextView.h
@@ -1018,3 +1018,13 @@ namespace std
 {
 ostream &operator<<(ostream &os, const ts::TextView &b);
 }
+
+// @c constexpr literal constructor for @c std::string_view
+// For unknown reasons, this enables creating @c constexpr constructs using @c std::string_view while the standard
+// one (""sv) does not.
+// I couldn't think of any better place to put this, so it's here. At least @c TextView is strongly related
+// to @c std::string_view.
+constexpr std::string_view operator"" _sv(const char *s, size_t n)
+{
+  return {s, n};
+}