// This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com /// @file runtime.c /// /// Management of runtime files (including packages) #include "nvim/api/private/helpers.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" #include "nvim/charset.h" #include "nvim/cmdexpand.h" #include "nvim/debugger.h" #include "nvim/eval.h" #include "nvim/eval/userfunc.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/lua/executor.h" #include "nvim/memline.h" #include "nvim/option.h" #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/profile.h" #include "nvim/runtime.h" #include "nvim/vim.h" /// Structure used to store info for each sourced file. /// It is shared between do_source() and getsourceline(). /// This is required, because it needs to be handed to do_cmdline() and /// sourcing can be done recursively. struct source_cookie { FILE *fp; ///< opened file for sourcing char *nextline; ///< if not NULL: line that was read ahead linenr_T sourcing_lnum; ///< line number of the source file int finished; ///< ":finish" used #if defined(USE_CRNL) int fileformat; ///< EOL_UNKNOWN, EOL_UNIX or EOL_DOS bool error; ///< true if LF found after CR-LF #endif linenr_T breakpoint; ///< next line with breakpoint or zero char *fname; ///< name of sourced file int dbg_tick; ///< debug_tick when breakpoint was set int level; ///< top nesting level of sourced file vimconv_T conv; ///< type of conversion }; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "runtime.c.generated.h" #endif garray_T exestack = { 0, 0, sizeof(estack_T), 50, NULL }; garray_T script_items = { 0, 0, sizeof(scriptitem_T), 4, NULL }; /// Initialize the execution stack. void estack_init(void) { ga_grow(&exestack, 10); estack_T *entry = ((estack_T *)exestack.ga_data) + exestack.ga_len; entry->es_type = ETYPE_TOP; entry->es_name = NULL; entry->es_lnum = 0; entry->es_info.ufunc = NULL; exestack.ga_len++; } /// Add an item to the execution stack. /// @return the new entry estack_T *estack_push(etype_T type, char *name, linenr_T lnum) { ga_grow(&exestack, 1); estack_T *entry = ((estack_T *)exestack.ga_data) + exestack.ga_len; entry->es_type = type; entry->es_name = name; entry->es_lnum = lnum; entry->es_info.ufunc = NULL; exestack.ga_len++; return entry; } /// Add a user function to the execution stack. void estack_push_ufunc(ufunc_T *ufunc, linenr_T lnum) { estack_T *entry = estack_push(ETYPE_UFUNC, (char *)(ufunc->uf_name_exp != NULL ? ufunc->uf_name_exp : ufunc->uf_name), lnum); if (entry != NULL) { entry->es_info.ufunc = ufunc; } } /// Take an item off of the execution stack. void estack_pop(void) { if (exestack.ga_len > 1) { exestack.ga_len--; } } /// Get the current value for in allocated memory. /// @param which ESTACK_SFILE for , ESTACK_STACK for or /// ESTACK_SCRIPT for