blob: 134cd095165f2c5ee0977749d28a9eabc5344aa8 [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar071d4272004-06-13 20:20:40 +00002 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10#include "vim.h"
11
12#ifdef FEAT_LINEBREAK
Bram Moolenaarf28dbce2016-01-29 22:03:47 +010013static int win_chartabsize(win_T *wp, char_u *p, colnr_T col);
Bram Moolenaar071d4272004-06-13 20:20:40 +000014#endif
15
16#ifdef FEAT_MBYTE
Bram Moolenaard7b734a2010-08-12 20:17:02 +020017# if defined(HAVE_WCHAR_H)
18# include <wchar.h> /* for towupper() and towlower() */
19# endif
Bram Moolenaarf28dbce2016-01-29 22:03:47 +010020static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp);
Bram Moolenaar071d4272004-06-13 20:20:40 +000021#endif
22
Bram Moolenaarf28dbce2016-01-29 22:03:47 +010023static unsigned nr2hex(unsigned c);
Bram Moolenaar071d4272004-06-13 20:20:40 +000024
25static int chartab_initialized = FALSE;
26
27/* b_chartab[] is an array of 32 bytes, each bit representing one of the
28 * characters 0-255. */
29#define SET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> 3] |= (1 << ((c) & 0x7))
30#define RESET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> 3] &= ~(1 << ((c) & 0x7))
31#define GET_CHARTAB(buf, c) ((buf)->b_chartab[(unsigned)(c) >> 3] & (1 << ((c) & 0x7)))
32
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +010033/* table used below, see init_chartab() for an explanation */
34static char_u g_chartab[256];
35
Bram Moolenaar071d4272004-06-13 20:20:40 +000036/*
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +010037 * Flags for g_chartab[].
38 */
39#define CT_CELL_MASK 0x07 /* mask: nr of display cells (1, 2 or 4) */
40#define CT_PRINT_CHAR 0x10 /* flag: set for printable chars */
41#define CT_ID_CHAR 0x20 /* flag: set for ID chars */
42#define CT_FNAME_CHAR 0x40 /* flag: set for file name chars */
43
44/*
45 * Fill g_chartab[]. Also fills curbuf->b_chartab[] with flags for keyword
Bram Moolenaar071d4272004-06-13 20:20:40 +000046 * characters for current buffer.
47 *
48 * Depends on the option settings 'iskeyword', 'isident', 'isfname',
49 * 'isprint' and 'encoding'.
50 *
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +010051 * The index in g_chartab[] depends on 'encoding':
Bram Moolenaar071d4272004-06-13 20:20:40 +000052 * - For non-multi-byte index with the byte (same as the character).
53 * - For DBCS index with the first byte.
54 * - For UTF-8 index with the character (when first byte is up to 0x80 it is
55 * the same as the character, if the first byte is 0x80 and above it depends
56 * on further bytes).
57 *
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +010058 * The contents of g_chartab[]:
Bram Moolenaar071d4272004-06-13 20:20:40 +000059 * - The lower two bits, masked by CT_CELL_MASK, give the number of display
60 * cells the character occupies (1 or 2). Not valid for UTF-8 above 0x80.
61 * - CT_PRINT_CHAR bit is set when the character is printable (no need to
62 * translate the character before displaying it). Note that only DBCS
63 * characters can have 2 display cells and still be printable.
64 * - CT_FNAME_CHAR bit is set when the character can be in a file name.
65 * - CT_ID_CHAR bit is set when the character can be in an identifier.
66 *
67 * Return FAIL if 'iskeyword', 'isident', 'isfname' or 'isprint' option has an
68 * error, OK otherwise.
69 */
70 int
Bram Moolenaar7454a062016-01-30 15:14:10 +010071init_chartab(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +000072{
73 return buf_init_chartab(curbuf, TRUE);
74}
75
76 int
Bram Moolenaar7454a062016-01-30 15:14:10 +010077buf_init_chartab(
78 buf_T *buf,
79 int global) /* FALSE: only set buf->b_chartab[] */
Bram Moolenaar071d4272004-06-13 20:20:40 +000080{
81 int c;
82 int c2;
83 char_u *p;
84 int i;
85 int tilde;
86 int do_isalpha;
87
88 if (global)
89 {
90 /*
91 * Set the default size for printable characters:
92 * From <Space> to '~' is 1 (printable), others are 2 (not printable).
93 * This also inits all 'isident' and 'isfname' flags to FALSE.
94 *
95 * EBCDIC: all chars below ' ' are not printable, all others are
96 * printable.
97 */
98 c = 0;
99 while (c < ' ')
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100100 g_chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000101#ifdef EBCDIC
102 while (c < 255)
103#else
104 while (c <= '~')
105#endif
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100106 g_chartab[c++] = 1 + CT_PRINT_CHAR;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000107#ifdef FEAT_FKMAP
108 if (p_altkeymap)
109 {
110 while (c < YE)
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100111 g_chartab[c++] = 1 + CT_PRINT_CHAR;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000112 }
113#endif
114 while (c < 256)
115 {
116#ifdef FEAT_MBYTE
117 /* UTF-8: bytes 0xa0 - 0xff are printable (latin1) */
118 if (enc_utf8 && c >= 0xa0)
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100119 g_chartab[c++] = CT_PRINT_CHAR + 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000120 /* euc-jp characters starting with 0x8e are single width */
121 else if (enc_dbcs == DBCS_JPNU && c == 0x8e)
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100122 g_chartab[c++] = CT_PRINT_CHAR + 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000123 /* other double-byte chars can be printable AND double-width */
124 else if (enc_dbcs != 0 && MB_BYTE2LEN(c) == 2)
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100125 g_chartab[c++] = CT_PRINT_CHAR + 2;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000126 else
127#endif
128 /* the rest is unprintable by default */
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100129 g_chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000130 }
131
132#ifdef FEAT_MBYTE
133 /* Assume that every multi-byte char is a filename character. */
134 for (c = 1; c < 256; ++c)
135 if ((enc_dbcs != 0 && MB_BYTE2LEN(c) > 1)
136 || (enc_dbcs == DBCS_JPNU && c == 0x8e)
137 || (enc_utf8 && c >= 0xa0))
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100138 g_chartab[c] |= CT_FNAME_CHAR;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000139#endif
140 }
141
142 /*
143 * Init word char flags all to FALSE
144 */
145 vim_memset(buf->b_chartab, 0, (size_t)32);
146#ifdef FEAT_MBYTE
Bram Moolenaar6bb68362005-03-22 23:03:44 +0000147 if (enc_dbcs != 0)
148 for (c = 0; c < 256; ++c)
149 {
150 /* double-byte characters are probably word characters */
151 if (MB_BYTE2LEN(c) == 2)
152 SET_CHARTAB(buf, c);
153 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000154#endif
155
156#ifdef FEAT_LISP
157 /*
158 * In lisp mode the '-' character is included in keywords.
159 */
160 if (buf->b_p_lisp)
161 SET_CHARTAB(buf, '-');
162#endif
163
164 /* Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
165 * options Each option is a list of characters, character numbers or
166 * ranges, separated by commas, e.g.: "200-210,x,#-178,-"
167 */
168 for (i = global ? 0 : 3; i <= 3; ++i)
169 {
170 if (i == 0)
171 p = p_isi; /* first round: 'isident' */
172 else if (i == 1)
173 p = p_isp; /* second round: 'isprint' */
174 else if (i == 2)
175 p = p_isf; /* third round: 'isfname' */
176 else /* i == 3 */
177 p = buf->b_p_isk; /* fourth round: 'iskeyword' */
178
179 while (*p)
180 {
181 tilde = FALSE;
182 do_isalpha = FALSE;
183 if (*p == '^' && p[1] != NUL)
184 {
185 tilde = TRUE;
186 ++p;
187 }
188 if (VIM_ISDIGIT(*p))
189 c = getdigits(&p);
190 else
Bram Moolenaar183bb3e2009-09-11 12:02:34 +0000191#ifdef FEAT_MBYTE
192 if (has_mbyte)
193 c = mb_ptr2char_adv(&p);
194 else
195#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000196 c = *p++;
197 c2 = -1;
198 if (*p == '-' && p[1] != NUL)
199 {
200 ++p;
201 if (VIM_ISDIGIT(*p))
202 c2 = getdigits(&p);
203 else
Bram Moolenaar2ac5e602009-11-03 15:04:20 +0000204#ifdef FEAT_MBYTE
205 if (has_mbyte)
206 c2 = mb_ptr2char_adv(&p);
207 else
208#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000209 c2 = *p++;
210 }
Bram Moolenaar2ac5e602009-11-03 15:04:20 +0000211 if (c <= 0 || c >= 256 || (c2 < c && c2 != -1) || c2 >= 256
Bram Moolenaar071d4272004-06-13 20:20:40 +0000212 || !(*p == NUL || *p == ','))
213 return FAIL;
214
215 if (c2 == -1) /* not a range */
216 {
217 /*
218 * A single '@' (not "@-@"):
219 * Decide on letters being ID/printable/keyword chars with
220 * standard function isalpha(). This takes care of locale for
221 * single-byte characters).
222 */
223 if (c == '@')
224 {
225 do_isalpha = TRUE;
226 c = 1;
227 c2 = 255;
228 }
229 else
230 c2 = c;
231 }
232 while (c <= c2)
233 {
Bram Moolenaardeefb632007-08-15 18:41:34 +0000234 /* Use the MB_ functions here, because isalpha() doesn't
235 * work properly when 'encoding' is "latin1" and the locale is
236 * "C". */
237 if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000238#ifdef FEAT_FKMAP
239 || (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))
240#endif
241 )
242 {
243 if (i == 0) /* (re)set ID flag */
244 {
245 if (tilde)
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100246 g_chartab[c] &= ~CT_ID_CHAR;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000247 else
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100248 g_chartab[c] |= CT_ID_CHAR;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000249 }
250 else if (i == 1) /* (re)set printable */
251 {
252 if ((c < ' '
253#ifndef EBCDIC
254 || c > '~'
255#endif
256#ifdef FEAT_FKMAP
257 || (p_altkeymap
258 && (F_isalpha(c) || F_isdigit(c)))
259#endif
260 )
261#ifdef FEAT_MBYTE
262 /* For double-byte we keep the cell width, so
263 * that we can detect it from the first byte. */
264 && !(enc_dbcs && MB_BYTE2LEN(c) == 2)
265#endif
266 )
267 {
268 if (tilde)
269 {
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100270 g_chartab[c] = (g_chartab[c] & ~CT_CELL_MASK)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000271 + ((dy_flags & DY_UHEX) ? 4 : 2);
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100272 g_chartab[c] &= ~CT_PRINT_CHAR;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000273 }
274 else
275 {
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100276 g_chartab[c] = (g_chartab[c] & ~CT_CELL_MASK) + 1;
277 g_chartab[c] |= CT_PRINT_CHAR;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000278 }
279 }
280 }
281 else if (i == 2) /* (re)set fname flag */
282 {
283 if (tilde)
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100284 g_chartab[c] &= ~CT_FNAME_CHAR;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000285 else
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100286 g_chartab[c] |= CT_FNAME_CHAR;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000287 }
288 else /* i == 3 */ /* (re)set keyword flag */
289 {
290 if (tilde)
291 RESET_CHARTAB(buf, c);
292 else
293 SET_CHARTAB(buf, c);
294 }
295 }
296 ++c;
297 }
Bram Moolenaar309379f2013-02-06 16:26:26 +0100298
299 c = *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000300 p = skip_to_option_part(p);
Bram Moolenaar309379f2013-02-06 16:26:26 +0100301 if (c == ',' && *p == NUL)
302 /* Trailing comma is not allowed. */
303 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000304 }
305 }
306 chartab_initialized = TRUE;
307 return OK;
308}
309
310/*
311 * Translate any special characters in buf[bufsize] in-place.
312 * The result is a string with only printable characters, but if there is not
313 * enough room, not all characters will be translated.
314 */
315 void
Bram Moolenaar7454a062016-01-30 15:14:10 +0100316trans_characters(
317 char_u *buf,
318 int bufsize)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000319{
320 int len; /* length of string needing translation */
321 int room; /* room in buffer after string */
322 char_u *trs; /* translated character */
323 int trs_len; /* length of trs[] */
324
325 len = (int)STRLEN(buf);
326 room = bufsize - len;
327 while (*buf != 0)
328 {
329# ifdef FEAT_MBYTE
330 /* Assume a multi-byte character doesn't need translation. */
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000331 if (has_mbyte && (trs_len = (*mb_ptr2len)(buf)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000332 len -= trs_len;
333 else
334# endif
335 {
336 trs = transchar_byte(*buf);
337 trs_len = (int)STRLEN(trs);
338 if (trs_len > 1)
339 {
340 room -= trs_len - 1;
341 if (room <= 0)
342 return;
343 mch_memmove(buf + trs_len, buf + 1, (size_t)len);
344 }
345 mch_memmove(buf, trs, (size_t)trs_len);
346 --len;
347 }
348 buf += trs_len;
349 }
350}
351
Bram Moolenaar7cc36e92007-03-27 10:42:05 +0000352#if defined(FEAT_EVAL) || defined(FEAT_TITLE) || defined(FEAT_INS_EXPAND) \
353 || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000354/*
355 * Translate a string into allocated memory, replacing special chars with
356 * printable chars. Returns NULL when out of memory.
357 */
358 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +0100359transstr(char_u *s)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000360{
361 char_u *res;
362 char_u *p;
363#ifdef FEAT_MBYTE
364 int l, len, c;
365 char_u hexbuf[11];
366#endif
367
368#ifdef FEAT_MBYTE
369 if (has_mbyte)
370 {
371 /* Compute the length of the result, taking account of unprintable
372 * multi-byte characters. */
373 len = 0;
374 p = s;
375 while (*p != NUL)
376 {
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000377 if ((l = (*mb_ptr2len)(p)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000378 {
379 c = (*mb_ptr2char)(p);
380 p += l;
381 if (vim_isprintc(c))
382 len += l;
383 else
384 {
385 transchar_hex(hexbuf, c);
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000386 len += (int)STRLEN(hexbuf);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000387 }
388 }
389 else
390 {
391 l = byte2cells(*p++);
392 if (l > 0)
393 len += l;
394 else
395 len += 4; /* illegal byte sequence */
396 }
397 }
398 res = alloc((unsigned)(len + 1));
399 }
400 else
401#endif
402 res = alloc((unsigned)(vim_strsize(s) + 1));
403 if (res != NULL)
404 {
405 *res = NUL;
406 p = s;
407 while (*p != NUL)
408 {
409#ifdef FEAT_MBYTE
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000410 if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000411 {
412 c = (*mb_ptr2char)(p);
413 if (vim_isprintc(c))
414 STRNCAT(res, p, l); /* append printable multi-byte char */
415 else
416 transchar_hex(res + STRLEN(res), c);
417 p += l;
418 }
419 else
420#endif
421 STRCAT(res, transchar_byte(*p++));
422 }
423 }
424 return res;
425}
426#endif
427
428#if defined(FEAT_SYN_HL) || defined(FEAT_INS_EXPAND) || defined(PROTO)
429/*
Bram Moolenaar217ad922005-03-20 22:37:15 +0000430 * Convert the string "str[orglen]" to do ignore-case comparing. Uses the
431 * current locale.
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000432 * When "buf" is NULL returns an allocated string (NULL for out-of-memory).
433 * Otherwise puts the result in "buf[buflen]".
Bram Moolenaar071d4272004-06-13 20:20:40 +0000434 */
435 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +0100436str_foldcase(
437 char_u *str,
438 int orglen,
439 char_u *buf,
440 int buflen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000441{
442 garray_T ga;
443 int i;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000444 int len = orglen;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000445
446#define GA_CHAR(i) ((char_u *)ga.ga_data)[i]
447#define GA_PTR(i) ((char_u *)ga.ga_data + i)
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000448#define STR_CHAR(i) (buf == NULL ? GA_CHAR(i) : buf[i])
449#define STR_PTR(i) (buf == NULL ? GA_PTR(i) : buf + i)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000450
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000451 /* Copy "str" into "buf" or allocated memory, unmodified. */
452 if (buf == NULL)
453 {
454 ga_init2(&ga, 1, 10);
455 if (ga_grow(&ga, len + 1) == FAIL)
456 return NULL;
457 mch_memmove(ga.ga_data, str, (size_t)len);
458 ga.ga_len = len;
459 }
460 else
461 {
462 if (len >= buflen) /* Ugly! */
463 len = buflen - 1;
464 mch_memmove(buf, str, (size_t)len);
465 }
466 if (buf == NULL)
467 GA_CHAR(len) = NUL;
468 else
469 buf[len] = NUL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000470
471 /* Make each character lower case. */
472 i = 0;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000473 while (STR_CHAR(i) != NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000474 {
475#ifdef FEAT_MBYTE
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000476 if (enc_utf8 || (has_mbyte && MB_BYTE2LEN(STR_CHAR(i)) > 1))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000477 {
478 if (enc_utf8)
479 {
Bram Moolenaarb9839212008-06-28 11:03:50 +0000480 int c = utf_ptr2char(STR_PTR(i));
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100481 int olen = utf_ptr2len(STR_PTR(i));
Bram Moolenaarb9839212008-06-28 11:03:50 +0000482 int lc = utf_tolower(c);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000483
Bram Moolenaarb9839212008-06-28 11:03:50 +0000484 /* Only replace the character when it is not an invalid
485 * sequence (ASCII character or more than one byte) and
486 * utf_tolower() doesn't return the original character. */
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100487 if ((c < 0x80 || olen > 1) && c != lc)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000488 {
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100489 int nlen = utf_char2len(lc);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000490
491 /* If the byte length changes need to shift the following
492 * characters forward or backward. */
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100493 if (olen != nlen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000494 {
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100495 if (nlen > olen)
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000496 {
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100497 if (buf == NULL
498 ? ga_grow(&ga, nlen - olen + 1) == FAIL
499 : len + nlen - olen >= buflen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000500 {
501 /* out of memory, keep old char */
502 lc = c;
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100503 nlen = olen;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000504 }
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000505 }
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100506 if (olen != nlen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000507 {
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000508 if (buf == NULL)
509 {
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100510 STRMOVE(GA_PTR(i) + nlen, GA_PTR(i) + olen);
511 ga.ga_len += nlen - olen;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000512 }
513 else
514 {
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100515 STRMOVE(buf + i + nlen, buf + i + olen);
516 len += nlen - olen;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000517 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000518 }
519 }
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000520 (void)utf_char2bytes(lc, STR_PTR(i));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000521 }
522 }
523 /* skip to next multi-byte char */
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000524 i += (*mb_ptr2len)(STR_PTR(i));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000525 }
526 else
527#endif
528 {
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000529 if (buf == NULL)
530 GA_CHAR(i) = TOLOWER_LOC(GA_CHAR(i));
531 else
532 buf[i] = TOLOWER_LOC(buf[i]);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000533 ++i;
534 }
535 }
536
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000537 if (buf == NULL)
538 return (char_u *)ga.ga_data;
539 return buf;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000540}
541#endif
542
543/*
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100544 * Catch 22: g_chartab[] can't be initialized before the options are
Bram Moolenaar071d4272004-06-13 20:20:40 +0000545 * initialized, and initializing options may cause transchar() to be called!
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100546 * When chartab_initialized == FALSE don't use g_chartab[].
Bram Moolenaar071d4272004-06-13 20:20:40 +0000547 * Does NOT work for multi-byte characters, c must be <= 255.
548 * Also doesn't work for the first byte of a multi-byte, "c" must be a
549 * character!
550 */
551static char_u transchar_buf[7];
552
553 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +0100554transchar(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000555{
556 int i;
557
558 i = 0;
559 if (IS_SPECIAL(c)) /* special key code, display as ~@ char */
560 {
561 transchar_buf[0] = '~';
562 transchar_buf[1] = '@';
563 i = 2;
564 c = K_SECOND(c);
565 }
566
567 if ((!chartab_initialized && (
568#ifdef EBCDIC
569 (c >= 64 && c < 255)
570#else
571 (c >= ' ' && c <= '~')
572#endif
573#ifdef FEAT_FKMAP
Bram Moolenaaree2615a2016-07-02 18:25:34 +0200574 || (p_altkeymap && F_ischar(c))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000575#endif
576 )) || (c < 256 && vim_isprintc_strict(c)))
577 {
578 /* printable character */
579 transchar_buf[i] = c;
580 transchar_buf[i + 1] = NUL;
581 }
582 else
583 transchar_nonprint(transchar_buf + i, c);
584 return transchar_buf;
585}
586
587#if defined(FEAT_MBYTE) || defined(PROTO)
588/*
589 * Like transchar(), but called with a byte instead of a character. Checks
590 * for an illegal UTF-8 byte.
591 */
592 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +0100593transchar_byte(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000594{
595 if (enc_utf8 && c >= 0x80)
596 {
597 transchar_nonprint(transchar_buf, c);
598 return transchar_buf;
599 }
600 return transchar(c);
601}
602#endif
603
604/*
605 * Convert non-printable character to two or more printable characters in
606 * "buf[]". "buf" needs to be able to hold five bytes.
607 * Does NOT work for multi-byte characters, c must be <= 255.
608 */
609 void
Bram Moolenaar7454a062016-01-30 15:14:10 +0100610transchar_nonprint(char_u *buf, int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000611{
612 if (c == NL)
613 c = NUL; /* we use newline in place of a NUL */
614 else if (c == CAR && get_fileformat(curbuf) == EOL_MAC)
615 c = NL; /* we use CR in place of NL in this case */
616
617 if (dy_flags & DY_UHEX) /* 'display' has "uhex" */
618 transchar_hex(buf, c);
619
620#ifdef EBCDIC
621 /* For EBCDIC only the characters 0-63 and 255 are not printable */
622 else if (CtrlChar(c) != 0 || c == DEL)
623#else
624 else if (c <= 0x7f) /* 0x00 - 0x1f and 0x7f */
625#endif
626 {
627 buf[0] = '^';
628#ifdef EBCDIC
629 if (c == DEL)
630 buf[1] = '?'; /* DEL displayed as ^? */
631 else
632 buf[1] = CtrlChar(c);
633#else
634 buf[1] = c ^ 0x40; /* DEL displayed as ^? */
635#endif
636
637 buf[2] = NUL;
638 }
639#ifdef FEAT_MBYTE
640 else if (enc_utf8 && c >= 0x80)
641 {
642 transchar_hex(buf, c);
643 }
644#endif
645#ifndef EBCDIC
646 else if (c >= ' ' + 0x80 && c <= '~' + 0x80) /* 0xa0 - 0xfe */
647 {
648 buf[0] = '|';
649 buf[1] = c - 0x80;
650 buf[2] = NUL;
651 }
652#else
653 else if (c < 64)
654 {
655 buf[0] = '~';
656 buf[1] = MetaChar(c);
657 buf[2] = NUL;
658 }
659#endif
660 else /* 0x80 - 0x9f and 0xff */
661 {
662 /*
663 * TODO: EBCDIC I don't know what to do with this chars, so I display
664 * them as '~?' for now
665 */
666 buf[0] = '~';
667#ifdef EBCDIC
668 buf[1] = '?'; /* 0xff displayed as ~? */
669#else
670 buf[1] = (c - 0x80) ^ 0x40; /* 0xff displayed as ~? */
671#endif
672 buf[2] = NUL;
673 }
674}
675
676 void
Bram Moolenaar7454a062016-01-30 15:14:10 +0100677transchar_hex(char_u *buf, int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000678{
679 int i = 0;
680
681 buf[0] = '<';
682#ifdef FEAT_MBYTE
683 if (c > 255)
684 {
685 buf[++i] = nr2hex((unsigned)c >> 12);
686 buf[++i] = nr2hex((unsigned)c >> 8);
687 }
688#endif
689 buf[++i] = nr2hex((unsigned)c >> 4);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000690 buf[++i] = nr2hex((unsigned)c);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000691 buf[++i] = '>';
692 buf[++i] = NUL;
693}
694
695/*
696 * Convert the lower 4 bits of byte "c" to its hex character.
697 * Lower case letters are used to avoid the confusion of <F1> being 0xf1 or
698 * function key 1.
699 */
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000700 static unsigned
Bram Moolenaar7454a062016-01-30 15:14:10 +0100701nr2hex(unsigned c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000702{
703 if ((c & 0xf) <= 9)
704 return (c & 0xf) + '0';
705 return (c & 0xf) - 10 + 'a';
706}
707
708/*
709 * Return number of display cells occupied by byte "b".
710 * Caller must make sure 0 <= b <= 255.
711 * For multi-byte mode "b" must be the first byte of a character.
712 * A TAB is counted as two cells: "^I".
713 * For UTF-8 mode this will return 0 for bytes >= 0x80, because the number of
714 * cells depends on further bytes.
715 */
716 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100717byte2cells(int b)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000718{
719#ifdef FEAT_MBYTE
720 if (enc_utf8 && b >= 0x80)
721 return 0;
722#endif
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100723 return (g_chartab[b] & CT_CELL_MASK);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000724}
725
726/*
727 * Return number of display cells occupied by character "c".
728 * "c" can be a special key (negative number) in which case 3 or 4 is returned.
729 * A TAB is counted as two cells: "^I" or four: "<09>".
730 */
731 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100732char2cells(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000733{
734 if (IS_SPECIAL(c))
735 return char2cells(K_SECOND(c)) + 2;
736#ifdef FEAT_MBYTE
737 if (c >= 0x80)
738 {
739 /* UTF-8: above 0x80 need to check the value */
740 if (enc_utf8)
741 return utf_char2cells(c);
742 /* DBCS: double-byte means double-width, except for euc-jp with first
743 * byte 0x8e */
744 if (enc_dbcs != 0 && c >= 0x100)
745 {
746 if (enc_dbcs == DBCS_JPNU && ((unsigned)c >> 8) == 0x8e)
747 return 1;
748 return 2;
749 }
750 }
751#endif
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100752 return (g_chartab[c & 0xff] & CT_CELL_MASK);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000753}
754
755/*
756 * Return number of display cells occupied by character at "*p".
757 * A TAB is counted as two cells: "^I" or four: "<09>".
758 */
759 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100760ptr2cells(char_u *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000761{
762#ifdef FEAT_MBYTE
763 /* For UTF-8 we need to look at more bytes if the first byte is >= 0x80. */
764 if (enc_utf8 && *p >= 0x80)
765 return utf_ptr2cells(p);
766 /* For DBCS we can tell the cell count from the first byte. */
767#endif
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100768 return (g_chartab[*p] & CT_CELL_MASK);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000769}
770
771/*
Bram Moolenaar06af6022012-01-26 13:40:08 +0100772 * Return the number of character cells string "s" will take on the screen,
Bram Moolenaar071d4272004-06-13 20:20:40 +0000773 * counting TABs as two characters: "^I".
774 */
775 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100776vim_strsize(char_u *s)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000777{
778 return vim_strnsize(s, (int)MAXCOL);
779}
780
781/*
Bram Moolenaar06af6022012-01-26 13:40:08 +0100782 * Return the number of character cells string "s[len]" will take on the
783 * screen, counting TABs as two characters: "^I".
Bram Moolenaar071d4272004-06-13 20:20:40 +0000784 */
785 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100786vim_strnsize(char_u *s, int len)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000787{
788 int size = 0;
789
790 while (*s != NUL && --len >= 0)
791 {
792#ifdef FEAT_MBYTE
793 if (has_mbyte)
794 {
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000795 int l = (*mb_ptr2len)(s);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000796
797 size += ptr2cells(s);
798 s += l;
799 len -= l - 1;
800 }
801 else
802#endif
803 size += byte2cells(*s++);
804 }
805 return size;
806}
807
808/*
809 * Return the number of characters 'c' will take on the screen, taking
810 * into account the size of a tab.
811 * Use a define to make it fast, this is used very often!!!
812 * Also see getvcol() below.
813 */
814
815#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
816 if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \
817 { \
818 int ts; \
819 ts = (buf)->b_p_ts; \
820 return (int)(ts - (col % ts)); \
821 } \
822 else \
823 return ptr2cells(p);
824
Bram Moolenaar071d4272004-06-13 20:20:40 +0000825 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100826chartabsize(char_u *p, colnr_T col)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000827{
828 RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col)
829}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000830
831#ifdef FEAT_LINEBREAK
832 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100833win_chartabsize(win_T *wp, char_u *p, colnr_T col)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000834{
835 RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col)
836}
837#endif
838
839/*
Bram Moolenaardc536092010-07-18 15:45:49 +0200840 * Return the number of characters the string 's' will take on the screen,
841 * taking into account the size of a tab.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000842 */
843 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100844linetabsize(char_u *s)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000845{
Bram Moolenaardc536092010-07-18 15:45:49 +0200846 return linetabsize_col(0, s);
847}
848
849/*
850 * Like linetabsize(), but starting at column "startcol".
851 */
852 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100853linetabsize_col(int startcol, char_u *s)
Bram Moolenaardc536092010-07-18 15:45:49 +0200854{
855 colnr_T col = startcol;
Bram Moolenaar597a4222014-06-25 14:39:50 +0200856 char_u *line = s; /* pointer to start of line, for breakindent */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000857
858 while (*s != NUL)
Bram Moolenaar597a4222014-06-25 14:39:50 +0200859 col += lbr_chartabsize_adv(line, &s, col);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000860 return (int)col;
861}
862
863/*
864 * Like linetabsize(), but for a given window instead of the current one.
865 */
866 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100867win_linetabsize(win_T *wp, char_u *line, colnr_T len)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000868{
869 colnr_T col = 0;
870 char_u *s;
871
Bram Moolenaar597a4222014-06-25 14:39:50 +0200872 for (s = line; *s != NUL && (len == MAXCOL || s < line + len);
873 mb_ptr_adv(s))
874 col += win_lbr_chartabsize(wp, line, s, col, NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000875 return (int)col;
876}
877
878/*
Bram Moolenaar81695252004-12-29 20:58:21 +0000879 * Return TRUE if 'c' is a normal identifier character:
880 * Letters and characters from the 'isident' option.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000881 */
882 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100883vim_isIDc(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000884{
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100885 return (c > 0 && c < 0x100 && (g_chartab[c] & CT_ID_CHAR));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000886}
887
888/*
889 * return TRUE if 'c' is a keyword character: Letters and characters from
890 * 'iskeyword' option for current buffer.
891 * For multi-byte characters mb_get_class() is used (builtin rules).
892 */
893 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100894vim_iswordc(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000895{
Bram Moolenaar9d182dd2013-01-23 15:53:15 +0100896 return vim_iswordc_buf(c, curbuf);
897}
898
899 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100900vim_iswordc_buf(int c, buf_T *buf)
Bram Moolenaar9d182dd2013-01-23 15:53:15 +0100901{
Bram Moolenaar071d4272004-06-13 20:20:40 +0000902#ifdef FEAT_MBYTE
903 if (c >= 0x100)
904 {
905 if (enc_dbcs != 0)
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000906 return dbcs_class((unsigned)c >> 8, (unsigned)(c & 0xff)) >= 2;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000907 if (enc_utf8)
908 return utf_class(c) >= 2;
909 }
910#endif
Bram Moolenaar9d182dd2013-01-23 15:53:15 +0100911 return (c > 0 && c < 0x100 && GET_CHARTAB(buf, c) != 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000912}
913
914/*
915 * Just like vim_iswordc() but uses a pointer to the (multi-byte) character.
916 */
917 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100918vim_iswordp(char_u *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000919{
920#ifdef FEAT_MBYTE
921 if (has_mbyte && MB_BYTE2LEN(*p) > 1)
922 return mb_get_class(p) >= 2;
923#endif
924 return GET_CHARTAB(curbuf, *p) != 0;
925}
926
Bram Moolenaar071d4272004-06-13 20:20:40 +0000927 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100928vim_iswordp_buf(char_u *p, buf_T *buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000929{
Bram Moolenaara50e5862013-01-30 17:30:17 +0100930#ifdef FEAT_MBYTE
Bram Moolenaar071d4272004-06-13 20:20:40 +0000931 if (has_mbyte && MB_BYTE2LEN(*p) > 1)
932 return mb_get_class(p) >= 2;
Bram Moolenaara50e5862013-01-30 17:30:17 +0100933#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000934 return (GET_CHARTAB(buf, *p) != 0);
935}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000936
937/*
938 * return TRUE if 'c' is a valid file-name character
939 * Assume characters above 0x100 are valid (multi-byte).
940 */
941 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100942vim_isfilec(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000943{
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100944 return (c >= 0x100 || (c > 0 && (g_chartab[c] & CT_FNAME_CHAR)));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000945}
946
947/*
Bram Moolenaardd87969c2007-08-21 13:07:12 +0000948 * return TRUE if 'c' is a valid file-name character or a wildcard character
949 * Assume characters above 0x100 are valid (multi-byte).
950 * Explicitly interpret ']' as a wildcard character as mch_has_wildcard("]")
951 * returns false.
952 */
953 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100954vim_isfilec_or_wc(int c)
Bram Moolenaardd87969c2007-08-21 13:07:12 +0000955{
956 char_u buf[2];
957
958 buf[0] = (char_u)c;
959 buf[1] = NUL;
960 return vim_isfilec(c) || c == ']' || mch_has_wildcard(buf);
961}
962
963/*
Bram Moolenaar071d4272004-06-13 20:20:40 +0000964 * return TRUE if 'c' is a printable character
965 * Assume characters above 0x100 are printable (multi-byte), except for
966 * Unicode.
967 */
968 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100969vim_isprintc(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000970{
971#ifdef FEAT_MBYTE
972 if (enc_utf8 && c >= 0x100)
973 return utf_printable(c);
974#endif
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100975 return (c >= 0x100 || (c > 0 && (g_chartab[c] & CT_PRINT_CHAR)));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000976}
977
978/*
979 * Strict version of vim_isprintc(c), don't return TRUE if "c" is the head
980 * byte of a double-byte character.
981 */
982 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100983vim_isprintc_strict(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000984{
985#ifdef FEAT_MBYTE
986 if (enc_dbcs != 0 && c < 0x100 && MB_BYTE2LEN(c) > 1)
987 return FALSE;
988 if (enc_utf8 && c >= 0x100)
989 return utf_printable(c);
990#endif
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +0100991 return (c >= 0x100 || (c > 0 && (g_chartab[c] & CT_PRINT_CHAR)));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000992}
993
994/*
995 * like chartabsize(), but also check for line breaks on the screen
996 */
997 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100998lbr_chartabsize(
999 char_u *line UNUSED, /* start of the line */
1000 unsigned char *s,
1001 colnr_T col)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001002{
1003#ifdef FEAT_LINEBREAK
Bram Moolenaar597a4222014-06-25 14:39:50 +02001004 if (!curwin->w_p_lbr && *p_sbr == NUL && !curwin->w_p_bri)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001005 {
1006#endif
1007#ifdef FEAT_MBYTE
1008 if (curwin->w_p_wrap)
1009 return win_nolbr_chartabsize(curwin, s, col, NULL);
1010#endif
1011 RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
1012#ifdef FEAT_LINEBREAK
1013 }
Bram Moolenaar597a4222014-06-25 14:39:50 +02001014 return win_lbr_chartabsize(curwin, line == NULL ? s : line, s, col, NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001015#endif
1016}
1017
1018/*
1019 * Call lbr_chartabsize() and advance the pointer.
1020 */
1021 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001022lbr_chartabsize_adv(
1023 char_u *line, /* start of the line */
1024 char_u **s,
1025 colnr_T col)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001026{
1027 int retval;
1028
Bram Moolenaar597a4222014-06-25 14:39:50 +02001029 retval = lbr_chartabsize(line, *s, col);
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001030 mb_ptr_adv(*s);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001031 return retval;
1032}
1033
1034/*
1035 * This function is used very often, keep it fast!!!!
1036 *
1037 * If "headp" not NULL, set *headp to the size of what we for 'showbreak'
1038 * string at start of line. Warning: *headp is only set if it's a non-zero
1039 * value, init to 0 before calling.
1040 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001041 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001042win_lbr_chartabsize(
1043 win_T *wp,
1044 char_u *line UNUSED, /* start of the line */
1045 char_u *s,
1046 colnr_T col,
1047 int *headp UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001048{
1049#ifdef FEAT_LINEBREAK
1050 int c;
1051 int size;
1052 colnr_T col2;
Bram Moolenaaree739b42014-07-02 19:37:42 +02001053 colnr_T col_adj = 0; /* col + screen size of tab */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001054 colnr_T colmax;
1055 int added;
1056# ifdef FEAT_MBYTE
1057 int mb_added = 0;
1058# else
1059# define mb_added 0
1060# endif
1061 int numberextra;
1062 char_u *ps;
1063 int tab_corr = (*s == TAB);
Bram Moolenaar402d2fe2005-04-15 21:00:38 +00001064 int n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001065
1066 /*
Bram Moolenaar597a4222014-06-25 14:39:50 +02001067 * No 'linebreak', 'showbreak' and 'breakindent': return quickly.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001068 */
Bram Moolenaar597a4222014-06-25 14:39:50 +02001069 if (!wp->w_p_lbr && !wp->w_p_bri && *p_sbr == NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001070#endif
1071 {
1072#ifdef FEAT_MBYTE
1073 if (wp->w_p_wrap)
1074 return win_nolbr_chartabsize(wp, s, col, headp);
1075#endif
1076 RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col)
1077 }
1078
1079#ifdef FEAT_LINEBREAK
1080 /*
1081 * First get normal size, without 'linebreak'
1082 */
1083 size = win_chartabsize(wp, s, col);
1084 c = *s;
Bram Moolenaaree739b42014-07-02 19:37:42 +02001085 if (tab_corr)
1086 col_adj = size - 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001087
1088 /*
1089 * If 'linebreak' set check at a blank before a non-blank if the line
1090 * needs a break here
1091 */
1092 if (wp->w_p_lbr
1093 && vim_isbreak(c)
1094 && !vim_isbreak(s[1])
Bram Moolenaar071d4272004-06-13 20:20:40 +00001095 && wp->w_p_wrap
Bram Moolenaar44a2f922016-03-19 22:11:51 +01001096# ifdef FEAT_WINDOWS
Bram Moolenaar071d4272004-06-13 20:20:40 +00001097 && wp->w_width != 0
1098# endif
1099 )
1100 {
1101 /*
1102 * Count all characters from first non-blank after a blank up to next
1103 * non-blank after a blank.
1104 */
1105 numberextra = win_col_off(wp);
1106 col2 = col;
Bram Moolenaaree739b42014-07-02 19:37:42 +02001107 colmax = (colnr_T)(W_WIDTH(wp) - numberextra - col_adj);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001108 if (col >= colmax)
Bram Moolenaar402d2fe2005-04-15 21:00:38 +00001109 {
Bram Moolenaaree739b42014-07-02 19:37:42 +02001110 colmax += col_adj;
1111 n = colmax + win_col_off2(wp);
Bram Moolenaar402d2fe2005-04-15 21:00:38 +00001112 if (n > 0)
Bram Moolenaaree739b42014-07-02 19:37:42 +02001113 colmax += (((col - colmax) / n) + 1) * n - col_adj;
Bram Moolenaar402d2fe2005-04-15 21:00:38 +00001114 }
1115
Bram Moolenaar071d4272004-06-13 20:20:40 +00001116 for (;;)
1117 {
1118 ps = s;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001119 mb_ptr_adv(s);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001120 c = *s;
1121 if (!(c != NUL
1122 && (vim_isbreak(c)
1123 || (!vim_isbreak(c)
1124 && (col2 == col || !vim_isbreak(*ps))))))
1125 break;
1126
1127 col2 += win_chartabsize(wp, s, col2);
1128 if (col2 >= colmax) /* doesn't fit */
1129 {
Bram Moolenaaree739b42014-07-02 19:37:42 +02001130 size = colmax - col + col_adj;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001131 tab_corr = FALSE;
1132 break;
1133 }
1134 }
1135 }
1136# ifdef FEAT_MBYTE
1137 else if (has_mbyte && size == 2 && MB_BYTE2LEN(*s) > 1
1138 && wp->w_p_wrap && in_win_border(wp, col))
1139 {
1140 ++size; /* Count the ">" in the last column. */
1141 mb_added = 1;
1142 }
1143# endif
1144
1145 /*
Bram Moolenaar597a4222014-06-25 14:39:50 +02001146 * May have to add something for 'breakindent' and/or 'showbreak'
1147 * string at start of line.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001148 * Set *headp to the size of what we add.
1149 */
1150 added = 0;
Bram Moolenaar597a4222014-06-25 14:39:50 +02001151 if ((*p_sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && col != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001152 {
Bram Moolenaard574ea22015-01-14 19:35:14 +01001153 colnr_T sbrlen = 0;
1154 int numberwidth = win_col_off(wp);
1155
1156 numberextra = numberwidth;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001157 col += numberextra + mb_added;
1158 if (col >= (colnr_T)W_WIDTH(wp))
1159 {
1160 col -= W_WIDTH(wp);
1161 numberextra = W_WIDTH(wp) - (numberextra - win_col_off2(wp));
Bram Moolenaard574ea22015-01-14 19:35:14 +01001162 if (col >= numberextra && numberextra > 0)
Bram Moolenaarfe3c4102014-10-31 12:42:01 +01001163 col %= numberextra;
Bram Moolenaar1c852102014-10-15 21:26:40 +02001164 if (*p_sbr != NUL)
1165 {
Bram Moolenaard574ea22015-01-14 19:35:14 +01001166 sbrlen = (colnr_T)MB_CHARLEN(p_sbr);
Bram Moolenaar1c852102014-10-15 21:26:40 +02001167 if (col >= sbrlen)
1168 col -= sbrlen;
1169 }
Bram Moolenaard574ea22015-01-14 19:35:14 +01001170 if (col >= numberextra && numberextra > 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001171 col = col % numberextra;
Bram Moolenaard574ea22015-01-14 19:35:14 +01001172 else if (col > 0 && numberextra > 0)
1173 col += numberwidth - win_col_off2(wp);
1174
1175 numberwidth -= win_col_off2(wp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001176 }
Bram Moolenaard574ea22015-01-14 19:35:14 +01001177 if (col == 0 || col + size + sbrlen > (colnr_T)W_WIDTH(wp))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001178 {
Bram Moolenaar597a4222014-06-25 14:39:50 +02001179 added = 0;
1180 if (*p_sbr != NUL)
Bram Moolenaard574ea22015-01-14 19:35:14 +01001181 {
1182 if (size + sbrlen + numberwidth > (colnr_T)W_WIDTH(wp))
1183 {
1184 /* calculate effective window width */
1185 int width = (colnr_T)W_WIDTH(wp) - sbrlen - numberwidth;
1186 int prev_width = col ? ((colnr_T)W_WIDTH(wp) - (sbrlen + col)) : 0;
1187 if (width == 0)
1188 width = (colnr_T)W_WIDTH(wp);
1189 added += ((size - prev_width) / width) * vim_strsize(p_sbr);
1190 if ((size - prev_width) % width)
1191 /* wrapped, add another length of 'sbr' */
1192 added += vim_strsize(p_sbr);
1193 }
1194 else
1195 added += vim_strsize(p_sbr);
1196 }
Bram Moolenaar597a4222014-06-25 14:39:50 +02001197 if (wp->w_p_bri)
1198 added += get_breakindent_win(wp, line);
1199
Bram Moolenaar95765082014-08-24 21:19:25 +02001200 size += added;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001201 if (col != 0)
1202 added = 0;
1203 }
1204 }
1205 if (headp != NULL)
1206 *headp = added + mb_added;
1207 return size;
1208#endif
1209}
1210
1211#if defined(FEAT_MBYTE) || defined(PROTO)
1212/*
1213 * Like win_lbr_chartabsize(), except that we know 'linebreak' is off and
1214 * 'wrap' is on. This means we need to check for a double-byte character that
1215 * doesn't fit at the end of the screen line.
1216 */
1217 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001218win_nolbr_chartabsize(
1219 win_T *wp,
1220 char_u *s,
1221 colnr_T col,
1222 int *headp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001223{
1224 int n;
1225
1226 if (*s == TAB && (!wp->w_p_list || lcs_tab1))
1227 {
1228 n = wp->w_buffer->b_p_ts;
1229 return (int)(n - (col % n));
1230 }
1231 n = ptr2cells(s);
1232 /* Add one cell for a double-width character in the last column of the
1233 * window, displayed with a ">". */
1234 if (n == 2 && MB_BYTE2LEN(*s) > 1 && in_win_border(wp, col))
1235 {
1236 if (headp != NULL)
1237 *headp = 1;
1238 return 3;
1239 }
1240 return n;
1241}
1242
1243/*
1244 * Return TRUE if virtual column "vcol" is in the rightmost column of window
1245 * "wp".
1246 */
1247 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001248in_win_border(win_T *wp, colnr_T vcol)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001249{
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001250 int width1; /* width of first line (after line number) */
1251 int width2; /* width of further lines */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001252
Bram Moolenaar44a2f922016-03-19 22:11:51 +01001253# ifdef FEAT_WINDOWS
Bram Moolenaar071d4272004-06-13 20:20:40 +00001254 if (wp->w_width == 0) /* there is no border */
1255 return FALSE;
Bram Moolenaar44a2f922016-03-19 22:11:51 +01001256# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00001257 width1 = W_WIDTH(wp) - win_col_off(wp);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001258 if ((int)vcol < width1 - 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001259 return FALSE;
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001260 if ((int)vcol == width1 - 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001261 return TRUE;
1262 width2 = width1 + win_col_off2(wp);
Bram Moolenaar8701cd62009-10-07 14:20:30 +00001263 if (width2 <= 0)
1264 return FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001265 return ((vcol - width1) % width2 == width2 - 1);
1266}
1267#endif /* FEAT_MBYTE */
1268
1269/*
1270 * Get virtual column number of pos.
1271 * start: on the first position of this character (TAB, ctrl)
1272 * cursor: where the cursor is on this character (first char, except for TAB)
1273 * end: on the last position of this character (TAB, ctrl)
1274 *
1275 * This is used very often, keep it fast!
1276 */
1277 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01001278getvcol(
1279 win_T *wp,
1280 pos_T *pos,
1281 colnr_T *start,
1282 colnr_T *cursor,
1283 colnr_T *end)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001284{
1285 colnr_T vcol;
1286 char_u *ptr; /* points to current char */
1287 char_u *posptr; /* points to char at pos->col */
Bram Moolenaar597a4222014-06-25 14:39:50 +02001288 char_u *line; /* start of the line */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001289 int incr;
1290 int head;
1291 int ts = wp->w_buffer->b_p_ts;
1292 int c;
1293
1294 vcol = 0;
Bram Moolenaar597a4222014-06-25 14:39:50 +02001295 line = ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
Bram Moolenaar37d619f2010-03-10 14:46:26 +01001296 if (pos->col == MAXCOL)
1297 posptr = NULL; /* continue until the NUL */
1298 else
1299 posptr = ptr + pos->col;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001300
1301 /*
1302 * This function is used very often, do some speed optimizations.
Bram Moolenaar597a4222014-06-25 14:39:50 +02001303 * When 'list', 'linebreak', 'showbreak' and 'breakindent' are not set
1304 * use a simple loop.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001305 * Also use this when 'list' is set but tabs take their normal size.
1306 */
1307 if ((!wp->w_p_list || lcs_tab1 != NUL)
1308#ifdef FEAT_LINEBREAK
Bram Moolenaar597a4222014-06-25 14:39:50 +02001309 && !wp->w_p_lbr && *p_sbr == NUL && !wp->w_p_bri
Bram Moolenaar071d4272004-06-13 20:20:40 +00001310#endif
1311 )
1312 {
1313#ifndef FEAT_MBYTE
1314 head = 0;
1315#endif
1316 for (;;)
1317 {
1318#ifdef FEAT_MBYTE
1319 head = 0;
1320#endif
1321 c = *ptr;
1322 /* make sure we don't go past the end of the line */
1323 if (c == NUL)
1324 {
1325 incr = 1; /* NUL at end of line only takes one column */
1326 break;
1327 }
1328 /* A tab gets expanded, depending on the current column */
1329 if (c == TAB)
1330 incr = ts - (vcol % ts);
1331 else
1332 {
1333#ifdef FEAT_MBYTE
1334 if (has_mbyte)
1335 {
1336 /* For utf-8, if the byte is >= 0x80, need to look at
1337 * further bytes to find the cell width. */
1338 if (enc_utf8 && c >= 0x80)
1339 incr = utf_ptr2cells(ptr);
1340 else
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +01001341 incr = g_chartab[c] & CT_CELL_MASK;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001342
1343 /* If a double-cell char doesn't fit at the end of a line
1344 * it wraps to the next line, it's like this char is three
1345 * cells wide. */
Bram Moolenaar9c33a7c2008-02-20 13:59:32 +00001346 if (incr == 2 && wp->w_p_wrap && MB_BYTE2LEN(*ptr) > 1
1347 && in_win_border(wp, vcol))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001348 {
1349 ++incr;
1350 head = 1;
1351 }
1352 }
1353 else
1354#endif
Bram Moolenaar88e8f9f2016-01-20 22:48:02 +01001355 incr = g_chartab[c] & CT_CELL_MASK;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001356 }
1357
Bram Moolenaar37d619f2010-03-10 14:46:26 +01001358 if (posptr != NULL && ptr >= posptr) /* character at pos->col */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001359 break;
1360
1361 vcol += incr;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001362 mb_ptr_adv(ptr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001363 }
1364 }
1365 else
1366 {
1367 for (;;)
1368 {
1369 /* A tab gets expanded, depending on the current column */
1370 head = 0;
Bram Moolenaar597a4222014-06-25 14:39:50 +02001371 incr = win_lbr_chartabsize(wp, line, ptr, vcol, &head);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001372 /* make sure we don't go past the end of the line */
1373 if (*ptr == NUL)
1374 {
1375 incr = 1; /* NUL at end of line only takes one column */
1376 break;
1377 }
1378
Bram Moolenaar37d619f2010-03-10 14:46:26 +01001379 if (posptr != NULL && ptr >= posptr) /* character at pos->col */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001380 break;
1381
1382 vcol += incr;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001383 mb_ptr_adv(ptr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001384 }
1385 }
1386 if (start != NULL)
1387 *start = vcol + head;
1388 if (end != NULL)
1389 *end = vcol + incr - 1;
1390 if (cursor != NULL)
1391 {
1392 if (*ptr == TAB
1393 && (State & NORMAL)
1394 && !wp->w_p_list
1395 && !virtual_active()
Bram Moolenaarf7ff6e82014-03-23 15:13:05 +01001396 && !(VIsual_active && (*p_sel == 'e' || ltoreq(*pos, VIsual)))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001397 )
1398 *cursor = vcol + incr - 1; /* cursor at end */
1399 else
1400 *cursor = vcol + head; /* cursor at start */
1401 }
1402}
1403
1404/*
1405 * Get virtual cursor column in the current window, pretending 'list' is off.
1406 */
1407 colnr_T
Bram Moolenaar7454a062016-01-30 15:14:10 +01001408getvcol_nolist(pos_T *posp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001409{
1410 int list_save = curwin->w_p_list;
1411 colnr_T vcol;
1412
1413 curwin->w_p_list = FALSE;
1414 getvcol(curwin, posp, NULL, &vcol, NULL);
1415 curwin->w_p_list = list_save;
1416 return vcol;
1417}
1418
1419#if defined(FEAT_VIRTUALEDIT) || defined(PROTO)
1420/*
1421 * Get virtual column in virtual mode.
1422 */
1423 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01001424getvvcol(
1425 win_T *wp,
1426 pos_T *pos,
1427 colnr_T *start,
1428 colnr_T *cursor,
1429 colnr_T *end)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001430{
1431 colnr_T col;
1432 colnr_T coladd;
1433 colnr_T endadd;
1434# ifdef FEAT_MBYTE
1435 char_u *ptr;
1436# endif
1437
1438 if (virtual_active())
1439 {
1440 /* For virtual mode, only want one value */
1441 getvcol(wp, pos, &col, NULL, NULL);
1442
1443 coladd = pos->coladd;
1444 endadd = 0;
1445# ifdef FEAT_MBYTE
1446 /* Cannot put the cursor on part of a wide character. */
1447 ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001448 if (pos->col < (colnr_T)STRLEN(ptr))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001449 {
1450 int c = (*mb_ptr2char)(ptr + pos->col);
1451
1452 if (c != TAB && vim_isprintc(c))
1453 {
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001454 endadd = (colnr_T)(char2cells(c) - 1);
Bram Moolenaara5792f52005-11-23 21:25:05 +00001455 if (coladd > endadd) /* past end of line */
1456 endadd = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001457 else
1458 coladd = 0;
1459 }
1460 }
1461# endif
1462 col += coladd;
1463 if (start != NULL)
1464 *start = col;
1465 if (cursor != NULL)
1466 *cursor = col;
1467 if (end != NULL)
1468 *end = col + endadd;
1469 }
1470 else
1471 getvcol(wp, pos, start, cursor, end);
1472}
1473#endif
1474
Bram Moolenaar071d4272004-06-13 20:20:40 +00001475/*
1476 * Get the leftmost and rightmost virtual column of pos1 and pos2.
1477 * Used for Visual block mode.
1478 */
1479 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01001480getvcols(
1481 win_T *wp,
1482 pos_T *pos1,
1483 pos_T *pos2,
1484 colnr_T *left,
1485 colnr_T *right)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001486{
1487 colnr_T from1, from2, to1, to2;
1488
1489 if (ltp(pos1, pos2))
1490 {
1491 getvvcol(wp, pos1, &from1, NULL, &to1);
1492 getvvcol(wp, pos2, &from2, NULL, &to2);
1493 }
1494 else
1495 {
1496 getvvcol(wp, pos2, &from1, NULL, &to1);
1497 getvvcol(wp, pos1, &from2, NULL, &to2);
1498 }
1499 if (from2 < from1)
1500 *left = from2;
1501 else
1502 *left = from1;
1503 if (to2 > to1)
1504 {
1505 if (*p_sel == 'e' && from2 - 1 >= to1)
1506 *right = from2 - 1;
1507 else
1508 *right = to2;
1509 }
1510 else
1511 *right = to1;
1512}
Bram Moolenaar071d4272004-06-13 20:20:40 +00001513
1514/*
1515 * skipwhite: skip over ' ' and '\t'.
1516 */
1517 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001518skipwhite(char_u *q)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001519{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001520 char_u *p = q;
1521
Bram Moolenaar071d4272004-06-13 20:20:40 +00001522 while (vim_iswhite(*p)) /* skip to next non-white */
1523 ++p;
1524 return p;
1525}
1526
1527/*
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001528 * skip over digits
Bram Moolenaar071d4272004-06-13 20:20:40 +00001529 */
1530 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001531skipdigits(char_u *q)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001532{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001533 char_u *p = q;
1534
Bram Moolenaar071d4272004-06-13 20:20:40 +00001535 while (VIM_ISDIGIT(*p)) /* skip to next non-digit */
1536 ++p;
1537 return p;
1538}
1539
Bram Moolenaarc4956c82006-03-12 21:58:43 +00001540#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) || defined(PROTO)
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001541/*
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001542 * skip over binary digits
1543 */
1544 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001545skipbin(char_u *q)
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001546{
1547 char_u *p = q;
1548
1549 while (vim_isbdigit(*p)) /* skip to next non-digit */
1550 ++p;
1551 return p;
1552}
1553
1554/*
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001555 * skip over digits and hex characters
1556 */
1557 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001558skiphex(char_u *q)
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001559{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001560 char_u *p = q;
1561
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001562 while (vim_isxdigit(*p)) /* skip to next non-digit */
1563 ++p;
1564 return p;
1565}
1566#endif
1567
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001568/*
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001569 * skip to bin digit (or NUL after the string)
1570 */
1571 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001572skiptobin(char_u *q)
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001573{
1574 char_u *p = q;
1575
1576 while (*p != NUL && !vim_isbdigit(*p)) /* skip to next digit */
1577 ++p;
1578 return p;
1579}
1580
1581/*
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001582 * skip to digit (or NUL after the string)
1583 */
1584 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001585skiptodigit(char_u *q)
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001586{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001587 char_u *p = q;
1588
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001589 while (*p != NUL && !VIM_ISDIGIT(*p)) /* skip to next digit */
1590 ++p;
1591 return p;
1592}
1593
1594/*
1595 * skip to hex character (or NUL after the string)
1596 */
1597 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001598skiptohex(char_u *q)
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001599{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001600 char_u *p = q;
1601
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001602 while (*p != NUL && !vim_isxdigit(*p)) /* skip to next digit */
1603 ++p;
1604 return p;
1605}
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001606
Bram Moolenaar071d4272004-06-13 20:20:40 +00001607/*
1608 * Variant of isdigit() that can handle characters > 0x100.
1609 * We don't use isdigit() here, because on some systems it also considers
1610 * superscript 1 to be a digit.
1611 * Use the VIM_ISDIGIT() macro for simple arguments.
1612 */
1613 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001614vim_isdigit(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001615{
1616 return (c >= '0' && c <= '9');
1617}
1618
1619/*
1620 * Variant of isxdigit() that can handle characters > 0x100.
1621 * We don't use isxdigit() here, because on some systems it also considers
1622 * superscript 1 to be a digit.
1623 */
1624 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001625vim_isxdigit(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001626{
1627 return (c >= '0' && c <= '9')
1628 || (c >= 'a' && c <= 'f')
1629 || (c >= 'A' && c <= 'F');
1630}
1631
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001632/*
1633 * Corollary of vim_isdigit and vim_isxdigit() that can handle
1634 * characters > 0x100.
1635 */
1636 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001637vim_isbdigit(int c)
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001638{
1639 return (c == '0' || c == '1');
1640}
1641
Bram Moolenaar78622822005-08-23 21:00:13 +00001642#if defined(FEAT_MBYTE) || defined(PROTO)
1643/*
1644 * Vim's own character class functions. These exist because many library
1645 * islower()/toupper() etc. do not work properly: they crash when used with
1646 * invalid values or can't handle latin1 when the locale is C.
1647 * Speed is most important here.
1648 */
1649#define LATIN1LOWER 'l'
1650#define LATIN1UPPER 'U'
1651
Bram Moolenaar6e7c7f32005-08-24 22:16:11 +00001652static char_u latin1flags[257] = " UUUUUUUUUUUUUUUUUUUUUUUUUU llllllllllllllllllllllllll UUUUUUUUUUUUUUUUUUUUUUU UUUUUUUllllllllllllllllllllllll llllllll";
Bram Moolenaar936347b2012-05-25 11:56:22 +02001653static char_u latin1upper[257] = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xf7\xd8\xd9\xda\xdb\xdc\xdd\xde\xff";
1654static char_u latin1lower[257] = " !\"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xd7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
Bram Moolenaar78622822005-08-23 21:00:13 +00001655
1656 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001657vim_islower(int c)
Bram Moolenaar78622822005-08-23 21:00:13 +00001658{
1659 if (c <= '@')
1660 return FALSE;
1661 if (c >= 0x80)
1662 {
1663 if (enc_utf8)
1664 return utf_islower(c);
1665 if (c >= 0x100)
1666 {
1667#ifdef HAVE_ISWLOWER
1668 if (has_mbyte)
1669 return iswlower(c);
1670#endif
1671 /* islower() can't handle these chars and may crash */
1672 return FALSE;
1673 }
1674 if (enc_latin1like)
1675 return (latin1flags[c] & LATIN1LOWER) == LATIN1LOWER;
1676 }
1677 return islower(c);
1678}
1679
1680 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001681vim_isupper(int c)
Bram Moolenaar78622822005-08-23 21:00:13 +00001682{
1683 if (c <= '@')
1684 return FALSE;
1685 if (c >= 0x80)
1686 {
1687 if (enc_utf8)
1688 return utf_isupper(c);
1689 if (c >= 0x100)
1690 {
1691#ifdef HAVE_ISWUPPER
1692 if (has_mbyte)
1693 return iswupper(c);
1694#endif
1695 /* islower() can't handle these chars and may crash */
1696 return FALSE;
1697 }
1698 if (enc_latin1like)
1699 return (latin1flags[c] & LATIN1UPPER) == LATIN1UPPER;
1700 }
1701 return isupper(c);
1702}
1703
1704 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001705vim_toupper(int c)
Bram Moolenaar78622822005-08-23 21:00:13 +00001706{
1707 if (c <= '@')
1708 return c;
1709 if (c >= 0x80)
1710 {
1711 if (enc_utf8)
1712 return utf_toupper(c);
1713 if (c >= 0x100)
1714 {
1715#ifdef HAVE_TOWUPPER
1716 if (has_mbyte)
1717 return towupper(c);
1718#endif
1719 /* toupper() can't handle these chars and may crash */
1720 return c;
1721 }
1722 if (enc_latin1like)
1723 return latin1upper[c];
1724 }
1725 return TOUPPER_LOC(c);
1726}
1727
1728 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001729vim_tolower(int c)
Bram Moolenaar78622822005-08-23 21:00:13 +00001730{
1731 if (c <= '@')
1732 return c;
1733 if (c >= 0x80)
1734 {
1735 if (enc_utf8)
1736 return utf_tolower(c);
1737 if (c >= 0x100)
1738 {
1739#ifdef HAVE_TOWLOWER
1740 if (has_mbyte)
1741 return towlower(c);
1742#endif
1743 /* tolower() can't handle these chars and may crash */
1744 return c;
1745 }
1746 if (enc_latin1like)
1747 return latin1lower[c];
1748 }
1749 return TOLOWER_LOC(c);
1750}
1751#endif
1752
Bram Moolenaar071d4272004-06-13 20:20:40 +00001753/*
1754 * skiptowhite: skip over text until ' ' or '\t' or NUL.
1755 */
1756 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001757skiptowhite(char_u *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001758{
1759 while (*p != ' ' && *p != '\t' && *p != NUL)
1760 ++p;
1761 return p;
1762}
1763
Bram Moolenaar85b11762016-02-27 18:13:23 +01001764#if defined(FEAT_LISTCMDS) || defined(FEAT_SIGNS) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001765/*
1766 * skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
1767 */
1768 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001769skiptowhite_esc(char_u *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001770{
1771 while (*p != ' ' && *p != '\t' && *p != NUL)
1772 {
1773 if ((*p == '\\' || *p == Ctrl_V) && *(p + 1) != NUL)
1774 ++p;
1775 ++p;
1776 }
1777 return p;
1778}
1779#endif
1780
1781/*
1782 * Getdigits: Get a number from a string and skip over it.
1783 * Note: the argument is a pointer to a char_u pointer!
1784 */
1785 long
Bram Moolenaar7454a062016-01-30 15:14:10 +01001786getdigits(char_u **pp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001787{
1788 char_u *p;
1789 long retval;
1790
1791 p = *pp;
1792 retval = atol((char *)p);
1793 if (*p == '-') /* skip negative sign */
1794 ++p;
1795 p = skipdigits(p); /* skip to next non-digit */
1796 *pp = p;
1797 return retval;
1798}
1799
1800/*
1801 * Return TRUE if "lbuf" is empty or only contains blanks.
1802 */
1803 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001804vim_isblankline(char_u *lbuf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001805{
1806 char_u *p;
1807
1808 p = skipwhite(lbuf);
1809 return (*p == NUL || *p == '\r' || *p == '\n');
1810}
1811
1812/*
1813 * Convert a string into a long and/or unsigned long, taking care of
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001814 * hexadecimal, octal, and binary numbers. Accepts a '-' sign.
1815 * If "prep" is not NULL, returns a flag to indicate the type of the number:
Bram Moolenaar071d4272004-06-13 20:20:40 +00001816 * 0 decimal
1817 * '0' octal
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001818 * 'B' bin
1819 * 'b' bin
Bram Moolenaar071d4272004-06-13 20:20:40 +00001820 * 'X' hex
1821 * 'x' hex
1822 * If "len" is not NULL, the length of the number in characters is returned.
1823 * If "nptr" is not NULL, the signed result is returned in it.
1824 * If "unptr" is not NULL, the unsigned result is returned in it.
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001825 * If "what" contains STR2NR_BIN recognize binary numbers
1826 * If "what" contains STR2NR_OCT recognize octal numbers
1827 * If "what" contains STR2NR_HEX recognize hex numbers
1828 * If "what" contains STR2NR_FORCE always assume bin/oct/hex.
Bram Moolenaar5d1bc782015-07-17 13:03:48 +02001829 * If maxlen > 0, check at a maximum maxlen chars
Bram Moolenaar071d4272004-06-13 20:20:40 +00001830 */
1831 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01001832vim_str2nr(
1833 char_u *start,
1834 int *prep, /* return: type of number 0 = decimal, 'x'
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001835 or 'X' is hex, '0' = octal, 'b' or 'B'
1836 is bin */
Bram Moolenaar7454a062016-01-30 15:14:10 +01001837 int *len, /* return: detected length of number */
1838 int what, /* what numbers to recognize */
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001839 varnumber_T *nptr, /* return: signed result */
1840 uvarnumber_T *unptr, /* return: unsigned result */
Bram Moolenaar7454a062016-01-30 15:14:10 +01001841 int maxlen) /* max length of string to check */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001842{
1843 char_u *ptr = start;
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001844 int pre = 0; /* default is decimal */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001845 int negative = FALSE;
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001846 uvarnumber_T un = 0;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001847 int n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001848
1849 if (ptr[0] == '-')
1850 {
1851 negative = TRUE;
1852 ++ptr;
1853 }
1854
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001855 /* Recognize hex, octal, and bin. */
Bram Moolenaar5d1bc782015-07-17 13:03:48 +02001856 if (ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9'
1857 && (maxlen == 0 || maxlen > 1))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001858 {
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001859 pre = ptr[1];
1860 if ((what & STR2NR_HEX)
1861 && (pre == 'X' || pre == 'x') && vim_isxdigit(ptr[2])
1862 && (maxlen == 0 || maxlen > 2))
1863 /* hexadecimal */
1864 ptr += 2;
1865 else if ((what & STR2NR_BIN)
1866 && (pre == 'B' || pre == 'b') && vim_isbdigit(ptr[2])
1867 && (maxlen == 0 || maxlen > 2))
1868 /* binary */
1869 ptr += 2;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001870 else
1871 {
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001872 /* decimal or octal, default is decimal */
1873 pre = 0;
1874 if (what & STR2NR_OCT)
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001875 {
1876 /* Don't interpret "0", "08" or "0129" as octal. */
1877 for (n = 1; VIM_ISDIGIT(ptr[n]); ++n)
1878 {
1879 if (ptr[n] > '7')
1880 {
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001881 pre = 0; /* can't be octal */
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001882 break;
1883 }
Bram Moolenaar06af6022012-01-26 13:40:08 +01001884 if (ptr[n] >= '0')
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001885 pre = '0'; /* assume octal */
Bram Moolenaar5d1bc782015-07-17 13:03:48 +02001886 if (n == maxlen)
1887 break;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001888 }
1889 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001890 }
1891 }
1892
1893 /*
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001894 * Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
1895 */
Bram Moolenaar5d1bc782015-07-17 13:03:48 +02001896 n = 1;
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001897 if (pre == 'B' || pre == 'b' || what == STR2NR_BIN + STR2NR_FORCE)
1898 {
1899 /* bin */
1900 if (pre != 0)
1901 n += 2; /* skip over "0b" */
1902 while ('0' <= *ptr && *ptr <= '1')
1903 {
1904 un = 2 * un + (unsigned long)(*ptr - '0');
1905 ++ptr;
1906 if (n++ == maxlen)
1907 break;
1908 }
1909 }
1910 else if (pre == '0' || what == STR2NR_OCT + STR2NR_FORCE)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001911 {
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001912 /* octal */
1913 while ('0' <= *ptr && *ptr <= '7')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001914 {
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001915 un = 8 * un + (uvarnumber_T)(*ptr - '0');
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001916 ++ptr;
Bram Moolenaar5d1bc782015-07-17 13:03:48 +02001917 if (n++ == maxlen)
1918 break;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001919 }
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001920 }
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001921 else if (pre != 0 || what == STR2NR_HEX + STR2NR_FORCE)
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001922 {
1923 /* hex */
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001924 if (pre != 0)
Bram Moolenaar5adfea12015-09-01 18:51:39 +02001925 n += 2; /* skip over "0x" */
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001926 while (vim_isxdigit(*ptr))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001927 {
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001928 un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001929 ++ptr;
Bram Moolenaar5d1bc782015-07-17 13:03:48 +02001930 if (n++ == maxlen)
1931 break;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001932 }
1933 }
1934 else
1935 {
1936 /* decimal */
1937 while (VIM_ISDIGIT(*ptr))
1938 {
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001939 un = 10 * un + (uvarnumber_T)(*ptr - '0');
Bram Moolenaar071d4272004-06-13 20:20:40 +00001940 ++ptr;
Bram Moolenaar5d1bc782015-07-17 13:03:48 +02001941 if (n++ == maxlen)
1942 break;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001943 }
1944 }
1945
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001946 if (prep != NULL)
1947 *prep = pre;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001948 if (len != NULL)
1949 *len = (int)(ptr - start);
1950 if (nptr != NULL)
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00001951 {
1952 if (negative) /* account for leading '-' for decimal numbers */
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001953 *nptr = -(varnumber_T)un;
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00001954 else
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001955 *nptr = (varnumber_T)un;
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00001956 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001957 if (unptr != NULL)
1958 *unptr = un;
1959}
1960
1961/*
1962 * Return the value of a single hex character.
1963 * Only valid when the argument is '0' - '9', 'A' - 'F' or 'a' - 'f'.
1964 */
1965 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001966hex2nr(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001967{
1968 if (c >= 'a' && c <= 'f')
1969 return c - 'a' + 10;
1970 if (c >= 'A' && c <= 'F')
1971 return c - 'A' + 10;
1972 return c - '0';
1973}
1974
1975#if defined(FEAT_TERMRESPONSE) \
1976 || (defined(FEAT_GUI_GTK) && defined(FEAT_WINDOWS)) || defined(PROTO)
1977/*
1978 * Convert two hex characters to a byte.
1979 * Return -1 if one of the characters is not hex.
1980 */
1981 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001982hexhex2nr(char_u *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001983{
1984 if (!vim_isxdigit(p[0]) || !vim_isxdigit(p[1]))
1985 return -1;
1986 return (hex2nr(p[0]) << 4) + hex2nr(p[1]);
1987}
1988#endif
1989
1990/*
1991 * Return TRUE if "str" starts with a backslash that should be removed.
1992 * For MS-DOS, WIN32 and OS/2 this is only done when the character after the
1993 * backslash is not a normal file name character.
1994 * '$' is a valid file name character, we don't remove the backslash before
1995 * it. This means it is not possible to use an environment variable after a
1996 * backslash. "C:\$VIM\doc" is taken literally, only "$VIM\doc" works.
1997 * Although "\ name" is valid, the backslash in "Program\ files" must be
1998 * removed. Assume a file name doesn't start with a space.
1999 * For multi-byte names, never remove a backslash before a non-ascii
2000 * character, assume that all multi-byte characters are valid file name
2001 * characters.
2002 */
2003 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01002004rem_backslash(char_u *str)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002005{
2006#ifdef BACKSLASH_IN_FILENAME
2007 return (str[0] == '\\'
2008# ifdef FEAT_MBYTE
2009 && str[1] < 0x80
2010# endif
2011 && (str[1] == ' '
2012 || (str[1] != NUL
2013 && str[1] != '*'
2014 && str[1] != '?'
2015 && !vim_isfilec(str[1]))));
2016#else
2017 return (str[0] == '\\' && str[1] != NUL);
2018#endif
2019}
2020
2021/*
2022 * Halve the number of backslashes in a file name argument.
2023 * For MS-DOS we only do this if the character after the backslash
2024 * is not a normal file character.
2025 */
2026 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01002027backslash_halve(char_u *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002028{
2029 for ( ; *p; ++p)
2030 if (rem_backslash(p))
Bram Moolenaar446cb832008-06-24 21:56:24 +00002031 STRMOVE(p, p + 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002032}
2033
2034/*
2035 * backslash_halve() plus save the result in allocated memory.
2036 */
2037 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01002038backslash_halve_save(char_u *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002039{
2040 char_u *res;
2041
2042 res = vim_strsave(p);
2043 if (res == NULL)
2044 return p;
2045 backslash_halve(res);
2046 return res;
2047}
2048
2049#if (defined(EBCDIC) && defined(FEAT_POSTSCRIPT)) || defined(PROTO)
2050/*
2051 * Table for EBCDIC to ASCII conversion unashamedly taken from xxd.c!
2052 * The first 64 entries have been added to map control characters defined in
2053 * ascii.h
2054 */
2055static char_u ebcdic2ascii_tab[256] =
2056{
2057 0000, 0001, 0002, 0003, 0004, 0011, 0006, 0177,
2058 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
2059 0020, 0021, 0022, 0023, 0024, 0012, 0010, 0027,
2060 0030, 0031, 0032, 0033, 0033, 0035, 0036, 0037,
2061 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
2062 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
2063 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
2064 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
2065 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
2066 0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
2067 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
2068 0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
2069 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
2070 0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
2071 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
2072 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
2073 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
2074 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
2075 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
2076 0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
2077 0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
2078 0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
2079 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
2080 0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
2081 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
2082 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
2083 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
2084 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
2085 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
2086 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
2087 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
2088 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377
2089};
2090
2091/*
2092 * Convert a buffer worth of characters from EBCDIC to ASCII. Only useful if
2093 * wanting 7-bit ASCII characters out the other end.
2094 */
2095 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01002096ebcdic2ascii(char_u *buffer, int len)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002097{
2098 int i;
2099
2100 for (i = 0; i < len; i++)
2101 buffer[i] = ebcdic2ascii_tab[buffer[i]];
2102}
2103#endif