]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/jdb_list.cpp
update
[l4.git] / kernel / fiasco / src / jdb / jdb_list.cpp
1 INTERFACE:
2
3 class Jdb_list
4 {
5 public:
6   virtual char const *get_mode_str() const { return "[std mode]"; }
7   virtual void next_mode() {}
8   virtual void next_sort() {}
9   virtual void *get_head() const = 0;
10   virtual int show_item(char *buffer, int max, void *item) const = 0;
11   virtual char const *show_head() const = 0;
12   virtual int seek(int cnt, void **item) = 0;
13   virtual bool enter_item(void * /*item*/) const { return true; }
14   virtual void *follow_link(void *a) { return a; }
15   virtual bool handle_key(void * /*item*/, int /*keycode*/) { return false; }
16   virtual void *parent(void * /*item*/) { return 0; }
17   virtual void *get_valid(void *a) { return a; }
18
19 private:
20   void *_start, *_last;
21   void *_current;
22
23 };
24
25
26 // ---------------------------------------------------------------------------
27 IMPLEMENTATION:
28
29 #include <climits>
30 #include <cstring>
31 #include <cstdio>
32
33 #include "jdb.h"
34 #include "jdb_core.h"
35 #include "jdb_screen.h"
36 #include "kernel_console.h"
37 #include "keycodes.h"
38 #include "simpleio.h"
39 #include <minmax.h>
40
41
42
43 PUBLIC
44 Jdb_list::Jdb_list()
45   : _start(0), _current(0)
46 {}
47
48 // set _t_start element of list
49 PUBLIC
50 void
51 Jdb_list::set_start(void *start)
52 {
53   _start = start;
54 }
55
56 // _t_start-- if possible
57 PUBLIC inline
58 bool
59 Jdb_list::line_back()
60 { return seek(-1, &_start); }
61
62 // _t_start++ if possible
63 PUBLIC inline
64 bool
65 Jdb_list::line_forw()
66 {
67   if (seek(1, &_last))
68     return seek(1, &_start);
69   else
70     return false;
71 }
72 #if 0
73   Thread *t = _t_start;
74   iter(+Jdb_screen::height()-2, &_t_start);
75   iter(-Jdb_screen::height()+3, &_t_start);
76   return t != _t_start;
77 }
78 #endif
79
80 // _t_start -= 24 if possible
81 PUBLIC
82 bool
83 Jdb_list::page_back()
84 { return seek(-Jdb_screen::height()+2, &_start); }
85
86 // _t_start += 24 if possible
87 PUBLIC
88 bool
89 Jdb_list::page_forw()
90 {
91   int fwd = seek(Jdb_screen::height()-2, &_last);
92   if (fwd)
93     return seek(fwd, &_start);
94   return false;
95 }
96
97 #if 0
98   Thread *t = _t_start;
99   iter(+Jdb_screen::height()*2-5, &_t_start);
100   iter(-Jdb_screen::height()  +3, &_t_start);
101   return t != _t_start;
102 }
103 #endif
104
105 // _t_start = first element of list
106 PUBLIC
107 bool
108 Jdb_list::goto_home()
109 { return seek(-99999, &_start); }
110
111 // _t_start = last element of list
112 PUBLIC
113 bool
114 Jdb_list::goto_end()
115 { return seek(99999, &_start); }
116 #if 0
117   Thread *t = _t_start;
118   iter(+9999, &_t_start);
119   iter(-Jdb_screen::height()+2, &_t_start);
120   return t != _t_start;
121 }
122 #endif
123
124 // search index of t_search starting from _t_start
125 PUBLIC
126 int
127 Jdb_list::lookup_in_visible_area(void *search)
128 {
129   unsigned i;
130   void *t;
131
132   for (i=0, t = _start; i < Jdb_screen::height()-3; ++i)
133     {
134       if (t == search)
135         return i;
136
137       seek(1, &t);
138     }
139
140   return -1;
141 }
142
143 // get y'th element of thread list starting from _t_start
144 PUBLIC
145 void *
146 Jdb_list::index(int y)
147 {
148   void *t = _start;
149
150   seek(y, &t);
151   return t;
152 }
153
154
155 PUBLIC
156 void
157 Jdb_list::show_line(void *i)
158 {
159   static char buffer[256];
160   Kconsole::console()->getchar_chance();
161   int pos = 0;
162   void *p = i;
163   while ((p = parent(p)))
164     {
165       buffer[pos] = ' ';
166       ++pos;
167     }
168
169   pos += show_item(buffer + pos, sizeof(buffer) - pos, i);
170   if (i)
171     printf("%.*s\033[K\n", min((int)Jdb_screen::width(), pos), buffer);
172 }
173
174 // show complete page using show callback function
175 PUBLIC
176 int
177 Jdb_list::page_show()
178 {
179   void *t = _start;
180   unsigned i = 0;
181   for (i = 0; i < Jdb_screen::height()-3; ++i)
182     {
183       if (!t)
184         break;
185       else
186         _last = t;
187
188       show_line(t);
189
190       if (!seek(1,&t))
191         return i;
192     }
193
194   return i - 1;
195 }
196
197 // show complete list using show callback function
198 PUBLIC
199 int
200 Jdb_list::complete_show()
201 {
202   void *t = _start;
203   int i = 0;
204   for (i = 0; ; ++i, seek(1, &t))
205     {
206       if (!t)
207         break;
208
209       show_line(t);
210     }
211
212   return i;
213 }
214
215 #if 0
216 PUBLIC
217 Jdb_module::Action_code
218 Jdb_thread_list::action(int cmd, void *&argbuf, char const *&fmt, int &)
219 {
220   static char const *const cpu_fmt = " cpu=%i\n";
221   static char const *const nfmt = "\n";
222   if (cmd == 0)
223     {
224       if (fmt != cpu_fmt && fmt != nfmt)
225         {
226           if (subcmd == 'c')
227             {
228               argbuf = &cpu;
229               fmt = cpu_fmt;
230             }
231           else
232             fmt = nfmt;
233           return EXTRA_INPUT;
234         }
235
236       Thread *t = Jdb::get_current_active();
237       switch (subcmd)
238         {
239         case 'r': cpu = 0; list_threads(t, 'r'); break;
240         case 'p': list_threads(t, 'p'); break;
241         case 'c': 
242                   if (Cpu::online(cpu))
243                     list_threads(Jdb::get_thread(cpu), 'r');
244                   else
245                     printf("\nCPU %u is not online!\n", cpu);
246                   cpu = 0;
247                   break;
248         case 't': Jdb::execute_command("lt"); break; // other module
249         }
250     }
251   else if (cmd == 1)
252     {
253       Console *gzip = Kconsole::console()->find_console(Console::GZIP);
254       if (gzip)
255         {
256           Thread *t = Jdb::get_current_active();
257           gzip->state(gzip->state() | Console::OUTENABLED);
258           long_output = 1;
259           Jdb_thread_list::init('p', t);
260           Jdb_thread_list::set_start(t);
261           Jdb_thread_list::goto_home();
262           Jdb_thread_list::complete_show(list_threads_show_thread);
263           long_output = 0;
264           gzip->state(gzip->state() & ~Console::OUTENABLED);
265         }
266       else
267         puts(" gzip module not available");
268     }
269
270   return NOTHING;
271 }
272 #endif
273
274
275 PUBLIC
276 void
277 Jdb_list::show_header()
278 {
279   Jdb::cursor();
280   printf("%.*s\033[K\n", Jdb_screen::width(), show_head());
281 }
282
283
284 PUBLIC
285 void
286 Jdb_list::do_list()
287 {
288   int y, y_max;
289   void *t;
290
291   if (!_start)
292     _start = get_head();
293
294   if (!_current)
295     _current = _start;
296
297   Jdb::clear_screen();
298   show_header();
299
300   if (!_start)
301     {
302       printf("[EMPTY]\n");
303       return;
304     }
305
306
307   for (;;)
308     {
309       // set y to position of t_current in current displayed list
310       y = lookup_in_visible_area(_current);
311       if (y == -1)
312         {
313           _start = _current;
314           y = 0;
315         }
316
317       for (bool resync=false; !resync;)
318         {
319           Jdb::cursor(2, 1);
320           y_max = page_show();
321
322           // clear rest of screen (if where less than 24 lines)
323           for (unsigned i = y_max; i < Jdb_screen::height()-3; ++i)
324             putstr("\033[K\n");
325
326           Jdb::printf_statline("xxxx",
327                                "<Space>=mode <Tab>=link <CR>=select",
328                                "%-15s", get_mode_str());
329
330           // key event loop
331           for (bool redraw=false; !redraw; )
332             {
333               Jdb::cursor(y+2, 1);
334               switch (int c=Jdb_core::getchar())
335                 {
336                 case KEY_CURSOR_UP:
337                 case 'k':
338                   if (y > 0)
339                     y--;
340                   else
341                     redraw = line_back();
342                   break;
343                 case KEY_CURSOR_DOWN:
344                 case 'j':
345                   if (y < y_max)
346                     y++;
347                   else
348                     redraw = line_forw();
349                   break;
350                 case KEY_PAGE_UP:
351                 case 'K':
352                   if (!(redraw = page_back()))
353                     y = 0;
354                   break;
355                 case KEY_PAGE_DOWN:
356                 case 'J':
357                   if (!(redraw = page_forw()))
358                     y = y_max;
359                   break;
360                 case KEY_CURSOR_HOME:
361                 case 'H':
362                   redraw = goto_home();
363                   y = 0;
364                   break;
365                 case KEY_CURSOR_END:
366                 case 'L':
367                   redraw = goto_end();
368                   y = y_max;
369                   break;
370                 case 's': // switch sort
371                   _current = index(y);
372                   next_sort();
373                   redraw = true;
374                   resync = true;
375                   break;
376                 case ' ': // switch mode
377                   _current = index(y);
378                   next_mode();
379                   _current = get_valid(_current);
380                   _start   = get_valid(_start);
381                   redraw = true;
382                   resync = true;
383                   break;
384                 case KEY_TAB: // go to associated object
385                   _current = index(y);
386                   t = follow_link(_current);
387                   if (t != _current)
388                     {
389                       _current = t;
390                       redraw = true;
391                       resync = true;
392                     }
393                   break;
394                 case KEY_RETURN:
395                   _current = index(y);
396                   if (!enter_item(_current))
397                     return;
398                   show_header();
399                   redraw = 1;
400                   break;
401                 case KEY_ESC:
402                   Jdb::abort_command();
403                   return;
404                 default:
405                   _current = index(y);
406                   if (!handle_key(_current, c) && Jdb::is_toplevel_cmd(c))
407                     return;
408
409                   show_header();
410                   redraw = 1;
411                   break;
412                 }
413             }
414         }
415     }
416 }
417