toolbox 0.1.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/bake/ruby/gdb.rb +135 -0
  4. data/bake/toolbox/gdb.rb +137 -0
  5. data/bake/toolbox/lldb.rb +137 -0
  6. data/context/fiber-debugging.md +171 -0
  7. data/context/getting-started.md +200 -0
  8. data/context/heap-debugging.md +351 -0
  9. data/context/index.yaml +28 -0
  10. data/context/object-inspection.md +208 -0
  11. data/context/stack-inspection.md +188 -0
  12. data/data/toolbox/command.py +479 -0
  13. data/data/toolbox/constants.py +200 -0
  14. data/data/toolbox/context.py +371 -0
  15. data/data/toolbox/debugger/__init__.py +101 -0
  16. data/data/toolbox/debugger/gdb_backend.py +664 -0
  17. data/data/toolbox/debugger/lldb_backend.py +986 -0
  18. data/data/toolbox/fiber.py +877 -0
  19. data/data/toolbox/format.py +205 -0
  20. data/data/toolbox/heap.py +679 -0
  21. data/data/toolbox/init.py +89 -0
  22. data/data/toolbox/print.py +79 -0
  23. data/data/toolbox/rarray.py +116 -0
  24. data/data/toolbox/rbasic.py +99 -0
  25. data/data/toolbox/rbignum.py +48 -0
  26. data/data/toolbox/rclass.py +136 -0
  27. data/data/toolbox/readme.md +214 -0
  28. data/data/toolbox/rexception.py +150 -0
  29. data/data/toolbox/rfloat.py +88 -0
  30. data/data/toolbox/rhash.py +151 -0
  31. data/data/toolbox/rstring.py +230 -0
  32. data/data/toolbox/rstruct.py +149 -0
  33. data/data/toolbox/rsymbol.py +278 -0
  34. data/data/toolbox/rvalue.py +183 -0
  35. data/data/toolbox/stack.py +620 -0
  36. data/lib/toolbox/gdb.rb +21 -0
  37. data/lib/toolbox/lldb.rb +21 -0
  38. data/lib/toolbox/version.rb +7 -1
  39. data/lib/toolbox.rb +9 -24
  40. data/license.md +21 -0
  41. data/readme.md +64 -0
  42. data/releases.md +9 -0
  43. data.tar.gz.sig +0 -0
  44. metadata +95 -165
  45. metadata.gz.sig +0 -0
  46. data/Rakefile +0 -61
  47. data/lib/dirs.rb +0 -9
  48. data/lib/toolbox/config.rb +0 -211
  49. data/lib/toolbox/default_controller.rb +0 -393
  50. data/lib/toolbox/helpers.rb +0 -11
  51. data/lib/toolbox/rendering.rb +0 -413
  52. data/lib/toolbox/searching.rb +0 -85
  53. data/lib/toolbox/session_params.rb +0 -63
  54. data/lib/toolbox/sorting.rb +0 -74
  55. data/locale/de/LC_MESSAGES/toolbox.mo +0 -0
  56. data/public/images/add.png +0 -0
  57. data/public/images/arrow_down.gif +0 -0
  58. data/public/images/arrow_up.gif +0 -0
  59. data/public/images/close.png +0 -0
  60. data/public/images/edit.gif +0 -0
  61. data/public/images/email.png +0 -0
  62. data/public/images/page.png +0 -0
  63. data/public/images/page_acrobat.png +0 -0
  64. data/public/images/page_add.png +0 -0
  65. data/public/images/page_copy.png +0 -0
  66. data/public/images/page_delete.png +0 -0
  67. data/public/images/page_edit.png +0 -0
  68. data/public/images/page_excel.png +0 -0
  69. data/public/images/page_list.png +0 -0
  70. data/public/images/page_save.png +0 -0
  71. data/public/images/page_word.png +0 -0
  72. data/public/images/remove.png +0 -0
  73. data/public/images/show.gif +0 -0
  74. data/public/images/spinner.gif +0 -0
  75. data/public/javascripts/popup.js +0 -498
  76. data/public/javascripts/toolbox.js +0 -18
  77. data/public/stylesheets/context_menu.css +0 -168
  78. data/public/stylesheets/popup.css +0 -30
  79. data/public/stylesheets/toolbox.css +0 -107
  80. data/view/toolbox/_collection.html.erb +0 -24
  81. data/view/toolbox/_collection_header.html.erb +0 -7
  82. data/view/toolbox/_context_menu.html.erb +0 -17
  83. data/view/toolbox/_dialogs.html.erb +0 -6
  84. data/view/toolbox/_form.html.erb +0 -30
  85. data/view/toolbox/_form_collection_row.html.erb +0 -18
  86. data/view/toolbox/_form_fieldset.html.erb +0 -30
  87. data/view/toolbox/_form_fieldset_row.html.erb +0 -19
  88. data/view/toolbox/_list.html.erb +0 -25
  89. data/view/toolbox/_list_row.html.erb +0 -10
  90. data/view/toolbox/_menu.html.erb +0 -7
  91. data/view/toolbox/_search_field.html.erb +0 -8
  92. data/view/toolbox/_show.html.erb +0 -12
  93. data/view/toolbox/_show_collection_row.html.erb +0 -6
  94. data/view/toolbox/_show_fieldset.html.erb +0 -21
  95. data/view/toolbox/edit.html.erb +0 -5
  96. data/view/toolbox/index.html.erb +0 -3
  97. data/view/toolbox/new.html.erb +0 -9
  98. data/view/toolbox/show.html.erb +0 -39
