Problem: Expand('<stack>') does not include the final line number.
Solution: Add the line nuber. (closes #6927)
vim_free(debug_newval);
debug_newval = NULL;
}
- sname = estack_sfile(FALSE);
+ sname = estack_sfile(ESTACK_NONE);
if (sname != NULL)
msg((char *)sname);
vim_free(sname);
}
else
{
- char_u *sname = estack_sfile(FALSE);
+ char_u *sname = estack_sfile(ESTACK_NONE);
int max = get_maxbacktrace_level(sname);
if (debug_backtrace_level > max)
int i = 0;
int max;
- sname = estack_sfile(FALSE);
+ sname = estack_sfile(ESTACK_NONE);
max = get_maxbacktrace_level(sname);
if (sname != NULL)
{
* '<cexpr>' to C-expression under the cursor
* '<cfile>' to path name under the cursor
* '<sfile>' to sourced file name
+ * '<stack>' to call stack
* '<slnum>' to sourced file line number
* '<afile>' to file name for autocommand
* '<abuf>' to buffer number for autocommand
case SPEC_SFILE: // file name for ":so" command
case SPEC_STACK: // call stack
- result = estack_sfile(spec_idx == SPEC_SFILE);
+ result = estack_sfile(spec_idx == SPEC_SFILE
+ ? ESTACK_SFILE : ESTACK_STACK);
if (result == NULL)
{
*errormsg = spec_idx == SPEC_SFILE
// Get the source name and lnum now, it may change before
// reaching do_errthrow().
- elem->sfile = estack_sfile(FALSE);
+ elem->sfile = estack_sfile(ESTACK_NONE);
elem->slnum = SOURCING_LNUM;
}
}
}
else
{
- excp->throw_name = estack_sfile(FALSE);
+ excp->throw_name = estack_sfile(ESTACK_NONE);
if (excp->throw_name == NULL)
excp->throw_name = vim_strsave((char_u *)"");
if (excp->throw_name == NULL)
if (SOURCING_NAME != NULL && other_sourcing_name())
{
- char_u *sname = estack_sfile(FALSE);
+ char_u *sname = estack_sfile(ESTACK_NONE);
char_u *tofree = sname;
if (sname == NULL)
estack_T *estack_push_ufunc(ufunc_T *ufunc, long lnum);
int estack_top_is_ufunc(ufunc_T *ufunc, long lnum);
estack_T *estack_pop(void);
-char_u *estack_sfile(int is_sfile);
+char_u *estack_sfile(estack_arg_T which);
void ex_runtime(exarg_T *eap);
int do_in_path(char_u *path, char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie);
int do_in_runtimepath(char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie);
/*
* Get the current value for <sfile> in allocated memory.
- * "is_sfile" is TRUE for <sfile> itself.
+ * "which" is ESTACK_SFILE for <sfile> and ESTACK_STACK for <stack>.
*/
char_u *
-estack_sfile(int is_sfile UNUSED)
+estack_sfile(estack_arg_T which UNUSED)
{
estack_T *entry;
#ifdef FEAT_EVAL
entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1;
#ifdef FEAT_EVAL
- if (is_sfile && entry->es_type != ETYPE_UFUNC)
+ if (which == ESTACK_SFILE && entry->es_type != ETYPE_UFUNC)
#endif
{
if (entry->es_name == NULL)
entry = ((estack_T *)exestack.ga_data) + idx;
if (entry->es_name != NULL)
{
+ long lnum = 0;
+
len = STRLEN(entry->es_name) + 15;
type_name = "";
if (entry->es_type != last_type)
len += STRLEN(type_name);
if (ga_grow(&ga, (int)len) == FAIL)
break;
- if (idx == exestack.ga_len - 1 || entry->es_lnum == 0)
- // For the bottom entry: do not add the line number, it is used
- // in <slnum>. Also leave it out when the number is not set.
+ if (idx == exestack.ga_len - 1)
+ lnum = which == ESTACK_STACK ? SOURCING_LNUM : 0;
+ else
+ lnum = entry->es_lnum;
+ if (lnum == 0)
+ // For the bottom entry of <sfile>: do not add the line number,
+ // it is used in <slnum>. Also leave it out when the number is
+ // not set.
vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s%s",
type_name, entry->es_name,
idx == exestack.ga_len - 1 ? "" : "..");
else
vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s[%ld]..",
- type_name, entry->es_name, entry->es_lnum);
+ type_name, entry->es_name, lnum);
ga.ga_len += (int)STRLEN((char *)ga.ga_data + ga.ga_len);
}
}
func Test_expand_sfile_and_stack()
call assert_match('test_expand_func\.vim$', s:sfile)
- let expected = 'script .*testdir/runtest.vim\[\d\+\]\.\.function RunTheTest\[\d\+\]\.\.Test_expand_sfile_and_stack$'
- call assert_match(expected , expand('<sfile>'))
- call assert_match(expected , expand('<stack>'))
+ let expected = 'script .*testdir/runtest.vim\[\d\+\]\.\.function RunTheTest\[\d\+\]\.\.Test_expand_sfile_and_stack'
+ call assert_match(expected .. '$', expand('<sfile>'))
+ call assert_match(expected .. '\[4\]' , expand('<stack>'))
" Call in script-local function
call assert_match('script .*testdir/runtest.vim\[\d\+\]\.\.function RunTheTest\[\d\+\]\.\.Test_expand_sfile_and_stack\[7\]\.\.<SNR>\d\+_expand_sfile$', s:expand_sfile())
" Use <stack> from sourced script.
let lines =<< trim END
+ " comment here
let g:stack_value = expand('<stack>')
END
call writefile(lines, 'Xstack')
source Xstack
- call assert_match('\<Xstack$', g:stack_value)
+ call assert_match('\<Xstack\[2\]', g:stack_value)
call delete('Xstack')
endfunc
prepare_assert_error(garray_T *gap)
{
char buf[NUMBUFLEN];
- char_u *sname = estack_sfile(FALSE);
+ char_u *sname = estack_sfile(ESTACK_NONE);
ga_init2(gap, 1, 100);
if (sname != NULL)
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1653,
/**/
1652,
/**/
# define USE_PRINTF_FORMAT_ATTRIBUTE
#endif
-typedef enum
-{
+typedef enum {
ASSERT_EQUAL,
ASSERT_NOTEQUAL,
ASSERT_MATCH,
USEPOPUP_HIDDEN // use info popup initially hidden
} use_popup_T;
+// Argument for estack_sfile().
+typedef enum {
+ ESTACK_NONE,
+ ESTACK_SFILE,
+ ESTACK_STACK
+} estack_arg_T;
+
// Flags for assignment functions.
#define LET_IS_CONST 1 // ":const"
#define LET_NO_COMMAND 2 // "var = expr" without ":let" or ":const"