summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby R. Bruce <bbruce@ucdavis.edu>2019-09-24 14:28:29 -0700
committerBobby R. Bruce <bbruce@ucdavis.edu>2019-09-30 19:50:26 +0000
commit772ca27a97239208d5eafb795c7ec92863d671ee (patch)
treedc3521b3b7b2da557c1256a97f04e4c09c472f77
parenta2286fe344f0fd6484f232329a56e9f07e2136de (diff)
downloadgem5-772ca27a97239208d5eafb795c7ec92863d671ee.tar.xz
misc: Added line wrapping functionality for Sim-Object desc
Descriptions were previously printed on one line, unless explicitly broken when writing the description of the Sim-Object. In this commit, line wrapping is enabled when printing these descriptions. Developers, when writing the Sim-Object descriptions, may now over multiple lines with triple double-quotes and still have the description output correctly when viewing the Sim-Objects within the CLI. E.g.: X86System previously had the following load_addr_mask component which was output as: load_addr_mask default: 18446744073709551615 desc: Address to mask loading binaries with, if 0, system \ auto-calculates the mask to be the most restrictive, otherwise it obeys a \ custom mask. This was defined by the developer via: load_addr_mask = Param.UInt64(0xffffffffffffffff, "Address to mask loading binaries with, if 0, system " "auto-calculates the mask to be the most restrictive, " "otherwise it obeys a custom mask.") This is now displayed as: load_addr_mask default: 18446744073709551615 desc: Address to mask loading binaries with, if 0, system auto-calculates the mask to be the most restrictive, otherwise it obeys a custom mask. JiraID: Gem5-57 Built: Linux (GCC) Tested: Ran quick tests for X86, ARM, and RISC-V Change-Id: If012304e50af60f6ba10c1fa2b44da8bac1c09cf Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21179 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
-rw-r--r--src/python/SConscript1
-rw-r--r--src/python/m5/main.py12
-rw-r--r--src/python/m5/util/terminal_formatter.py133
3 files changed, 142 insertions, 4 deletions
diff --git a/src/python/SConscript b/src/python/SConscript
index 758ab3df9..8264e380b 100644
--- a/src/python/SConscript
+++ b/src/python/SConscript
@@ -61,6 +61,7 @@ PySource('m5.util', 'm5/util/sorteddict.py')
PySource('m5.util', 'm5/util/terminal.py')
PySource('m5.util', 'm5/util/pybind.py')
PySource('m5.util', 'm5/util/fdthelper.py')
+PySource('m5.util', 'm5/util/terminal_formatter.py')
PySource('m5.internal', 'm5/internal/__init__.py')
PySource('m5.internal', 'm5/internal/params.py')
diff --git a/src/python/m5/main.py b/src/python/m5/main.py
index 295108c9d..92d9bb4f1 100644
--- a/src/python/m5/main.py
+++ b/src/python/m5/main.py
@@ -227,6 +227,7 @@ def main(*args):
from . import trace
from .util import inform, fatal, panic, isInteractive
+ from m5.util.terminal_formatter import TerminalFormatter
if len(args) == 0:
options, arguments = parse_options()
@@ -306,18 +307,21 @@ def main(*args):
print("SimObjects:")
objects = list(SimObject.allClasses.keys())
objects.sort()
+ terminal_formatter = TerminalFormatter()
for name in objects:
obj = SimObject.allClasses[name]
- print(" %s" % obj)
+ print(terminal_formatter.format_output(str(obj), indent=4))
params = list(obj._params.keys())
params.sort()
for pname in params:
param = obj._params[pname]
default = getattr(param, 'default', '')
- print(" %s" % pname)
+ print(terminal_formatter.format_output(pname, indent=8))
if default:
- print(" default: %s" % default)
- print(" desc: %s" % param.desc)
+ print(terminal_formatter.format_output(
+ str(default), label="default: ", indent=21))
+ print(terminal_formatter.format_output(
+ param.desc, label="desc: ", indent=21))
print()
print()
diff --git a/src/python/m5/util/terminal_formatter.py b/src/python/m5/util/terminal_formatter.py
new file mode 100644
index 000000000..84c21dbe4
--- /dev/null
+++ b/src/python/m5/util/terminal_formatter.py
@@ -0,0 +1,133 @@
+# Copyright (c) 2019 The Regents of the University of California
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Bobby R. Bruce
+
+
+
+import textwrap
+
+class TerminalFormatter:
+
+ def __init__(self, max_width=80):
+ # text_width holds the actual width we'll be wrapping to.
+ # This takes into account the current terminal size.
+ self.__text_width = min(max_width, self.__terminal_size()[0])
+
+ def __terminal_size(self):
+ import fcntl, termios, struct
+ h, w, hp, wp = struct.unpack('HHHH',
+ fcntl.ioctl(0, termios.TIOCGWINSZ,
+ struct.pack('HHHH', 0, 0, 0, 0)))
+ return w, h
+
+ def __get_paragraphs(self, text, flatten=False):
+
+ """
+ This function takes a text and returns a list of constituent
+ paragraphs, defining a paragraph as a block of text separated from
+ other text by a blank line (or one containing only whitespace). If the
+ "flatten" argument is set to true, all line breaks within paragraphs
+ will be removed.
+
+ E.g.:
+
+ text = '''Hello, this is
+ paragraph number 1.
+
+ This is paragraph number 2.
+
+ And this is
+ paragraph number 3.
+ '''
+
+ __get_paragraphs(text, False)
+ ["Hello, this is\nparagraph number 1", "This is paragraph number 2.",
+ "And this is\npagraph number 3."]
+
+ __get_paragraphs(text, True)
+ ["Hello, this is paragraph number 1", "This is paragraph number 2.",
+ "And this is pagraph number 3."]
+ """
+
+ paragraphs = []
+ cur_paragraph = []
+
+ for line in text.splitlines():
+ stripped = line.strip()
+ if not stripped: #I.e. a blank line.
+ paragraphs.append(
+ {False: "\n", True: " "}[flatten].join(cur_paragraph))
+ cur_paragraph = []
+ else:
+ cur_paragraph.append(stripped)
+
+ paragraphs.append(
+ {False: "\n", True: " "}[flatten].join(cur_paragraph))
+
+ return paragraphs
+
+ def format_output(self, text, label="", indent=0):
+ """
+ This function aids in the formatting of outputs. When obtaining
+ the list of sim object we desire the output in the following
+ format:
+
+ desc: Address to mask loading binaries with, if 0,
+ system auto-calculates the mask to be the most
+ restrictive, otherwise it obeys a custom mask.
+
+ We must take into account the width of the text, and wrap
+ accordingly. We also must display the label.
+
+ Keyword arguments:
+
+ text --- The description text.
+ label --- The label of the output (e.g. "desc: ").
+ indent --- The white space width before each line.
+ """
+
+ if not text.strip():
+ return ""
+
+ # The text may be over multiple lines (as when using triple
+ # double quotes). First, we split the text into its constituent
+ # paragraphs and remove new line characters from each.
+ paragraphs = self.__get_paragraphs(text, True)
+
+ # Wrap and Indent the paragraphs
+ wrapper = textwrap.TextWrapper(width =
+ max((self.__text_width - indent),1))
+ # The first paragraph is special case due to the inclusion of the label
+ formatted_paragraphs = [' ' * max((indent - len(label)),0) \
+ + label + wrapper.wrap(paragraphs[0])[0]]
+ for paragraph in paragraphs:
+ for line in wrapper.wrap(paragraph[1:])[1:]:
+ formatted_paragraphs.append(' ' * indent + line)
+ formatted_paragraphs.append('\n')
+
+ # Remove the last line break
+ return '\n'.join(formatted_paragraphs[:-1])