Mercurial > vim
annotate src/termlib.c @ 19081:3b1f83fdaabc v8.2.0101
patch 8.2.0101: crash when passing null object to ":echomsg"
Commit: https://github.com/vim/vim/commit/9db2afe46d3208775d1c3075bbee073a17f8fdc6
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Jan 8 18:56:20 2020 +0100
patch 8.2.0101: crash when passing null object to ":echomsg"
Problem: Crash when passing null object to ":echomsg".
Solution: Check for NULL pointer. (Yasuhiro Matsumoto, closes https://github.com/vim/vim/issues/5460)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 08 Jan 2020 19:00:04 +0100 |
parents | 7e7ec935e7c8 |
children | 4c5eec1ef612 |
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 | |
289 if (_match(id, tmp) == len) { | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
290 tmp += len; // find '=' '@' or '#' |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
291 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
|
292 return 0; // deleted entry |
7 | 293 hold= *buf; |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
294 while (*++tmp && *tmp != ':') { // not at end of field |
7 | 295 switch(*tmp) { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
296 case '\\': // Expand escapes here |
7 | 297 switch(*++tmp) { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
298 case 0: // ignore backslashes |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
299 tmp--; // at end of entry |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
300 break; // shouldn't happen |
7 | 301 case 'e': |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
302 case 'E': // ESC |
7 | 303 *(*buf)++ = ESC; |
304 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
305 case 'n': // \n |
7 | 306 *(*buf)++ = '\n'; |
307 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
308 case 'r': // \r |
7 | 309 *(*buf)++ = '\r'; |
310 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
311 case 't': // \t |
7 | 312 *(*buf)++ = '\t'; |
313 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
314 case 'b': // \b |
7 | 315 *(*buf)++ = '\b'; |
316 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
317 case 'f': // \f |
7 | 318 *(*buf)++ = '\f'; |
319 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
320 case '0': // \nnn |
7 | 321 case '1': |
322 case '2': | |
323 case '3': | |
324 case '4': | |
325 case '5': | |
326 case '6': | |
327 case '7': | |
328 case '8': | |
329 case '9': | |
330 **buf = 0; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
331 // get up to three digits |
7 | 332 for (i = 0; i < 3 && VIM_ISDIGIT(*tmp); ++i) |
333 **buf = **buf * 8 + *tmp++ - '0'; | |
334 (*buf)++; | |
335 tmp--; | |
336 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
337 default: // \x, for all other x |
7 | 338 *(*buf)++= *tmp; |
339 } | |
340 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
341 case '^': // control characters |
7 | 342 ++tmp; |
343 *(*buf)++ = Ctrl_chr(*tmp); | |
344 break; | |
345 default: | |
346 *(*buf)++ = *tmp; | |
347 } | |
348 } | |
349 *(*buf)++ = 0; | |
350 return hold; | |
351 } | |
352 } while (*tmp); | |
353 | |
354 return 0; | |
355 } | |
356 | |
357 /* | |
358 * Module: tgoto | |
359 * | |
360 * Purpose: decode cm cursor motion string. | |
361 * | |
362 * Calling conventions: cm is cursor motion string. line, col, are the | |
363 * desired destination. | |
364 * | |
365 * Returned values: a string pointing to the decoded string, or "OOPS" if it | |
366 * cannot be decoded. | |
367 * | |
368 * Notes | |
369 * The accepted escapes are: | |
370 * %d as in printf, 0 origin. | |
371 * %2, %3 like %02d, %03d in printf. | |
372 * %. like %c | |
373 * %+x adds <x> to value, then %. | |
374 * %>xy if value>x, adds y. No output. | |
375 * %i increments line& col, no output. | |
376 * %r reverses order of line&col. No output. | |
377 * %% prints as a single %. | |
378 * %n exclusive or row & col with 0140. | |
379 * %B BCD, no output. | |
380 * %D reverse coding (x-2*(x%16)), no output. | |
381 */ | |
382 | |
383 char * | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
384 tgoto( |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
385 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
|
386 int col, // column, x position |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
387 int line) // line, y position |
7 | 388 { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
389 char gx, gy, // x, y |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
390 *ptr, // pointer in 'cm' |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
391 reverse = 0, // reverse flag |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
392 *bufp, // pointer in returned string |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
393 addup = 0, // add upline |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
394 addbak = 0, // add backup |
7 | 395 c; |
396 static char buffer[32]; | |
397 | |
398 if (!cm) | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
399 return "OOPS"; // Kludge, but standard |
7 | 400 |
401 bufp = buffer; | |
402 ptr = cm; | |
403 | |
404 while (*ptr) { | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
405 if ((c = *ptr++) != '%') { // normal char |
7 | 406 *bufp++ = c; |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
407 } else { // % escape |
7 | 408 switch(c = *ptr++) { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
409 case 'd': // decimal |
7 | 410 bufp = _addfmt(bufp, "%d", line); |
411 line = col; | |
412 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
413 case '2': // 2 digit decimal |
7 | 414 bufp = _addfmt(bufp, "%02d", line); |
415 line = col; | |
416 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
417 case '3': // 3 digit decimal |
7 | 418 bufp = _addfmt(bufp, "%03d", line); |
419 line = col; | |
420 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
421 case '>': // %>xy: if >x, add y |
7 | 422 gx = *ptr++; |
423 gy = *ptr++; | |
424 if (col>gx) col += gy; | |
425 if (line>gx) line += gy; | |
426 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
427 case '+': // %+c: add c |
7 | 428 line += *ptr++; |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
429 case '.': // print x/y |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
430 if (line == '\t' || // these are |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
431 line == '\n' || // chars that |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
432 line == '\004' || // UNIX hates |
7 | 433 line == '\0') { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
434 line++; // so go to next pos |
7 | 435 if (reverse == (line == col)) |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
436 addup=1; // and mark UP |
7 | 437 else |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
438 addbak=1; // or BC |
7 | 439 } |
440 *bufp++=line; | |
441 line = col; | |
442 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
443 case 'r': // r: reverse |
7 | 444 gx = line; |
445 line = col; | |
446 col = gx; | |
447 reverse = 1; | |
448 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
449 case 'i': // increment (1-origin screen) |
7 | 450 col++; |
451 line++; | |
452 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
453 case '%': // %%=% literally |
7 | 454 *bufp++='%'; |
455 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
456 case 'n': // magic DM2500 code |
7 | 457 line ^= 0140; |
458 col ^= 0140; | |
459 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
460 case 'B': // bcd encoding |
7 | 461 line = line/10<<4+line%10; |
462 col = col/10<<4+col%10; | |
463 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
464 case 'D': // magic Delta Data code |
7 | 465 line = line-2*(line&15); |
466 col = col-2*(col&15); | |
467 break; | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
468 default: // Unknown escape |
7 | 469 return "OOPS"; |
470 } | |
471 } | |
472 } | |
473 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
474 if (addup) // add upline |
7 | 475 if (UP) { |
476 ptr=UP; | |
477 while (VIM_ISDIGIT(*ptr) || *ptr == '.') | |
478 ptr++; | |
479 if (*ptr == '*') | |
480 ptr++; | |
481 while (*ptr) | |
482 *bufp++ = *ptr++; | |
483 } | |
484 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
485 if (addbak) // add backspace |
7 | 486 if (BC) { |
487 ptr=BC; | |
488 while (VIM_ISDIGIT(*ptr) || *ptr == '.') | |
489 ptr++; | |
490 if (*ptr == '*') | |
491 ptr++; | |
492 while (*ptr) | |
493 *bufp++ = *ptr++; | |
494 } | |
495 else | |
496 *bufp++='\b'; | |
497 | |
498 *bufp = 0; | |
499 | |
500 return(buffer); | |
501 } | |
502 | |
503 /* | |
504 * Module: tputs | |
505 * | |
506 * Purpose: decode padding information | |
507 * | |
508 * Calling conventions: cp = string to be padded, affcnt = # of items affected | |
509 * (lines, characters, whatever), outc = routine to output 1 character. | |
510 * | |
511 * Returned values: none | |
512 * | |
513 * Notes | |
514 * cp has padding information ahead of it, in the form | |
515 * nnnTEXT or nnn*TEXT. nnn is the number of milliseconds to delay, | |
516 * and may be a decimal (nnn.mmm). If the asterisk is given, then | |
517 * the delay is multiplied by afcnt. The delay is produced by outputting | |
518 * a number of nulls (or other padding char) after printing the | |
519 * TEXT. | |
520 * | |
521 */ | |
522 | |
523 long _bauds[16]={ | |
524 0, 50, 75, 110, | |
525 134, 150, 200, 300, | |
526 600, 1200, 1800, 2400, | |
527 4800, 9600, 19200, 19200 }; | |
528 | |
529 int | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
530 tputs( |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
531 char *cp, // string to print |
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
532 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
|
533 void (*outc)(unsigned int)) // routine to output 1 character |
7 | 534 { |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
535 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
|
536 counter, // digits |
7805
0b6c37dd858d
commit https://github.com/vim/vim/commit/baaa7e9ec7398a813e21285c272fa99792642077
Christian Brabandt <cb@256bit.org>
parents:
2823
diff
changeset
|
537 atol(const char *); |
7 | 538 |
539 if (VIM_ISDIGIT(*cp)) { | |
540 counter = 0; | |
541 frac = 1000; | |
542 while (VIM_ISDIGIT(*cp)) | |
543 counter = counter * 10L + (long)(*cp++ - '0'); | |
544 if (*cp == '.') | |
545 while (VIM_ISDIGIT(*++cp)) { | |
546 counter = counter * 10L + (long)(*cp++ - '0'); | |
547 frac = frac * 10; | |
548 } | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
549 if (*cp!='*') { // multiply by affected lines |
7 | 550 if (affcnt>1) affcnt = 1; |
551 } | |
552 else | |
553 cp++; | |
554 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
555 // Calculate number of characters for padding counter/frac ms delay |
7 | 556 if (ospeed) |
557 counter = (counter * _bauds[ospeed] * (long)affcnt) / frac; | |
558 | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
559 while (*cp) // output string |
7 | 560 (*outc)(*cp++); |
561 if (ospeed) | |
18814
7e7ec935e7c8
patch 8.1.2395: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
12716
diff
changeset
|
562 while (counter--) // followed by pad characters |
7 | 563 (*outc)(PC); |
564 } | |
565 else | |
566 while (*cp) | |
567 (*outc)(*cp++); | |
568 return 0; | |
569 } | |
570 | |
571 /* | |
572 * Module: tutil.c | |
573 * | |
574 * 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
|
575 * Returns length of text common to s1 and s2. |
7 | 576 */ |
577 static int | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
578 _match(char *s1, char *s2) |
7 | 579 { |
580 int i = 0; | |
581 | |
582 while (s1[i] && s1[i] == s2[i]) | |
583 i++; | |
584 | |
585 return i; | |
586 } | |
587 | |
588 /* | |
589 * finds next c in s that's a member of set, returns pointer | |
590 */ | |
591 static char * | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
592 _find(char *s, char *set) |
7 | 593 { |
594 for(; *s; s++) | |
595 { | |
596 char *ptr = set; | |
597 | |
598 while (*ptr && *s != *ptr) | |
599 ptr++; | |
600 | |
601 if (*ptr) | |
602 return s; | |
603 } | |
604 | |
605 return s; | |
606 } | |
607 | |
608 /* | |
609 * add val to buf according to format fmt | |
610 */ | |
611 static char * | |
7835
4d7ce6c03fda
commit https://github.com/vim/vim/commit/764b23c8fd3369cb05ae9122abf3ca16fec539d7
Christian Brabandt <cb@256bit.org>
parents:
7805
diff
changeset
|
612 _addfmt(char *buf, char *fmt, int val) |
7 | 613 { |
614 sprintf(buf, fmt, val); | |
615 while (*buf) | |
616 buf++; | |
617 return buf; | |
618 } |