1 | #ifndef NVIM_EX_EVAL_H |
2 | #define NVIM_EX_EVAL_H |
3 | |
4 | #include "nvim/pos.h" // for linenr_T |
5 | #include "nvim/ex_cmds_defs.h" // for exarg_T |
6 | |
7 | /* |
8 | * A list used for saving values of "emsg_silent". Used by ex_try() to save the |
9 | * value of "emsg_silent" if it was non-zero. When this is done, the CSF_SILENT |
10 | * flag below is set. |
11 | */ |
12 | |
13 | typedef struct eslist_elem eslist_T; |
14 | struct eslist_elem { |
15 | int saved_emsg_silent; /* saved value of "emsg_silent" */ |
16 | eslist_T *next; /* next element on the list */ |
17 | }; |
18 | |
19 | /* |
20 | * For conditional commands a stack is kept of nested conditionals. |
21 | * When cs_idx < 0, there is no conditional command. |
22 | */ |
23 | #define CSTACK_LEN 50 |
24 | |
25 | struct condstack { |
26 | int cs_flags[CSTACK_LEN]; // CSF_ flags |
27 | char cs_pending[CSTACK_LEN]; // CSTP_: what's pending in ":finally" |
28 | union { |
29 | void *csp_rv[CSTACK_LEN]; // return typeval for pending return |
30 | void *csp_ex[CSTACK_LEN]; // exception for pending throw |
31 | } cs_pend; |
32 | void *cs_forinfo[CSTACK_LEN]; // info used by ":for" |
33 | int cs_line[CSTACK_LEN]; // line nr of ":while"/":for" line |
34 | int cs_idx; // current entry, or -1 if none |
35 | int cs_looplevel; // nr of nested ":while"s and ":for"s |
36 | int cs_trylevel; // nr of nested ":try"s |
37 | eslist_T *cs_emsg_silent_list; // saved values of "emsg_silent" |
38 | int cs_lflags; // loop flags: CSL_ flags |
39 | }; |
40 | # define cs_rettv cs_pend.csp_rv |
41 | # define cs_exception cs_pend.csp_ex |
42 | |
43 | /* There is no CSF_IF, the lack of CSF_WHILE, CSF_FOR and CSF_TRY means ":if" |
44 | * was used. */ |
45 | # define CSF_TRUE 0x0001 /* condition was TRUE */ |
46 | # define CSF_ACTIVE 0x0002 /* current state is active */ |
47 | # define CSF_ELSE 0x0004 /* ":else" has been passed */ |
48 | # define CSF_WHILE 0x0008 /* is a ":while" */ |
49 | # define CSF_FOR 0x0010 /* is a ":for" */ |
50 | |
51 | # define CSF_TRY 0x0100 /* is a ":try" */ |
52 | # define CSF_FINALLY 0x0200 /* ":finally" has been passed */ |
53 | # define CSF_THROWN 0x0400 /* exception thrown to this try conditional */ |
54 | # define CSF_CAUGHT 0x0800 /* exception caught by this try conditional */ |
55 | # define CSF_SILENT 0x1000 /* "emsg_silent" reset by ":try" */ |
56 | /* Note that CSF_ELSE is only used when CSF_TRY and CSF_WHILE are unset |
57 | * (an ":if"), and CSF_SILENT is only used when CSF_TRY is set. */ |
58 | |
59 | /* |
60 | * What's pending for being reactivated at the ":endtry" of this try |
61 | * conditional: |
62 | */ |
63 | # define CSTP_NONE 0 /* nothing pending in ":finally" clause */ |
64 | # define CSTP_ERROR 1 /* an error is pending */ |
65 | # define CSTP_INTERRUPT 2 /* an interrupt is pending */ |
66 | # define CSTP_THROW 4 /* a throw is pending */ |
67 | # define CSTP_BREAK 8 /* ":break" is pending */ |
68 | # define CSTP_CONTINUE 16 /* ":continue" is pending */ |
69 | # define CSTP_RETURN 24 /* ":return" is pending */ |
70 | # define CSTP_FINISH 32 /* ":finish" is pending */ |
71 | |
72 | /* |
73 | * Flags for the cs_lflags item in struct condstack. |
74 | */ |
75 | # define CSL_HAD_LOOP 1 /* just found ":while" or ":for" */ |
76 | # define CSL_HAD_ENDLOOP 2 /* just found ":endwhile" or ":endfor" */ |
77 | # define CSL_HAD_CONT 4 /* just found ":continue" */ |
78 | # define CSL_HAD_FINA 8 /* just found ":finally" */ |
79 | |
80 | /* |
81 | * A list of error messages that can be converted to an exception. "throw_msg" |
82 | * is only set in the first element of the list. Usually, it points to the |
83 | * original message stored in that element, but sometimes it points to a later |
84 | * message in the list. See cause_errthrow() below. |
85 | */ |
86 | struct msglist { |
87 | char_u *msg; /* original message */ |
88 | char_u *throw_msg; /* msg to throw: usually original one */ |
89 | struct msglist *next; /* next of several messages in a row */ |
90 | }; |
91 | |
92 | // The exception types. |
93 | typedef enum |
94 | { |
95 | ET_USER, // exception caused by ":throw" command |
96 | ET_ERROR, // error exception |
97 | ET_INTERRUPT, // interrupt exception triggered by Ctrl-C |
98 | } except_type_T; |
99 | |
100 | /* |
101 | * Structure describing an exception. |
102 | * (don't use "struct exception", it's used by the math library). |
103 | */ |
104 | typedef struct vim_exception except_T; |
105 | struct vim_exception { |
106 | except_type_T type; // exception type |
107 | char_u *value; // exception value |
108 | struct msglist *messages; // message(s) causing error exception |
109 | char_u *throw_name; // name of the throw point |
110 | linenr_T throw_lnum; // line number of the throw point |
111 | except_T *caught; // next exception on the caught stack |
112 | }; |
113 | |
114 | /* |
115 | * Structure to save the error/interrupt/exception state between calls to |
116 | * enter_cleanup() and leave_cleanup(). Must be allocated as an automatic |
117 | * variable by the (common) caller of these functions. |
118 | */ |
119 | typedef struct cleanup_stuff cleanup_T; |
120 | struct cleanup_stuff { |
121 | int pending; /* error/interrupt/exception state */ |
122 | except_T *exception; /* exception value */ |
123 | }; |
124 | |
125 | #ifdef INCLUDE_GENERATED_DECLARATIONS |
126 | # include "ex_eval.h.generated.h" |
127 | #endif |
128 | #endif // NVIM_EX_EVAL_H |
129 | |