]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Add line wrapper
authorPetr Machata <pmachata@redhat.com>
Fri, 1 Oct 2010 01:10:28 +0000 (03:10 +0200)
committerPetr Machata <pmachata@redhat.com>
Fri, 1 Oct 2010 01:10:28 +0000 (03:10 +0200)
- it's not currently used, but we will use this for formatting of check
  documentation and options

dwarflint/Makefile.am
dwarflint/wrap.cc [new file with mode: 0644]
dwarflint/wrap.hh [new file with mode: 0644]

index e5f0ee26ea7ac5e2fec779959f22beba345d8c16..7d61ff98d2511d26787e3b86173ae3c3c0f38a1b 100644 (file)
@@ -61,6 +61,7 @@ dwarflint_SOURCES = \
        sections.cc sections.hh sections.ii \
        tables.cc tables.hh \
        where.c where.h \
+       wrap.cc wrap.hh \
        check_debug_abbrev.cc check_debug_abbrev.hh check_debug_abbrev.ii \
        check_debug_info.cc check_debug_info.hh check_debug_info.ii \
        check_debug_line.cc check_debug_line.hh check_debug_line.ii \
diff --git a/dwarflint/wrap.cc b/dwarflint/wrap.cc
new file mode 100644 (file)
index 0000000..736091d
--- /dev/null
@@ -0,0 +1,169 @@
+/* Pedantic checking of DWARF files
+
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#include "wrap.hh"
+#include <cassert>
+#include <cstring>
+
+namespace
+{
+  size_t
+  skip_blank (std::string const &str, size_t pos)
+  {
+    while (pos < str.size () && isblank (str[pos]))
+      pos++;
+    return pos;
+  }
+}
+
+wrapline_t::wrapline_t (size_t start, size_t end, size_t indent)
+  : _m_start (start)
+  , _m_end (end)
+  , _m_indent (indent)
+{
+  assert (end >= start);
+}
+
+std::string
+wrapline_t::build (std::string const &image) const
+{
+  assert (_m_end <= image.size ());
+  std::string main = image.substr (_m_start, _m_end - _m_start);
+  char padding[_m_indent + 1];
+  std::memset (padding, ' ', _m_indent);
+  padding[_m_indent] = 0;
+  return std::string (padding) + main;
+}
+
+wrap_str::wrap_str (std::string const &str, unsigned width)
+  : _m_image (str)
+{
+  size_t pos = 0;
+  bool newline = true;
+  size_t indent = 0;
+  while (pos < str.size ())
+    {
+      size_t last = pos;
+
+      // This is how long a line we can allocate.
+      size_t length = width;
+
+      // For newlines, i.e. right after hard EOL (\n) in input string,
+      // we look for indentation and bullets.
+      if (newline)
+       {
+         pos = skip_blank (str, pos);
+         if (pos < str.size () && str[pos] == '-')
+           pos = skip_blank (str, pos + 1);
+         indent = pos - last;
+       }
+      length -= indent;
+
+      // Take the remainder of the line, but don't cross hard EOLs.
+      for (; length > 0 && pos < str.size (); --length)
+       if (str[pos] == '\n')
+         break;
+       else
+         pos++;
+
+      // We may have ended mid-word.  Look back to first white space.
+      // Look as far back as the end of previous line.
+      size_t space = pos;
+      for (; space > last; --space)
+       if (space == str.size () || isspace (str[space]))
+         break;
+
+      // While skipping back, we might end at the very beginning.  If
+      // that's the case, we have a word that doesn't fit user limit.
+      // Include it whole anyway.
+      if (space == last)
+       {
+         space = pos;
+         while (space < str.size () && !isspace (str[space]))
+           space++;
+       }
+
+      // We have a line!
+      push_back (wrapline_t (last, space, newline ? 0 : indent));
+
+      // Skip useless white space at the end of the line, up to EOL.
+      while (space < str.size () && isspace (str[space]) && str[space] != '\n')
+       space++;
+
+      if (str[space] == '\n')
+       {
+         space++;
+         indent = 0;
+         newline = true;
+       }
+      else
+       newline = false;
+
+      pos = space;
+    }
+}
+
+std::string
+wrap_str::join () const
+{
+  std::string ret;
+  for (const_iterator it = begin (); it != end (); ++it)
+    ret += it->build (_m_image) + "\n";
+  return ret;
+}
+
+namespace
+{
+  class tests
+  {
+    std::string
+    wrap (std::string const &str, size_t width)
+    {
+      return wrap_str (str, width).join ();
+    }
+
+  public:
+    tests ()
+    {
+      assert (wrap ("a b c d", 1) == "a\nb\nc\nd\n");
+      assert (wrap ("a bbbbb c d", 1) == "a\nbbbbb\nc\nd\n");
+      assert (wrap ("a b", 3) == "a b\n");
+      assert (wrap (" a b", 3) == " a\n b\n");
+      assert (wrap (" a b", 4) == " a b\n");
+      assert (wrap (" a b c d", 4) == " a b\n c d\n");
+      assert (wrap ("ab cd ef gh ij", 2) == "ab\ncd\nef\ngh\nij\n");
+      assert (wrap ("ab cd ef gh ij", 3) == "ab\ncd\nef\ngh\nij\n");
+      assert (wrap ("ab cd ef gh ij", 4) == "ab\ncd\nef\ngh\nij\n");
+      assert (wrap ("ab cd ef gh ij", 5) == "ab cd\nef gh\nij\n");
+      assert (wrap ("", 5) == "");
+      assert (wrap ("", 0) == "");
+      assert (wrap ("\n", 5) == "\n");
+      assert (wrap ("\n\n", 5) == "\n\n");
+      assert (wrap ("\n\n", 0) == "\n\n");
+      assert (wrap ("ab\ncd ef gh ij", 5) == "ab\ncd ef\ngh ij\n");
+    }
+  } _;
+}
diff --git a/dwarflint/wrap.hh b/dwarflint/wrap.hh
new file mode 100644 (file)
index 0000000..50826b6
--- /dev/null
@@ -0,0 +1,63 @@
+/* Pedantic checking of DWARF files
+
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifndef DWARFLINT_WRAP_HH
+#define DWARFLINT_WRAP_HH
+
+#include <string>
+#include <vector>
+
+class wrapline_t
+{
+  size_t _m_start;
+  size_t _m_end;
+  size_t _m_indent;
+
+public:
+  wrapline_t (size_t start, size_t end, size_t indent);
+  std::string build (std::string const &image) const;
+};
+
+class wrap_str
+  : private std::vector<wrapline_t>
+{
+  std::string const &_m_image;
+
+public:
+  typedef std::vector<wrapline_t> super_t;
+  using super_t::operator [];
+  using super_t::size;
+  using super_t::const_iterator;
+  using super_t::begin;
+  using super_t::end;
+  using super_t::empty;
+
+  wrap_str (std::string const &str, unsigned width);
+
+  std::string join () const;
+};
+
+#endif//DWARFLINT_WRAP_HH