Mercurial > vim
annotate src/termlib.c @ 33613:31fb1a760ad6 v9.0.2050
patch 9.0.2050: Vim9: crash with deferred function call and exception
Commit: https://github.com/vim/vim/commit/c59c1e0d88651a71ece7366e418f1253abbe2a28
Author: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Thu Oct 19 10:52:34 2023 +0200
patch 9.0.2050: Vim9: crash with deferred function call and exception
Problem: Vim9: crash with deferred function call and exception
Solution: Save and restore exception state
Crash when a deferred function is called after an exception and another
exception is thrown
closes: #13376
closes: #13377
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 19 Oct 2023 11:00:07 +0200 |
parents | 50555279168b |
children |
rev | line source |
---|---|
10042
4aead6a9b7a9
commit https://github.com/vim/vim/commit/edf3f97ae2af024708ebb4ac614227327033ca47
Christian Brabandt <cb@256bit.org>
parents:
8340
diff
changeset
|
1 /* vi:set ts=8 sts=4 sw=4 noet: */ |
7 | 2 /* |
3 * The following software is (C) 1984 Peter da Silva, the Mad Australian, in | |
4 * the public domain. It may be re-distributed for any purpose with the | |
5 * inclusion of this notice. | |
6 */ | |
7 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
8 // Modified by Bram Moolenaar for use with VIM - Vi Improved. |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
9 // A few bugs removed by Olaf 'Rhialto' Seibert. |
7 | 10 |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
11 // TERMLIB: Terminal independent database. |
7 | 12 |
13 #include "vim.h" | |
14 #include "termlib.pro" | |
15 | |
12716
351cf7c67bbe
patch 8.0.1236: Mac features are confusing
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
16 #if !defined(AMIGA) && !defined(VMS) |
7 | 17 # include <sgtty.h> |
18 #endif | |
19 | |
7805
0b6c37dd858d
commit https://github.com/vim/vim/commit/baaa7e9ec7398a813e21285c272fa99792642077
Christian Brabandt <cb@256bit.org>
parents:
2823
diff
changeset
|
20 static int getent(char *, char *, FILE *, int); |
0b6c37dd858d
commit https://github.com/vim/vim/commit/baaa7e9ec7398a813e21285c272fa99792642077
Christian Brabandt <cb@256bit.org>
parents:
2823
diff
changeset
|
21 static int nextent(char *, FILE *, int); |
0b6c37dd858d
commit https://github.com/vim/vim/commit/baaa7e9ec7398a813e21285c272fa99792642077
Christian Brabandt <cb@256bit.org>
parents:
2823
diff
changeset
|
22 static int _match(char *, char *); |
0b6c37dd858d
commit https://github.com/vim/vim/commit/baaa7e9ec7398a813e21285c272fa99792642077
Christian Brabandt <cb@256bit.org>
parents:
2823
diff
changeset
|
23 static char *_addfmt(char *, char *, int); |
0b6c37dd858d
commit https://github.com/vim/vim/commit/baaa7e9ec7398a813e21285c272fa99792642077
Christian Brabandt <cb@256bit.org>
parents:
2823
diff
changeset
|
24 static char *_find(char *, char *); |
7 | 25 |
26 /* | |
27 * Global variables for termlib | |
28 */ | |
29 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
30 char *tent; // Pointer to terminal entry, set by tgetent |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
31 char PC = 0; // Pad character, default NULL |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
32 char *UP = 0, *BC = 0; // Pointers to UP and BC strings from database |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
33 short ospeed; // Baud rate (1-16, 1=300, 16=19200), as in stty |
7 | 34 |
35 /* | |
36 * Module: tgetent | |
37 * | |
38 * Purpose: Get termcap entry for <term> into buffer at <tbuf>. | |
39 * | |
40 * Calling conventions: char tbuf[TBUFSZ+], term=canonical name for terminal. | |
41 * | |
42 * Returned values: 1 = success, -1 = can't open file, | |
43 * 0 = can't find terminal. | |
44 * | |
45 * Notes: | |
46 * - Should probably supply static buffer. | |
47 * - Uses environment variables "TERM" and "TERMCAP". If TERM = term (that is, | |
48 * if the argument matches the environment) then it looks at TERMCAP. | |
49 * - If TERMCAP begins with a slash, then it assumes this is the file to | |
50 * search rather than /etc/termcap. | |
51 * - If TERMCAP does not begin with a slash, and it matches TERM, then this is | |
52 * used as the entry. | |
53 * - This could be simplified considerably for non-UNIX systems. | |
54 */ | |
55 | |
56 #ifndef TERMCAPFILE | |
57 # ifdef AMIGA | |
58 # define TERMCAPFILE "s:termcap" | |
59 # else | |
60 # ifdef VMS | |
61 # define TERMCAPFILE "VIMRUNTIME:termcap" | |
62 # else | |
63 # define TERMCAPFILE "/etc/termcap" | |
64 # endif | |
65 # endif | |
66 #endif | |
67 | |
68 int | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
69 tgetent( |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
70 char *tbuf, // Buffer to hold termcap entry, TBUFSZ bytes max |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
71 char *term) // Name of terminal |
7 | 72 { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
73 char tcbuf[32]; // Temp buffer to handle |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
74 char *tcptr = tcbuf; // extended entries |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
75 char *tcap = TERMCAPFILE; // Default termcap file |
7 | 76 char *tmp; |
77 FILE *termcap; | |
78 int retval = 0; | |
79 int len; | |
80 | |
81 if ((tmp = (char *)mch_getenv((char_u *)"TERMCAP")) != NULL) | |
82 { | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
83 if (*tmp == '/') // TERMCAP = name of termcap file |
7 | 84 { |
85 tcap = tmp ; | |
86 #if defined(AMIGA) | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
87 // Convert /usr/share/lib/termcap to usr:share/lib/termcap |
7 | 88 tcap++; |
89 tmp = strchr(tcap, '/'); | |
90 if (tmp) | |
91 *tmp = ':'; | |
92 #endif | |
93 } | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
94 else // TERMCAP = termcap entry itself |
7 | 95 { |
96 int tlen = strlen(term); | |
97 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
98 while (*tmp && *tmp != ':') // Check if TERM matches |
7 | 99 { |
100 char *nexttmp; | |
101 | |
102 while (*tmp == '|') | |
103 tmp++; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
104 nexttmp = _find(tmp, ":|"); // Rhialto |
7 | 105 if (tmp+tlen == nexttmp && _match(tmp, term) == tlen) |
106 { | |
107 strcpy(tbuf, tmp); | |
108 tent = tbuf; | |
109 return 1; | |
110 } | |
111 else | |
112 tmp = nexttmp; | |
113 } | |
114 } | |
115 } | |
116 if (!(termcap = mch_fopen(tcap, "r"))) | |
117 { | |
118 strcpy(tbuf, tcap); | |
119 return -1; | |
120 } | |
121 | |
122 len = 0; | |
123 while (getent(tbuf + len, term, termcap, TBUFSZ - len)) | |
124 { | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
125 tcptr = tcbuf; // Rhialto |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
126 if ((term = tgetstr("tc", &tcptr))) // extended entry |
7 | 127 { |
128 rewind(termcap); | |
129 len = strlen(tbuf); | |
130 } | |
131 else | |
132 { | |
133 retval = 1; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
134 tent = tbuf; // reset it back to the beginning |
7 | 135 break; |
136 } | |
137 } | |
138 fclose(termcap); | |
139 return retval; | |
140 } | |
141 | |
142 static int | |
8340
c66e1f50c142
commit https://github.com/vim/vim/commit/2f6271b1e7cff985cac66f6850116bcf3fcccd58
Christian Brabandt <cb@256bit.org>
parents:
7835
diff
changeset
|
143 getent(char *tbuf, char *term, FILE *termcap, int buflen) |
7 | 144 { |
145 char *tptr; | |
146 int tlen = strlen(term); | |
147 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
148 while (nextent(tbuf, termcap, buflen)) // For each possible entry |
7 | 149 { |
150 tptr = tbuf; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
151 while (*tptr && *tptr != ':') // : terminates name field |
7 | 152 { |
153 char *nexttptr; | |
154 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
155 while (*tptr == '|') // | separates names |
7 | 156 tptr++; |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
157 nexttptr = _find(tptr, ":|"); // Rhialto |
7 | 158 if (tptr + tlen == nexttptr && |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
159 _match(tptr, term) == tlen) // FOUND! |
7 | 160 { |
161 tent = tbuf; | |
162 return 1; | |
163 } | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
164 else // Look for next name |
7 | 165 tptr = nexttptr; |
166 } | |
167 } | |
168 return 0; | |
169 } | |
170 | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
171 /* |
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
172 * Read 1 entry from TERMCAP file. |
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
173 */ |
7 | 174 static int |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
175 nextent(char *tbuf, FILE *termcap, int buflen) |
7 | 176 { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
177 char *lbuf = tbuf; // lbuf=line buffer |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
178 // read lines straight into buffer |
7 | 179 |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
180 while (lbuf < tbuf+buflen && // There's room and |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
181 fgets(lbuf, (int)(tbuf+buflen-lbuf), termcap)) // another line |
7 | 182 { |
183 int llen = strlen(lbuf); | |
184 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
185 if (*lbuf == '#') // eat comments |
7 | 186 continue; |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
187 if (lbuf[-1] == ':' && // and whitespace |
7 | 188 lbuf[0] == '\t' && |
189 lbuf[1] == ':') | |
190 { | |
1621 | 191 STRMOVE(lbuf, lbuf + 2); |
7 | 192 llen -= 2; |
193 } | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
194 if (lbuf[llen-2] == '\\') // and continuations |
7 | 195 lbuf += llen-2; |
196 else | |
197 { | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
198 lbuf[llen-1]=0; // no continuation, return |
7 | 199 return 1; |
200 } | |
201 } | |
202 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
203 return 0; // ran into end of file |
7 | 204 } |
205 | |
206 /* | |
207 * Module: tgetflag | |
208 * | |
209 * Purpose: returns flag true or false as to the existence of a given entry. | |
210 * used with 'bs', 'am', etc... | |
211 * | |
212 * Calling conventions: id is the 2 character capability id. | |
213 * | |
214 * Returned values: 1 for success, 0 for failure. | |
215 */ | |
216 | |
217 int | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
218 tgetflag(char *id) |
7 | 219 { |
220 char buf[256], *ptr = buf; | |
221 | |
222 return tgetstr(id, &ptr) ? 1 : 0; | |
223 } | |
224 | |
225 /* | |
226 * Module: tgetnum | |
227 * | |
228 * Purpose: get numeric value such as 'li' or 'co' from termcap. | |
229 * | |
230 * Calling conventions: id = 2 character id. | |
231 * | |
232 * Returned values: -1 for failure, else numerical value. | |
233 */ | |
234 | |
235 int | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
236 tgetnum(char *id) |
7 | 237 { |
238 char *ptr, buf[256]; | |
239 ptr = buf; | |
240 | |
241 if (tgetstr(id, &ptr)) | |
242 return atoi(buf); | |
243 else | |
244 return 0; | |
245 } | |
246 | |
247 /* | |
248 * Module: tgetstr | |
249 * | |
250 * Purpose: get terminal capability string from database. | |
251 * | |
252 * Calling conventions: id is the two character capability id. | |
253 * (*buf) points into a hold buffer for the | |
254 * id. the capability is copied into the buffer | |
255 * and (*buf) is advanced to point to the next | |
256 * free byte in the buffer. | |
257 * | |
258 * Returned values: 0 = no such entry, otherwise returns original | |
259 * (*buf) (now a pointer to the string). | |
260 * | |
261 * Notes | |
262 * It also decodes certain escape sequences in the buffer. | |
263 * they should be obvious from the code: | |
264 * \E = escape. | |
265 * \n, \r, \t, \f, \b match the 'c' escapes. | |
266 * ^x matches control-x (^@...^_). | |
267 * \nnn matches nnn octal. | |
268 * \x, where x is anything else, matches x. I differ | |
269 * from the standard library here, in that I allow ^: to match | |
270 * :. | |
271 * | |
272 */ | |
273 | |
274 char * | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
275 tgetstr(char *id, char **buf) |
7 | 276 { |
277 int len = strlen(id); | |
278 char *tmp=tent; | |
279 char *hold; | |
280 int i; | |
281 | |
282 do { | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
283 tmp = _find(tmp, ":"); // For each field |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
284 while (*tmp == ':') // skip empty fields |
7 | 285 tmp++; |
286 if (!*tmp) | |
287 break; | |
288 | |
31804
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
289 if (_match(id, tmp) == len) |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
290 { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
291 tmp += len; // find '=' '@' or '#' |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
292 if (*tmp == '@') // :xx@: entry for tc |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
293 return 0; // deleted entry |
7 | 294 hold= *buf; |
31804
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
295 while (*++tmp && *tmp != ':') // not at end of field |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
296 { |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
297 switch(*tmp) |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
298 { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
299 case '\\': // Expand escapes here |
31804
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
300 switch(*++tmp) |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
301 { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
302 case 0: // ignore backslashes |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
303 tmp--; // at end of entry |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
304 break; // shouldn't happen |
7 | 305 case 'e': |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
306 case 'E': // ESC |
7 | 307 *(*buf)++ = ESC; |
308 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
309 case 'n': // \n |
7 | 310 *(*buf)++ = '\n'; |
311 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
312 case 'r': // \r |
7 | 313 *(*buf)++ = '\r'; |
314 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
315 case 't': // \t |
7 | 316 *(*buf)++ = '\t'; |
317 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
318 case 'b': // \b |
7 | 319 *(*buf)++ = '\b'; |
320 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
321 case 'f': // \f |
7 | 322 *(*buf)++ = '\f'; |
323 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
324 case '0': // \nnn |
7 | 325 case '1': |
326 case '2': | |
327 case '3': | |
328 case '4': | |
329 case '5': | |
330 case '6': | |
331 case '7': | |
332 case '8': | |
333 case '9': | |
334 **buf = 0; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
335 // get up to three digits |
7 | 336 for (i = 0; i < 3 && VIM_ISDIGIT(*tmp); ++i) |
337 **buf = **buf * 8 + *tmp++ - '0'; | |
338 (*buf)++; | |
339 tmp--; | |
340 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
341 default: // \x, for all other x |
7 | 342 *(*buf)++= *tmp; |
343 } | |
344 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
345 case '^': // control characters |
7 | 346 ++tmp; |
347 *(*buf)++ = Ctrl_chr(*tmp); | |
348 break; | |
349 default: | |
350 *(*buf)++ = *tmp; | |
351 } | |
352 } | |
353 *(*buf)++ = 0; | |
354 return hold; | |
355 } | |
356 } while (*tmp); | |
357 | |
358 return 0; | |
359 } | |
360 | |
361 /* | |
362 * Module: tgoto | |
363 * | |
364 * Purpose: decode cm cursor motion string. | |
365 * | |
366 * Calling conventions: cm is cursor motion string. line, col, are the | |
367 * desired destination. | |
368 * | |
369 * Returned values: a string pointing to the decoded string, or "OOPS" if it | |
370 * cannot be decoded. | |
371 * | |
372 * Notes | |
373 * The accepted escapes are: | |
374 * %d as in printf, 0 origin. | |
375 * %2, %3 like %02d, %03d in printf. | |
376 * %. like %c | |
377 * %+x adds <x> to value, then %. | |
378 * %>xy if value>x, adds y. No output. | |
379 * %i increments line& col, no output. | |
380 * %r reverses order of line&col. No output. | |
381 * %% prints as a single %. | |
382 * %n exclusive or row & col with 0140. | |
383 * %B BCD, no output. | |
384 * %D reverse coding (x-2*(x%16)), no output. | |
385 */ | |
386 | |
387 char * | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
388 tgoto( |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
389 char *cm, // cm string, from termcap |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
390 int col, // column, x position |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
391 int line) // line, y position |
7 | 392 { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
393 char gx, gy, // x, y |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
394 *ptr, // pointer in 'cm' |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
395 reverse = 0, // reverse flag |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
396 *bufp, // pointer in returned string |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
397 addup = 0, // add upline |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
398 addbak = 0, // add backup |
7 | 399 c; |
400 static char buffer[32]; | |
401 | |
402 if (!cm) | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
403 return "OOPS"; // Kludge, but standard |
7 | 404 |
405 bufp = buffer; | |
406 ptr = cm; | |
407 | |
31804
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
408 while (*ptr) |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
409 { |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
410 if ((c = *ptr++) != '%') // normal char |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
411 { |
7 | 412 *bufp++ = c; |
31804
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
413 } |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
414 else |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
415 { // % escape |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
416 switch(c = *ptr++) |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
417 { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
418 case 'd': // decimal |
7 | 419 bufp = _addfmt(bufp, "%d", line); |
420 line = col; | |
421 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
422 case '2': // 2 digit decimal |
7 | 423 bufp = _addfmt(bufp, "%02d", line); |
424 line = col; | |
425 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
426 case '3': // 3 digit decimal |
7 | 427 bufp = _addfmt(bufp, "%03d", line); |
428 line = col; | |
429 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
430 case '>': // %>xy: if >x, add y |
7 | 431 gx = *ptr++; |
432 gy = *ptr++; | |
433 if (col>gx) col += gy; | |
434 if (line>gx) line += gy; | |
435 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
436 case '+': // %+c: add c |
7 | 437 line += *ptr++; |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
438 case '.': // print x/y |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
439 if (line == '\t' || // these are |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
440 line == '\n' || // chars that |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
441 line == '\004' || // UNIX hates |
31804
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
442 line == '\0') |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
443 { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
444 line++; // so go to next pos |
7 | 445 if (reverse == (line == col)) |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
446 addup=1; // and mark UP |
7 | 447 else |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
448 addbak=1; // or BC |
7 | 449 } |
450 *bufp++=line; | |
451 line = col; | |
452 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
453 case 'r': // r: reverse |
7 | 454 gx = line; |
455 line = col; | |
456 col = gx; | |
457 reverse = 1; | |
458 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
459 case 'i': // increment (1-origin screen) |
7 | 460 col++; |
461 line++; | |
462 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
463 case '%': // %%=% literally |
7 | 464 *bufp++='%'; |
465 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
466 case 'n': // magic DM2500 code |
7 | 467 line ^= 0140; |
468 col ^= 0140; | |
469 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
470 case 'B': // bcd encoding |
7 | 471 line = line/10<<4+line%10; |
472 col = col/10<<4+col%10; | |
473 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
474 case 'D': // magic Delta Data code |
7 | 475 line = line-2*(line&15); |
476 col = col-2*(col&15); | |
477 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
478 default: // Unknown escape |
7 | 479 return "OOPS"; |
480 } | |
481 } | |
482 } | |
483 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
484 if (addup) // add upline |
31804
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
485 if (UP) |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
486 { |
7 | 487 ptr=UP; |
488 while (VIM_ISDIGIT(*ptr) || *ptr == '.') | |
489 ptr++; | |
490 if (*ptr == '*') | |
491 ptr++; | |
492 while (*ptr) | |
493 *bufp++ = *ptr++; | |
494 } | |
495 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
496 if (addbak) // add backspace |
31804
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
497 if (BC) |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
498 { |
7 | 499 ptr=BC; |
500 while (VIM_ISDIGIT(*ptr) || *ptr == '.') | |
501 ptr++; | |
502 if (*ptr == '*') | |
503 ptr++; | |
504 while (*ptr) | |
505 *bufp++ = *ptr++; | |
506 } | |
507 else | |
508 *bufp++='\b'; | |
509 | |
510 *bufp = 0; | |
511 | |
512 return(buffer); | |
513 } | |
514 | |
515 /* | |
516 * Module: tputs | |
517 * | |
518 * Purpose: decode padding information | |
519 * | |
520 * Calling conventions: cp = string to be padded, affcnt = # of items affected | |
521 * (lines, characters, whatever), outc = routine to output 1 character. | |
522 * | |
523 * Returned values: none | |
524 * | |
525 * Notes | |
526 * cp has padding information ahead of it, in the form | |
527 * nnnTEXT or nnn*TEXT. nnn is the number of milliseconds to delay, | |
528 * and may be a decimal (nnn.mmm). If the asterisk is given, then | |
529 * the delay is multiplied by afcnt. The delay is produced by outputting | |
530 * a number of nulls (or other padding char) after printing the | |
531 * TEXT. | |
532 * | |
533 */ | |
534 | |
535 long _bauds[16]={ | |
536 0, 50, 75, 110, | |
537 134, 150, 200, 300, | |
538 600, 1200, 1800, 2400, | |
539 4800, 9600, 19200, 19200 }; | |
540 | |
541 int | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
542 tputs( |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
543 char *cp, // string to print |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
544 int affcnt, // Number of lines affected |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
545 void (*outc)(unsigned int)) // routine to output 1 character |
7 | 546 { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
547 long frac, // 10^(#digits after decimal point) |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
548 counter, // digits |
7805
0b6c37dd858d
commit https://github.com/vim/vim/commit/baaa7e9ec7398a813e21285c272fa99792642077
Christian Brabandt <cb@256bit.org>
parents:
2823
diff
changeset
|
549 atol(const char *); |
7 | 550 |
31804
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
551 if (VIM_ISDIGIT(*cp)) |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
552 { |
7 | 553 counter = 0; |
554 frac = 1000; | |
555 while (VIM_ISDIGIT(*cp)) | |
556 counter = counter * 10L + (long)(*cp++ - '0'); | |
557 if (*cp == '.') | |
31804
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
558 while (VIM_ISDIGIT(*++cp)) |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
559 { |
7 | 560 counter = counter * 10L + (long)(*cp++ - '0'); |
561 frac = frac * 10; | |
562 } | |
31804
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
563 if (*cp!='*') // multiply by affected lines |
50555279168b
patch 9.0.1234: the code style has to be checked manually
Bram Moolenaar <Bram@vim.org>
parents:
24814
diff
changeset
|
564 { |
7 | 565 if (affcnt>1) affcnt = 1; |
566 } | |
567 else | |
568 cp++; | |
569 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
570 // Calculate number of characters for padding counter/frac ms delay |
7 | 571 if (ospeed) |
572 counter = (counter * _bauds[ospeed] * (long)affcnt) / frac; | |
573 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
574 while (*cp) // output string |
7 | 575 (*outc)(*cp++); |
576 if (ospeed) | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
577 while (counter--) // followed by pad characters |
7 | 578 (*outc)(PC); |
579 } | |
580 else | |
581 while (*cp) | |
582 (*outc)(*cp++); | |
583 return 0; | |
584 } | |
585 | |
586 /* | |
587 * Module: tutil.c | |
588 * | |
589 * Purpose: Utility routines for TERMLIB functions. | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
590 * Returns length of text common to s1 and s2. |
7 | 591 */ |
592 static int | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
593 _match(char *s1, char *s2) |
7 | 594 { |
595 int i = 0; | |
596 | |
597 while (s1[i] && s1[i] == s2[i]) | |
598 i++; | |
599 | |
600 return i; | |
601 } | |
602 | |
603 /* | |
604 * finds next c in s that's a member of set, returns pointer | |
605 */ | |
606 static char * | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
607 _find(char *s, char *set) |
7 | 608 { |
24814
4c5eec1ef612
patch 8.2.2945: some buffer related code is not tested
Bram Moolenaar <Bram@vim.org>
parents:
18814
diff
changeset
|
609 for (; *s; s++) |
7 | 610 { |
611 char *ptr = set; | |
612 | |
613 while (*ptr && *s != *ptr) | |
614 ptr++; | |
615 | |
616 if (*ptr) | |
617 return s; | |
618 } | |
619 | |
620 return s; | |
621 } | |
622 | |
623 /* | |
624 * add val to buf according to format fmt | |
625 */ | |
626 static char * | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
627 _addfmt(char *buf, char *fmt, int val) |
7 | 628 { |
629 sprintf(buf, fmt, val); | |
630 while (*buf) | |
631 buf++; | |
632 return buf; | |
633 } |