@@ -68,6 +68,10 @@ typedef struct sn_prl_S
6868#if defined(FEAT_EVAL ) || defined(PROTO )
6969static int debug_greedy = FALSE; /* batch mode debugging: don't save
7070 and restore typeahead. */
71+ static int get_maxbacktrace_level (void );
72+ static void do_setdebugtracelevel (char_u * arg );
73+ static void do_checkbacktracelevel (void );
74+ static void do_showbacktrace (char_u * cmd );
7175
7276/*
7377 * do_debug(): Debug mode.
@@ -101,6 +105,10 @@ do_debug(cmd)
101105#define CMD_FINISH 4
102106#define CMD_QUIT 5
103107#define CMD_INTERRUPT 6
108+ #define CMD_BACKTRACE 7
109+ #define CMD_FRAME 8
110+ #define CMD_UP 9
111+ #define CMD_DOWN 10
104112
105113#ifdef ALWAYS_USE_GUI
106114 /* Can't do this when there is no terminal for input/output. */
@@ -178,6 +186,7 @@ do_debug(cmd)
178186# endif
179187
180188 cmdline_row = msg_row ;
189+ msg_starthere ();
181190 if (cmdline != NULL )
182191 {
183192 /* If this is a debug command, set "last_cmd".
@@ -197,15 +206,40 @@ do_debug(cmd)
197206 case 's' : last_cmd = CMD_STEP ;
198207 tail = "tep" ;
199208 break ;
200- case 'f' : last_cmd = CMD_FINISH ;
201- tail = "inish" ;
209+ case 'f' :
210+ last_cmd = 0 ;
211+ if (p [1 ] == 'r' )
212+ {
213+ last_cmd = CMD_FRAME ;
214+ tail = "rame" ;
215+ }
216+ else
217+ {
218+ last_cmd = CMD_FINISH ;
219+ tail = "inish" ;
220+ }
202221 break ;
203222 case 'q' : last_cmd = CMD_QUIT ;
204223 tail = "uit" ;
205224 break ;
206225 case 'i' : last_cmd = CMD_INTERRUPT ;
207226 tail = "nterrupt" ;
208227 break ;
228+ case 'b' : last_cmd = CMD_BACKTRACE ;
229+ if (p [1 ] == 't' )
230+ tail = "t" ;
231+ else
232+ tail = "acktrace" ;
233+ break ;
234+ case 'w' : last_cmd = CMD_BACKTRACE ;
235+ tail = "here" ;
236+ break ;
237+ case 'u' : last_cmd = CMD_UP ;
238+ tail = "p" ;
239+ break ;
240+ case 'd' : last_cmd = CMD_DOWN ;
241+ tail = "own" ;
242+ break ;
209243 default : last_cmd = 0 ;
210244 }
211245 if (last_cmd != 0 )
@@ -217,7 +251,7 @@ do_debug(cmd)
217251 ++ p ;
218252 ++ tail ;
219253 }
220- if (ASCII_ISALPHA (* p ))
254+ if (ASCII_ISALPHA (* p ) && last_cmd != CMD_FRAME )
221255 last_cmd = 0 ;
222256 }
223257 }
@@ -250,7 +284,31 @@ do_debug(cmd)
250284 /* Do not repeat ">interrupt" cmd, continue stepping. */
251285 last_cmd = CMD_STEP ;
252286 break ;
287+ case CMD_BACKTRACE :
288+ do_showbacktrace (cmd );
289+ continue ;
290+ case CMD_FRAME :
291+ if (* p == NUL )
292+ {
293+ do_showbacktrace (cmd );
294+ }
295+ else
296+ {
297+ p = skipwhite (p );
298+ do_setdebugtracelevel (p );
299+ }
300+ continue ;
301+ case CMD_UP :
302+ debug_backtrace_level ++ ;
303+ do_checkbacktracelevel ();
304+ continue ;
305+ case CMD_DOWN :
306+ debug_backtrace_level -- ;
307+ do_checkbacktracelevel ();
308+ continue ;
253309 }
310+ /* Going out reset backtrace_level */
311+ debug_backtrace_level = 0 ;
254312 break ;
255313 }
256314
@@ -285,6 +343,92 @@ do_debug(cmd)
285343 debug_did_msg = TRUE;
286344}
287345
346+ static int
347+ get_maxbacktrace_level (void )
348+ {
349+ char * p , * q ;
350+ int maxbacktrace = 1 ;
351+
352+ maxbacktrace = 0 ;
353+ if (sourcing_name != NULL )
354+ {
355+ p = (char * )sourcing_name ;
356+ while ((q = strstr (p , ".." )) != NULL )
357+ {
358+ p = q + 2 ;
359+ maxbacktrace ++ ;
360+ }
361+ }
362+ return maxbacktrace ;
363+ }
364+
365+ static void
366+ do_setdebugtracelevel (char_u * arg )
367+ {
368+ int level ;
369+
370+ level = atoi ((char * )arg );
371+ if (* arg == '+' || level < 0 )
372+ debug_backtrace_level += level ;
373+ else
374+ debug_backtrace_level = level ;
375+
376+ do_checkbacktracelevel ();
377+ }
378+
379+ static void
380+ do_checkbacktracelevel (void )
381+ {
382+ if (debug_backtrace_level < 0 )
383+ {
384+ debug_backtrace_level = 0 ;
385+ MSG (_ ("frame is zero" ));
386+ }
387+ else
388+ {
389+ int max = get_maxbacktrace_level ();
390+
391+ if (debug_backtrace_level > max )
392+ {
393+ debug_backtrace_level = max ;
394+ smsg ((char_u * )_ ("frame at highest level: %d" ), max );
395+ }
396+ }
397+ }
398+
399+ static void
400+ do_showbacktrace (char_u * cmd )
401+ {
402+ char * cur ;
403+ char * next ;
404+ int i = 0 ;
405+ int max = get_maxbacktrace_level ();
406+
407+ if (sourcing_name != NULL )
408+ {
409+ cur = (char * )sourcing_name ;
410+ while (!got_int )
411+ {
412+ next = strstr (cur , ".." );
413+ if (next != NULL )
414+ * next = NUL ;
415+ if (i == max - debug_backtrace_level )
416+ smsg ((char_u * )"->%d %s" , max - i , cur );
417+ else
418+ smsg ((char_u * )" %d %s" , max - i , cur );
419+ ++ i ;
420+ if (next == NULL )
421+ break ;
422+ * next = '.' ;
423+ cur = next + 2 ;
424+ }
425+ }
426+ if (sourcing_lnum != 0 )
427+ smsg ((char_u * )_ ("line %ld: %s" ), (long )sourcing_lnum , cmd );
428+ else
429+ smsg ((char_u * )_ ("cmd: %s" ), cmd );
430+ }
431+
288432/*
289433 * ":debug".
290434 */
0 commit comments