blob: 87ad3033329c3135edd2ad7ba65ee1ff51e57dc1 [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
17static int win_nolbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col, int *headp));
18#endif
19
Bram Moolenaar0ab2a882009-05-13 10:51:08 +000020static unsigned nr2hex __ARGS((unsigned c));
Bram Moolenaar071d4272004-06-13 20:20:40 +000021
22static int chartab_initialized = FALSE;
23
24/* b_chartab[] is an array of 32 bytes, each bit representing one of the
25 * characters 0-255. */
26#define SET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> 3] |= (1 << ((c) & 0x7))
27#define RESET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> 3] &= ~(1 << ((c) & 0x7))
28#define GET_CHARTAB(buf, c) ((buf)->b_chartab[(unsigned)(c) >> 3] & (1 << ((c) & 0x7)))
29
30/*
31 * Fill chartab[]. Also fills curbuf->b_chartab[] with flags for keyword
32 * characters for current buffer.
33 *
34 * Depends on the option settings 'iskeyword', 'isident', 'isfname',
35 * 'isprint' and 'encoding'.
36 *
37 * The index in chartab[] depends on 'encoding':
38 * - For non-multi-byte index with the byte (same as the character).
39 * - For DBCS index with the first byte.
40 * - For UTF-8 index with the character (when first byte is up to 0x80 it is
41 * the same as the character, if the first byte is 0x80 and above it depends
42 * on further bytes).
43 *
44 * The contents of chartab[]:
45 * - The lower two bits, masked by CT_CELL_MASK, give the number of display
46 * cells the character occupies (1 or 2). Not valid for UTF-8 above 0x80.
47 * - CT_PRINT_CHAR bit is set when the character is printable (no need to
48 * translate the character before displaying it). Note that only DBCS
49 * characters can have 2 display cells and still be printable.
50 * - CT_FNAME_CHAR bit is set when the character can be in a file name.
51 * - CT_ID_CHAR bit is set when the character can be in an identifier.
52 *
53 * Return FAIL if 'iskeyword', 'isident', 'isfname' or 'isprint' option has an
54 * error, OK otherwise.
55 */
56 int
57init_chartab()
58{
59 return buf_init_chartab(curbuf, TRUE);
60}
61
62 int
63buf_init_chartab(buf, global)
64 buf_T *buf;
65 int global; /* FALSE: only set buf->b_chartab[] */
66{
67 int c;
68 int c2;
69 char_u *p;
70 int i;
71 int tilde;
72 int do_isalpha;
73
74 if (global)
75 {
76 /*
77 * Set the default size for printable characters:
78 * From <Space> to '~' is 1 (printable), others are 2 (not printable).
79 * This also inits all 'isident' and 'isfname' flags to FALSE.
80 *
81 * EBCDIC: all chars below ' ' are not printable, all others are
82 * printable.
83 */
84 c = 0;
85 while (c < ' ')
86 chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
87#ifdef EBCDIC
88 while (c < 255)
89#else
90 while (c <= '~')
91#endif
92 chartab[c++] = 1 + CT_PRINT_CHAR;
93#ifdef FEAT_FKMAP
94 if (p_altkeymap)
95 {
96 while (c < YE)
97 chartab[c++] = 1 + CT_PRINT_CHAR;
98 }
99#endif
100 while (c < 256)
101 {
102#ifdef FEAT_MBYTE
103 /* UTF-8: bytes 0xa0 - 0xff are printable (latin1) */
104 if (enc_utf8 && c >= 0xa0)
105 chartab[c++] = CT_PRINT_CHAR + 1;
106 /* euc-jp characters starting with 0x8e are single width */
107 else if (enc_dbcs == DBCS_JPNU && c == 0x8e)
108 chartab[c++] = CT_PRINT_CHAR + 1;
109 /* other double-byte chars can be printable AND double-width */
110 else if (enc_dbcs != 0 && MB_BYTE2LEN(c) == 2)
111 chartab[c++] = CT_PRINT_CHAR + 2;
112 else
113#endif
114 /* the rest is unprintable by default */
115 chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
116 }
117
118#ifdef FEAT_MBYTE
119 /* Assume that every multi-byte char is a filename character. */
120 for (c = 1; c < 256; ++c)
121 if ((enc_dbcs != 0 && MB_BYTE2LEN(c) > 1)
122 || (enc_dbcs == DBCS_JPNU && c == 0x8e)
123 || (enc_utf8 && c >= 0xa0))
124 chartab[c] |= CT_FNAME_CHAR;
125#endif
126 }
127
128 /*
129 * Init word char flags all to FALSE
130 */
131 vim_memset(buf->b_chartab, 0, (size_t)32);
132#ifdef FEAT_MBYTE
Bram Moolenaar6bb68362005-03-22 23:03:44 +0000133 if (enc_dbcs != 0)
134 for (c = 0; c < 256; ++c)
135 {
136 /* double-byte characters are probably word characters */
137 if (MB_BYTE2LEN(c) == 2)
138 SET_CHARTAB(buf, c);
139 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000140#endif
141
142#ifdef FEAT_LISP
143 /*
144 * In lisp mode the '-' character is included in keywords.
145 */
146 if (buf->b_p_lisp)
147 SET_CHARTAB(buf, '-');
148#endif
149
150 /* Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
151 * options Each option is a list of characters, character numbers or
152 * ranges, separated by commas, e.g.: "200-210,x,#-178,-"
153 */
154 for (i = global ? 0 : 3; i <= 3; ++i)
155 {
156 if (i == 0)
157 p = p_isi; /* first round: 'isident' */
158 else if (i == 1)
159 p = p_isp; /* second round: 'isprint' */
160 else if (i == 2)
161 p = p_isf; /* third round: 'isfname' */
162 else /* i == 3 */
163 p = buf->b_p_isk; /* fourth round: 'iskeyword' */
164
165 while (*p)
166 {
167 tilde = FALSE;
168 do_isalpha = FALSE;
169 if (*p == '^' && p[1] != NUL)
170 {
171 tilde = TRUE;
172 ++p;
173 }
174 if (VIM_ISDIGIT(*p))
175 c = getdigits(&p);
176 else
Bram Moolenaar183bb3e2009-09-11 12:02:34 +0000177#ifdef FEAT_MBYTE
178 if (has_mbyte)
179 c = mb_ptr2char_adv(&p);
180 else
181#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000182 c = *p++;
183 c2 = -1;
184 if (*p == '-' && p[1] != NUL)
185 {
186 ++p;
187 if (VIM_ISDIGIT(*p))
188 c2 = getdigits(&p);
189 else
Bram Moolenaar2ac5e602009-11-03 15:04:20 +0000190#ifdef FEAT_MBYTE
191 if (has_mbyte)
192 c2 = mb_ptr2char_adv(&p);
193 else
194#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000195 c2 = *p++;
196 }
Bram Moolenaar2ac5e602009-11-03 15:04:20 +0000197 if (c <= 0 || c >= 256 || (c2 < c && c2 != -1) || c2 >= 256
Bram Moolenaar071d4272004-06-13 20:20:40 +0000198 || !(*p == NUL || *p == ','))
199 return FAIL;
200
201 if (c2 == -1) /* not a range */
202 {
203 /*
204 * A single '@' (not "@-@"):
205 * Decide on letters being ID/printable/keyword chars with
206 * standard function isalpha(). This takes care of locale for
207 * single-byte characters).
208 */
209 if (c == '@')
210 {
211 do_isalpha = TRUE;
212 c = 1;
213 c2 = 255;
214 }
215 else
216 c2 = c;
217 }
218 while (c <= c2)
219 {
Bram Moolenaardeefb632007-08-15 18:41:34 +0000220 /* Use the MB_ functions here, because isalpha() doesn't
221 * work properly when 'encoding' is "latin1" and the locale is
222 * "C". */
223 if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000224#ifdef FEAT_FKMAP
225 || (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))
226#endif
227 )
228 {
229 if (i == 0) /* (re)set ID flag */
230 {
231 if (tilde)
232 chartab[c] &= ~CT_ID_CHAR;
233 else
234 chartab[c] |= CT_ID_CHAR;
235 }
236 else if (i == 1) /* (re)set printable */
237 {
238 if ((c < ' '
239#ifndef EBCDIC
240 || c > '~'
241#endif
242#ifdef FEAT_FKMAP
243 || (p_altkeymap
244 && (F_isalpha(c) || F_isdigit(c)))
245#endif
246 )
247#ifdef FEAT_MBYTE
248 /* For double-byte we keep the cell width, so
249 * that we can detect it from the first byte. */
250 && !(enc_dbcs && MB_BYTE2LEN(c) == 2)
251#endif
252 )
253 {
254 if (tilde)
255 {
256 chartab[c] = (chartab[c] & ~CT_CELL_MASK)
257 + ((dy_flags & DY_UHEX) ? 4 : 2);
258 chartab[c] &= ~CT_PRINT_CHAR;
259 }
260 else
261 {
262 chartab[c] = (chartab[c] & ~CT_CELL_MASK) + 1;
263 chartab[c] |= CT_PRINT_CHAR;
264 }
265 }
266 }
267 else if (i == 2) /* (re)set fname flag */
268 {
269 if (tilde)
270 chartab[c] &= ~CT_FNAME_CHAR;
271 else
272 chartab[c] |= CT_FNAME_CHAR;
273 }
274 else /* i == 3 */ /* (re)set keyword flag */
275 {
276 if (tilde)
277 RESET_CHARTAB(buf, c);
278 else
279 SET_CHARTAB(buf, c);
280 }
281 }
282 ++c;
283 }
284 p = skip_to_option_part(p);
285 }
286 }
287 chartab_initialized = TRUE;
288 return OK;
289}
290
291/*
292 * Translate any special characters in buf[bufsize] in-place.
293 * The result is a string with only printable characters, but if there is not
294 * enough room, not all characters will be translated.
295 */
296 void
297trans_characters(buf, bufsize)
298 char_u *buf;
299 int bufsize;
300{
301 int len; /* length of string needing translation */
302 int room; /* room in buffer after string */
303 char_u *trs; /* translated character */
304 int trs_len; /* length of trs[] */
305
306 len = (int)STRLEN(buf);
307 room = bufsize - len;
308 while (*buf != 0)
309 {
310# ifdef FEAT_MBYTE
311 /* Assume a multi-byte character doesn't need translation. */
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000312 if (has_mbyte && (trs_len = (*mb_ptr2len)(buf)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000313 len -= trs_len;
314 else
315# endif
316 {
317 trs = transchar_byte(*buf);
318 trs_len = (int)STRLEN(trs);
319 if (trs_len > 1)
320 {
321 room -= trs_len - 1;
322 if (room <= 0)
323 return;
324 mch_memmove(buf + trs_len, buf + 1, (size_t)len);
325 }
326 mch_memmove(buf, trs, (size_t)trs_len);
327 --len;
328 }
329 buf += trs_len;
330 }
331}
332
Bram Moolenaar7cc36e92007-03-27 10:42:05 +0000333#if defined(FEAT_EVAL) || defined(FEAT_TITLE) || defined(FEAT_INS_EXPAND) \
334 || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000335/*
336 * Translate a string into allocated memory, replacing special chars with
337 * printable chars. Returns NULL when out of memory.
338 */
339 char_u *
340transstr(s)
341 char_u *s;
342{
343 char_u *res;
344 char_u *p;
345#ifdef FEAT_MBYTE
346 int l, len, c;
347 char_u hexbuf[11];
348#endif
349
350#ifdef FEAT_MBYTE
351 if (has_mbyte)
352 {
353 /* Compute the length of the result, taking account of unprintable
354 * multi-byte characters. */
355 len = 0;
356 p = s;
357 while (*p != NUL)
358 {
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000359 if ((l = (*mb_ptr2len)(p)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000360 {
361 c = (*mb_ptr2char)(p);
362 p += l;
363 if (vim_isprintc(c))
364 len += l;
365 else
366 {
367 transchar_hex(hexbuf, c);
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000368 len += (int)STRLEN(hexbuf);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000369 }
370 }
371 else
372 {
373 l = byte2cells(*p++);
374 if (l > 0)
375 len += l;
376 else
377 len += 4; /* illegal byte sequence */
378 }
379 }
380 res = alloc((unsigned)(len + 1));
381 }
382 else
383#endif
384 res = alloc((unsigned)(vim_strsize(s) + 1));
385 if (res != NULL)
386 {
387 *res = NUL;
388 p = s;
389 while (*p != NUL)
390 {
391#ifdef FEAT_MBYTE
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000392 if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000393 {
394 c = (*mb_ptr2char)(p);
395 if (vim_isprintc(c))
396 STRNCAT(res, p, l); /* append printable multi-byte char */
397 else
398 transchar_hex(res + STRLEN(res), c);
399 p += l;
400 }
401 else
402#endif
403 STRCAT(res, transchar_byte(*p++));
404 }
405 }
406 return res;
407}
408#endif
409
410#if defined(FEAT_SYN_HL) || defined(FEAT_INS_EXPAND) || defined(PROTO)
411/*
Bram Moolenaar217ad922005-03-20 22:37:15 +0000412 * Convert the string "str[orglen]" to do ignore-case comparing. Uses the
413 * current locale.
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000414 * When "buf" is NULL returns an allocated string (NULL for out-of-memory).
415 * Otherwise puts the result in "buf[buflen]".
Bram Moolenaar071d4272004-06-13 20:20:40 +0000416 */
417 char_u *
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000418str_foldcase(str, orglen, buf, buflen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000419 char_u *str;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000420 int orglen;
421 char_u *buf;
422 int buflen;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000423{
424 garray_T ga;
425 int i;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000426 int len = orglen;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000427
428#define GA_CHAR(i) ((char_u *)ga.ga_data)[i]
429#define GA_PTR(i) ((char_u *)ga.ga_data + i)
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000430#define STR_CHAR(i) (buf == NULL ? GA_CHAR(i) : buf[i])
431#define STR_PTR(i) (buf == NULL ? GA_PTR(i) : buf + i)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000432
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000433 /* Copy "str" into "buf" or allocated memory, unmodified. */
434 if (buf == NULL)
435 {
436 ga_init2(&ga, 1, 10);
437 if (ga_grow(&ga, len + 1) == FAIL)
438 return NULL;
439 mch_memmove(ga.ga_data, str, (size_t)len);
440 ga.ga_len = len;
441 }
442 else
443 {
444 if (len >= buflen) /* Ugly! */
445 len = buflen - 1;
446 mch_memmove(buf, str, (size_t)len);
447 }
448 if (buf == NULL)
449 GA_CHAR(len) = NUL;
450 else
451 buf[len] = NUL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000452
453 /* Make each character lower case. */
454 i = 0;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000455 while (STR_CHAR(i) != NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000456 {
457#ifdef FEAT_MBYTE
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000458 if (enc_utf8 || (has_mbyte && MB_BYTE2LEN(STR_CHAR(i)) > 1))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000459 {
460 if (enc_utf8)
461 {
Bram Moolenaarb9839212008-06-28 11:03:50 +0000462 int c = utf_ptr2char(STR_PTR(i));
463 int ol = utf_ptr2len(STR_PTR(i));
464 int lc = utf_tolower(c);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000465
Bram Moolenaarb9839212008-06-28 11:03:50 +0000466 /* Only replace the character when it is not an invalid
467 * sequence (ASCII character or more than one byte) and
468 * utf_tolower() doesn't return the original character. */
469 if ((c < 0x80 || ol > 1) && c != lc)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000470 {
Bram Moolenaar071d4272004-06-13 20:20:40 +0000471 int nl = utf_char2len(lc);
472
473 /* If the byte length changes need to shift the following
474 * characters forward or backward. */
475 if (ol != nl)
476 {
477 if (nl > ol)
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000478 {
479 if (buf == NULL ? ga_grow(&ga, nl - ol + 1) == FAIL
480 : len + nl - ol >= buflen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000481 {
482 /* out of memory, keep old char */
483 lc = c;
484 nl = ol;
485 }
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000486 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000487 if (ol != nl)
488 {
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000489 if (buf == NULL)
490 {
Bram Moolenaar446cb832008-06-24 21:56:24 +0000491 STRMOVE(GA_PTR(i) + nl, GA_PTR(i) + ol);
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000492 ga.ga_len += nl - ol;
493 }
494 else
495 {
Bram Moolenaar446cb832008-06-24 21:56:24 +0000496 STRMOVE(buf + i + nl, buf + i + ol);
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000497 len += nl - ol;
498 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000499 }
500 }
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000501 (void)utf_char2bytes(lc, STR_PTR(i));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000502 }
503 }
504 /* skip to next multi-byte char */
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000505 i += (*mb_ptr2len)(STR_PTR(i));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000506 }
507 else
508#endif
509 {
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000510 if (buf == NULL)
511 GA_CHAR(i) = TOLOWER_LOC(GA_CHAR(i));
512 else
513 buf[i] = TOLOWER_LOC(buf[i]);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000514 ++i;
515 }
516 }
517
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000518 if (buf == NULL)
519 return (char_u *)ga.ga_data;
520 return buf;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000521}
522#endif
523
524/*
525 * Catch 22: chartab[] can't be initialized before the options are
526 * initialized, and initializing options may cause transchar() to be called!
527 * When chartab_initialized == FALSE don't use chartab[].
528 * Does NOT work for multi-byte characters, c must be <= 255.
529 * Also doesn't work for the first byte of a multi-byte, "c" must be a
530 * character!
531 */
532static char_u transchar_buf[7];
533
534 char_u *
535transchar(c)
536 int c;
537{
538 int i;
539
540 i = 0;
541 if (IS_SPECIAL(c)) /* special key code, display as ~@ char */
542 {
543 transchar_buf[0] = '~';
544 transchar_buf[1] = '@';
545 i = 2;
546 c = K_SECOND(c);
547 }
548
549 if ((!chartab_initialized && (
550#ifdef EBCDIC
551 (c >= 64 && c < 255)
552#else
553 (c >= ' ' && c <= '~')
554#endif
555#ifdef FEAT_FKMAP
556 || F_ischar(c)
557#endif
558 )) || (c < 256 && vim_isprintc_strict(c)))
559 {
560 /* printable character */
561 transchar_buf[i] = c;
562 transchar_buf[i + 1] = NUL;
563 }
564 else
565 transchar_nonprint(transchar_buf + i, c);
566 return transchar_buf;
567}
568
569#if defined(FEAT_MBYTE) || defined(PROTO)
570/*
571 * Like transchar(), but called with a byte instead of a character. Checks
572 * for an illegal UTF-8 byte.
573 */
574 char_u *
575transchar_byte(c)
576 int c;
577{
578 if (enc_utf8 && c >= 0x80)
579 {
580 transchar_nonprint(transchar_buf, c);
581 return transchar_buf;
582 }
583 return transchar(c);
584}
585#endif
586
587/*
588 * Convert non-printable character to two or more printable characters in
589 * "buf[]". "buf" needs to be able to hold five bytes.
590 * Does NOT work for multi-byte characters, c must be <= 255.
591 */
592 void
593transchar_nonprint(buf, c)
594 char_u *buf;
595 int c;
596{
597 if (c == NL)
598 c = NUL; /* we use newline in place of a NUL */
599 else if (c == CAR && get_fileformat(curbuf) == EOL_MAC)
600 c = NL; /* we use CR in place of NL in this case */
601
602 if (dy_flags & DY_UHEX) /* 'display' has "uhex" */
603 transchar_hex(buf, c);
604
605#ifdef EBCDIC
606 /* For EBCDIC only the characters 0-63 and 255 are not printable */
607 else if (CtrlChar(c) != 0 || c == DEL)
608#else
609 else if (c <= 0x7f) /* 0x00 - 0x1f and 0x7f */
610#endif
611 {
612 buf[0] = '^';
613#ifdef EBCDIC
614 if (c == DEL)
615 buf[1] = '?'; /* DEL displayed as ^? */
616 else
617 buf[1] = CtrlChar(c);
618#else
619 buf[1] = c ^ 0x40; /* DEL displayed as ^? */
620#endif
621
622 buf[2] = NUL;
623 }
624#ifdef FEAT_MBYTE
625 else if (enc_utf8 && c >= 0x80)
626 {
627 transchar_hex(buf, c);
628 }
629#endif
630#ifndef EBCDIC
631 else if (c >= ' ' + 0x80 && c <= '~' + 0x80) /* 0xa0 - 0xfe */
632 {
633 buf[0] = '|';
634 buf[1] = c - 0x80;
635 buf[2] = NUL;
636 }
637#else
638 else if (c < 64)
639 {
640 buf[0] = '~';
641 buf[1] = MetaChar(c);
642 buf[2] = NUL;
643 }
644#endif
645 else /* 0x80 - 0x9f and 0xff */
646 {
647 /*
648 * TODO: EBCDIC I don't know what to do with this chars, so I display
649 * them as '~?' for now
650 */
651 buf[0] = '~';
652#ifdef EBCDIC
653 buf[1] = '?'; /* 0xff displayed as ~? */
654#else
655 buf[1] = (c - 0x80) ^ 0x40; /* 0xff displayed as ~? */
656#endif
657 buf[2] = NUL;
658 }
659}
660
661 void
662transchar_hex(buf, c)
663 char_u *buf;
664 int c;
665{
666 int i = 0;
667
668 buf[0] = '<';
669#ifdef FEAT_MBYTE
670 if (c > 255)
671 {
672 buf[++i] = nr2hex((unsigned)c >> 12);
673 buf[++i] = nr2hex((unsigned)c >> 8);
674 }
675#endif
676 buf[++i] = nr2hex((unsigned)c >> 4);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000677 buf[++i] = nr2hex((unsigned)c);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000678 buf[++i] = '>';
679 buf[++i] = NUL;
680}
681
682/*
683 * Convert the lower 4 bits of byte "c" to its hex character.
684 * Lower case letters are used to avoid the confusion of <F1> being 0xf1 or
685 * function key 1.
686 */
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000687 static unsigned
Bram Moolenaar071d4272004-06-13 20:20:40 +0000688nr2hex(c)
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000689 unsigned c;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000690{
691 if ((c & 0xf) <= 9)
692 return (c & 0xf) + '0';
693 return (c & 0xf) - 10 + 'a';
694}
695
696/*
697 * Return number of display cells occupied by byte "b".
698 * Caller must make sure 0 <= b <= 255.
699 * For multi-byte mode "b" must be the first byte of a character.
700 * A TAB is counted as two cells: "^I".
701 * For UTF-8 mode this will return 0 for bytes >= 0x80, because the number of
702 * cells depends on further bytes.
703 */
704 int
705byte2cells(b)
706 int b;
707{
708#ifdef FEAT_MBYTE
709 if (enc_utf8 && b >= 0x80)
710 return 0;
711#endif
712 return (chartab[b] & CT_CELL_MASK);
713}
714
715/*
716 * Return number of display cells occupied by character "c".
717 * "c" can be a special key (negative number) in which case 3 or 4 is returned.
718 * A TAB is counted as two cells: "^I" or four: "<09>".
719 */
720 int
721char2cells(c)
722 int c;
723{
724 if (IS_SPECIAL(c))
725 return char2cells(K_SECOND(c)) + 2;
726#ifdef FEAT_MBYTE
727 if (c >= 0x80)
728 {
729 /* UTF-8: above 0x80 need to check the value */
730 if (enc_utf8)
731 return utf_char2cells(c);
732 /* DBCS: double-byte means double-width, except for euc-jp with first
733 * byte 0x8e */
734 if (enc_dbcs != 0 && c >= 0x100)
735 {
736 if (enc_dbcs == DBCS_JPNU && ((unsigned)c >> 8) == 0x8e)
737 return 1;
738 return 2;
739 }
740 }
741#endif
742 return (chartab[c & 0xff] & CT_CELL_MASK);
743}
744
745/*
746 * Return number of display cells occupied by character at "*p".
747 * A TAB is counted as two cells: "^I" or four: "<09>".
748 */
749 int
750ptr2cells(p)
751 char_u *p;
752{
753#ifdef FEAT_MBYTE
754 /* For UTF-8 we need to look at more bytes if the first byte is >= 0x80. */
755 if (enc_utf8 && *p >= 0x80)
756 return utf_ptr2cells(p);
757 /* For DBCS we can tell the cell count from the first byte. */
758#endif
759 return (chartab[*p] & CT_CELL_MASK);
760}
761
762/*
763 * Return the number of characters string "s" will take on the screen,
764 * counting TABs as two characters: "^I".
765 */
766 int
767vim_strsize(s)
768 char_u *s;
769{
770 return vim_strnsize(s, (int)MAXCOL);
771}
772
773/*
774 * Return the number of characters string "s[len]" will take on the screen,
775 * counting TABs as two characters: "^I".
776 */
777 int
778vim_strnsize(s, len)
779 char_u *s;
780 int len;
781{
782 int size = 0;
783
784 while (*s != NUL && --len >= 0)
785 {
786#ifdef FEAT_MBYTE
787 if (has_mbyte)
788 {
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000789 int l = (*mb_ptr2len)(s);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000790
791 size += ptr2cells(s);
792 s += l;
793 len -= l - 1;
794 }
795 else
796#endif
797 size += byte2cells(*s++);
798 }
799 return size;
800}
801
802/*
803 * Return the number of characters 'c' will take on the screen, taking
804 * into account the size of a tab.
805 * Use a define to make it fast, this is used very often!!!
806 * Also see getvcol() below.
807 */
808
809#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
810 if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \
811 { \
812 int ts; \
813 ts = (buf)->b_p_ts; \
814 return (int)(ts - (col % ts)); \
815 } \
816 else \
817 return ptr2cells(p);
818
819#if defined(FEAT_VREPLACE) || defined(FEAT_EX_EXTRA) || defined(FEAT_GUI) \
820 || defined(FEAT_VIRTUALEDIT) || defined(PROTO)
821 int
822chartabsize(p, col)
823 char_u *p;
824 colnr_T col;
825{
826 RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col)
827}
828#endif
829
830#ifdef FEAT_LINEBREAK
831 static int
832win_chartabsize(wp, p, col)
833 win_T *wp;
834 char_u *p;
835 colnr_T col;
836{
837 RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col)
838}
839#endif
840
841/*
Bram Moolenaardc536092010-07-18 15:45:49 +0200842 * Return the number of characters the string 's' will take on the screen,
843 * taking into account the size of a tab.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000844 */
845 int
846linetabsize(s)
847 char_u *s;
848{
Bram Moolenaardc536092010-07-18 15:45:49 +0200849 return linetabsize_col(0, s);
850}
851
852/*
853 * Like linetabsize(), but starting at column "startcol".
854 */
855 int
856linetabsize_col(startcol, s)
857 int startcol;
858 char_u *s;
859{
860 colnr_T col = startcol;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000861
862 while (*s != NUL)
863 col += lbr_chartabsize_adv(&s, col);
864 return (int)col;
865}
866
867/*
868 * Like linetabsize(), but for a given window instead of the current one.
869 */
870 int
871win_linetabsize(wp, p, len)
872 win_T *wp;
873 char_u *p;
874 colnr_T len;
875{
876 colnr_T col = 0;
877 char_u *s;
878
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +0000879 for (s = p; *s != NUL && (len == MAXCOL || s < p + len); mb_ptr_adv(s))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000880 col += win_lbr_chartabsize(wp, s, col, NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000881 return (int)col;
882}
883
884/*
Bram Moolenaar81695252004-12-29 20:58:21 +0000885 * Return TRUE if 'c' is a normal identifier character:
886 * Letters and characters from the 'isident' option.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000887 */
888 int
889vim_isIDc(c)
890 int c;
891{
892 return (c > 0 && c < 0x100 && (chartab[c] & CT_ID_CHAR));
893}
894
895/*
896 * return TRUE if 'c' is a keyword character: Letters and characters from
897 * 'iskeyword' option for current buffer.
898 * For multi-byte characters mb_get_class() is used (builtin rules).
899 */
900 int
901vim_iswordc(c)
902 int c;
903{
904#ifdef FEAT_MBYTE
905 if (c >= 0x100)
906 {
907 if (enc_dbcs != 0)
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000908 return dbcs_class((unsigned)c >> 8, (unsigned)(c & 0xff)) >= 2;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000909 if (enc_utf8)
910 return utf_class(c) >= 2;
911 }
912#endif
913 return (c > 0 && c < 0x100 && GET_CHARTAB(curbuf, c) != 0);
914}
915
916/*
917 * Just like vim_iswordc() but uses a pointer to the (multi-byte) character.
918 */
919 int
920vim_iswordp(p)
921 char_u *p;
922{
923#ifdef FEAT_MBYTE
924 if (has_mbyte && MB_BYTE2LEN(*p) > 1)
925 return mb_get_class(p) >= 2;
926#endif
927 return GET_CHARTAB(curbuf, *p) != 0;
928}
929
930#if defined(FEAT_SYN_HL) || defined(PROTO)
931 int
932vim_iswordc_buf(p, buf)
933 char_u *p;
934 buf_T *buf;
935{
936# ifdef FEAT_MBYTE
937 if (has_mbyte && MB_BYTE2LEN(*p) > 1)
938 return mb_get_class(p) >= 2;
939# endif
940 return (GET_CHARTAB(buf, *p) != 0);
941}
Bram Moolenaarc4956c82006-03-12 21:58:43 +0000942#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000943
944/*
945 * return TRUE if 'c' is a valid file-name character
946 * Assume characters above 0x100 are valid (multi-byte).
947 */
948 int
949vim_isfilec(c)
950 int c;
951{
952 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_FNAME_CHAR)));
953}
954
955/*
Bram Moolenaardd87969c2007-08-21 13:07:12 +0000956 * return TRUE if 'c' is a valid file-name character or a wildcard character
957 * Assume characters above 0x100 are valid (multi-byte).
958 * Explicitly interpret ']' as a wildcard character as mch_has_wildcard("]")
959 * returns false.
960 */
961 int
962vim_isfilec_or_wc(c)
963 int c;
964{
965 char_u buf[2];
966
967 buf[0] = (char_u)c;
968 buf[1] = NUL;
969 return vim_isfilec(c) || c == ']' || mch_has_wildcard(buf);
970}
971
972/*
Bram Moolenaar071d4272004-06-13 20:20:40 +0000973 * return TRUE if 'c' is a printable character
974 * Assume characters above 0x100 are printable (multi-byte), except for
975 * Unicode.
976 */
977 int
978vim_isprintc(c)
979 int c;
980{
981#ifdef FEAT_MBYTE
982 if (enc_utf8 && c >= 0x100)
983 return utf_printable(c);
984#endif
985 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR)));
986}
987
988/*
989 * Strict version of vim_isprintc(c), don't return TRUE if "c" is the head
990 * byte of a double-byte character.
991 */
992 int
993vim_isprintc_strict(c)
994 int c;
995{
996#ifdef FEAT_MBYTE
997 if (enc_dbcs != 0 && c < 0x100 && MB_BYTE2LEN(c) > 1)
998 return FALSE;
999 if (enc_utf8 && c >= 0x100)
1000 return utf_printable(c);
1001#endif
1002 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR)));
1003}
1004
1005/*
1006 * like chartabsize(), but also check for line breaks on the screen
1007 */
1008 int
1009lbr_chartabsize(s, col)
1010 unsigned char *s;
1011 colnr_T col;
1012{
1013#ifdef FEAT_LINEBREAK
1014 if (!curwin->w_p_lbr && *p_sbr == NUL)
1015 {
1016#endif
1017#ifdef FEAT_MBYTE
1018 if (curwin->w_p_wrap)
1019 return win_nolbr_chartabsize(curwin, s, col, NULL);
1020#endif
1021 RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
1022#ifdef FEAT_LINEBREAK
1023 }
1024 return win_lbr_chartabsize(curwin, s, col, NULL);
1025#endif
1026}
1027
1028/*
1029 * Call lbr_chartabsize() and advance the pointer.
1030 */
1031 int
1032lbr_chartabsize_adv(s, col)
1033 char_u **s;
1034 colnr_T col;
1035{
1036 int retval;
1037
1038 retval = lbr_chartabsize(*s, col);
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001039 mb_ptr_adv(*s);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001040 return retval;
1041}
1042
1043/*
1044 * This function is used very often, keep it fast!!!!
1045 *
1046 * If "headp" not NULL, set *headp to the size of what we for 'showbreak'
1047 * string at start of line. Warning: *headp is only set if it's a non-zero
1048 * value, init to 0 before calling.
1049 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001050 int
1051win_lbr_chartabsize(wp, s, col, headp)
1052 win_T *wp;
1053 char_u *s;
1054 colnr_T col;
Bram Moolenaar0c094b92009-05-14 20:20:33 +00001055 int *headp UNUSED;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001056{
1057#ifdef FEAT_LINEBREAK
1058 int c;
1059 int size;
1060 colnr_T col2;
1061 colnr_T colmax;
1062 int added;
1063# ifdef FEAT_MBYTE
1064 int mb_added = 0;
1065# else
1066# define mb_added 0
1067# endif
1068 int numberextra;
1069 char_u *ps;
1070 int tab_corr = (*s == TAB);
Bram Moolenaar402d2fe2005-04-15 21:00:38 +00001071 int n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001072
1073 /*
1074 * No 'linebreak' and 'showbreak': return quickly.
1075 */
1076 if (!wp->w_p_lbr && *p_sbr == NUL)
1077#endif
1078 {
1079#ifdef FEAT_MBYTE
1080 if (wp->w_p_wrap)
1081 return win_nolbr_chartabsize(wp, s, col, headp);
1082#endif
1083 RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col)
1084 }
1085
1086#ifdef FEAT_LINEBREAK
1087 /*
1088 * First get normal size, without 'linebreak'
1089 */
1090 size = win_chartabsize(wp, s, col);
1091 c = *s;
1092
1093 /*
1094 * If 'linebreak' set check at a blank before a non-blank if the line
1095 * needs a break here
1096 */
1097 if (wp->w_p_lbr
1098 && vim_isbreak(c)
1099 && !vim_isbreak(s[1])
1100 && !wp->w_p_list
1101 && wp->w_p_wrap
1102# ifdef FEAT_VERTSPLIT
1103 && wp->w_width != 0
1104# endif
1105 )
1106 {
1107 /*
1108 * Count all characters from first non-blank after a blank up to next
1109 * non-blank after a blank.
1110 */
1111 numberextra = win_col_off(wp);
1112 col2 = col;
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001113 colmax = (colnr_T)(W_WIDTH(wp) - numberextra);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001114 if (col >= colmax)
Bram Moolenaar402d2fe2005-04-15 21:00:38 +00001115 {
1116 n = colmax + win_col_off2(wp);
1117 if (n > 0)
1118 colmax += (((col - colmax) / n) + 1) * n;
1119 }
1120
Bram Moolenaar071d4272004-06-13 20:20:40 +00001121 for (;;)
1122 {
1123 ps = s;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001124 mb_ptr_adv(s);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001125 c = *s;
1126 if (!(c != NUL
1127 && (vim_isbreak(c)
1128 || (!vim_isbreak(c)
1129 && (col2 == col || !vim_isbreak(*ps))))))
1130 break;
1131
1132 col2 += win_chartabsize(wp, s, col2);
1133 if (col2 >= colmax) /* doesn't fit */
1134 {
1135 size = colmax - col;
1136 tab_corr = FALSE;
1137 break;
1138 }
1139 }
1140 }
1141# ifdef FEAT_MBYTE
1142 else if (has_mbyte && size == 2 && MB_BYTE2LEN(*s) > 1
1143 && wp->w_p_wrap && in_win_border(wp, col))
1144 {
1145 ++size; /* Count the ">" in the last column. */
1146 mb_added = 1;
1147 }
1148# endif
1149
1150 /*
1151 * May have to add something for 'showbreak' string at start of line
1152 * Set *headp to the size of what we add.
1153 */
1154 added = 0;
1155 if (*p_sbr != NUL && wp->w_p_wrap && col != 0)
1156 {
1157 numberextra = win_col_off(wp);
1158 col += numberextra + mb_added;
1159 if (col >= (colnr_T)W_WIDTH(wp))
1160 {
1161 col -= W_WIDTH(wp);
1162 numberextra = W_WIDTH(wp) - (numberextra - win_col_off2(wp));
1163 if (numberextra > 0)
1164 col = col % numberextra;
1165 }
1166 if (col == 0 || col + size > (colnr_T)W_WIDTH(wp))
1167 {
1168 added = vim_strsize(p_sbr);
1169 if (tab_corr)
1170 size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
1171 else
1172 size += added;
1173 if (col != 0)
1174 added = 0;
1175 }
1176 }
1177 if (headp != NULL)
1178 *headp = added + mb_added;
1179 return size;
1180#endif
1181}
1182
1183#if defined(FEAT_MBYTE) || defined(PROTO)
1184/*
1185 * Like win_lbr_chartabsize(), except that we know 'linebreak' is off and
1186 * 'wrap' is on. This means we need to check for a double-byte character that
1187 * doesn't fit at the end of the screen line.
1188 */
1189 static int
1190win_nolbr_chartabsize(wp, s, col, headp)
1191 win_T *wp;
1192 char_u *s;
1193 colnr_T col;
1194 int *headp;
1195{
1196 int n;
1197
1198 if (*s == TAB && (!wp->w_p_list || lcs_tab1))
1199 {
1200 n = wp->w_buffer->b_p_ts;
1201 return (int)(n - (col % n));
1202 }
1203 n = ptr2cells(s);
1204 /* Add one cell for a double-width character in the last column of the
1205 * window, displayed with a ">". */
1206 if (n == 2 && MB_BYTE2LEN(*s) > 1 && in_win_border(wp, col))
1207 {
1208 if (headp != NULL)
1209 *headp = 1;
1210 return 3;
1211 }
1212 return n;
1213}
1214
1215/*
1216 * Return TRUE if virtual column "vcol" is in the rightmost column of window
1217 * "wp".
1218 */
1219 int
1220in_win_border(wp, vcol)
1221 win_T *wp;
1222 colnr_T vcol;
1223{
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001224 int width1; /* width of first line (after line number) */
1225 int width2; /* width of further lines */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001226
1227#ifdef FEAT_VERTSPLIT
1228 if (wp->w_width == 0) /* there is no border */
1229 return FALSE;
1230#endif
1231 width1 = W_WIDTH(wp) - win_col_off(wp);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001232 if ((int)vcol < width1 - 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001233 return FALSE;
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001234 if ((int)vcol == width1 - 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001235 return TRUE;
1236 width2 = width1 + win_col_off2(wp);
Bram Moolenaar8701cd62009-10-07 14:20:30 +00001237 if (width2 <= 0)
1238 return FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001239 return ((vcol - width1) % width2 == width2 - 1);
1240}
1241#endif /* FEAT_MBYTE */
1242
1243/*
1244 * Get virtual column number of pos.
1245 * start: on the first position of this character (TAB, ctrl)
1246 * cursor: where the cursor is on this character (first char, except for TAB)
1247 * end: on the last position of this character (TAB, ctrl)
1248 *
1249 * This is used very often, keep it fast!
1250 */
1251 void
1252getvcol(wp, pos, start, cursor, end)
1253 win_T *wp;
1254 pos_T *pos;
1255 colnr_T *start;
1256 colnr_T *cursor;
1257 colnr_T *end;
1258{
1259 colnr_T vcol;
1260 char_u *ptr; /* points to current char */
1261 char_u *posptr; /* points to char at pos->col */
1262 int incr;
1263 int head;
1264 int ts = wp->w_buffer->b_p_ts;
1265 int c;
1266
1267 vcol = 0;
1268 ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
Bram Moolenaar37d619f2010-03-10 14:46:26 +01001269 if (pos->col == MAXCOL)
1270 posptr = NULL; /* continue until the NUL */
1271 else
1272 posptr = ptr + pos->col;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001273
1274 /*
1275 * This function is used very often, do some speed optimizations.
1276 * When 'list', 'linebreak' and 'showbreak' are not set use a simple loop.
1277 * Also use this when 'list' is set but tabs take their normal size.
1278 */
1279 if ((!wp->w_p_list || lcs_tab1 != NUL)
1280#ifdef FEAT_LINEBREAK
1281 && !wp->w_p_lbr && *p_sbr == NUL
1282#endif
1283 )
1284 {
1285#ifndef FEAT_MBYTE
1286 head = 0;
1287#endif
1288 for (;;)
1289 {
1290#ifdef FEAT_MBYTE
1291 head = 0;
1292#endif
1293 c = *ptr;
1294 /* make sure we don't go past the end of the line */
1295 if (c == NUL)
1296 {
1297 incr = 1; /* NUL at end of line only takes one column */
1298 break;
1299 }
1300 /* A tab gets expanded, depending on the current column */
1301 if (c == TAB)
1302 incr = ts - (vcol % ts);
1303 else
1304 {
1305#ifdef FEAT_MBYTE
1306 if (has_mbyte)
1307 {
1308 /* For utf-8, if the byte is >= 0x80, need to look at
1309 * further bytes to find the cell width. */
1310 if (enc_utf8 && c >= 0x80)
1311 incr = utf_ptr2cells(ptr);
1312 else
1313 incr = CHARSIZE(c);
1314
1315 /* If a double-cell char doesn't fit at the end of a line
1316 * it wraps to the next line, it's like this char is three
1317 * cells wide. */
Bram Moolenaar9c33a7c2008-02-20 13:59:32 +00001318 if (incr == 2 && wp->w_p_wrap && MB_BYTE2LEN(*ptr) > 1
1319 && in_win_border(wp, vcol))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001320 {
1321 ++incr;
1322 head = 1;
1323 }
1324 }
1325 else
1326#endif
1327 incr = CHARSIZE(c);
1328 }
1329
Bram Moolenaar37d619f2010-03-10 14:46:26 +01001330 if (posptr != NULL && ptr >= posptr) /* character at pos->col */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001331 break;
1332
1333 vcol += incr;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001334 mb_ptr_adv(ptr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001335 }
1336 }
1337 else
1338 {
1339 for (;;)
1340 {
1341 /* A tab gets expanded, depending on the current column */
1342 head = 0;
1343 incr = win_lbr_chartabsize(wp, ptr, vcol, &head);
1344 /* make sure we don't go past the end of the line */
1345 if (*ptr == NUL)
1346 {
1347 incr = 1; /* NUL at end of line only takes one column */
1348 break;
1349 }
1350
Bram Moolenaar37d619f2010-03-10 14:46:26 +01001351 if (posptr != NULL && ptr >= posptr) /* character at pos->col */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001352 break;
1353
1354 vcol += incr;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001355 mb_ptr_adv(ptr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001356 }
1357 }
1358 if (start != NULL)
1359 *start = vcol + head;
1360 if (end != NULL)
1361 *end = vcol + incr - 1;
1362 if (cursor != NULL)
1363 {
1364 if (*ptr == TAB
1365 && (State & NORMAL)
1366 && !wp->w_p_list
1367 && !virtual_active()
1368#ifdef FEAT_VISUAL
1369 && !(VIsual_active
1370 && (*p_sel == 'e' || ltoreq(*pos, VIsual)))
1371#endif
1372 )
1373 *cursor = vcol + incr - 1; /* cursor at end */
1374 else
1375 *cursor = vcol + head; /* cursor at start */
1376 }
1377}
1378
1379/*
1380 * Get virtual cursor column in the current window, pretending 'list' is off.
1381 */
1382 colnr_T
1383getvcol_nolist(posp)
1384 pos_T *posp;
1385{
1386 int list_save = curwin->w_p_list;
1387 colnr_T vcol;
1388
1389 curwin->w_p_list = FALSE;
1390 getvcol(curwin, posp, NULL, &vcol, NULL);
1391 curwin->w_p_list = list_save;
1392 return vcol;
1393}
1394
1395#if defined(FEAT_VIRTUALEDIT) || defined(PROTO)
1396/*
1397 * Get virtual column in virtual mode.
1398 */
1399 void
1400getvvcol(wp, pos, start, cursor, end)
1401 win_T *wp;
1402 pos_T *pos;
1403 colnr_T *start;
1404 colnr_T *cursor;
1405 colnr_T *end;
1406{
1407 colnr_T col;
1408 colnr_T coladd;
1409 colnr_T endadd;
1410# ifdef FEAT_MBYTE
1411 char_u *ptr;
1412# endif
1413
1414 if (virtual_active())
1415 {
1416 /* For virtual mode, only want one value */
1417 getvcol(wp, pos, &col, NULL, NULL);
1418
1419 coladd = pos->coladd;
1420 endadd = 0;
1421# ifdef FEAT_MBYTE
1422 /* Cannot put the cursor on part of a wide character. */
1423 ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001424 if (pos->col < (colnr_T)STRLEN(ptr))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001425 {
1426 int c = (*mb_ptr2char)(ptr + pos->col);
1427
1428 if (c != TAB && vim_isprintc(c))
1429 {
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001430 endadd = (colnr_T)(char2cells(c) - 1);
Bram Moolenaara5792f52005-11-23 21:25:05 +00001431 if (coladd > endadd) /* past end of line */
1432 endadd = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001433 else
1434 coladd = 0;
1435 }
1436 }
1437# endif
1438 col += coladd;
1439 if (start != NULL)
1440 *start = col;
1441 if (cursor != NULL)
1442 *cursor = col;
1443 if (end != NULL)
1444 *end = col + endadd;
1445 }
1446 else
1447 getvcol(wp, pos, start, cursor, end);
1448}
1449#endif
1450
1451#if defined(FEAT_VISUAL) || defined(PROTO)
1452/*
1453 * Get the leftmost and rightmost virtual column of pos1 and pos2.
1454 * Used for Visual block mode.
1455 */
1456 void
1457getvcols(wp, pos1, pos2, left, right)
1458 win_T *wp;
1459 pos_T *pos1, *pos2;
1460 colnr_T *left, *right;
1461{
1462 colnr_T from1, from2, to1, to2;
1463
1464 if (ltp(pos1, pos2))
1465 {
1466 getvvcol(wp, pos1, &from1, NULL, &to1);
1467 getvvcol(wp, pos2, &from2, NULL, &to2);
1468 }
1469 else
1470 {
1471 getvvcol(wp, pos2, &from1, NULL, &to1);
1472 getvvcol(wp, pos1, &from2, NULL, &to2);
1473 }
1474 if (from2 < from1)
1475 *left = from2;
1476 else
1477 *left = from1;
1478 if (to2 > to1)
1479 {
1480 if (*p_sel == 'e' && from2 - 1 >= to1)
1481 *right = from2 - 1;
1482 else
1483 *right = to2;
1484 }
1485 else
1486 *right = to1;
1487}
1488#endif
1489
1490/*
1491 * skipwhite: skip over ' ' and '\t'.
1492 */
1493 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001494skipwhite(q)
1495 char_u *q;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001496{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001497 char_u *p = q;
1498
Bram Moolenaar071d4272004-06-13 20:20:40 +00001499 while (vim_iswhite(*p)) /* skip to next non-white */
1500 ++p;
1501 return p;
1502}
1503
1504/*
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001505 * skip over digits
Bram Moolenaar071d4272004-06-13 20:20:40 +00001506 */
1507 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001508skipdigits(q)
1509 char_u *q;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001510{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001511 char_u *p = q;
1512
Bram Moolenaar071d4272004-06-13 20:20:40 +00001513 while (VIM_ISDIGIT(*p)) /* skip to next non-digit */
1514 ++p;
1515 return p;
1516}
1517
Bram Moolenaarc4956c82006-03-12 21:58:43 +00001518#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) || defined(PROTO)
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001519/*
1520 * skip over digits and hex characters
1521 */
1522 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001523skiphex(q)
1524 char_u *q;
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001525{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001526 char_u *p = q;
1527
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001528 while (vim_isxdigit(*p)) /* skip to next non-digit */
1529 ++p;
1530 return p;
1531}
1532#endif
1533
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001534#if defined(FEAT_EX_EXTRA) || defined(PROTO)
1535/*
1536 * skip to digit (or NUL after the string)
1537 */
1538 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001539skiptodigit(q)
1540 char_u *q;
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001541{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001542 char_u *p = q;
1543
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001544 while (*p != NUL && !VIM_ISDIGIT(*p)) /* skip to next digit */
1545 ++p;
1546 return p;
1547}
1548
1549/*
1550 * skip to hex character (or NUL after the string)
1551 */
1552 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001553skiptohex(q)
1554 char_u *q;
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001555{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001556 char_u *p = q;
1557
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001558 while (*p != NUL && !vim_isxdigit(*p)) /* skip to next digit */
1559 ++p;
1560 return p;
1561}
1562#endif
1563
Bram Moolenaar071d4272004-06-13 20:20:40 +00001564/*
1565 * Variant of isdigit() that can handle characters > 0x100.
1566 * We don't use isdigit() here, because on some systems it also considers
1567 * superscript 1 to be a digit.
1568 * Use the VIM_ISDIGIT() macro for simple arguments.
1569 */
1570 int
1571vim_isdigit(c)
1572 int c;
1573{
1574 return (c >= '0' && c <= '9');
1575}
1576
1577/*
1578 * Variant of isxdigit() that can handle characters > 0x100.
1579 * We don't use isxdigit() here, because on some systems it also considers
1580 * superscript 1 to be a digit.
1581 */
1582 int
1583vim_isxdigit(c)
1584 int c;
1585{
1586 return (c >= '0' && c <= '9')
1587 || (c >= 'a' && c <= 'f')
1588 || (c >= 'A' && c <= 'F');
1589}
1590
Bram Moolenaar78622822005-08-23 21:00:13 +00001591#if defined(FEAT_MBYTE) || defined(PROTO)
1592/*
1593 * Vim's own character class functions. These exist because many library
1594 * islower()/toupper() etc. do not work properly: they crash when used with
1595 * invalid values or can't handle latin1 when the locale is C.
1596 * Speed is most important here.
1597 */
1598#define LATIN1LOWER 'l'
1599#define LATIN1UPPER 'U'
1600
1601/* !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]%_'abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ */
Bram Moolenaar6e7c7f32005-08-24 22:16:11 +00001602static char_u latin1flags[257] = " UUUUUUUUUUUUUUUUUUUUUUUUUU llllllllllllllllllllllllll UUUUUUUUUUUUUUUUUUUUUUU UUUUUUUllllllllllllllllllllllll llllllll";
1603static char_u latin1upper[257] = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ÷ØÙÚÛÜÝÞÿ";
1604static char_u latin1lower[257] = " !\"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿àáâãäåæçèéêëìíîïðñòóôõö×øùúûüýþßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ";
Bram Moolenaar78622822005-08-23 21:00:13 +00001605
1606 int
1607vim_islower(c)
1608 int c;
1609{
1610 if (c <= '@')
1611 return FALSE;
1612 if (c >= 0x80)
1613 {
1614 if (enc_utf8)
1615 return utf_islower(c);
1616 if (c >= 0x100)
1617 {
1618#ifdef HAVE_ISWLOWER
1619 if (has_mbyte)
1620 return iswlower(c);
1621#endif
1622 /* islower() can't handle these chars and may crash */
1623 return FALSE;
1624 }
1625 if (enc_latin1like)
1626 return (latin1flags[c] & LATIN1LOWER) == LATIN1LOWER;
1627 }
1628 return islower(c);
1629}
1630
1631 int
1632vim_isupper(c)
1633 int c;
1634{
1635 if (c <= '@')
1636 return FALSE;
1637 if (c >= 0x80)
1638 {
1639 if (enc_utf8)
1640 return utf_isupper(c);
1641 if (c >= 0x100)
1642 {
1643#ifdef HAVE_ISWUPPER
1644 if (has_mbyte)
1645 return iswupper(c);
1646#endif
1647 /* islower() can't handle these chars and may crash */
1648 return FALSE;
1649 }
1650 if (enc_latin1like)
1651 return (latin1flags[c] & LATIN1UPPER) == LATIN1UPPER;
1652 }
1653 return isupper(c);
1654}
1655
1656 int
1657vim_toupper(c)
1658 int c;
1659{
1660 if (c <= '@')
1661 return c;
1662 if (c >= 0x80)
1663 {
1664 if (enc_utf8)
1665 return utf_toupper(c);
1666 if (c >= 0x100)
1667 {
1668#ifdef HAVE_TOWUPPER
1669 if (has_mbyte)
1670 return towupper(c);
1671#endif
1672 /* toupper() can't handle these chars and may crash */
1673 return c;
1674 }
1675 if (enc_latin1like)
1676 return latin1upper[c];
1677 }
1678 return TOUPPER_LOC(c);
1679}
1680
1681 int
1682vim_tolower(c)
1683 int c;
1684{
1685 if (c <= '@')
1686 return c;
1687 if (c >= 0x80)
1688 {
1689 if (enc_utf8)
1690 return utf_tolower(c);
1691 if (c >= 0x100)
1692 {
1693#ifdef HAVE_TOWLOWER
1694 if (has_mbyte)
1695 return towlower(c);
1696#endif
1697 /* tolower() can't handle these chars and may crash */
1698 return c;
1699 }
1700 if (enc_latin1like)
1701 return latin1lower[c];
1702 }
1703 return TOLOWER_LOC(c);
1704}
1705#endif
1706
Bram Moolenaar071d4272004-06-13 20:20:40 +00001707/*
1708 * skiptowhite: skip over text until ' ' or '\t' or NUL.
1709 */
1710 char_u *
1711skiptowhite(p)
1712 char_u *p;
1713{
1714 while (*p != ' ' && *p != '\t' && *p != NUL)
1715 ++p;
1716 return p;
1717}
1718
1719#if defined(FEAT_LISTCMDS) || defined(FEAT_SIGNS) || defined(FEAT_SNIFF) \
1720 || defined(PROTO)
1721/*
1722 * skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
1723 */
1724 char_u *
1725skiptowhite_esc(p)
1726 char_u *p;
1727{
1728 while (*p != ' ' && *p != '\t' && *p != NUL)
1729 {
1730 if ((*p == '\\' || *p == Ctrl_V) && *(p + 1) != NUL)
1731 ++p;
1732 ++p;
1733 }
1734 return p;
1735}
1736#endif
1737
1738/*
1739 * Getdigits: Get a number from a string and skip over it.
1740 * Note: the argument is a pointer to a char_u pointer!
1741 */
1742 long
1743getdigits(pp)
1744 char_u **pp;
1745{
1746 char_u *p;
1747 long retval;
1748
1749 p = *pp;
1750 retval = atol((char *)p);
1751 if (*p == '-') /* skip negative sign */
1752 ++p;
1753 p = skipdigits(p); /* skip to next non-digit */
1754 *pp = p;
1755 return retval;
1756}
1757
1758/*
1759 * Return TRUE if "lbuf" is empty or only contains blanks.
1760 */
1761 int
1762vim_isblankline(lbuf)
1763 char_u *lbuf;
1764{
1765 char_u *p;
1766
1767 p = skipwhite(lbuf);
1768 return (*p == NUL || *p == '\r' || *p == '\n');
1769}
1770
1771/*
1772 * Convert a string into a long and/or unsigned long, taking care of
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00001773 * hexadecimal and octal numbers. Accepts a '-' sign.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001774 * If "hexp" is not NULL, returns a flag to indicate the type of the number:
1775 * 0 decimal
1776 * '0' octal
1777 * 'X' hex
1778 * 'x' hex
1779 * If "len" is not NULL, the length of the number in characters is returned.
1780 * If "nptr" is not NULL, the signed result is returned in it.
1781 * If "unptr" is not NULL, the unsigned result is returned in it.
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001782 * If "dooct" is non-zero recognize octal numbers, when > 1 always assume
1783 * octal number.
Bram Moolenaar97b2ad32006-03-18 21:40:56 +00001784 * If "dohex" is non-zero recognize hex numbers, when > 1 always assume
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001785 * hex number.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001786 */
1787 void
1788vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr)
1789 char_u *start;
1790 int *hexp; /* return: type of number 0 = decimal, 'x'
1791 or 'X' is hex, '0' = octal */
1792 int *len; /* return: detected length of number */
1793 int dooct; /* recognize octal number */
1794 int dohex; /* recognize hex number */
1795 long *nptr; /* return: signed result */
1796 unsigned long *unptr; /* return: unsigned result */
1797{
1798 char_u *ptr = start;
1799 int hex = 0; /* default is decimal */
1800 int negative = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001801 unsigned long un = 0;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001802 int n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001803
1804 if (ptr[0] == '-')
1805 {
1806 negative = TRUE;
1807 ++ptr;
1808 }
1809
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001810 /* Recognize hex and octal. */
1811 if (ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001812 {
1813 hex = ptr[1];
1814 if (dohex && (hex == 'X' || hex == 'x') && vim_isxdigit(ptr[2]))
1815 ptr += 2; /* hexadecimal */
1816 else
1817 {
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001818 hex = 0; /* default is decimal */
1819 if (dooct)
1820 {
1821 /* Don't interpret "0", "08" or "0129" as octal. */
1822 for (n = 1; VIM_ISDIGIT(ptr[n]); ++n)
1823 {
1824 if (ptr[n] > '7')
1825 {
1826 hex = 0; /* can't be octal */
1827 break;
1828 }
1829 if (ptr[n] > '0')
1830 hex = '0'; /* assume octal */
1831 }
1832 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001833 }
1834 }
1835
1836 /*
1837 * Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
1838 */
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001839 if (hex == '0' || dooct > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001840 {
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001841 /* octal */
1842 while ('0' <= *ptr && *ptr <= '7')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001843 {
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001844 un = 8 * un + (unsigned long)(*ptr - '0');
1845 ++ptr;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001846 }
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001847 }
1848 else if (hex != 0 || dohex > 1)
1849 {
1850 /* hex */
1851 while (vim_isxdigit(*ptr))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001852 {
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001853 un = 16 * un + (unsigned long)hex2nr(*ptr);
1854 ++ptr;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001855 }
1856 }
1857 else
1858 {
1859 /* decimal */
1860 while (VIM_ISDIGIT(*ptr))
1861 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001862 un = 10 * un + (unsigned long)(*ptr - '0');
1863 ++ptr;
1864 }
1865 }
1866
Bram Moolenaar071d4272004-06-13 20:20:40 +00001867 if (hexp != NULL)
1868 *hexp = hex;
1869 if (len != NULL)
1870 *len = (int)(ptr - start);
1871 if (nptr != NULL)
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00001872 {
1873 if (negative) /* account for leading '-' for decimal numbers */
1874 *nptr = -(long)un;
1875 else
1876 *nptr = (long)un;
1877 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001878 if (unptr != NULL)
1879 *unptr = un;
1880}
1881
1882/*
1883 * Return the value of a single hex character.
1884 * Only valid when the argument is '0' - '9', 'A' - 'F' or 'a' - 'f'.
1885 */
1886 int
1887hex2nr(c)
1888 int c;
1889{
1890 if (c >= 'a' && c <= 'f')
1891 return c - 'a' + 10;
1892 if (c >= 'A' && c <= 'F')
1893 return c - 'A' + 10;
1894 return c - '0';
1895}
1896
1897#if defined(FEAT_TERMRESPONSE) \
1898 || (defined(FEAT_GUI_GTK) && defined(FEAT_WINDOWS)) || defined(PROTO)
1899/*
1900 * Convert two hex characters to a byte.
1901 * Return -1 if one of the characters is not hex.
1902 */
1903 int
1904hexhex2nr(p)
1905 char_u *p;
1906{
1907 if (!vim_isxdigit(p[0]) || !vim_isxdigit(p[1]))
1908 return -1;
1909 return (hex2nr(p[0]) << 4) + hex2nr(p[1]);
1910}
1911#endif
1912
1913/*
1914 * Return TRUE if "str" starts with a backslash that should be removed.
1915 * For MS-DOS, WIN32 and OS/2 this is only done when the character after the
1916 * backslash is not a normal file name character.
1917 * '$' is a valid file name character, we don't remove the backslash before
1918 * it. This means it is not possible to use an environment variable after a
1919 * backslash. "C:\$VIM\doc" is taken literally, only "$VIM\doc" works.
1920 * Although "\ name" is valid, the backslash in "Program\ files" must be
1921 * removed. Assume a file name doesn't start with a space.
1922 * For multi-byte names, never remove a backslash before a non-ascii
1923 * character, assume that all multi-byte characters are valid file name
1924 * characters.
1925 */
1926 int
1927rem_backslash(str)
1928 char_u *str;
1929{
1930#ifdef BACKSLASH_IN_FILENAME
1931 return (str[0] == '\\'
1932# ifdef FEAT_MBYTE
1933 && str[1] < 0x80
1934# endif
1935 && (str[1] == ' '
1936 || (str[1] != NUL
1937 && str[1] != '*'
1938 && str[1] != '?'
1939 && !vim_isfilec(str[1]))));
1940#else
1941 return (str[0] == '\\' && str[1] != NUL);
1942#endif
1943}
1944
1945/*
1946 * Halve the number of backslashes in a file name argument.
1947 * For MS-DOS we only do this if the character after the backslash
1948 * is not a normal file character.
1949 */
1950 void
1951backslash_halve(p)
1952 char_u *p;
1953{
1954 for ( ; *p; ++p)
1955 if (rem_backslash(p))
Bram Moolenaar446cb832008-06-24 21:56:24 +00001956 STRMOVE(p, p + 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001957}
1958
1959/*
1960 * backslash_halve() plus save the result in allocated memory.
1961 */
1962 char_u *
1963backslash_halve_save(p)
1964 char_u *p;
1965{
1966 char_u *res;
1967
1968 res = vim_strsave(p);
1969 if (res == NULL)
1970 return p;
1971 backslash_halve(res);
1972 return res;
1973}
1974
1975#if (defined(EBCDIC) && defined(FEAT_POSTSCRIPT)) || defined(PROTO)
1976/*
1977 * Table for EBCDIC to ASCII conversion unashamedly taken from xxd.c!
1978 * The first 64 entries have been added to map control characters defined in
1979 * ascii.h
1980 */
1981static char_u ebcdic2ascii_tab[256] =
1982{
1983 0000, 0001, 0002, 0003, 0004, 0011, 0006, 0177,
1984 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
1985 0020, 0021, 0022, 0023, 0024, 0012, 0010, 0027,
1986 0030, 0031, 0032, 0033, 0033, 0035, 0036, 0037,
1987 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
1988 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
1989 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
1990 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
1991 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
1992 0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
1993 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
1994 0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
1995 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
1996 0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
1997 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
1998 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
1999 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
2000 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
2001 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
2002 0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
2003 0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
2004 0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
2005 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
2006 0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
2007 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
2008 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
2009 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
2010 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
2011 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
2012 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
2013 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
2014 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377
2015};
2016
2017/*
2018 * Convert a buffer worth of characters from EBCDIC to ASCII. Only useful if
2019 * wanting 7-bit ASCII characters out the other end.
2020 */
2021 void
2022ebcdic2ascii(buffer, len)
2023 char_u *buffer;
2024 int len;
2025{
2026 int i;
2027
2028 for (i = 0; i < len; i++)
2029 buffer[i] = ebcdic2ascii_tab[buffer[i]];
2030}
2031#endif