blob: 6f39cf6d076d283f561c86ba6eb543df42e2b287 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* vi:set ts=8 sts=4 sw=4:
2 *
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
13static int win_chartabsize __ARGS((win_T *wp, char_u *p, colnr_T col));
14#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 Moolenaar071d4272004-06-13 20:20:40 +000020static int win_nolbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col, int *headp));
21#endif
22
Bram Moolenaar0ab2a882009-05-13 10:51:08 +000023static unsigned nr2hex __ARGS((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
33/*
34 * Fill chartab[]. Also fills curbuf->b_chartab[] with flags for keyword
35 * characters for current buffer.
36 *
37 * Depends on the option settings 'iskeyword', 'isident', 'isfname',
38 * 'isprint' and 'encoding'.
39 *
40 * The index in chartab[] depends on 'encoding':
41 * - For non-multi-byte index with the byte (same as the character).
42 * - For DBCS index with the first byte.
43 * - For UTF-8 index with the character (when first byte is up to 0x80 it is
44 * the same as the character, if the first byte is 0x80 and above it depends
45 * on further bytes).
46 *
47 * The contents of chartab[]:
48 * - The lower two bits, masked by CT_CELL_MASK, give the number of display
49 * cells the character occupies (1 or 2). Not valid for UTF-8 above 0x80.
50 * - CT_PRINT_CHAR bit is set when the character is printable (no need to
51 * translate the character before displaying it). Note that only DBCS
52 * characters can have 2 display cells and still be printable.
53 * - CT_FNAME_CHAR bit is set when the character can be in a file name.
54 * - CT_ID_CHAR bit is set when the character can be in an identifier.
55 *
56 * Return FAIL if 'iskeyword', 'isident', 'isfname' or 'isprint' option has an
57 * error, OK otherwise.
58 */
59 int
60init_chartab()
61{
62 return buf_init_chartab(curbuf, TRUE);
63}
64
65 int
66buf_init_chartab(buf, global)
67 buf_T *buf;
68 int global; /* FALSE: only set buf->b_chartab[] */
69{
70 int c;
71 int c2;
72 char_u *p;
73 int i;
74 int tilde;
75 int do_isalpha;
76
77 if (global)
78 {
79 /*
80 * Set the default size for printable characters:
81 * From <Space> to '~' is 1 (printable), others are 2 (not printable).
82 * This also inits all 'isident' and 'isfname' flags to FALSE.
83 *
84 * EBCDIC: all chars below ' ' are not printable, all others are
85 * printable.
86 */
87 c = 0;
88 while (c < ' ')
89 chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
90#ifdef EBCDIC
91 while (c < 255)
92#else
93 while (c <= '~')
94#endif
95 chartab[c++] = 1 + CT_PRINT_CHAR;
96#ifdef FEAT_FKMAP
97 if (p_altkeymap)
98 {
99 while (c < YE)
100 chartab[c++] = 1 + CT_PRINT_CHAR;
101 }
102#endif
103 while (c < 256)
104 {
105#ifdef FEAT_MBYTE
106 /* UTF-8: bytes 0xa0 - 0xff are printable (latin1) */
107 if (enc_utf8 && c >= 0xa0)
108 chartab[c++] = CT_PRINT_CHAR + 1;
109 /* euc-jp characters starting with 0x8e are single width */
110 else if (enc_dbcs == DBCS_JPNU && c == 0x8e)
111 chartab[c++] = CT_PRINT_CHAR + 1;
112 /* other double-byte chars can be printable AND double-width */
113 else if (enc_dbcs != 0 && MB_BYTE2LEN(c) == 2)
114 chartab[c++] = CT_PRINT_CHAR + 2;
115 else
116#endif
117 /* the rest is unprintable by default */
118 chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
119 }
120
121#ifdef FEAT_MBYTE
122 /* Assume that every multi-byte char is a filename character. */
123 for (c = 1; c < 256; ++c)
124 if ((enc_dbcs != 0 && MB_BYTE2LEN(c) > 1)
125 || (enc_dbcs == DBCS_JPNU && c == 0x8e)
126 || (enc_utf8 && c >= 0xa0))
127 chartab[c] |= CT_FNAME_CHAR;
128#endif
129 }
130
131 /*
132 * Init word char flags all to FALSE
133 */
134 vim_memset(buf->b_chartab, 0, (size_t)32);
135#ifdef FEAT_MBYTE
Bram Moolenaar6bb68362005-03-22 23:03:44 +0000136 if (enc_dbcs != 0)
137 for (c = 0; c < 256; ++c)
138 {
139 /* double-byte characters are probably word characters */
140 if (MB_BYTE2LEN(c) == 2)
141 SET_CHARTAB(buf, c);
142 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000143#endif
144
145#ifdef FEAT_LISP
146 /*
147 * In lisp mode the '-' character is included in keywords.
148 */
149 if (buf->b_p_lisp)
150 SET_CHARTAB(buf, '-');
151#endif
152
153 /* Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
154 * options Each option is a list of characters, character numbers or
155 * ranges, separated by commas, e.g.: "200-210,x,#-178,-"
156 */
157 for (i = global ? 0 : 3; i <= 3; ++i)
158 {
159 if (i == 0)
160 p = p_isi; /* first round: 'isident' */
161 else if (i == 1)
162 p = p_isp; /* second round: 'isprint' */
163 else if (i == 2)
164 p = p_isf; /* third round: 'isfname' */
165 else /* i == 3 */
166 p = buf->b_p_isk; /* fourth round: 'iskeyword' */
167
168 while (*p)
169 {
170 tilde = FALSE;
171 do_isalpha = FALSE;
172 if (*p == '^' && p[1] != NUL)
173 {
174 tilde = TRUE;
175 ++p;
176 }
177 if (VIM_ISDIGIT(*p))
178 c = getdigits(&p);
179 else
Bram Moolenaar183bb3e2009-09-11 12:02:34 +0000180#ifdef FEAT_MBYTE
181 if (has_mbyte)
182 c = mb_ptr2char_adv(&p);
183 else
184#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000185 c = *p++;
186 c2 = -1;
187 if (*p == '-' && p[1] != NUL)
188 {
189 ++p;
190 if (VIM_ISDIGIT(*p))
191 c2 = getdigits(&p);
192 else
Bram Moolenaar2ac5e602009-11-03 15:04:20 +0000193#ifdef FEAT_MBYTE
194 if (has_mbyte)
195 c2 = mb_ptr2char_adv(&p);
196 else
197#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000198 c2 = *p++;
199 }
Bram Moolenaar2ac5e602009-11-03 15:04:20 +0000200 if (c <= 0 || c >= 256 || (c2 < c && c2 != -1) || c2 >= 256
Bram Moolenaar071d4272004-06-13 20:20:40 +0000201 || !(*p == NUL || *p == ','))
202 return FAIL;
203
204 if (c2 == -1) /* not a range */
205 {
206 /*
207 * A single '@' (not "@-@"):
208 * Decide on letters being ID/printable/keyword chars with
209 * standard function isalpha(). This takes care of locale for
210 * single-byte characters).
211 */
212 if (c == '@')
213 {
214 do_isalpha = TRUE;
215 c = 1;
216 c2 = 255;
217 }
218 else
219 c2 = c;
220 }
221 while (c <= c2)
222 {
Bram Moolenaardeefb632007-08-15 18:41:34 +0000223 /* Use the MB_ functions here, because isalpha() doesn't
224 * work properly when 'encoding' is "latin1" and the locale is
225 * "C". */
226 if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000227#ifdef FEAT_FKMAP
228 || (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))
229#endif
230 )
231 {
232 if (i == 0) /* (re)set ID flag */
233 {
234 if (tilde)
235 chartab[c] &= ~CT_ID_CHAR;
236 else
237 chartab[c] |= CT_ID_CHAR;
238 }
239 else if (i == 1) /* (re)set printable */
240 {
241 if ((c < ' '
242#ifndef EBCDIC
243 || c > '~'
244#endif
245#ifdef FEAT_FKMAP
246 || (p_altkeymap
247 && (F_isalpha(c) || F_isdigit(c)))
248#endif
249 )
250#ifdef FEAT_MBYTE
251 /* For double-byte we keep the cell width, so
252 * that we can detect it from the first byte. */
253 && !(enc_dbcs && MB_BYTE2LEN(c) == 2)
254#endif
255 )
256 {
257 if (tilde)
258 {
259 chartab[c] = (chartab[c] & ~CT_CELL_MASK)
260 + ((dy_flags & DY_UHEX) ? 4 : 2);
261 chartab[c] &= ~CT_PRINT_CHAR;
262 }
263 else
264 {
265 chartab[c] = (chartab[c] & ~CT_CELL_MASK) + 1;
266 chartab[c] |= CT_PRINT_CHAR;
267 }
268 }
269 }
270 else if (i == 2) /* (re)set fname flag */
271 {
272 if (tilde)
273 chartab[c] &= ~CT_FNAME_CHAR;
274 else
275 chartab[c] |= CT_FNAME_CHAR;
276 }
277 else /* i == 3 */ /* (re)set keyword flag */
278 {
279 if (tilde)
280 RESET_CHARTAB(buf, c);
281 else
282 SET_CHARTAB(buf, c);
283 }
284 }
285 ++c;
286 }
287 p = skip_to_option_part(p);
288 }
289 }
290 chartab_initialized = TRUE;
291 return OK;
292}
293
294/*
295 * Translate any special characters in buf[bufsize] in-place.
296 * The result is a string with only printable characters, but if there is not
297 * enough room, not all characters will be translated.
298 */
299 void
300trans_characters(buf, bufsize)
301 char_u *buf;
302 int bufsize;
303{
304 int len; /* length of string needing translation */
305 int room; /* room in buffer after string */
306 char_u *trs; /* translated character */
307 int trs_len; /* length of trs[] */
308
309 len = (int)STRLEN(buf);
310 room = bufsize - len;
311 while (*buf != 0)
312 {
313# ifdef FEAT_MBYTE
314 /* Assume a multi-byte character doesn't need translation. */
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000315 if (has_mbyte && (trs_len = (*mb_ptr2len)(buf)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000316 len -= trs_len;
317 else
318# endif
319 {
320 trs = transchar_byte(*buf);
321 trs_len = (int)STRLEN(trs);
322 if (trs_len > 1)
323 {
324 room -= trs_len - 1;
325 if (room <= 0)
326 return;
327 mch_memmove(buf + trs_len, buf + 1, (size_t)len);
328 }
329 mch_memmove(buf, trs, (size_t)trs_len);
330 --len;
331 }
332 buf += trs_len;
333 }
334}
335
Bram Moolenaar7cc36e92007-03-27 10:42:05 +0000336#if defined(FEAT_EVAL) || defined(FEAT_TITLE) || defined(FEAT_INS_EXPAND) \
337 || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000338/*
339 * Translate a string into allocated memory, replacing special chars with
340 * printable chars. Returns NULL when out of memory.
341 */
342 char_u *
343transstr(s)
344 char_u *s;
345{
346 char_u *res;
347 char_u *p;
348#ifdef FEAT_MBYTE
349 int l, len, c;
350 char_u hexbuf[11];
351#endif
352
353#ifdef FEAT_MBYTE
354 if (has_mbyte)
355 {
356 /* Compute the length of the result, taking account of unprintable
357 * multi-byte characters. */
358 len = 0;
359 p = s;
360 while (*p != NUL)
361 {
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000362 if ((l = (*mb_ptr2len)(p)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000363 {
364 c = (*mb_ptr2char)(p);
365 p += l;
366 if (vim_isprintc(c))
367 len += l;
368 else
369 {
370 transchar_hex(hexbuf, c);
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000371 len += (int)STRLEN(hexbuf);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000372 }
373 }
374 else
375 {
376 l = byte2cells(*p++);
377 if (l > 0)
378 len += l;
379 else
380 len += 4; /* illegal byte sequence */
381 }
382 }
383 res = alloc((unsigned)(len + 1));
384 }
385 else
386#endif
387 res = alloc((unsigned)(vim_strsize(s) + 1));
388 if (res != NULL)
389 {
390 *res = NUL;
391 p = s;
392 while (*p != NUL)
393 {
394#ifdef FEAT_MBYTE
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000395 if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000396 {
397 c = (*mb_ptr2char)(p);
398 if (vim_isprintc(c))
399 STRNCAT(res, p, l); /* append printable multi-byte char */
400 else
401 transchar_hex(res + STRLEN(res), c);
402 p += l;
403 }
404 else
405#endif
406 STRCAT(res, transchar_byte(*p++));
407 }
408 }
409 return res;
410}
411#endif
412
413#if defined(FEAT_SYN_HL) || defined(FEAT_INS_EXPAND) || defined(PROTO)
414/*
Bram Moolenaar217ad922005-03-20 22:37:15 +0000415 * Convert the string "str[orglen]" to do ignore-case comparing. Uses the
416 * current locale.
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000417 * When "buf" is NULL returns an allocated string (NULL for out-of-memory).
418 * Otherwise puts the result in "buf[buflen]".
Bram Moolenaar071d4272004-06-13 20:20:40 +0000419 */
420 char_u *
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000421str_foldcase(str, orglen, buf, buflen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000422 char_u *str;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000423 int orglen;
424 char_u *buf;
425 int buflen;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000426{
427 garray_T ga;
428 int i;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000429 int len = orglen;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000430
431#define GA_CHAR(i) ((char_u *)ga.ga_data)[i]
432#define GA_PTR(i) ((char_u *)ga.ga_data + i)
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000433#define STR_CHAR(i) (buf == NULL ? GA_CHAR(i) : buf[i])
434#define STR_PTR(i) (buf == NULL ? GA_PTR(i) : buf + i)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000435
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000436 /* Copy "str" into "buf" or allocated memory, unmodified. */
437 if (buf == NULL)
438 {
439 ga_init2(&ga, 1, 10);
440 if (ga_grow(&ga, len + 1) == FAIL)
441 return NULL;
442 mch_memmove(ga.ga_data, str, (size_t)len);
443 ga.ga_len = len;
444 }
445 else
446 {
447 if (len >= buflen) /* Ugly! */
448 len = buflen - 1;
449 mch_memmove(buf, str, (size_t)len);
450 }
451 if (buf == NULL)
452 GA_CHAR(len) = NUL;
453 else
454 buf[len] = NUL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000455
456 /* Make each character lower case. */
457 i = 0;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000458 while (STR_CHAR(i) != NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000459 {
460#ifdef FEAT_MBYTE
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000461 if (enc_utf8 || (has_mbyte && MB_BYTE2LEN(STR_CHAR(i)) > 1))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000462 {
463 if (enc_utf8)
464 {
Bram Moolenaarb9839212008-06-28 11:03:50 +0000465 int c = utf_ptr2char(STR_PTR(i));
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100466 int olen = utf_ptr2len(STR_PTR(i));
Bram Moolenaarb9839212008-06-28 11:03:50 +0000467 int lc = utf_tolower(c);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000468
Bram Moolenaarb9839212008-06-28 11:03:50 +0000469 /* Only replace the character when it is not an invalid
470 * sequence (ASCII character or more than one byte) and
471 * utf_tolower() doesn't return the original character. */
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100472 if ((c < 0x80 || olen > 1) && c != lc)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000473 {
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100474 int nlen = utf_char2len(lc);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000475
476 /* If the byte length changes need to shift the following
477 * characters forward or backward. */
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100478 if (olen != nlen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000479 {
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100480 if (nlen > olen)
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000481 {
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100482 if (buf == NULL
483 ? ga_grow(&ga, nlen - olen + 1) == FAIL
484 : len + nlen - olen >= buflen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000485 {
486 /* out of memory, keep old char */
487 lc = c;
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100488 nlen = olen;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000489 }
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000490 }
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100491 if (olen != nlen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000492 {
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000493 if (buf == NULL)
494 {
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100495 STRMOVE(GA_PTR(i) + nlen, GA_PTR(i) + olen);
496 ga.ga_len += nlen - olen;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000497 }
498 else
499 {
Bram Moolenaar70b2a562012-01-10 22:26:17 +0100500 STRMOVE(buf + i + nlen, buf + i + olen);
501 len += nlen - olen;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000502 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000503 }
504 }
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000505 (void)utf_char2bytes(lc, STR_PTR(i));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000506 }
507 }
508 /* skip to next multi-byte char */
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000509 i += (*mb_ptr2len)(STR_PTR(i));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000510 }
511 else
512#endif
513 {
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000514 if (buf == NULL)
515 GA_CHAR(i) = TOLOWER_LOC(GA_CHAR(i));
516 else
517 buf[i] = TOLOWER_LOC(buf[i]);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000518 ++i;
519 }
520 }
521
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000522 if (buf == NULL)
523 return (char_u *)ga.ga_data;
524 return buf;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000525}
526#endif
527
528/*
529 * Catch 22: chartab[] can't be initialized before the options are
530 * initialized, and initializing options may cause transchar() to be called!
531 * When chartab_initialized == FALSE don't use chartab[].
532 * Does NOT work for multi-byte characters, c must be <= 255.
533 * Also doesn't work for the first byte of a multi-byte, "c" must be a
534 * character!
535 */
536static char_u transchar_buf[7];
537
538 char_u *
539transchar(c)
540 int c;
541{
542 int i;
543
544 i = 0;
545 if (IS_SPECIAL(c)) /* special key code, display as ~@ char */
546 {
547 transchar_buf[0] = '~';
548 transchar_buf[1] = '@';
549 i = 2;
550 c = K_SECOND(c);
551 }
552
553 if ((!chartab_initialized && (
554#ifdef EBCDIC
555 (c >= 64 && c < 255)
556#else
557 (c >= ' ' && c <= '~')
558#endif
559#ifdef FEAT_FKMAP
560 || F_ischar(c)
561#endif
562 )) || (c < 256 && vim_isprintc_strict(c)))
563 {
564 /* printable character */
565 transchar_buf[i] = c;
566 transchar_buf[i + 1] = NUL;
567 }
568 else
569 transchar_nonprint(transchar_buf + i, c);
570 return transchar_buf;
571}
572
573#if defined(FEAT_MBYTE) || defined(PROTO)
574/*
575 * Like transchar(), but called with a byte instead of a character. Checks
576 * for an illegal UTF-8 byte.
577 */
578 char_u *
579transchar_byte(c)
580 int c;
581{
582 if (enc_utf8 && c >= 0x80)
583 {
584 transchar_nonprint(transchar_buf, c);
585 return transchar_buf;
586 }
587 return transchar(c);
588}
589#endif
590
591/*
592 * Convert non-printable character to two or more printable characters in
593 * "buf[]". "buf" needs to be able to hold five bytes.
594 * Does NOT work for multi-byte characters, c must be <= 255.
595 */
596 void
597transchar_nonprint(buf, c)
598 char_u *buf;
599 int c;
600{
601 if (c == NL)
602 c = NUL; /* we use newline in place of a NUL */
603 else if (c == CAR && get_fileformat(curbuf) == EOL_MAC)
604 c = NL; /* we use CR in place of NL in this case */
605
606 if (dy_flags & DY_UHEX) /* 'display' has "uhex" */
607 transchar_hex(buf, c);
608
609#ifdef EBCDIC
610 /* For EBCDIC only the characters 0-63 and 255 are not printable */
611 else if (CtrlChar(c) != 0 || c == DEL)
612#else
613 else if (c <= 0x7f) /* 0x00 - 0x1f and 0x7f */
614#endif
615 {
616 buf[0] = '^';
617#ifdef EBCDIC
618 if (c == DEL)
619 buf[1] = '?'; /* DEL displayed as ^? */
620 else
621 buf[1] = CtrlChar(c);
622#else
623 buf[1] = c ^ 0x40; /* DEL displayed as ^? */
624#endif
625
626 buf[2] = NUL;
627 }
628#ifdef FEAT_MBYTE
629 else if (enc_utf8 && c >= 0x80)
630 {
631 transchar_hex(buf, c);
632 }
633#endif
634#ifndef EBCDIC
635 else if (c >= ' ' + 0x80 && c <= '~' + 0x80) /* 0xa0 - 0xfe */
636 {
637 buf[0] = '|';
638 buf[1] = c - 0x80;
639 buf[2] = NUL;
640 }
641#else
642 else if (c < 64)
643 {
644 buf[0] = '~';
645 buf[1] = MetaChar(c);
646 buf[2] = NUL;
647 }
648#endif
649 else /* 0x80 - 0x9f and 0xff */
650 {
651 /*
652 * TODO: EBCDIC I don't know what to do with this chars, so I display
653 * them as '~?' for now
654 */
655 buf[0] = '~';
656#ifdef EBCDIC
657 buf[1] = '?'; /* 0xff displayed as ~? */
658#else
659 buf[1] = (c - 0x80) ^ 0x40; /* 0xff displayed as ~? */
660#endif
661 buf[2] = NUL;
662 }
663}
664
665 void
666transchar_hex(buf, c)
667 char_u *buf;
668 int c;
669{
670 int i = 0;
671
672 buf[0] = '<';
673#ifdef FEAT_MBYTE
674 if (c > 255)
675 {
676 buf[++i] = nr2hex((unsigned)c >> 12);
677 buf[++i] = nr2hex((unsigned)c >> 8);
678 }
679#endif
680 buf[++i] = nr2hex((unsigned)c >> 4);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000681 buf[++i] = nr2hex((unsigned)c);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000682 buf[++i] = '>';
683 buf[++i] = NUL;
684}
685
686/*
687 * Convert the lower 4 bits of byte "c" to its hex character.
688 * Lower case letters are used to avoid the confusion of <F1> being 0xf1 or
689 * function key 1.
690 */
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000691 static unsigned
Bram Moolenaar071d4272004-06-13 20:20:40 +0000692nr2hex(c)
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000693 unsigned c;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000694{
695 if ((c & 0xf) <= 9)
696 return (c & 0xf) + '0';
697 return (c & 0xf) - 10 + 'a';
698}
699
700/*
701 * Return number of display cells occupied by byte "b".
702 * Caller must make sure 0 <= b <= 255.
703 * For multi-byte mode "b" must be the first byte of a character.
704 * A TAB is counted as two cells: "^I".
705 * For UTF-8 mode this will return 0 for bytes >= 0x80, because the number of
706 * cells depends on further bytes.
707 */
708 int
709byte2cells(b)
710 int b;
711{
712#ifdef FEAT_MBYTE
713 if (enc_utf8 && b >= 0x80)
714 return 0;
715#endif
716 return (chartab[b] & CT_CELL_MASK);
717}
718
719/*
720 * Return number of display cells occupied by character "c".
721 * "c" can be a special key (negative number) in which case 3 or 4 is returned.
722 * A TAB is counted as two cells: "^I" or four: "<09>".
723 */
724 int
725char2cells(c)
726 int c;
727{
728 if (IS_SPECIAL(c))
729 return char2cells(K_SECOND(c)) + 2;
730#ifdef FEAT_MBYTE
731 if (c >= 0x80)
732 {
733 /* UTF-8: above 0x80 need to check the value */
734 if (enc_utf8)
735 return utf_char2cells(c);
736 /* DBCS: double-byte means double-width, except for euc-jp with first
737 * byte 0x8e */
738 if (enc_dbcs != 0 && c >= 0x100)
739 {
740 if (enc_dbcs == DBCS_JPNU && ((unsigned)c >> 8) == 0x8e)
741 return 1;
742 return 2;
743 }
744 }
745#endif
746 return (chartab[c & 0xff] & CT_CELL_MASK);
747}
748
749/*
750 * Return number of display cells occupied by character at "*p".
751 * A TAB is counted as two cells: "^I" or four: "<09>".
752 */
753 int
754ptr2cells(p)
755 char_u *p;
756{
757#ifdef FEAT_MBYTE
758 /* For UTF-8 we need to look at more bytes if the first byte is >= 0x80. */
759 if (enc_utf8 && *p >= 0x80)
760 return utf_ptr2cells(p);
761 /* For DBCS we can tell the cell count from the first byte. */
762#endif
763 return (chartab[*p] & CT_CELL_MASK);
764}
765
766/*
Bram Moolenaar06af6022012-01-26 13:40:08 +0100767 * Return the number of character cells string "s" will take on the screen,
Bram Moolenaar071d4272004-06-13 20:20:40 +0000768 * counting TABs as two characters: "^I".
769 */
770 int
771vim_strsize(s)
772 char_u *s;
773{
774 return vim_strnsize(s, (int)MAXCOL);
775}
776
777/*
Bram Moolenaar06af6022012-01-26 13:40:08 +0100778 * Return the number of character cells string "s[len]" will take on the
779 * screen, counting TABs as two characters: "^I".
Bram Moolenaar071d4272004-06-13 20:20:40 +0000780 */
781 int
782vim_strnsize(s, len)
783 char_u *s;
784 int len;
785{
786 int size = 0;
787
788 while (*s != NUL && --len >= 0)
789 {
790#ifdef FEAT_MBYTE
791 if (has_mbyte)
792 {
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000793 int l = (*mb_ptr2len)(s);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000794
795 size += ptr2cells(s);
796 s += l;
797 len -= l - 1;
798 }
799 else
800#endif
801 size += byte2cells(*s++);
802 }
803 return size;
804}
805
806/*
807 * Return the number of characters 'c' will take on the screen, taking
808 * into account the size of a tab.
809 * Use a define to make it fast, this is used very often!!!
810 * Also see getvcol() below.
811 */
812
813#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
814 if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \
815 { \
816 int ts; \
817 ts = (buf)->b_p_ts; \
818 return (int)(ts - (col % ts)); \
819 } \
820 else \
821 return ptr2cells(p);
822
823#if defined(FEAT_VREPLACE) || defined(FEAT_EX_EXTRA) || defined(FEAT_GUI) \
824 || defined(FEAT_VIRTUALEDIT) || defined(PROTO)
825 int
826chartabsize(p, col)
827 char_u *p;
828 colnr_T col;
829{
830 RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col)
831}
832#endif
833
834#ifdef FEAT_LINEBREAK
835 static int
836win_chartabsize(wp, p, col)
837 win_T *wp;
838 char_u *p;
839 colnr_T col;
840{
841 RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col)
842}
843#endif
844
845/*
Bram Moolenaardc536092010-07-18 15:45:49 +0200846 * Return the number of characters the string 's' will take on the screen,
847 * taking into account the size of a tab.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000848 */
849 int
850linetabsize(s)
851 char_u *s;
852{
Bram Moolenaardc536092010-07-18 15:45:49 +0200853 return linetabsize_col(0, s);
854}
855
856/*
857 * Like linetabsize(), but starting at column "startcol".
858 */
859 int
860linetabsize_col(startcol, s)
861 int startcol;
862 char_u *s;
863{
864 colnr_T col = startcol;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000865
866 while (*s != NUL)
867 col += lbr_chartabsize_adv(&s, col);
868 return (int)col;
869}
870
871/*
872 * Like linetabsize(), but for a given window instead of the current one.
873 */
874 int
875win_linetabsize(wp, p, len)
876 win_T *wp;
877 char_u *p;
878 colnr_T len;
879{
880 colnr_T col = 0;
881 char_u *s;
882
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +0000883 for (s = p; *s != NUL && (len == MAXCOL || s < p + len); mb_ptr_adv(s))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000884 col += win_lbr_chartabsize(wp, s, col, NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000885 return (int)col;
886}
887
888/*
Bram Moolenaar81695252004-12-29 20:58:21 +0000889 * Return TRUE if 'c' is a normal identifier character:
890 * Letters and characters from the 'isident' option.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000891 */
892 int
893vim_isIDc(c)
894 int c;
895{
896 return (c > 0 && c < 0x100 && (chartab[c] & CT_ID_CHAR));
897}
898
899/*
900 * return TRUE if 'c' is a keyword character: Letters and characters from
901 * 'iskeyword' option for current buffer.
902 * For multi-byte characters mb_get_class() is used (builtin rules).
903 */
904 int
905vim_iswordc(c)
906 int c;
907{
Bram Moolenaar9d182dd2013-01-23 15:53:15 +0100908 return vim_iswordc_buf(c, curbuf);
909}
910
911 int
912vim_iswordc_buf(c, buf)
913 int c;
914 buf_T *buf;
915{
Bram Moolenaar071d4272004-06-13 20:20:40 +0000916#ifdef FEAT_MBYTE
917 if (c >= 0x100)
918 {
919 if (enc_dbcs != 0)
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000920 return dbcs_class((unsigned)c >> 8, (unsigned)(c & 0xff)) >= 2;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000921 if (enc_utf8)
922 return utf_class(c) >= 2;
923 }
924#endif
Bram Moolenaar9d182dd2013-01-23 15:53:15 +0100925 return (c > 0 && c < 0x100 && GET_CHARTAB(buf, c) != 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000926}
927
928/*
929 * Just like vim_iswordc() but uses a pointer to the (multi-byte) character.
930 */
931 int
932vim_iswordp(p)
933 char_u *p;
934{
935#ifdef FEAT_MBYTE
936 if (has_mbyte && MB_BYTE2LEN(*p) > 1)
937 return mb_get_class(p) >= 2;
938#endif
939 return GET_CHARTAB(curbuf, *p) != 0;
940}
941
942#if defined(FEAT_SYN_HL) || defined(PROTO)
943 int
Bram Moolenaar9d182dd2013-01-23 15:53:15 +0100944vim_iswordp_buf(p, buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000945 char_u *p;
946 buf_T *buf;
947{
948# ifdef FEAT_MBYTE
949 if (has_mbyte && MB_BYTE2LEN(*p) > 1)
950 return mb_get_class(p) >= 2;
951# endif
952 return (GET_CHARTAB(buf, *p) != 0);
953}
Bram Moolenaarc4956c82006-03-12 21:58:43 +0000954#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000955
956/*
957 * return TRUE if 'c' is a valid file-name character
958 * Assume characters above 0x100 are valid (multi-byte).
959 */
960 int
961vim_isfilec(c)
962 int c;
963{
964 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_FNAME_CHAR)));
965}
966
967/*
Bram Moolenaardd87969c2007-08-21 13:07:12 +0000968 * return TRUE if 'c' is a valid file-name character or a wildcard character
969 * Assume characters above 0x100 are valid (multi-byte).
970 * Explicitly interpret ']' as a wildcard character as mch_has_wildcard("]")
971 * returns false.
972 */
973 int
974vim_isfilec_or_wc(c)
975 int c;
976{
977 char_u buf[2];
978
979 buf[0] = (char_u)c;
980 buf[1] = NUL;
981 return vim_isfilec(c) || c == ']' || mch_has_wildcard(buf);
982}
983
984/*
Bram Moolenaar071d4272004-06-13 20:20:40 +0000985 * return TRUE if 'c' is a printable character
986 * Assume characters above 0x100 are printable (multi-byte), except for
987 * Unicode.
988 */
989 int
990vim_isprintc(c)
991 int c;
992{
993#ifdef FEAT_MBYTE
994 if (enc_utf8 && c >= 0x100)
995 return utf_printable(c);
996#endif
997 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR)));
998}
999
1000/*
1001 * Strict version of vim_isprintc(c), don't return TRUE if "c" is the head
1002 * byte of a double-byte character.
1003 */
1004 int
1005vim_isprintc_strict(c)
1006 int c;
1007{
1008#ifdef FEAT_MBYTE
1009 if (enc_dbcs != 0 && c < 0x100 && MB_BYTE2LEN(c) > 1)
1010 return FALSE;
1011 if (enc_utf8 && c >= 0x100)
1012 return utf_printable(c);
1013#endif
1014 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR)));
1015}
1016
1017/*
1018 * like chartabsize(), but also check for line breaks on the screen
1019 */
1020 int
1021lbr_chartabsize(s, col)
1022 unsigned char *s;
1023 colnr_T col;
1024{
1025#ifdef FEAT_LINEBREAK
1026 if (!curwin->w_p_lbr && *p_sbr == NUL)
1027 {
1028#endif
1029#ifdef FEAT_MBYTE
1030 if (curwin->w_p_wrap)
1031 return win_nolbr_chartabsize(curwin, s, col, NULL);
1032#endif
1033 RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
1034#ifdef FEAT_LINEBREAK
1035 }
1036 return win_lbr_chartabsize(curwin, s, col, NULL);
1037#endif
1038}
1039
1040/*
1041 * Call lbr_chartabsize() and advance the pointer.
1042 */
1043 int
1044lbr_chartabsize_adv(s, col)
1045 char_u **s;
1046 colnr_T col;
1047{
1048 int retval;
1049
1050 retval = lbr_chartabsize(*s, col);
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001051 mb_ptr_adv(*s);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001052 return retval;
1053}
1054
1055/*
1056 * This function is used very often, keep it fast!!!!
1057 *
1058 * If "headp" not NULL, set *headp to the size of what we for 'showbreak'
1059 * string at start of line. Warning: *headp is only set if it's a non-zero
1060 * value, init to 0 before calling.
1061 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001062 int
1063win_lbr_chartabsize(wp, s, col, headp)
1064 win_T *wp;
1065 char_u *s;
1066 colnr_T col;
Bram Moolenaar0c094b92009-05-14 20:20:33 +00001067 int *headp UNUSED;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001068{
1069#ifdef FEAT_LINEBREAK
1070 int c;
1071 int size;
1072 colnr_T col2;
1073 colnr_T colmax;
1074 int added;
1075# ifdef FEAT_MBYTE
1076 int mb_added = 0;
1077# else
1078# define mb_added 0
1079# endif
1080 int numberextra;
1081 char_u *ps;
1082 int tab_corr = (*s == TAB);
Bram Moolenaar402d2fe2005-04-15 21:00:38 +00001083 int n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001084
1085 /*
1086 * No 'linebreak' and 'showbreak': return quickly.
1087 */
1088 if (!wp->w_p_lbr && *p_sbr == NUL)
1089#endif
1090 {
1091#ifdef FEAT_MBYTE
1092 if (wp->w_p_wrap)
1093 return win_nolbr_chartabsize(wp, s, col, headp);
1094#endif
1095 RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col)
1096 }
1097
1098#ifdef FEAT_LINEBREAK
1099 /*
1100 * First get normal size, without 'linebreak'
1101 */
1102 size = win_chartabsize(wp, s, col);
1103 c = *s;
1104
1105 /*
1106 * If 'linebreak' set check at a blank before a non-blank if the line
1107 * needs a break here
1108 */
1109 if (wp->w_p_lbr
1110 && vim_isbreak(c)
1111 && !vim_isbreak(s[1])
1112 && !wp->w_p_list
1113 && wp->w_p_wrap
1114# ifdef FEAT_VERTSPLIT
1115 && wp->w_width != 0
1116# endif
1117 )
1118 {
1119 /*
1120 * Count all characters from first non-blank after a blank up to next
1121 * non-blank after a blank.
1122 */
1123 numberextra = win_col_off(wp);
1124 col2 = col;
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001125 colmax = (colnr_T)(W_WIDTH(wp) - numberextra);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001126 if (col >= colmax)
Bram Moolenaar402d2fe2005-04-15 21:00:38 +00001127 {
1128 n = colmax + win_col_off2(wp);
1129 if (n > 0)
1130 colmax += (((col - colmax) / n) + 1) * n;
1131 }
1132
Bram Moolenaar071d4272004-06-13 20:20:40 +00001133 for (;;)
1134 {
1135 ps = s;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001136 mb_ptr_adv(s);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001137 c = *s;
1138 if (!(c != NUL
1139 && (vim_isbreak(c)
1140 || (!vim_isbreak(c)
1141 && (col2 == col || !vim_isbreak(*ps))))))
1142 break;
1143
1144 col2 += win_chartabsize(wp, s, col2);
1145 if (col2 >= colmax) /* doesn't fit */
1146 {
1147 size = colmax - col;
1148 tab_corr = FALSE;
1149 break;
1150 }
1151 }
1152 }
1153# ifdef FEAT_MBYTE
1154 else if (has_mbyte && size == 2 && MB_BYTE2LEN(*s) > 1
1155 && wp->w_p_wrap && in_win_border(wp, col))
1156 {
1157 ++size; /* Count the ">" in the last column. */
1158 mb_added = 1;
1159 }
1160# endif
1161
1162 /*
1163 * May have to add something for 'showbreak' string at start of line
1164 * Set *headp to the size of what we add.
1165 */
1166 added = 0;
1167 if (*p_sbr != NUL && wp->w_p_wrap && col != 0)
1168 {
1169 numberextra = win_col_off(wp);
1170 col += numberextra + mb_added;
1171 if (col >= (colnr_T)W_WIDTH(wp))
1172 {
1173 col -= W_WIDTH(wp);
1174 numberextra = W_WIDTH(wp) - (numberextra - win_col_off2(wp));
1175 if (numberextra > 0)
1176 col = col % numberextra;
1177 }
1178 if (col == 0 || col + size > (colnr_T)W_WIDTH(wp))
1179 {
1180 added = vim_strsize(p_sbr);
1181 if (tab_corr)
1182 size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
1183 else
1184 size += added;
1185 if (col != 0)
1186 added = 0;
1187 }
1188 }
1189 if (headp != NULL)
1190 *headp = added + mb_added;
1191 return size;
1192#endif
1193}
1194
1195#if defined(FEAT_MBYTE) || defined(PROTO)
1196/*
1197 * Like win_lbr_chartabsize(), except that we know 'linebreak' is off and
1198 * 'wrap' is on. This means we need to check for a double-byte character that
1199 * doesn't fit at the end of the screen line.
1200 */
1201 static int
1202win_nolbr_chartabsize(wp, s, col, headp)
1203 win_T *wp;
1204 char_u *s;
1205 colnr_T col;
1206 int *headp;
1207{
1208 int n;
1209
1210 if (*s == TAB && (!wp->w_p_list || lcs_tab1))
1211 {
1212 n = wp->w_buffer->b_p_ts;
1213 return (int)(n - (col % n));
1214 }
1215 n = ptr2cells(s);
1216 /* Add one cell for a double-width character in the last column of the
1217 * window, displayed with a ">". */
1218 if (n == 2 && MB_BYTE2LEN(*s) > 1 && in_win_border(wp, col))
1219 {
1220 if (headp != NULL)
1221 *headp = 1;
1222 return 3;
1223 }
1224 return n;
1225}
1226
1227/*
1228 * Return TRUE if virtual column "vcol" is in the rightmost column of window
1229 * "wp".
1230 */
1231 int
1232in_win_border(wp, vcol)
1233 win_T *wp;
1234 colnr_T vcol;
1235{
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001236 int width1; /* width of first line (after line number) */
1237 int width2; /* width of further lines */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001238
1239#ifdef FEAT_VERTSPLIT
1240 if (wp->w_width == 0) /* there is no border */
1241 return FALSE;
1242#endif
1243 width1 = W_WIDTH(wp) - win_col_off(wp);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001244 if ((int)vcol < width1 - 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001245 return FALSE;
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001246 if ((int)vcol == width1 - 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001247 return TRUE;
1248 width2 = width1 + win_col_off2(wp);
Bram Moolenaar8701cd62009-10-07 14:20:30 +00001249 if (width2 <= 0)
1250 return FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001251 return ((vcol - width1) % width2 == width2 - 1);
1252}
1253#endif /* FEAT_MBYTE */
1254
1255/*
1256 * Get virtual column number of pos.
1257 * start: on the first position of this character (TAB, ctrl)
1258 * cursor: where the cursor is on this character (first char, except for TAB)
1259 * end: on the last position of this character (TAB, ctrl)
1260 *
1261 * This is used very often, keep it fast!
1262 */
1263 void
1264getvcol(wp, pos, start, cursor, end)
1265 win_T *wp;
1266 pos_T *pos;
1267 colnr_T *start;
1268 colnr_T *cursor;
1269 colnr_T *end;
1270{
1271 colnr_T vcol;
1272 char_u *ptr; /* points to current char */
1273 char_u *posptr; /* points to char at pos->col */
1274 int incr;
1275 int head;
1276 int ts = wp->w_buffer->b_p_ts;
1277 int c;
1278
1279 vcol = 0;
1280 ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
Bram Moolenaar37d619f2010-03-10 14:46:26 +01001281 if (pos->col == MAXCOL)
1282 posptr = NULL; /* continue until the NUL */
1283 else
1284 posptr = ptr + pos->col;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001285
1286 /*
1287 * This function is used very often, do some speed optimizations.
1288 * When 'list', 'linebreak' and 'showbreak' are not set use a simple loop.
1289 * Also use this when 'list' is set but tabs take their normal size.
1290 */
1291 if ((!wp->w_p_list || lcs_tab1 != NUL)
1292#ifdef FEAT_LINEBREAK
1293 && !wp->w_p_lbr && *p_sbr == NUL
1294#endif
1295 )
1296 {
1297#ifndef FEAT_MBYTE
1298 head = 0;
1299#endif
1300 for (;;)
1301 {
1302#ifdef FEAT_MBYTE
1303 head = 0;
1304#endif
1305 c = *ptr;
1306 /* make sure we don't go past the end of the line */
1307 if (c == NUL)
1308 {
1309 incr = 1; /* NUL at end of line only takes one column */
1310 break;
1311 }
1312 /* A tab gets expanded, depending on the current column */
1313 if (c == TAB)
1314 incr = ts - (vcol % ts);
1315 else
1316 {
1317#ifdef FEAT_MBYTE
1318 if (has_mbyte)
1319 {
1320 /* For utf-8, if the byte is >= 0x80, need to look at
1321 * further bytes to find the cell width. */
1322 if (enc_utf8 && c >= 0x80)
1323 incr = utf_ptr2cells(ptr);
1324 else
1325 incr = CHARSIZE(c);
1326
1327 /* If a double-cell char doesn't fit at the end of a line
1328 * it wraps to the next line, it's like this char is three
1329 * cells wide. */
Bram Moolenaar9c33a7c2008-02-20 13:59:32 +00001330 if (incr == 2 && wp->w_p_wrap && MB_BYTE2LEN(*ptr) > 1
1331 && in_win_border(wp, vcol))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001332 {
1333 ++incr;
1334 head = 1;
1335 }
1336 }
1337 else
1338#endif
1339 incr = CHARSIZE(c);
1340 }
1341
Bram Moolenaar37d619f2010-03-10 14:46:26 +01001342 if (posptr != NULL && ptr >= posptr) /* character at pos->col */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001343 break;
1344
1345 vcol += incr;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001346 mb_ptr_adv(ptr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001347 }
1348 }
1349 else
1350 {
1351 for (;;)
1352 {
1353 /* A tab gets expanded, depending on the current column */
1354 head = 0;
1355 incr = win_lbr_chartabsize(wp, ptr, vcol, &head);
1356 /* make sure we don't go past the end of the line */
1357 if (*ptr == NUL)
1358 {
1359 incr = 1; /* NUL at end of line only takes one column */
1360 break;
1361 }
1362
Bram Moolenaar37d619f2010-03-10 14:46:26 +01001363 if (posptr != NULL && ptr >= posptr) /* character at pos->col */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001364 break;
1365
1366 vcol += incr;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001367 mb_ptr_adv(ptr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001368 }
1369 }
1370 if (start != NULL)
1371 *start = vcol + head;
1372 if (end != NULL)
1373 *end = vcol + incr - 1;
1374 if (cursor != NULL)
1375 {
1376 if (*ptr == TAB
1377 && (State & NORMAL)
1378 && !wp->w_p_list
1379 && !virtual_active()
1380#ifdef FEAT_VISUAL
1381 && !(VIsual_active
1382 && (*p_sel == 'e' || ltoreq(*pos, VIsual)))
1383#endif
1384 )
1385 *cursor = vcol + incr - 1; /* cursor at end */
1386 else
1387 *cursor = vcol + head; /* cursor at start */
1388 }
1389}
1390
1391/*
1392 * Get virtual cursor column in the current window, pretending 'list' is off.
1393 */
1394 colnr_T
1395getvcol_nolist(posp)
1396 pos_T *posp;
1397{
1398 int list_save = curwin->w_p_list;
1399 colnr_T vcol;
1400
1401 curwin->w_p_list = FALSE;
1402 getvcol(curwin, posp, NULL, &vcol, NULL);
1403 curwin->w_p_list = list_save;
1404 return vcol;
1405}
1406
1407#if defined(FEAT_VIRTUALEDIT) || defined(PROTO)
1408/*
1409 * Get virtual column in virtual mode.
1410 */
1411 void
1412getvvcol(wp, pos, start, cursor, end)
1413 win_T *wp;
1414 pos_T *pos;
1415 colnr_T *start;
1416 colnr_T *cursor;
1417 colnr_T *end;
1418{
1419 colnr_T col;
1420 colnr_T coladd;
1421 colnr_T endadd;
1422# ifdef FEAT_MBYTE
1423 char_u *ptr;
1424# endif
1425
1426 if (virtual_active())
1427 {
1428 /* For virtual mode, only want one value */
1429 getvcol(wp, pos, &col, NULL, NULL);
1430
1431 coladd = pos->coladd;
1432 endadd = 0;
1433# ifdef FEAT_MBYTE
1434 /* Cannot put the cursor on part of a wide character. */
1435 ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001436 if (pos->col < (colnr_T)STRLEN(ptr))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001437 {
1438 int c = (*mb_ptr2char)(ptr + pos->col);
1439
1440 if (c != TAB && vim_isprintc(c))
1441 {
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001442 endadd = (colnr_T)(char2cells(c) - 1);
Bram Moolenaara5792f52005-11-23 21:25:05 +00001443 if (coladd > endadd) /* past end of line */
1444 endadd = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001445 else
1446 coladd = 0;
1447 }
1448 }
1449# endif
1450 col += coladd;
1451 if (start != NULL)
1452 *start = col;
1453 if (cursor != NULL)
1454 *cursor = col;
1455 if (end != NULL)
1456 *end = col + endadd;
1457 }
1458 else
1459 getvcol(wp, pos, start, cursor, end);
1460}
1461#endif
1462
1463#if defined(FEAT_VISUAL) || defined(PROTO)
1464/*
1465 * Get the leftmost and rightmost virtual column of pos1 and pos2.
1466 * Used for Visual block mode.
1467 */
1468 void
1469getvcols(wp, pos1, pos2, left, right)
1470 win_T *wp;
1471 pos_T *pos1, *pos2;
1472 colnr_T *left, *right;
1473{
1474 colnr_T from1, from2, to1, to2;
1475
1476 if (ltp(pos1, pos2))
1477 {
1478 getvvcol(wp, pos1, &from1, NULL, &to1);
1479 getvvcol(wp, pos2, &from2, NULL, &to2);
1480 }
1481 else
1482 {
1483 getvvcol(wp, pos2, &from1, NULL, &to1);
1484 getvvcol(wp, pos1, &from2, NULL, &to2);
1485 }
1486 if (from2 < from1)
1487 *left = from2;
1488 else
1489 *left = from1;
1490 if (to2 > to1)
1491 {
1492 if (*p_sel == 'e' && from2 - 1 >= to1)
1493 *right = from2 - 1;
1494 else
1495 *right = to2;
1496 }
1497 else
1498 *right = to1;
1499}
1500#endif
1501
1502/*
1503 * skipwhite: skip over ' ' and '\t'.
1504 */
1505 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001506skipwhite(q)
1507 char_u *q;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001508{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001509 char_u *p = q;
1510
Bram Moolenaar071d4272004-06-13 20:20:40 +00001511 while (vim_iswhite(*p)) /* skip to next non-white */
1512 ++p;
1513 return p;
1514}
1515
1516/*
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001517 * skip over digits
Bram Moolenaar071d4272004-06-13 20:20:40 +00001518 */
1519 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001520skipdigits(q)
1521 char_u *q;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001522{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001523 char_u *p = q;
1524
Bram Moolenaar071d4272004-06-13 20:20:40 +00001525 while (VIM_ISDIGIT(*p)) /* skip to next non-digit */
1526 ++p;
1527 return p;
1528}
1529
Bram Moolenaarc4956c82006-03-12 21:58:43 +00001530#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) || defined(PROTO)
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001531/*
1532 * skip over digits and hex characters
1533 */
1534 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001535skiphex(q)
1536 char_u *q;
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001537{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001538 char_u *p = q;
1539
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001540 while (vim_isxdigit(*p)) /* skip to next non-digit */
1541 ++p;
1542 return p;
1543}
1544#endif
1545
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001546#if defined(FEAT_EX_EXTRA) || defined(PROTO)
1547/*
1548 * skip to digit (or NUL after the string)
1549 */
1550 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001551skiptodigit(q)
1552 char_u *q;
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001553{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001554 char_u *p = q;
1555
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001556 while (*p != NUL && !VIM_ISDIGIT(*p)) /* skip to next digit */
1557 ++p;
1558 return p;
1559}
1560
1561/*
1562 * skip to hex character (or NUL after the string)
1563 */
1564 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001565skiptohex(q)
1566 char_u *q;
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001567{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001568 char_u *p = q;
1569
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001570 while (*p != NUL && !vim_isxdigit(*p)) /* skip to next digit */
1571 ++p;
1572 return p;
1573}
1574#endif
1575
Bram Moolenaar071d4272004-06-13 20:20:40 +00001576/*
1577 * Variant of isdigit() that can handle characters > 0x100.
1578 * We don't use isdigit() here, because on some systems it also considers
1579 * superscript 1 to be a digit.
1580 * Use the VIM_ISDIGIT() macro for simple arguments.
1581 */
1582 int
1583vim_isdigit(c)
1584 int c;
1585{
1586 return (c >= '0' && c <= '9');
1587}
1588
1589/*
1590 * Variant of isxdigit() that can handle characters > 0x100.
1591 * We don't use isxdigit() here, because on some systems it also considers
1592 * superscript 1 to be a digit.
1593 */
1594 int
1595vim_isxdigit(c)
1596 int c;
1597{
1598 return (c >= '0' && c <= '9')
1599 || (c >= 'a' && c <= 'f')
1600 || (c >= 'A' && c <= 'F');
1601}
1602
Bram Moolenaar78622822005-08-23 21:00:13 +00001603#if defined(FEAT_MBYTE) || defined(PROTO)
1604/*
1605 * Vim's own character class functions. These exist because many library
1606 * islower()/toupper() etc. do not work properly: they crash when used with
1607 * invalid values or can't handle latin1 when the locale is C.
1608 * Speed is most important here.
1609 */
1610#define LATIN1LOWER 'l'
1611#define LATIN1UPPER 'U'
1612
Bram Moolenaar6e7c7f32005-08-24 22:16:11 +00001613static char_u latin1flags[257] = " UUUUUUUUUUUUUUUUUUUUUUUUUU llllllllllllllllllllllllll UUUUUUUUUUUUUUUUUUUUUUU UUUUUUUllllllllllllllllllllllll llllllll";
Bram Moolenaar936347b2012-05-25 11:56:22 +02001614static 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";
1615static 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 +00001616
1617 int
1618vim_islower(c)
1619 int c;
1620{
1621 if (c <= '@')
1622 return FALSE;
1623 if (c >= 0x80)
1624 {
1625 if (enc_utf8)
1626 return utf_islower(c);
1627 if (c >= 0x100)
1628 {
1629#ifdef HAVE_ISWLOWER
1630 if (has_mbyte)
1631 return iswlower(c);
1632#endif
1633 /* islower() can't handle these chars and may crash */
1634 return FALSE;
1635 }
1636 if (enc_latin1like)
1637 return (latin1flags[c] & LATIN1LOWER) == LATIN1LOWER;
1638 }
1639 return islower(c);
1640}
1641
1642 int
1643vim_isupper(c)
1644 int c;
1645{
1646 if (c <= '@')
1647 return FALSE;
1648 if (c >= 0x80)
1649 {
1650 if (enc_utf8)
1651 return utf_isupper(c);
1652 if (c >= 0x100)
1653 {
1654#ifdef HAVE_ISWUPPER
1655 if (has_mbyte)
1656 return iswupper(c);
1657#endif
1658 /* islower() can't handle these chars and may crash */
1659 return FALSE;
1660 }
1661 if (enc_latin1like)
1662 return (latin1flags[c] & LATIN1UPPER) == LATIN1UPPER;
1663 }
1664 return isupper(c);
1665}
1666
1667 int
1668vim_toupper(c)
1669 int c;
1670{
1671 if (c <= '@')
1672 return c;
1673 if (c >= 0x80)
1674 {
1675 if (enc_utf8)
1676 return utf_toupper(c);
1677 if (c >= 0x100)
1678 {
1679#ifdef HAVE_TOWUPPER
1680 if (has_mbyte)
1681 return towupper(c);
1682#endif
1683 /* toupper() can't handle these chars and may crash */
1684 return c;
1685 }
1686 if (enc_latin1like)
1687 return latin1upper[c];
1688 }
1689 return TOUPPER_LOC(c);
1690}
1691
1692 int
1693vim_tolower(c)
1694 int c;
1695{
1696 if (c <= '@')
1697 return c;
1698 if (c >= 0x80)
1699 {
1700 if (enc_utf8)
1701 return utf_tolower(c);
1702 if (c >= 0x100)
1703 {
1704#ifdef HAVE_TOWLOWER
1705 if (has_mbyte)
1706 return towlower(c);
1707#endif
1708 /* tolower() can't handle these chars and may crash */
1709 return c;
1710 }
1711 if (enc_latin1like)
1712 return latin1lower[c];
1713 }
1714 return TOLOWER_LOC(c);
1715}
1716#endif
1717
Bram Moolenaar071d4272004-06-13 20:20:40 +00001718/*
1719 * skiptowhite: skip over text until ' ' or '\t' or NUL.
1720 */
1721 char_u *
1722skiptowhite(p)
1723 char_u *p;
1724{
1725 while (*p != ' ' && *p != '\t' && *p != NUL)
1726 ++p;
1727 return p;
1728}
1729
1730#if defined(FEAT_LISTCMDS) || defined(FEAT_SIGNS) || defined(FEAT_SNIFF) \
1731 || defined(PROTO)
1732/*
1733 * skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
1734 */
1735 char_u *
1736skiptowhite_esc(p)
1737 char_u *p;
1738{
1739 while (*p != ' ' && *p != '\t' && *p != NUL)
1740 {
1741 if ((*p == '\\' || *p == Ctrl_V) && *(p + 1) != NUL)
1742 ++p;
1743 ++p;
1744 }
1745 return p;
1746}
1747#endif
1748
1749/*
1750 * Getdigits: Get a number from a string and skip over it.
1751 * Note: the argument is a pointer to a char_u pointer!
1752 */
1753 long
1754getdigits(pp)
1755 char_u **pp;
1756{
1757 char_u *p;
1758 long retval;
1759
1760 p = *pp;
1761 retval = atol((char *)p);
1762 if (*p == '-') /* skip negative sign */
1763 ++p;
1764 p = skipdigits(p); /* skip to next non-digit */
1765 *pp = p;
1766 return retval;
1767}
1768
1769/*
1770 * Return TRUE if "lbuf" is empty or only contains blanks.
1771 */
1772 int
1773vim_isblankline(lbuf)
1774 char_u *lbuf;
1775{
1776 char_u *p;
1777
1778 p = skipwhite(lbuf);
1779 return (*p == NUL || *p == '\r' || *p == '\n');
1780}
1781
1782/*
1783 * Convert a string into a long and/or unsigned long, taking care of
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00001784 * hexadecimal and octal numbers. Accepts a '-' sign.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001785 * If "hexp" is not NULL, returns a flag to indicate the type of the number:
1786 * 0 decimal
1787 * '0' octal
1788 * 'X' hex
1789 * 'x' hex
1790 * If "len" is not NULL, the length of the number in characters is returned.
1791 * If "nptr" is not NULL, the signed result is returned in it.
1792 * If "unptr" is not NULL, the unsigned result is returned in it.
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001793 * If "dooct" is non-zero recognize octal numbers, when > 1 always assume
1794 * octal number.
Bram Moolenaar97b2ad32006-03-18 21:40:56 +00001795 * If "dohex" is non-zero recognize hex numbers, when > 1 always assume
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001796 * hex number.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001797 */
1798 void
1799vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr)
1800 char_u *start;
1801 int *hexp; /* return: type of number 0 = decimal, 'x'
1802 or 'X' is hex, '0' = octal */
1803 int *len; /* return: detected length of number */
1804 int dooct; /* recognize octal number */
1805 int dohex; /* recognize hex number */
1806 long *nptr; /* return: signed result */
1807 unsigned long *unptr; /* return: unsigned result */
1808{
1809 char_u *ptr = start;
1810 int hex = 0; /* default is decimal */
1811 int negative = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001812 unsigned long un = 0;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001813 int n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001814
1815 if (ptr[0] == '-')
1816 {
1817 negative = TRUE;
1818 ++ptr;
1819 }
1820
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001821 /* Recognize hex and octal. */
1822 if (ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001823 {
1824 hex = ptr[1];
1825 if (dohex && (hex == 'X' || hex == 'x') && vim_isxdigit(ptr[2]))
1826 ptr += 2; /* hexadecimal */
1827 else
1828 {
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001829 hex = 0; /* default is decimal */
1830 if (dooct)
1831 {
1832 /* Don't interpret "0", "08" or "0129" as octal. */
1833 for (n = 1; VIM_ISDIGIT(ptr[n]); ++n)
1834 {
1835 if (ptr[n] > '7')
1836 {
1837 hex = 0; /* can't be octal */
1838 break;
1839 }
Bram Moolenaar06af6022012-01-26 13:40:08 +01001840 if (ptr[n] >= '0')
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001841 hex = '0'; /* assume octal */
1842 }
1843 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001844 }
1845 }
1846
1847 /*
1848 * Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
1849 */
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001850 if (hex == '0' || dooct > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001851 {
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001852 /* octal */
1853 while ('0' <= *ptr && *ptr <= '7')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001854 {
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001855 un = 8 * un + (unsigned long)(*ptr - '0');
1856 ++ptr;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001857 }
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001858 }
1859 else if (hex != 0 || dohex > 1)
1860 {
1861 /* hex */
1862 while (vim_isxdigit(*ptr))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001863 {
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001864 un = 16 * un + (unsigned long)hex2nr(*ptr);
1865 ++ptr;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001866 }
1867 }
1868 else
1869 {
1870 /* decimal */
1871 while (VIM_ISDIGIT(*ptr))
1872 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001873 un = 10 * un + (unsigned long)(*ptr - '0');
1874 ++ptr;
1875 }
1876 }
1877
Bram Moolenaar071d4272004-06-13 20:20:40 +00001878 if (hexp != NULL)
1879 *hexp = hex;
1880 if (len != NULL)
1881 *len = (int)(ptr - start);
1882 if (nptr != NULL)
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00001883 {
1884 if (negative) /* account for leading '-' for decimal numbers */
1885 *nptr = -(long)un;
1886 else
1887 *nptr = (long)un;
1888 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001889 if (unptr != NULL)
1890 *unptr = un;
1891}
1892
1893/*
1894 * Return the value of a single hex character.
1895 * Only valid when the argument is '0' - '9', 'A' - 'F' or 'a' - 'f'.
1896 */
1897 int
1898hex2nr(c)
1899 int c;
1900{
1901 if (c >= 'a' && c <= 'f')
1902 return c - 'a' + 10;
1903 if (c >= 'A' && c <= 'F')
1904 return c - 'A' + 10;
1905 return c - '0';
1906}
1907
1908#if defined(FEAT_TERMRESPONSE) \
1909 || (defined(FEAT_GUI_GTK) && defined(FEAT_WINDOWS)) || defined(PROTO)
1910/*
1911 * Convert two hex characters to a byte.
1912 * Return -1 if one of the characters is not hex.
1913 */
1914 int
1915hexhex2nr(p)
1916 char_u *p;
1917{
1918 if (!vim_isxdigit(p[0]) || !vim_isxdigit(p[1]))
1919 return -1;
1920 return (hex2nr(p[0]) << 4) + hex2nr(p[1]);
1921}
1922#endif
1923
1924/*
1925 * Return TRUE if "str" starts with a backslash that should be removed.
1926 * For MS-DOS, WIN32 and OS/2 this is only done when the character after the
1927 * backslash is not a normal file name character.
1928 * '$' is a valid file name character, we don't remove the backslash before
1929 * it. This means it is not possible to use an environment variable after a
1930 * backslash. "C:\$VIM\doc" is taken literally, only "$VIM\doc" works.
1931 * Although "\ name" is valid, the backslash in "Program\ files" must be
1932 * removed. Assume a file name doesn't start with a space.
1933 * For multi-byte names, never remove a backslash before a non-ascii
1934 * character, assume that all multi-byte characters are valid file name
1935 * characters.
1936 */
1937 int
1938rem_backslash(str)
1939 char_u *str;
1940{
1941#ifdef BACKSLASH_IN_FILENAME
1942 return (str[0] == '\\'
1943# ifdef FEAT_MBYTE
1944 && str[1] < 0x80
1945# endif
1946 && (str[1] == ' '
1947 || (str[1] != NUL
1948 && str[1] != '*'
1949 && str[1] != '?'
1950 && !vim_isfilec(str[1]))));
1951#else
1952 return (str[0] == '\\' && str[1] != NUL);
1953#endif
1954}
1955
1956/*
1957 * Halve the number of backslashes in a file name argument.
1958 * For MS-DOS we only do this if the character after the backslash
1959 * is not a normal file character.
1960 */
1961 void
1962backslash_halve(p)
1963 char_u *p;
1964{
1965 for ( ; *p; ++p)
1966 if (rem_backslash(p))
Bram Moolenaar446cb832008-06-24 21:56:24 +00001967 STRMOVE(p, p + 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001968}
1969
1970/*
1971 * backslash_halve() plus save the result in allocated memory.
1972 */
1973 char_u *
1974backslash_halve_save(p)
1975 char_u *p;
1976{
1977 char_u *res;
1978
1979 res = vim_strsave(p);
1980 if (res == NULL)
1981 return p;
1982 backslash_halve(res);
1983 return res;
1984}
1985
1986#if (defined(EBCDIC) && defined(FEAT_POSTSCRIPT)) || defined(PROTO)
1987/*
1988 * Table for EBCDIC to ASCII conversion unashamedly taken from xxd.c!
1989 * The first 64 entries have been added to map control characters defined in
1990 * ascii.h
1991 */
1992static char_u ebcdic2ascii_tab[256] =
1993{
1994 0000, 0001, 0002, 0003, 0004, 0011, 0006, 0177,
1995 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
1996 0020, 0021, 0022, 0023, 0024, 0012, 0010, 0027,
1997 0030, 0031, 0032, 0033, 0033, 0035, 0036, 0037,
1998 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
1999 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
2000 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
2001 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
2002 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
2003 0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
2004 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
2005 0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
2006 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
2007 0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
2008 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
2009 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
2010 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
2011 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
2012 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
2013 0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
2014 0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
2015 0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
2016 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
2017 0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
2018 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
2019 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
2020 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
2021 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
2022 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
2023 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
2024 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
2025 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377
2026};
2027
2028/*
2029 * Convert a buffer worth of characters from EBCDIC to ASCII. Only useful if
2030 * wanting 7-bit ASCII characters out the other end.
2031 */
2032 void
2033ebcdic2ascii(buffer, len)
2034 char_u *buffer;
2035 int len;
2036{
2037 int i;
2038
2039 for (i = 0; i < len; i++)
2040 buffer[i] = ebcdic2ascii_tab[buffer[i]];
2041}
2042#endif