summaryrefslogtreecommitdiff
path: root/src/misc2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/misc2.c')
-rw-r--r--src/misc2.c186
1 files changed, 131 insertions, 55 deletions
diff --git a/src/misc2.c b/src/misc2.c
index 4fdbc2798..fd882ff99 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -16,6 +16,10 @@
# include <fcntl.h> /* for chdir() */
#endif
+static char_u *username = NULL; /* cached result of mch_get_user_name() */
+
+static char_u *ff_expand_buffer = NULL; /* used for expanding filenames */
+
#if defined(FEAT_VIRTUALEDIT) || defined(PROTO)
static int coladvance2 __ARGS((pos_T *pos, int addspaces, int finetune, colnr_T wcol));
@@ -922,15 +926,29 @@ do_outofmem_msg(size)
}
#if defined(EXITFREE) || defined(PROTO)
+
+# if defined(FEAT_SEARCHPATH)
+static void free_findfile __ARGS((void));
+# endif
+
/*
* Free everything that we allocated.
* Can be used to detect memory leaks, e.g., with ccmalloc.
- * Doesn't do nearly all that is required...
+ * NOTE: This is tricky! Things are freed that functions depend on. Don't be
+ * surprised if Vim crashes...
+ * Some things can't be freed, esp. things local to a library function.
*/
void
free_all_mem()
{
buf_T *buf, *nextbuf;
+ static int entered = FALSE;
+
+ /* When we cause a crash here it is caught and Vim tries to exit cleanly.
+ * Don't try freeing everything again. */
+ if (entered)
+ return;
+ entered = TRUE;
++autocmd_block; /* don't want to trigger autocommands here */
@@ -939,20 +957,30 @@ free_all_mem()
spell_free_all();
# endif
-#if defined(FEAT_USR_CMDS)
+# if defined(FEAT_USR_CMDS)
/* Clear user commands (before deleting buffers). */
ex_comclear(NULL);
-#endif
+# endif
# ifdef FEAT_MENU
/* Clear menus. */
do_cmdline_cmd((char_u *)"aunmenu *");
# endif
- /* Clear mappings and abbreviations. */
+ /* Clear mappings, abbreviations, breakpoints. */
do_cmdline_cmd((char_u *)"mapclear");
do_cmdline_cmd((char_u *)"mapclear!");
do_cmdline_cmd((char_u *)"abclear");
+# if defined(FEAT_EVAL)
+ do_cmdline_cmd((char_u *)"breakdel *");
+# endif
+
+# ifdef FEAT_TITLE
+ free_titles();
+# endif
+# if defined(FEAT_SEARCHPATH)
+ free_findfile();
+# endif
/* Obviously named calls. */
# if defined(FEAT_EVAL)
@@ -963,11 +991,44 @@ free_all_mem()
free_all_autocmds();
# endif
clear_termcodes();
+ free_all_options();
+ free_all_marks();
+ alist_clear(&global_alist);
+ free_homedir();
+ free_search_patterns();
+ free_old_sub();
+ free_last_insert();
+ free_prev_shellcmd();
+ free_regexp_stuff();
+ free_tag_stuff();
+ free_cd_dir();
+ set_expr_line(NULL);
+ diff_clear();
+
+ /* Free some global vars. */
+ vim_free(username);
+ vim_free(clip_exclude_prog);
+ vim_free(last_cmdline);
+ vim_free(new_last_cmdline);
+ vim_free(keep_msg);
+ vim_free(ff_expand_buffer);
/* Clear cmdline history. */
p_hi = 0;
init_history();
+#ifdef FEAT_QUICKFIX
+ qf_free_all();
+#endif
+
+ /* Close all script inputs. */
+ close_all_scripts();
+
+#if defined(FEAT_WINDOWS)
+ /* Destroy all windows. Must come before freeing buffers. */
+ win_free_all();
+#endif
+
/* Free all buffers. */
for (buf = firstbuf; buf != NULL; )
{
@@ -979,9 +1040,8 @@ free_all_mem()
buf = firstbuf;
}
-#if defined(FEAT_WINDOWS)
- /* Destroy all windows. */
- win_free_all();
+#ifdef FEAT_ARABIC
+ free_cmdline_buf();
#endif
/* Clear registers. */
@@ -989,6 +1049,10 @@ free_all_mem()
ResetRedobuff();
ResetRedobuff();
+#ifdef FEAT_CLIENTSERVER
+ vim_free(serverDelayedStartName);
+#endif
+
/* highlight info */
free_highlight();
@@ -1006,12 +1070,18 @@ free_all_mem()
eval_clear();
# endif
+ free_termoptions();
+
/* screenlines (can't display anything now!) */
free_screenlines();
#if defined(USE_XSMP)
xsmp_close();
#endif
+#ifdef FEAT_GUI_GTK
+ gui_mch_free_all();
+#endif
+ clear_hl_tables();
vim_free(IObuff);
vim_free(NameBuff);
@@ -3642,11 +3712,9 @@ typedef struct ff_search_ctx_T
char_u **ffsc_stopdirs_v;
#endif
int ffsc_need_dir;
-}ff_search_ctx_T;
-static ff_search_ctx_T *ff_search_ctx = NULL;
+} ff_search_ctx_T;
-/* used for expanding filenames */
-static char_u *ff_expand_buffer = NULL;
+static ff_search_ctx_T *ff_search_ctx = NULL;
/* locally needed functions */
#ifdef FEAT_PATH_EXTRA
@@ -3994,8 +4062,7 @@ vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
ff_expand_buffer[len++] = *wc_part++;
}
ff_expand_buffer[len] = NUL;
- ff_search_ctx->ffsc_wc_path =
- vim_strsave(ff_expand_buffer);
+ ff_search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
if (ff_search_ctx->ffsc_wc_path == NULL)
goto error_return;
@@ -4085,7 +4152,7 @@ vim_findfile_stopdir(buf)
vim_findfile_cleanup(ctx)
void *ctx;
{
- if (NULL == ctx)
+ if (ctx == NULL)
return;
ff_search_ctx = ctx;
@@ -4452,8 +4519,8 @@ vim_findfile(search_ctx)
* still wildcards left, push the directories for further
* search
*/
- for (i = ctx->ffs_filearray_cur; i < ctx->ffs_filearray_size;
- ++i)
+ for (i = ctx->ffs_filearray_cur;
+ i < ctx->ffs_filearray_size; ++i)
{
if (!mch_isdir(ctx->ffs_filearray[i]))
continue; /* not a directory */
@@ -4474,7 +4541,8 @@ vim_findfile(search_ctx)
*/
if (STRNCMP(ctx->ffs_wc_path, "**", 2) == 0)
{
- for (i = ctx->ffs_filearray_cur; i < ctx->ffs_filearray_size; ++i)
+ for (i = ctx->ffs_filearray_cur;
+ i < ctx->ffs_filearray_size; ++i)
{
if (fnamecmp(ctx->ffs_filearray[i], ctx->ffs_fix_path) == 0)
continue; /* don't repush same directory */
@@ -4875,8 +4943,7 @@ ff_push(ctx)
ff_stack_T *ctx;
{
/* check for NULL pointer, not to return an error to the user, but
- * to prevent a crash
- */
+ * to prevent a crash */
if (ctx != NULL)
{
ctx->ffs_prev = ff_search_ctx->ffsc_stack_ptr;
@@ -5045,6 +5112,18 @@ find_file_in_path(ptr, len, options, first, rel_fname)
FALSE, rel_fname);
}
+static char_u *ff_file_to_find = NULL;
+static void *fdip_search_ctx = NULL;
+
+#if defined(EXITFREE)
+ static void
+free_findfile()
+{
+ vim_free(ff_file_to_find);
+ vim_findfile_cleanup(fdip_search_ctx);
+}
+#endif
+
/*
* Find the directory name "ptr[len]" in the path.
*
@@ -5076,9 +5155,7 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
int need_dir; /* looking for directory name */
char_u *rel_fname; /* file name we are looking relative to. */
{
- static void *search_ctx = NULL;
static char_u *dir;
- static char_u *file_to_find = NULL;
static int did_findfile_init = FALSE;
char_u save_char;
char_u *file_name = NULL;
@@ -5100,33 +5177,33 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
expand_env(ptr, NameBuff, MAXPATHL);
ptr[len] = save_char;
- vim_free(file_to_find);
- file_to_find = vim_strsave(NameBuff);
- if (file_to_find == NULL) /* out of memory */
+ vim_free(ff_file_to_find);
+ ff_file_to_find = vim_strsave(NameBuff);
+ if (ff_file_to_find == NULL) /* out of memory */
{
file_name = NULL;
goto theend;
}
}
- rel_to_curdir = (file_to_find[0] == '.'
- && (file_to_find[1] == NUL
- || vim_ispathsep(file_to_find[1])
- || (file_to_find[1] == '.'
- && (file_to_find[2] == NUL
- || vim_ispathsep(file_to_find[2])))));
- if (vim_isAbsName(file_to_find)
+ rel_to_curdir = (ff_file_to_find[0] == '.'
+ && (ff_file_to_find[1] == NUL
+ || vim_ispathsep(ff_file_to_find[1])
+ || (ff_file_to_find[1] == '.'
+ && (ff_file_to_find[2] == NUL
+ || vim_ispathsep(ff_file_to_find[2])))));
+ if (vim_isAbsName(ff_file_to_find)
/* "..", "../path", "." and "./path": don't use the path_option */
|| rel_to_curdir
#if defined(MSWIN) || defined(MSDOS) || defined(OS2)
/* handle "\tmp" as absolute path */
- || vim_ispathsep(file_to_find[0])
+ || vim_ispathsep(ff_file_to_find[0])
/* handle "c:name" as absulute path */
- || (file_to_find[0] != NUL && file_to_find[1] == ':')
+ || (ff_file_to_find[0] != NUL && ff_file_to_find[1] == ':')
#endif
#ifdef AMIGA
/* handle ":tmp" as absolute path */
- || file_to_find[0] == ':'
+ || ff_file_to_find[0] == ':'
#endif
)
{
@@ -5140,9 +5217,9 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
int l;
int run;
- if (path_with_url(file_to_find))
+ if (path_with_url(ff_file_to_find))
{
- file_name = vim_strsave(file_to_find);
+ file_name = vim_strsave(ff_file_to_find);
goto theend;
}
@@ -5150,7 +5227,7 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
* Otherwise or when this fails use the current directory. */
for (run = 1; run <= 2; ++run)
{
- l = (int)STRLEN(file_to_find);
+ l = (int)STRLEN(ff_file_to_find);
if (run == 1
&& rel_to_curdir
&& (options & FNAME_REL)
@@ -5158,12 +5235,12 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
&& STRLEN(rel_fname) + l < MAXPATHL)
{
STRCPY(NameBuff, rel_fname);
- STRCPY(gettail(NameBuff), file_to_find);
+ STRCPY(gettail(NameBuff), ff_file_to_find);
l = (int)STRLEN(NameBuff);
}
else
{
- STRCPY(NameBuff, file_to_find);
+ STRCPY(NameBuff, ff_file_to_find);
run = 2;
}
@@ -5203,7 +5280,7 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
if (first == TRUE)
{
/* vim_findfile_free_visited can handle a possible NULL pointer */
- vim_findfile_free_visited(search_ctx);
+ vim_findfile_free_visited(fdip_search_ctx);
dir = path_option;
did_findfile_init = FALSE;
}
@@ -5213,7 +5290,7 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
if (did_findfile_init)
{
ff_search_ctx->ffsc_need_dir = need_dir;
- file_name = vim_findfile(search_ctx);
+ file_name = vim_findfile(fdip_search_ctx);
ff_search_ctx->ffsc_need_dir = FALSE;
if (file_name != NULL)
break;
@@ -5228,8 +5305,8 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
{
/* We searched all paths of the option, now we can
* free the search context. */
- vim_findfile_cleanup(search_ctx);
- search_ctx = NULL;
+ vim_findfile_cleanup(fdip_search_ctx);
+ fdip_search_ctx = NULL;
break;
}
@@ -5246,9 +5323,10 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
#else
r_ptr = NULL;
#endif
- search_ctx = vim_findfile_init(buf, file_to_find, r_ptr, 100,
- FALSE, TRUE, search_ctx, FALSE, rel_fname);
- if (search_ctx != NULL)
+ fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find,
+ r_ptr, 100, FALSE, TRUE,
+ fdip_search_ctx, FALSE, rel_fname);
+ if (fdip_search_ctx != NULL)
did_findfile_init = TRUE;
vim_free(buf);
}
@@ -5260,19 +5338,19 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
{
if (need_dir)
EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
- file_to_find);
+ ff_file_to_find);
else
EMSG2(_("E345: Can't find file \"%s\" in path"),
- file_to_find);
+ ff_file_to_find);
}
else
{
if (need_dir)
EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
- file_to_find);
+ ff_file_to_find);
else
EMSG2(_("E347: No more file \"%s\" found in path"),
- file_to_find);
+ ff_file_to_find);
}
}
@@ -5320,16 +5398,14 @@ get_user_name(buf, len)
char_u *buf;
int len;
{
- static char_u *name = NULL;
-
- if (name == NULL)
+ if (username == NULL)
{
if (mch_get_user_name(buf, len) == FAIL)
return FAIL;
- name = vim_strsave(buf);
+ username = vim_strsave(buf);
}
else
- STRNCPY(buf, name, len);
+ STRNCPY(buf, username, len);
return OK;
}