@@ -0,0 +1,205 @@
1
+ """
2
+ ANSI color codes for GDB output formatting.
3
+
4
+ This module provides utilities for colorizing GDB output to make metadata
5
+ less prominent and values more readable.
6
+ """
7
+
8
+ import sys
9
+ import rvalue
10
+
11
+ class Style:
12
+ """Sentinel object representing a style."""
13
+ def __init__(self, name):
14
+ self.name = name
15
+
16
+ def __repr__(self):
17
+ return f"Style({self.name})"
18
+
19
+ # Style sentinels
20
+ reset = Style('reset')
21
+ metadata = Style('metadata')
22
+ address = Style('address')
23
+ type = Style('type')
24
+ value = Style('value')
25
+ string = Style('string')
26
+ number = Style('number')
27
+ symbol = Style('symbol')
28
+ method = Style('method') # Alias for symbol (method names)
29
+ error = Style('error')
30
+ bold = Style('bold')
31
+ dim = Style('dim')
32
+ title = Style('title') # For section headers in help text
33
+ placeholder = Style('placeholder') # For help text placeholders (parameters, options)
34
+ example = Style('example') # For example commands in help text
35
+
36
+ class Text:
37
+ """Plain text output without any formatting."""
38
+
39
+ def __init__(self, output=None):
40
+ """Initialize text terminal.
41
+
42
+ Args:
43
+ output: Output stream (default: sys.stdout)
44
+ """
45
+ self.output = output or sys.stdout
46
+
47
+ def print(self, *args, end='\n'):
48
+ """Print arguments to output stream.
49
+
50
+ Args:
51
+ *args: Arguments to print (strings, Style sentinels, or objects with print_to)
52
+ end: String appended after the last arg (default: newline)
53
+ """
54
+ for arg in args:
55
+ if isinstance(arg, Style):
56
+ # Skip style sentinels in plain text mode
57
+ continue
58
+ elif hasattr(arg, 'print_to'):
59
+ # Let object print itself
60
+ arg.print_to(self)
61
+ else:
62
+ self.output.write(str(arg))
63
+ self.output.write(end)
64
+
65
+ def print_type_tag(self, type_name, addr=None, details=None):
66
+ """Print a type tag like <T_ARRAY@0xABCD embedded length=3>.
67
+
68
+ Arguments:
69
+ type_name: Type name (e.g., "T_ARRAY", "void *")
70
+ addr: Optional hex address (as integer or hex string without 0x)
71
+ details: Optional details string (e.g., "embedded length=3")
72
+ """
73
+ if isinstance(addr, int):
74
+ addr = f"{addr:x}"
75
+
76
+ self.print(metadata, '<', reset, type, type_name, reset, end='')
77
+
78
+ if addr:
79
+ # @ symbol in dim, address in magenta
80
+ self.print(metadata, '@', reset, address, f'0x{addr}', reset, end='')
81
+
82
+ if details:
83
+ self.print(metadata, f' {details}', reset, end='')
84
+
85
+ self.print(metadata, '>', reset, end='')
86
+
87
+ class XTerm(Text):
88
+ """ANSI color/style output for terminal."""
89
+
90
+ # ANSI codes
91
+ RESET = '\033[0m'
92
+ BOLD = '\033[1m'
93
+ DIM = '\033[2m'
94
+
95
+ RED = '\033[31m'
96
+ GREEN = '\033[32m'
97
+ YELLOW = '\033[33m'
98
+ BLUE = '\033[34m'
99
+ MAGENTA = '\033[35m'
100
+ CYAN = '\033[36m'
101
+ WHITE = '\033[37m'
102
+
103
+ BRIGHT_RED = '\033[91m'
104
+ BRIGHT_GREEN = '\033[92m'
105
+ BRIGHT_YELLOW = '\033[93m'
106
+ BRIGHT_BLUE = '\033[94m'
107
+ BRIGHT_MAGENTA = '\033[95m'
108
+ BRIGHT_CYAN = '\033[96m'
109
+
110
+ def __init__(self, output=None):
111
+ """Initialize ANSI terminal.
112
+
113
+ Args:
114
+ output: Output stream (default: sys.stdout)
115
+ """
116
+ super().__init__(output)
117
+ # Map style sentinels to ANSI codes
118
+ self.style_map = {
119
+ reset: self.RESET,
120
+ metadata: self.DIM, # Type tag brackets <>
121
+ address: self.MAGENTA, # Memory addresses in type tags
122
+ type: self.CYAN, # Type names (T_ARRAY, VALUE, etc.)
123
+ string: self.GREEN,
124
+ number: self.CYAN,
125
+ symbol: self.YELLOW,
126
+ method: self.YELLOW, # Same as symbol
127
+ error: self.RED,
128
+ bold: self.BOLD,
129
+ dim: self.DIM,
130
+ title: self.BOLD, # Section headers in help text
131
+ placeholder: self.BLUE, # Help text placeholders
132
+ example: self.GREEN, # Example commands in help text
133
+ }
134
+
135
+ def print(self, *args, end='\n'):
136
+ """Print arguments to output stream with ANSI formatting.
137
+
138
+ Args:
139
+ *args: Arguments to print (strings, Style sentinels, or objects with print_to)
140
+ end: String appended after the last arg (default: newline)
141
+ """
142
+ for arg in args:
143
+ if isinstance(arg, Style):
144
+ # Print ANSI code for style
145
+ self.output.write(self.style_map.get(arg, ''))
146
+ elif hasattr(arg, 'print_to'):
147
+ # Let object print itself
148
+ arg.print_to(self)
149
+ else:
150
+ self.output.write(str(arg))
151
+ self.output.write(end)
152
+
153
+ # Helper for creating the appropriate terminal based on TTY status
154
+ def create_terminal(from_tty):
155
+ """Create a terminal instance based on whether we're in a TTY."""
156
+ if from_tty:
157
+ return XTerm()
158
+ else:
159
+ return Text()
160
+
161
+ class Printer:
162
+ """Printer that combines terminal formatting with recursive printing logic."""
163
+
164
+ def __init__(self, terminal, max_depth, debug_mode=False):
165
+ self.terminal = terminal
166
+ self.max_depth = max_depth
167
+ self.debug_mode = debug_mode
168
+
169
+ def debug(self, message):
170
+ """Print debug messages only when debug mode is enabled."""
171
+ if self.debug_mode:
172
+ print(f"DEBUG: {message}", file=sys.stderr)
173
+
174
+ def print(self, *args):
175
+ """Print arguments using the terminal's formatting."""
176
+ self.terminal.print(*args)
177
+
178
+ def print_indent(self, depth):
179
+ """Print indentation based on depth."""
180
+ print(" " * depth, end='')
181
+
182
+ def print_with_indent(self, depth, message, end='\n'):
183
+ """Print a message with proper indentation based on depth."""
184
+ self.print_indent(depth)
185
+ print(message, end=end)
186
+
187
+ def print_key_label(self, depth, index):
188
+ """Print a consistently formatted key label."""
189
+ self.print_with_indent(depth, f"[{index:>4}] K: ", end='')
190
+
191
+ def print_value_label(self, depth):
192
+ """Print a consistently formatted value label."""
193
+ self.print_with_indent(depth, f" V: ", end='')
194
+
195
+ def print_item_label(self, depth, index):
196
+ """Print a consistently formatted array item label."""
197
+ self.print_with_indent(depth, f"[{index:>4}] I: ", end='')
198
+
199
+ def print_value(self, ruby_value, depth):
200
+ """Print a Ruby value at the given depth."""
201
+ value_int = int(ruby_value)
202
+ self.debug(f"print_value: value=0x{value_int:x}, depth={depth}")
203
+
204
+ ruby_object = rvalue.interpret(ruby_value)
205
+ ruby_object.print_recursive(self, depth)