diff options
-rw-r--r-- | src/nvim/eval.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_cmds_defs.h | 91 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 18 | ||||
-rw-r--r-- | src/nvim/ex_eval.c | 35 | ||||
-rw-r--r-- | src/nvim/ex_eval.h | 44 |
5 files changed, 93 insertions, 97 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 4c76b1b2e8..902d68dcf9 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -23652,7 +23652,7 @@ void ex_return(exarg_T *eap) int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv) { int idx; - struct condstack *cstack = eap->cstack; + cstack_T *const cstack = eap->cstack; if (reanimate) /* Undo the return. */ diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index 3a9fd01dd9..4a40cc54b4 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -12,31 +12,29 @@ # include "ex_cmds_enum.generated.h" #endif -/* - * When adding an Ex command: - * 1. Add an entry to the table in src/nvim/ex_cmds.lua. Keep it sorted on the - * shortest version of the command name that works. If it doesn't start with - * a lower case letter, add it at the end. - * - * Each table entry is a table with the following keys: - * - * Key | Description - * ------- | ------------------------------------------------------------- - * command | Name of the command. Required. - * enum | Name of the enum entry. If not set defaults to CMD_{command}. - * flags | A set of the flags from below list joined by bitwise or. - * func | Name of the function containing the implementation. - * - * Referenced function should be either non-static one or defined in - * ex_docmd.c and be coercible to ex_func_T type from below. - * - * All keys not described in the above table are reserved for future use. - * - * 2. Add a "case: CMD_xxx" in the big switch in ex_docmd.c. - * 3. Add an entry in the index for Ex commands at ":help ex-cmd-index". - * 4. Add documentation in ../doc/xxx.txt. Add a tag for both the short and - * long name of the command. - */ +// When adding an Ex command: +// 1. Add an entry to the table in src/nvim/ex_cmds.lua. Keep it sorted on the +// shortest version of the command name that works. If it doesn't start with +// a lower case letter, add it at the end. +// +// Each table entry is a table with the following keys: +// +// Key | Description +// ------- | ------------------------------------------------------------- +// command | Name of the command. Required. +// enum | Name of the enum entry. If not set defaults to CMD_{command}. +// flags | A set of the flags from below list joined by bitwise or. +// func | Name of the function containing the implementation. +// +// Referenced function should be either non-static one or defined in +// ex_docmd.c and be coercible to ex_func_T type from below. +// +// All keys not described in the above table are reserved for future use. +// +// 2. Add a "case: CMD_xxx" in the big switch in ex_docmd.c. +// 3. Add an entry in the index for Ex commands at ":help ex-cmd-index". +// 4. Add documentation in ../doc/xxx.txt. Add a tag for both the short and +// long name of the command. #define RANGE 0x001 /* allow a linespecs */ #define BANG 0x002 /* allow a ! after the command name */ @@ -98,6 +96,47 @@ typedef struct cmdname { int cmd_addr_type; ///< Flag for address type } CommandDefinition; +// A list used for saving values of "emsg_silent". Used by ex_try() to save the +// value of "emsg_silent" if it was non-zero. When this is done, the CSF_SILENT +// flag below is set. +typedef struct eslist_elem eslist_T; +struct eslist_elem { + int saved_emsg_silent; // saved value of "emsg_silent" + eslist_T *next; // next element on the list +}; + +// For conditional commands a stack is kept of nested conditionals. +// When cs_idx < 0, there is no conditional command. +enum { + CSTACK_LEN = 50, +}; + +typedef struct { + int cs_flags[CSTACK_LEN]; // CSF_ flags + char cs_pending[CSTACK_LEN]; // CSTP_: what's pending in ":finally" + union { + void *csp_rv[CSTACK_LEN]; // return typeval for pending return + void *csp_ex[CSTACK_LEN]; // exception for pending throw + } cs_pend; + void *cs_forinfo[CSTACK_LEN]; // info used by ":for" + int cs_line[CSTACK_LEN]; // line nr of ":while"/":for" line + int cs_idx; // current entry, or -1 if none + int cs_looplevel; // nr of nested ":while"s and ":for"s + int cs_trylevel; // nr of nested ":try"s + eslist_T *cs_emsg_silent_list; // saved values of "emsg_silent" + int cs_lflags; // loop flags: CSL_ flags +} cstack_T; +# define cs_rettv cs_pend.csp_rv +# define cs_exception cs_pend.csp_ex + +// Flags for the cs_lflags item in cstack_T. +enum { + CSL_HAD_LOOP = 1, // just found ":while" or ":for" + CSL_HAD_ENDLOOP = 2, // just found ":endwhile" or ":endfor" + CSL_HAD_CONT = 4, // just found ":continue" + CSL_HAD_FINA = 8, // just found ":finally" +}; + /// Arguments used for Ex commands. struct exarg { char_u *arg; ///< argument of the command @@ -128,7 +167,7 @@ struct exarg { char_u *errmsg; ///< returned error message LineGetter getline; ///< Function used to get the next line void *cookie; ///< argument for getline() - struct condstack *cstack; ///< condition stack for ":if" etc. + cstack_T *cstack; ///< condition stack for ":if" etc. }; #define FORCE_BIN 1 // ":edit ++bin file" diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 30c1373445..d16ad9db2c 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -325,13 +325,13 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, int count = 0; /* line number count */ int did_inc = FALSE; /* incremented RedrawingDisabled */ int retval = OK; - struct condstack cstack; /* conditional stack */ - garray_T lines_ga; /* keep lines for ":while"/":for" */ - int current_line = 0; /* active line in lines_ga */ - char_u *fname = NULL; /* function or script name */ - linenr_T *breakpoint = NULL; /* ptr to breakpoint field in cookie */ - int *dbg_tick = NULL; /* ptr to dbg_tick field in cookie */ - struct dbg_stuff debug_saved; /* saved things for debug mode */ + cstack_T cstack; // conditional stack + garray_T lines_ga; // keep lines for ":while"/":for" + int current_line = 0; // active line in lines_ga + char_u *fname = NULL; // function or script name + linenr_T *breakpoint = NULL; // ptr to breakpoint field in cookie + int *dbg_tick = NULL; // ptr to dbg_tick field in cookie + struct dbg_stuff debug_saved; // saved things for debug mode int initial_trylevel; struct msglist **saved_msg_list = NULL; struct msglist *private_msg_list; @@ -361,7 +361,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, EMSG(_("E169: Command too recursive")); // When converting to an exception, we do not include the command name // since this is not an error of the specific command. - do_errthrow((struct condstack *)NULL, (char_u *)NULL); + do_errthrow((cstack_T *)NULL, (char_u *)NULL); msg_list = saved_msg_list; return FAIL; } @@ -1545,7 +1545,7 @@ static bool parse_one_cmd( */ static char_u * do_one_cmd(char_u **cmdlinep, int flags, - struct condstack *cstack, + cstack_T *cstack, LineGetter fgetline, void *cookie /* argument for fgetline() */ ) diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 28bc222827..f70a568e4a 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -307,7 +307,7 @@ void free_global_msglist(void) * error exception. If cstack is NULL, postpone the throw until do_cmdline() * has returned (see do_one_cmd()). */ -void do_errthrow(struct condstack *cstack, char_u *cmdname) +void do_errthrow(cstack_T *cstack, char_u *cmdname) { /* * Ensure that all commands in nested function calls and sourced files @@ -339,7 +339,7 @@ void do_errthrow(struct condstack *cstack, char_u *cmdname) * exception if appropriate. Return TRUE if the current exception is discarded, * FALSE otherwise. */ -int do_intthrow(struct condstack *cstack) +int do_intthrow(cstack_T *cstack) { // If no interrupt occurred or no try conditional is active and no exception // is being thrown, do nothing (for compatibility of non-EH scripts). @@ -795,7 +795,7 @@ void ex_if(exarg_T *eap) { int skip; int result; - struct condstack *cstack = eap->cstack; + cstack_T *const cstack = eap->cstack; if (cstack->cs_idx == CSTACK_LEN - 1) eap->errmsg = (char_u *)N_("E579: :if nesting too deep"); @@ -852,7 +852,7 @@ void ex_else(exarg_T *eap) { int skip; int result; - struct condstack *cstack = eap->cstack; + cstack_T *const cstack = eap->cstack; skip = CHECK_SKIP; @@ -926,7 +926,7 @@ void ex_while(exarg_T *eap) bool error; int skip; int result; - struct condstack *cstack = eap->cstack; + cstack_T *const cstack = eap->cstack; if (cstack->cs_idx == CSTACK_LEN - 1) eap->errmsg = (char_u *)N_("E585: :while/:for nesting too deep"); @@ -1005,7 +1005,7 @@ void ex_while(exarg_T *eap) void ex_continue(exarg_T *eap) { int idx; - struct condstack *cstack = eap->cstack; + cstack_T *const cstack = eap->cstack; if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) eap->errmsg = (char_u *)N_("E586: :continue without :while or :for"); @@ -1039,7 +1039,7 @@ void ex_continue(exarg_T *eap) void ex_break(exarg_T *eap) { int idx; - struct condstack *cstack = eap->cstack; + cstack_T *const cstack = eap->cstack; if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) eap->errmsg = (char_u *)N_("E587: :break without :while or :for"); @@ -1061,7 +1061,7 @@ void ex_break(exarg_T *eap) */ void ex_endwhile(exarg_T *eap) { - struct condstack *cstack = eap->cstack; + cstack_T *const cstack = eap->cstack; int idx; char_u *err; int csf; @@ -1164,7 +1164,7 @@ void ex_throw(exarg_T *eap) * for ":throw" (user exception) and error and interrupt exceptions. Also * used for rethrowing an uncaught exception. */ -void do_throw(struct condstack *cstack) +void do_throw(cstack_T *cstack) { int idx; int inactivate_try = FALSE; @@ -1225,7 +1225,7 @@ void do_throw(struct condstack *cstack) void ex_try(exarg_T *eap) { int skip; - struct condstack *cstack = eap->cstack; + cstack_T *const cstack = eap->cstack; if (cstack->cs_idx == CSTACK_LEN - 1) eap->errmsg = (char_u *)N_("E601: :try nesting too deep"); @@ -1260,7 +1260,7 @@ void ex_try(exarg_T *eap) * to save the value. */ if (emsg_silent) { - eslist_T *elem = xmalloc(sizeof(struct eslist_elem)); + eslist_T *elem = xmalloc(sizeof(*elem)); elem->saved_emsg_silent = emsg_silent; elem->next = cstack->cs_emsg_silent_list; cstack->cs_emsg_silent_list = elem; @@ -1286,7 +1286,7 @@ void ex_catch(exarg_T *eap) char_u *save_cpo; regmatch_T regmatch; int prev_got_int; - struct condstack *cstack = eap->cstack; + cstack_T *const cstack = eap->cstack; char_u *pat; if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) { @@ -1432,7 +1432,7 @@ void ex_finally(exarg_T *eap) int idx; int skip = FALSE; int pending = CSTP_NONE; - struct condstack *cstack = eap->cstack; + cstack_T *const cstack = eap->cstack; if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) eap->errmsg = (char_u *)N_("E606: :finally without :try"); @@ -1555,7 +1555,7 @@ void ex_endtry(exarg_T *eap) int rethrow = FALSE; int pending = CSTP_NONE; void *rettv = NULL; - struct condstack *cstack = eap->cstack; + cstack_T *const cstack = eap->cstack; if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) { eap->errmsg = (char_u *)N_("E602: :endtry without :try"); @@ -1882,7 +1882,7 @@ void leave_cleanup(cleanup_T *csp) * entered, is restored (used by ex_endtry()). This is normally done only * when such a try conditional is left. */ -int cleanup_conditionals(struct condstack *cstack, int searched_cond, int inclusive) +int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive) { int idx; int stop = FALSE; @@ -1990,7 +1990,7 @@ int cleanup_conditionals(struct condstack *cstack, int searched_cond, int inclus /* * Return an appropriate error message for a missing endwhile/endfor/endif. */ -static char_u *get_end_emsg(struct condstack *cstack) +static char_u *get_end_emsg(cstack_T *cstack) { if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE) return e_endwhile; @@ -2007,7 +2007,8 @@ static char_u *get_end_emsg(struct condstack *cstack) * type. * Also free "for info" structures where needed. */ -void rewind_conditionals(struct condstack *cstack, int idx, int cond_type, int *cond_level) +void rewind_conditionals(cstack_T *cstack, int idx, int cond_type, + int *cond_level) { while (cstack->cs_idx > idx) { if (cstack->cs_flags[cstack->cs_idx] & cond_type) diff --git a/src/nvim/ex_eval.h b/src/nvim/ex_eval.h index 2237b6aca3..d8388c9156 100644 --- a/src/nvim/ex_eval.h +++ b/src/nvim/ex_eval.h @@ -4,42 +4,6 @@ #include "nvim/pos.h" // for linenr_T #include "nvim/ex_cmds_defs.h" // for exarg_T -/* - * A list used for saving values of "emsg_silent". Used by ex_try() to save the - * value of "emsg_silent" if it was non-zero. When this is done, the CSF_SILENT - * flag below is set. - */ - -typedef struct eslist_elem eslist_T; -struct eslist_elem { - int saved_emsg_silent; /* saved value of "emsg_silent" */ - eslist_T *next; /* next element on the list */ -}; - -/* - * For conditional commands a stack is kept of nested conditionals. - * When cs_idx < 0, there is no conditional command. - */ -#define CSTACK_LEN 50 - -struct condstack { - int cs_flags[CSTACK_LEN]; // CSF_ flags - char cs_pending[CSTACK_LEN]; // CSTP_: what's pending in ":finally" - union { - void *csp_rv[CSTACK_LEN]; // return typeval for pending return - void *csp_ex[CSTACK_LEN]; // exception for pending throw - } cs_pend; - void *cs_forinfo[CSTACK_LEN]; // info used by ":for" - int cs_line[CSTACK_LEN]; // line nr of ":while"/":for" line - int cs_idx; // current entry, or -1 if none - int cs_looplevel; // nr of nested ":while"s and ":for"s - int cs_trylevel; // nr of nested ":try"s - eslist_T *cs_emsg_silent_list; // saved values of "emsg_silent" - int cs_lflags; // loop flags: CSL_ flags -}; -# define cs_rettv cs_pend.csp_rv -# define cs_exception cs_pend.csp_ex - /* There is no CSF_IF, the lack of CSF_WHILE, CSF_FOR and CSF_TRY means ":if" * was used. */ # define CSF_TRUE 0x0001 /* condition was TRUE */ @@ -70,14 +34,6 @@ struct condstack { # define CSTP_FINISH 32 /* ":finish" is pending */ /* - * Flags for the cs_lflags item in struct condstack. - */ -# define CSL_HAD_LOOP 1 /* just found ":while" or ":for" */ -# define CSL_HAD_ENDLOOP 2 /* just found ":endwhile" or ":endfor" */ -# define CSL_HAD_CONT 4 /* just found ":continue" */ -# define CSL_HAD_FINA 8 /* just found ":finally" */ - -/* * A list of error messages that can be converted to an exception. "throw_msg" * is only set in the first element of the list. Usually, it points to the * original message stored in that element, but sometimes it points to a later |