@@ -48,6 +48,31 @@ def get(self):
4848 return self .out
4949
5050
51+ def choose (b , t , f ):
52+ if b :
53+ return t
54+ return f
55+
56+
57+ def start_of_app (width , address ):
58+ return "{:>#10x}┬{}┐\n " .format (address , "─" * width )
59+
60+
61+ def end_of_app (width , address , continuing ):
62+ left_corner = choose (continuing , "┼" , "┴" )
63+ right_corner = choose (continuing , "┤" , "┘" )
64+ return "{:>#10x}{}{}{}\n " .format (address , left_corner , "─" * width , right_corner )
65+
66+
67+ def app_bracket (width , left , right ):
68+ if len (left ) + len (right ) >= (width - 1 ):
69+ room_for_left = width - 1 - 1 - len (right )
70+ left = "{}…" .format (left [0 :room_for_left ])
71+ left_size = width - len (right )
72+ content = "{:<{left_size}}{}" .format (left , right , left_size = left_size )
73+ return "{}│{}│\n " .format (" " * 10 , content )
74+
75+
5176class HumanReadableDisplay (Display ):
5277 """
5378 Format output as a string meant to be human readable.
@@ -87,30 +112,21 @@ def list_apps(self, apps, verbose, quiet):
87112 # In quiet mode just show the names.
88113 self .out += " " .join ([app .get_name () for app in apps ])
89114
90- def show_app_map (self , apps , start_address ):
91- def choose (b , t , f ):
92- if b :
93- return t
94- return f
95-
96- def start_of_app (width , address ):
97- return "{:>#10x}┬{}┐\n " .format (address , "─" * width )
98-
99- def end_of_app (width , address , continuing ):
100- left_corner = choose (continuing , "┼" , "┴" )
101- right_corner = choose (continuing , "┤" , "┘" )
102- return "{:>#10x}{}{}{}\n " .format (
103- address , left_corner , "─" * width , right_corner
104- )
105-
106- def app_bracket (width , left , right ):
107- if len (left ) + len (right ) >= (width - 1 ):
108- room_for_left = width - 1 - 1 - len (right )
109- left = "{}…" .format (left [0 :room_for_left ])
110- left_size = width - len (right )
111- content = "{:<{left_size}}{}" .format (left , right , left_size = left_size )
112- return "{}│{}│\n " .format (" " * 10 , content )
113-
115+ def show_app_map_from_address (self , apps , start_address ):
116+ """
117+ Print a layout map of apps assuming they are located back-to-back
118+ starting from `start_address`. Example:
119+
120+ ```
121+ 0x30000┬──────────────────────────────────────────────────┐
122+ │App: blink [Installed]│
123+ │ Length: 16384 (0x4000) │
124+ 0x34000┼──────────────────────────────────────────────────┤
125+ │App: blink [Installed]│
126+ │ Length: 16384 (0x4000) │
127+ 0x3c000┴──────────────────────────────────────────────────┘
128+ ```
129+ """
114130 out = ""
115131 address = start_address
116132 for i , app in enumerate (apps ):
@@ -136,6 +152,54 @@ def app_bracket(width, left, right):
136152
137153 self .out += out
138154
155+ def show_app_map_actual_address (self , apps ):
156+ """
157+ Show a map of installed applications with known addresses. Example:
158+
159+ ```
160+ 0x30000┬──────────────────────────────────────────────────┐
161+ │App: blink [Installed]│
162+ │ Length: 16384 (0x4000) │
163+ 0x34000┴──────────────────────────────────────────────────┘
164+ 0x38000┬──────────────────────────────────────────────────┐
165+ │App: blink [Installed]│
166+ │ Length: 16384 (0x4000) │
167+ 0x3c000┴──────────────────────────────────────────────────┘
168+ ```
169+ """
170+
171+ out = ""
172+ prev_address = - 1
173+ for i , app in enumerate (apps ):
174+ size = app .get_size ()
175+ active_address = app .get_address ()
176+
177+ if active_address != prev_address :
178+ out += start_of_app (50 , active_address )
179+
180+ if isinstance (app , TabApp ):
181+ title = "App: {}" .format (app .get_name ())
182+ out += app_bracket (50 , title , "[From TAB]" )
183+ elif isinstance (app , InstalledApp ):
184+ title = "App: {}" .format (app .get_name ())
185+ out += app_bracket (50 , title , "[Installed]" )
186+ elif isinstance (app , PaddingApp ):
187+ out += app_bracket (50 , "Padding" , "" )
188+ out += app_bracket (50 , " Length: {} ({:#x})" .format (size , size ), "" )
189+
190+ prev_address = active_address + size
191+
192+ # Check if the next app starts at the address the current app ends
193+ # at.
194+ immediately_after = False
195+ if i < len (apps ) - 1 :
196+ next_address = apps [i + 1 ].get_address ()
197+ immediately_after = prev_address == next_address
198+
199+ out += end_of_app (50 , prev_address , immediately_after )
200+
201+ self .out += out
202+
139203 def show_board_visual (self , apps ):
140204 def horizontal_add (existing , new ):
141205 existing_lines = existing .split ("\n " )
0 commit comments