summaryrefslogtreecommitdiffstats
path: root/src/scriptfile.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-07-26 15:37:02 +0200
committerBram Moolenaar <Bram@vim.org>2020-07-26 15:37:02 +0200
commita5d0423fa16f18b4576a2a07e50034e489587a7d (patch)
tree67bfe997079bb1a9f17db6a829b29d6369a922a3 /src/scriptfile.c
parentd66cdcd43a598825add743bc95642cd8ed705252 (diff)
patch 8.2.1297: when a test fails it's often not easy to see wherev8.2.1297
Problem: When a test fails it's often not easy to see what the call stack is. Solution: Add more entries from the call stack in the exception message.
Diffstat (limited to 'src/scriptfile.c')
-rw-r--r--src/scriptfile.c70
1 files changed, 40 insertions, 30 deletions
diff --git a/src/scriptfile.c b/src/scriptfile.c
index ce269a1cd2..ce9c15d31b 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -111,58 +111,68 @@ estack_pop(void)
/*
* Get the current value for <sfile> in allocated memory.
+ * "is_sfile" is TRUE for <sfile> itself.
*/
char_u *
-estack_sfile(void)
+estack_sfile(int is_sfile)
{
estack_T *entry;
#ifdef FEAT_EVAL
+ garray_T ga;
size_t len;
int idx;
- char *res;
- size_t done;
+ etype_T last_type = ETYPE_SCRIPT;
+ char *type_name;
#endif
entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1;
- if (entry->es_name == NULL)
- return NULL;
#ifdef FEAT_EVAL
- if (entry->es_info.ufunc == NULL)
+ if (is_sfile && entry->es_type != ETYPE_UFUNC)
#endif
+ {
+ if (entry->es_name == NULL)
+ return NULL;
return vim_strsave(entry->es_name);
-
+ }
#ifdef FEAT_EVAL
+ // Give information about each stack entry up to the root.
// For a function we compose the call stack, as it was done in the past:
// "function One[123]..Two[456]..Three"
- len = STRLEN(entry->es_name) + 10;
- for (idx = exestack.ga_len - 2; idx >= 0; --idx)
+ ga_init2(&ga, sizeof(char), 100);
+ for (idx = 0; idx < exestack.ga_len; ++idx)
{
entry = ((estack_T *)exestack.ga_data) + idx;
- if (entry->es_name == NULL || entry->es_info.ufunc == NULL)
+ if (entry->es_name != NULL)
{
- ++idx;
- break;
+ len = STRLEN(entry->es_name) + 15;
+ type_name = "";
+ if (entry->es_type != last_type)
+ {
+ switch (entry->es_type)
+ {
+ case ETYPE_SCRIPT: type_name = "script "; break;
+ case ETYPE_UFUNC: type_name = "function "; break;
+ default: type_name = ""; break;
+ }
+ last_type = entry->es_type;
+ }
+ len += STRLEN(type_name);
+ if (ga_grow(&ga, 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.
+ vim_snprintf(ga.ga_data + ga.ga_len, len, "%s%s%s",
+ type_name, entry->es_name,
+ idx == exestack.ga_len - 1 ? "" : "..");
+ else
+ vim_snprintf(ga.ga_data + ga.ga_len, len, "%s%s[%ld]..",
+ type_name, entry->es_name, entry->es_lnum);
+ ga.ga_len += STRLEN(ga.ga_data + ga.ga_len);
}
- len += STRLEN(entry->es_name) + 15;
}
- res = (char *)alloc((int)len);
- if (res != NULL)
- {
- STRCPY(res, "function ");
- while (idx < exestack.ga_len - 1)
- {
- done = STRLEN(res);
- entry = ((estack_T *)exestack.ga_data) + idx;
- vim_snprintf(res + done, len - done, "%s[%ld]..",
- entry->es_name, entry->es_lnum);
- ++idx;
- }
- done = STRLEN(res);
- entry = ((estack_T *)exestack.ga_data) + idx;
- vim_snprintf(res + done, len - done, "%s", entry->es_name);
- }
- return (char_u *)res;
+ return (char_u *)ga.ga_data;
#endif
}