blob: cc02563b297c7776ca34b2b1335677134a54f03d [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
190 c2 = *p++;
191 }
192 if (c <= 0 || (c2 < c && c2 != -1) || c2 >= 256
193 || !(*p == NUL || *p == ','))
194 return FAIL;
195
196 if (c2 == -1) /* not a range */
197 {
198 /*
199 * A single '@' (not "@-@"):
200 * Decide on letters being ID/printable/keyword chars with
201 * standard function isalpha(). This takes care of locale for
202 * single-byte characters).
203 */
204 if (c == '@')
205 {
206 do_isalpha = TRUE;
207 c = 1;
208 c2 = 255;
209 }
210 else
211 c2 = c;
212 }
213 while (c <= c2)
214 {
Bram Moolenaardeefb632007-08-15 18:41:34 +0000215 /* Use the MB_ functions here, because isalpha() doesn't
216 * work properly when 'encoding' is "latin1" and the locale is
217 * "C". */
218 if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000219#ifdef FEAT_FKMAP
220 || (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))
221#endif
222 )
223 {
224 if (i == 0) /* (re)set ID flag */
225 {
226 if (tilde)
227 chartab[c] &= ~CT_ID_CHAR;
228 else
229 chartab[c] |= CT_ID_CHAR;
230 }
231 else if (i == 1) /* (re)set printable */
232 {
233 if ((c < ' '
234#ifndef EBCDIC
235 || c > '~'
236#endif
237#ifdef FEAT_FKMAP
238 || (p_altkeymap
239 && (F_isalpha(c) || F_isdigit(c)))
240#endif
241 )
242#ifdef FEAT_MBYTE
243 /* For double-byte we keep the cell width, so
244 * that we can detect it from the first byte. */
245 && !(enc_dbcs && MB_BYTE2LEN(c) == 2)
246#endif
247 )
248 {
249 if (tilde)
250 {
251 chartab[c] = (chartab[c] & ~CT_CELL_MASK)
252 + ((dy_flags & DY_UHEX) ? 4 : 2);
253 chartab[c] &= ~CT_PRINT_CHAR;
254 }
255 else
256 {
257 chartab[c] = (chartab[c] & ~CT_CELL_MASK) + 1;
258 chartab[c] |= CT_PRINT_CHAR;
259 }
260 }
261 }
262 else if (i == 2) /* (re)set fname flag */
263 {
264 if (tilde)
265 chartab[c] &= ~CT_FNAME_CHAR;
266 else
267 chartab[c] |= CT_FNAME_CHAR;
268 }
269 else /* i == 3 */ /* (re)set keyword flag */
270 {
271 if (tilde)
272 RESET_CHARTAB(buf, c);
273 else
274 SET_CHARTAB(buf, c);
275 }
276 }
277 ++c;
278 }
279 p = skip_to_option_part(p);
280 }
281 }
282 chartab_initialized = TRUE;
283 return OK;
284}
285
286/*
287 * Translate any special characters in buf[bufsize] in-place.
288 * The result is a string with only printable characters, but if there is not
289 * enough room, not all characters will be translated.
290 */
291 void
292trans_characters(buf, bufsize)
293 char_u *buf;
294 int bufsize;
295{
296 int len; /* length of string needing translation */
297 int room; /* room in buffer after string */
298 char_u *trs; /* translated character */
299 int trs_len; /* length of trs[] */
300
301 len = (int)STRLEN(buf);
302 room = bufsize - len;
303 while (*buf != 0)
304 {
305# ifdef FEAT_MBYTE
306 /* Assume a multi-byte character doesn't need translation. */
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000307 if (has_mbyte && (trs_len = (*mb_ptr2len)(buf)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000308 len -= trs_len;
309 else
310# endif
311 {
312 trs = transchar_byte(*buf);
313 trs_len = (int)STRLEN(trs);
314 if (trs_len > 1)
315 {
316 room -= trs_len - 1;
317 if (room <= 0)
318 return;
319 mch_memmove(buf + trs_len, buf + 1, (size_t)len);
320 }
321 mch_memmove(buf, trs, (size_t)trs_len);
322 --len;
323 }
324 buf += trs_len;
325 }
326}
327
Bram Moolenaar7cc36e92007-03-27 10:42:05 +0000328#if defined(FEAT_EVAL) || defined(FEAT_TITLE) || defined(FEAT_INS_EXPAND) \
329 || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000330/*
331 * Translate a string into allocated memory, replacing special chars with
332 * printable chars. Returns NULL when out of memory.
333 */
334 char_u *
335transstr(s)
336 char_u *s;
337{
338 char_u *res;
339 char_u *p;
340#ifdef FEAT_MBYTE
341 int l, len, c;
342 char_u hexbuf[11];
343#endif
344
345#ifdef FEAT_MBYTE
346 if (has_mbyte)
347 {
348 /* Compute the length of the result, taking account of unprintable
349 * multi-byte characters. */
350 len = 0;
351 p = s;
352 while (*p != NUL)
353 {
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000354 if ((l = (*mb_ptr2len)(p)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000355 {
356 c = (*mb_ptr2char)(p);
357 p += l;
358 if (vim_isprintc(c))
359 len += l;
360 else
361 {
362 transchar_hex(hexbuf, c);
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000363 len += (int)STRLEN(hexbuf);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000364 }
365 }
366 else
367 {
368 l = byte2cells(*p++);
369 if (l > 0)
370 len += l;
371 else
372 len += 4; /* illegal byte sequence */
373 }
374 }
375 res = alloc((unsigned)(len + 1));
376 }
377 else
378#endif
379 res = alloc((unsigned)(vim_strsize(s) + 1));
380 if (res != NULL)
381 {
382 *res = NUL;
383 p = s;
384 while (*p != NUL)
385 {
386#ifdef FEAT_MBYTE
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000387 if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000388 {
389 c = (*mb_ptr2char)(p);
390 if (vim_isprintc(c))
391 STRNCAT(res, p, l); /* append printable multi-byte char */
392 else
393 transchar_hex(res + STRLEN(res), c);
394 p += l;
395 }
396 else
397#endif
398 STRCAT(res, transchar_byte(*p++));
399 }
400 }
401 return res;
402}
403#endif
404
405#if defined(FEAT_SYN_HL) || defined(FEAT_INS_EXPAND) || defined(PROTO)
406/*
Bram Moolenaar217ad922005-03-20 22:37:15 +0000407 * Convert the string "str[orglen]" to do ignore-case comparing. Uses the
408 * current locale.
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000409 * When "buf" is NULL returns an allocated string (NULL for out-of-memory).
410 * Otherwise puts the result in "buf[buflen]".
Bram Moolenaar071d4272004-06-13 20:20:40 +0000411 */
412 char_u *
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000413str_foldcase(str, orglen, buf, buflen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000414 char_u *str;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000415 int orglen;
416 char_u *buf;
417 int buflen;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000418{
419 garray_T ga;
420 int i;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000421 int len = orglen;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000422
423#define GA_CHAR(i) ((char_u *)ga.ga_data)[i]
424#define GA_PTR(i) ((char_u *)ga.ga_data + i)
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000425#define STR_CHAR(i) (buf == NULL ? GA_CHAR(i) : buf[i])
426#define STR_PTR(i) (buf == NULL ? GA_PTR(i) : buf + i)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000427
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000428 /* Copy "str" into "buf" or allocated memory, unmodified. */
429 if (buf == NULL)
430 {
431 ga_init2(&ga, 1, 10);
432 if (ga_grow(&ga, len + 1) == FAIL)
433 return NULL;
434 mch_memmove(ga.ga_data, str, (size_t)len);
435 ga.ga_len = len;
436 }
437 else
438 {
439 if (len >= buflen) /* Ugly! */
440 len = buflen - 1;
441 mch_memmove(buf, str, (size_t)len);
442 }
443 if (buf == NULL)
444 GA_CHAR(len) = NUL;
445 else
446 buf[len] = NUL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000447
448 /* Make each character lower case. */
449 i = 0;
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000450 while (STR_CHAR(i) != NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000451 {
452#ifdef FEAT_MBYTE
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000453 if (enc_utf8 || (has_mbyte && MB_BYTE2LEN(STR_CHAR(i)) > 1))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000454 {
455 if (enc_utf8)
456 {
Bram Moolenaarb9839212008-06-28 11:03:50 +0000457 int c = utf_ptr2char(STR_PTR(i));
458 int ol = utf_ptr2len(STR_PTR(i));
459 int lc = utf_tolower(c);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000460
Bram Moolenaarb9839212008-06-28 11:03:50 +0000461 /* Only replace the character when it is not an invalid
462 * sequence (ASCII character or more than one byte) and
463 * utf_tolower() doesn't return the original character. */
464 if ((c < 0x80 || ol > 1) && c != lc)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000465 {
Bram Moolenaar071d4272004-06-13 20:20:40 +0000466 int nl = utf_char2len(lc);
467
468 /* If the byte length changes need to shift the following
469 * characters forward or backward. */
470 if (ol != nl)
471 {
472 if (nl > ol)
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000473 {
474 if (buf == NULL ? ga_grow(&ga, nl - ol + 1) == FAIL
475 : len + nl - ol >= buflen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000476 {
477 /* out of memory, keep old char */
478 lc = c;
479 nl = ol;
480 }
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000481 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000482 if (ol != nl)
483 {
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000484 if (buf == NULL)
485 {
Bram Moolenaar446cb832008-06-24 21:56:24 +0000486 STRMOVE(GA_PTR(i) + nl, GA_PTR(i) + ol);
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000487 ga.ga_len += nl - ol;
488 }
489 else
490 {
Bram Moolenaar446cb832008-06-24 21:56:24 +0000491 STRMOVE(buf + i + nl, buf + i + ol);
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000492 len += nl - ol;
493 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000494 }
495 }
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000496 (void)utf_char2bytes(lc, STR_PTR(i));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000497 }
498 }
499 /* skip to next multi-byte char */
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000500 i += (*mb_ptr2len)(STR_PTR(i));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000501 }
502 else
503#endif
504 {
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000505 if (buf == NULL)
506 GA_CHAR(i) = TOLOWER_LOC(GA_CHAR(i));
507 else
508 buf[i] = TOLOWER_LOC(buf[i]);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000509 ++i;
510 }
511 }
512
Bram Moolenaar6ebb1142005-01-25 21:58:26 +0000513 if (buf == NULL)
514 return (char_u *)ga.ga_data;
515 return buf;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000516}
517#endif
518
519/*
520 * Catch 22: chartab[] can't be initialized before the options are
521 * initialized, and initializing options may cause transchar() to be called!
522 * When chartab_initialized == FALSE don't use chartab[].
523 * Does NOT work for multi-byte characters, c must be <= 255.
524 * Also doesn't work for the first byte of a multi-byte, "c" must be a
525 * character!
526 */
527static char_u transchar_buf[7];
528
529 char_u *
530transchar(c)
531 int c;
532{
533 int i;
534
535 i = 0;
536 if (IS_SPECIAL(c)) /* special key code, display as ~@ char */
537 {
538 transchar_buf[0] = '~';
539 transchar_buf[1] = '@';
540 i = 2;
541 c = K_SECOND(c);
542 }
543
544 if ((!chartab_initialized && (
545#ifdef EBCDIC
546 (c >= 64 && c < 255)
547#else
548 (c >= ' ' && c <= '~')
549#endif
550#ifdef FEAT_FKMAP
551 || F_ischar(c)
552#endif
553 )) || (c < 256 && vim_isprintc_strict(c)))
554 {
555 /* printable character */
556 transchar_buf[i] = c;
557 transchar_buf[i + 1] = NUL;
558 }
559 else
560 transchar_nonprint(transchar_buf + i, c);
561 return transchar_buf;
562}
563
564#if defined(FEAT_MBYTE) || defined(PROTO)
565/*
566 * Like transchar(), but called with a byte instead of a character. Checks
567 * for an illegal UTF-8 byte.
568 */
569 char_u *
570transchar_byte(c)
571 int c;
572{
573 if (enc_utf8 && c >= 0x80)
574 {
575 transchar_nonprint(transchar_buf, c);
576 return transchar_buf;
577 }
578 return transchar(c);
579}
580#endif
581
582/*
583 * Convert non-printable character to two or more printable characters in
584 * "buf[]". "buf" needs to be able to hold five bytes.
585 * Does NOT work for multi-byte characters, c must be <= 255.
586 */
587 void
588transchar_nonprint(buf, c)
589 char_u *buf;
590 int c;
591{
592 if (c == NL)
593 c = NUL; /* we use newline in place of a NUL */
594 else if (c == CAR && get_fileformat(curbuf) == EOL_MAC)
595 c = NL; /* we use CR in place of NL in this case */
596
597 if (dy_flags & DY_UHEX) /* 'display' has "uhex" */
598 transchar_hex(buf, c);
599
600#ifdef EBCDIC
601 /* For EBCDIC only the characters 0-63 and 255 are not printable */
602 else if (CtrlChar(c) != 0 || c == DEL)
603#else
604 else if (c <= 0x7f) /* 0x00 - 0x1f and 0x7f */
605#endif
606 {
607 buf[0] = '^';
608#ifdef EBCDIC
609 if (c == DEL)
610 buf[1] = '?'; /* DEL displayed as ^? */
611 else
612 buf[1] = CtrlChar(c);
613#else
614 buf[1] = c ^ 0x40; /* DEL displayed as ^? */
615#endif
616
617 buf[2] = NUL;
618 }
619#ifdef FEAT_MBYTE
620 else if (enc_utf8 && c >= 0x80)
621 {
622 transchar_hex(buf, c);
623 }
624#endif
625#ifndef EBCDIC
626 else if (c >= ' ' + 0x80 && c <= '~' + 0x80) /* 0xa0 - 0xfe */
627 {
628 buf[0] = '|';
629 buf[1] = c - 0x80;
630 buf[2] = NUL;
631 }
632#else
633 else if (c < 64)
634 {
635 buf[0] = '~';
636 buf[1] = MetaChar(c);
637 buf[2] = NUL;
638 }
639#endif
640 else /* 0x80 - 0x9f and 0xff */
641 {
642 /*
643 * TODO: EBCDIC I don't know what to do with this chars, so I display
644 * them as '~?' for now
645 */
646 buf[0] = '~';
647#ifdef EBCDIC
648 buf[1] = '?'; /* 0xff displayed as ~? */
649#else
650 buf[1] = (c - 0x80) ^ 0x40; /* 0xff displayed as ~? */
651#endif
652 buf[2] = NUL;
653 }
654}
655
656 void
657transchar_hex(buf, c)
658 char_u *buf;
659 int c;
660{
661 int i = 0;
662
663 buf[0] = '<';
664#ifdef FEAT_MBYTE
665 if (c > 255)
666 {
667 buf[++i] = nr2hex((unsigned)c >> 12);
668 buf[++i] = nr2hex((unsigned)c >> 8);
669 }
670#endif
671 buf[++i] = nr2hex((unsigned)c >> 4);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000672 buf[++i] = nr2hex((unsigned)c);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000673 buf[++i] = '>';
674 buf[++i] = NUL;
675}
676
677/*
678 * Convert the lower 4 bits of byte "c" to its hex character.
679 * Lower case letters are used to avoid the confusion of <F1> being 0xf1 or
680 * function key 1.
681 */
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000682 static unsigned
Bram Moolenaar071d4272004-06-13 20:20:40 +0000683nr2hex(c)
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000684 unsigned c;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000685{
686 if ((c & 0xf) <= 9)
687 return (c & 0xf) + '0';
688 return (c & 0xf) - 10 + 'a';
689}
690
691/*
692 * Return number of display cells occupied by byte "b".
693 * Caller must make sure 0 <= b <= 255.
694 * For multi-byte mode "b" must be the first byte of a character.
695 * A TAB is counted as two cells: "^I".
696 * For UTF-8 mode this will return 0 for bytes >= 0x80, because the number of
697 * cells depends on further bytes.
698 */
699 int
700byte2cells(b)
701 int b;
702{
703#ifdef FEAT_MBYTE
704 if (enc_utf8 && b >= 0x80)
705 return 0;
706#endif
707 return (chartab[b] & CT_CELL_MASK);
708}
709
710/*
711 * Return number of display cells occupied by character "c".
712 * "c" can be a special key (negative number) in which case 3 or 4 is returned.
713 * A TAB is counted as two cells: "^I" or four: "<09>".
714 */
715 int
716char2cells(c)
717 int c;
718{
719 if (IS_SPECIAL(c))
720 return char2cells(K_SECOND(c)) + 2;
721#ifdef FEAT_MBYTE
722 if (c >= 0x80)
723 {
724 /* UTF-8: above 0x80 need to check the value */
725 if (enc_utf8)
726 return utf_char2cells(c);
727 /* DBCS: double-byte means double-width, except for euc-jp with first
728 * byte 0x8e */
729 if (enc_dbcs != 0 && c >= 0x100)
730 {
731 if (enc_dbcs == DBCS_JPNU && ((unsigned)c >> 8) == 0x8e)
732 return 1;
733 return 2;
734 }
735 }
736#endif
737 return (chartab[c & 0xff] & CT_CELL_MASK);
738}
739
740/*
741 * Return number of display cells occupied by character at "*p".
742 * A TAB is counted as two cells: "^I" or four: "<09>".
743 */
744 int
745ptr2cells(p)
746 char_u *p;
747{
748#ifdef FEAT_MBYTE
749 /* For UTF-8 we need to look at more bytes if the first byte is >= 0x80. */
750 if (enc_utf8 && *p >= 0x80)
751 return utf_ptr2cells(p);
752 /* For DBCS we can tell the cell count from the first byte. */
753#endif
754 return (chartab[*p] & CT_CELL_MASK);
755}
756
757/*
758 * Return the number of characters string "s" will take on the screen,
759 * counting TABs as two characters: "^I".
760 */
761 int
762vim_strsize(s)
763 char_u *s;
764{
765 return vim_strnsize(s, (int)MAXCOL);
766}
767
768/*
769 * Return the number of characters string "s[len]" will take on the screen,
770 * counting TABs as two characters: "^I".
771 */
772 int
773vim_strnsize(s, len)
774 char_u *s;
775 int len;
776{
777 int size = 0;
778
779 while (*s != NUL && --len >= 0)
780 {
781#ifdef FEAT_MBYTE
782 if (has_mbyte)
783 {
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000784 int l = (*mb_ptr2len)(s);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000785
786 size += ptr2cells(s);
787 s += l;
788 len -= l - 1;
789 }
790 else
791#endif
792 size += byte2cells(*s++);
793 }
794 return size;
795}
796
797/*
798 * Return the number of characters 'c' will take on the screen, taking
799 * into account the size of a tab.
800 * Use a define to make it fast, this is used very often!!!
801 * Also see getvcol() below.
802 */
803
804#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
805 if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \
806 { \
807 int ts; \
808 ts = (buf)->b_p_ts; \
809 return (int)(ts - (col % ts)); \
810 } \
811 else \
812 return ptr2cells(p);
813
814#if defined(FEAT_VREPLACE) || defined(FEAT_EX_EXTRA) || defined(FEAT_GUI) \
815 || defined(FEAT_VIRTUALEDIT) || defined(PROTO)
816 int
817chartabsize(p, col)
818 char_u *p;
819 colnr_T col;
820{
821 RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col)
822}
823#endif
824
825#ifdef FEAT_LINEBREAK
826 static int
827win_chartabsize(wp, p, col)
828 win_T *wp;
829 char_u *p;
830 colnr_T col;
831{
832 RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col)
833}
834#endif
835
836/*
837 * return the number of characters the string 's' will take on the screen,
838 * taking into account the size of a tab
839 */
840 int
841linetabsize(s)
842 char_u *s;
843{
844 colnr_T col = 0;
845
846 while (*s != NUL)
847 col += lbr_chartabsize_adv(&s, col);
848 return (int)col;
849}
850
851/*
852 * Like linetabsize(), but for a given window instead of the current one.
853 */
854 int
855win_linetabsize(wp, p, len)
856 win_T *wp;
857 char_u *p;
858 colnr_T len;
859{
860 colnr_T col = 0;
861 char_u *s;
862
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +0000863 for (s = p; *s != NUL && (len == MAXCOL || s < p + len); mb_ptr_adv(s))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000864 col += win_lbr_chartabsize(wp, s, col, NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000865 return (int)col;
866}
867
868/*
Bram Moolenaar81695252004-12-29 20:58:21 +0000869 * Return TRUE if 'c' is a normal identifier character:
870 * Letters and characters from the 'isident' option.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000871 */
872 int
873vim_isIDc(c)
874 int c;
875{
876 return (c > 0 && c < 0x100 && (chartab[c] & CT_ID_CHAR));
877}
878
879/*
880 * return TRUE if 'c' is a keyword character: Letters and characters from
881 * 'iskeyword' option for current buffer.
882 * For multi-byte characters mb_get_class() is used (builtin rules).
883 */
884 int
885vim_iswordc(c)
886 int c;
887{
888#ifdef FEAT_MBYTE
889 if (c >= 0x100)
890 {
891 if (enc_dbcs != 0)
Bram Moolenaar0ab2a882009-05-13 10:51:08 +0000892 return dbcs_class((unsigned)c >> 8, (unsigned)(c & 0xff)) >= 2;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000893 if (enc_utf8)
894 return utf_class(c) >= 2;
895 }
896#endif
897 return (c > 0 && c < 0x100 && GET_CHARTAB(curbuf, c) != 0);
898}
899
900/*
901 * Just like vim_iswordc() but uses a pointer to the (multi-byte) character.
902 */
903 int
904vim_iswordp(p)
905 char_u *p;
906{
907#ifdef FEAT_MBYTE
908 if (has_mbyte && MB_BYTE2LEN(*p) > 1)
909 return mb_get_class(p) >= 2;
910#endif
911 return GET_CHARTAB(curbuf, *p) != 0;
912}
913
914#if defined(FEAT_SYN_HL) || defined(PROTO)
915 int
916vim_iswordc_buf(p, buf)
917 char_u *p;
918 buf_T *buf;
919{
920# ifdef FEAT_MBYTE
921 if (has_mbyte && MB_BYTE2LEN(*p) > 1)
922 return mb_get_class(p) >= 2;
923# endif
924 return (GET_CHARTAB(buf, *p) != 0);
925}
Bram Moolenaarc4956c82006-03-12 21:58:43 +0000926#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000927
928/*
929 * return TRUE if 'c' is a valid file-name character
930 * Assume characters above 0x100 are valid (multi-byte).
931 */
932 int
933vim_isfilec(c)
934 int c;
935{
936 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_FNAME_CHAR)));
937}
938
939/*
Bram Moolenaardd87969c2007-08-21 13:07:12 +0000940 * return TRUE if 'c' is a valid file-name character or a wildcard character
941 * Assume characters above 0x100 are valid (multi-byte).
942 * Explicitly interpret ']' as a wildcard character as mch_has_wildcard("]")
943 * returns false.
944 */
945 int
946vim_isfilec_or_wc(c)
947 int c;
948{
949 char_u buf[2];
950
951 buf[0] = (char_u)c;
952 buf[1] = NUL;
953 return vim_isfilec(c) || c == ']' || mch_has_wildcard(buf);
954}
955
956/*
Bram Moolenaar071d4272004-06-13 20:20:40 +0000957 * return TRUE if 'c' is a printable character
958 * Assume characters above 0x100 are printable (multi-byte), except for
959 * Unicode.
960 */
961 int
962vim_isprintc(c)
963 int c;
964{
965#ifdef FEAT_MBYTE
966 if (enc_utf8 && c >= 0x100)
967 return utf_printable(c);
968#endif
969 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR)));
970}
971
972/*
973 * Strict version of vim_isprintc(c), don't return TRUE if "c" is the head
974 * byte of a double-byte character.
975 */
976 int
977vim_isprintc_strict(c)
978 int c;
979{
980#ifdef FEAT_MBYTE
981 if (enc_dbcs != 0 && c < 0x100 && MB_BYTE2LEN(c) > 1)
982 return FALSE;
983 if (enc_utf8 && c >= 0x100)
984 return utf_printable(c);
985#endif
986 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR)));
987}
988
989/*
990 * like chartabsize(), but also check for line breaks on the screen
991 */
992 int
993lbr_chartabsize(s, col)
994 unsigned char *s;
995 colnr_T col;
996{
997#ifdef FEAT_LINEBREAK
998 if (!curwin->w_p_lbr && *p_sbr == NUL)
999 {
1000#endif
1001#ifdef FEAT_MBYTE
1002 if (curwin->w_p_wrap)
1003 return win_nolbr_chartabsize(curwin, s, col, NULL);
1004#endif
1005 RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
1006#ifdef FEAT_LINEBREAK
1007 }
1008 return win_lbr_chartabsize(curwin, s, col, NULL);
1009#endif
1010}
1011
1012/*
1013 * Call lbr_chartabsize() and advance the pointer.
1014 */
1015 int
1016lbr_chartabsize_adv(s, col)
1017 char_u **s;
1018 colnr_T col;
1019{
1020 int retval;
1021
1022 retval = lbr_chartabsize(*s, col);
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001023 mb_ptr_adv(*s);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001024 return retval;
1025}
1026
1027/*
1028 * This function is used very often, keep it fast!!!!
1029 *
1030 * If "headp" not NULL, set *headp to the size of what we for 'showbreak'
1031 * string at start of line. Warning: *headp is only set if it's a non-zero
1032 * value, init to 0 before calling.
1033 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001034 int
1035win_lbr_chartabsize(wp, s, col, headp)
1036 win_T *wp;
1037 char_u *s;
1038 colnr_T col;
Bram Moolenaar0c094b92009-05-14 20:20:33 +00001039 int *headp UNUSED;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001040{
1041#ifdef FEAT_LINEBREAK
1042 int c;
1043 int size;
1044 colnr_T col2;
1045 colnr_T colmax;
1046 int added;
1047# ifdef FEAT_MBYTE
1048 int mb_added = 0;
1049# else
1050# define mb_added 0
1051# endif
1052 int numberextra;
1053 char_u *ps;
1054 int tab_corr = (*s == TAB);
Bram Moolenaar402d2fe2005-04-15 21:00:38 +00001055 int n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001056
1057 /*
1058 * No 'linebreak' and 'showbreak': return quickly.
1059 */
1060 if (!wp->w_p_lbr && *p_sbr == NUL)
1061#endif
1062 {
1063#ifdef FEAT_MBYTE
1064 if (wp->w_p_wrap)
1065 return win_nolbr_chartabsize(wp, s, col, headp);
1066#endif
1067 RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col)
1068 }
1069
1070#ifdef FEAT_LINEBREAK
1071 /*
1072 * First get normal size, without 'linebreak'
1073 */
1074 size = win_chartabsize(wp, s, col);
1075 c = *s;
1076
1077 /*
1078 * If 'linebreak' set check at a blank before a non-blank if the line
1079 * needs a break here
1080 */
1081 if (wp->w_p_lbr
1082 && vim_isbreak(c)
1083 && !vim_isbreak(s[1])
1084 && !wp->w_p_list
1085 && wp->w_p_wrap
1086# ifdef FEAT_VERTSPLIT
1087 && wp->w_width != 0
1088# endif
1089 )
1090 {
1091 /*
1092 * Count all characters from first non-blank after a blank up to next
1093 * non-blank after a blank.
1094 */
1095 numberextra = win_col_off(wp);
1096 col2 = col;
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001097 colmax = (colnr_T)(W_WIDTH(wp) - numberextra);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001098 if (col >= colmax)
Bram Moolenaar402d2fe2005-04-15 21:00:38 +00001099 {
1100 n = colmax + win_col_off2(wp);
1101 if (n > 0)
1102 colmax += (((col - colmax) / n) + 1) * n;
1103 }
1104
Bram Moolenaar071d4272004-06-13 20:20:40 +00001105 for (;;)
1106 {
1107 ps = s;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001108 mb_ptr_adv(s);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001109 c = *s;
1110 if (!(c != NUL
1111 && (vim_isbreak(c)
1112 || (!vim_isbreak(c)
1113 && (col2 == col || !vim_isbreak(*ps))))))
1114 break;
1115
1116 col2 += win_chartabsize(wp, s, col2);
1117 if (col2 >= colmax) /* doesn't fit */
1118 {
1119 size = colmax - col;
1120 tab_corr = FALSE;
1121 break;
1122 }
1123 }
1124 }
1125# ifdef FEAT_MBYTE
1126 else if (has_mbyte && size == 2 && MB_BYTE2LEN(*s) > 1
1127 && wp->w_p_wrap && in_win_border(wp, col))
1128 {
1129 ++size; /* Count the ">" in the last column. */
1130 mb_added = 1;
1131 }
1132# endif
1133
1134 /*
1135 * May have to add something for 'showbreak' string at start of line
1136 * Set *headp to the size of what we add.
1137 */
1138 added = 0;
1139 if (*p_sbr != NUL && wp->w_p_wrap && col != 0)
1140 {
1141 numberextra = win_col_off(wp);
1142 col += numberextra + mb_added;
1143 if (col >= (colnr_T)W_WIDTH(wp))
1144 {
1145 col -= W_WIDTH(wp);
1146 numberextra = W_WIDTH(wp) - (numberextra - win_col_off2(wp));
1147 if (numberextra > 0)
1148 col = col % numberextra;
1149 }
1150 if (col == 0 || col + size > (colnr_T)W_WIDTH(wp))
1151 {
1152 added = vim_strsize(p_sbr);
1153 if (tab_corr)
1154 size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
1155 else
1156 size += added;
1157 if (col != 0)
1158 added = 0;
1159 }
1160 }
1161 if (headp != NULL)
1162 *headp = added + mb_added;
1163 return size;
1164#endif
1165}
1166
1167#if defined(FEAT_MBYTE) || defined(PROTO)
1168/*
1169 * Like win_lbr_chartabsize(), except that we know 'linebreak' is off and
1170 * 'wrap' is on. This means we need to check for a double-byte character that
1171 * doesn't fit at the end of the screen line.
1172 */
1173 static int
1174win_nolbr_chartabsize(wp, s, col, headp)
1175 win_T *wp;
1176 char_u *s;
1177 colnr_T col;
1178 int *headp;
1179{
1180 int n;
1181
1182 if (*s == TAB && (!wp->w_p_list || lcs_tab1))
1183 {
1184 n = wp->w_buffer->b_p_ts;
1185 return (int)(n - (col % n));
1186 }
1187 n = ptr2cells(s);
1188 /* Add one cell for a double-width character in the last column of the
1189 * window, displayed with a ">". */
1190 if (n == 2 && MB_BYTE2LEN(*s) > 1 && in_win_border(wp, col))
1191 {
1192 if (headp != NULL)
1193 *headp = 1;
1194 return 3;
1195 }
1196 return n;
1197}
1198
1199/*
1200 * Return TRUE if virtual column "vcol" is in the rightmost column of window
1201 * "wp".
1202 */
1203 int
1204in_win_border(wp, vcol)
1205 win_T *wp;
1206 colnr_T vcol;
1207{
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001208 int width1; /* width of first line (after line number) */
1209 int width2; /* width of further lines */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001210
1211#ifdef FEAT_VERTSPLIT
1212 if (wp->w_width == 0) /* there is no border */
1213 return FALSE;
1214#endif
1215 width1 = W_WIDTH(wp) - win_col_off(wp);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001216 if ((int)vcol < width1 - 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001217 return FALSE;
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001218 if ((int)vcol == width1 - 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001219 return TRUE;
1220 width2 = width1 + win_col_off2(wp);
Bram Moolenaar8701cd62009-10-07 14:20:30 +00001221 if (width2 <= 0)
1222 return FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001223 return ((vcol - width1) % width2 == width2 - 1);
1224}
1225#endif /* FEAT_MBYTE */
1226
1227/*
1228 * Get virtual column number of pos.
1229 * start: on the first position of this character (TAB, ctrl)
1230 * cursor: where the cursor is on this character (first char, except for TAB)
1231 * end: on the last position of this character (TAB, ctrl)
1232 *
1233 * This is used very often, keep it fast!
1234 */
1235 void
1236getvcol(wp, pos, start, cursor, end)
1237 win_T *wp;
1238 pos_T *pos;
1239 colnr_T *start;
1240 colnr_T *cursor;
1241 colnr_T *end;
1242{
1243 colnr_T vcol;
1244 char_u *ptr; /* points to current char */
1245 char_u *posptr; /* points to char at pos->col */
1246 int incr;
1247 int head;
1248 int ts = wp->w_buffer->b_p_ts;
1249 int c;
1250
1251 vcol = 0;
1252 ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
1253 posptr = ptr + pos->col;
1254
1255 /*
1256 * This function is used very often, do some speed optimizations.
1257 * When 'list', 'linebreak' and 'showbreak' are not set use a simple loop.
1258 * Also use this when 'list' is set but tabs take their normal size.
1259 */
1260 if ((!wp->w_p_list || lcs_tab1 != NUL)
1261#ifdef FEAT_LINEBREAK
1262 && !wp->w_p_lbr && *p_sbr == NUL
1263#endif
1264 )
1265 {
1266#ifndef FEAT_MBYTE
1267 head = 0;
1268#endif
1269 for (;;)
1270 {
1271#ifdef FEAT_MBYTE
1272 head = 0;
1273#endif
1274 c = *ptr;
1275 /* make sure we don't go past the end of the line */
1276 if (c == NUL)
1277 {
1278 incr = 1; /* NUL at end of line only takes one column */
1279 break;
1280 }
1281 /* A tab gets expanded, depending on the current column */
1282 if (c == TAB)
1283 incr = ts - (vcol % ts);
1284 else
1285 {
1286#ifdef FEAT_MBYTE
1287 if (has_mbyte)
1288 {
1289 /* For utf-8, if the byte is >= 0x80, need to look at
1290 * further bytes to find the cell width. */
1291 if (enc_utf8 && c >= 0x80)
1292 incr = utf_ptr2cells(ptr);
1293 else
1294 incr = CHARSIZE(c);
1295
1296 /* If a double-cell char doesn't fit at the end of a line
1297 * it wraps to the next line, it's like this char is three
1298 * cells wide. */
Bram Moolenaar9c33a7c2008-02-20 13:59:32 +00001299 if (incr == 2 && wp->w_p_wrap && MB_BYTE2LEN(*ptr) > 1
1300 && in_win_border(wp, vcol))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001301 {
1302 ++incr;
1303 head = 1;
1304 }
1305 }
1306 else
1307#endif
1308 incr = CHARSIZE(c);
1309 }
1310
1311 if (ptr >= posptr) /* character at pos->col */
1312 break;
1313
1314 vcol += incr;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001315 mb_ptr_adv(ptr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001316 }
1317 }
1318 else
1319 {
1320 for (;;)
1321 {
1322 /* A tab gets expanded, depending on the current column */
1323 head = 0;
1324 incr = win_lbr_chartabsize(wp, ptr, vcol, &head);
1325 /* make sure we don't go past the end of the line */
1326 if (*ptr == NUL)
1327 {
1328 incr = 1; /* NUL at end of line only takes one column */
1329 break;
1330 }
1331
1332 if (ptr >= posptr) /* character at pos->col */
1333 break;
1334
1335 vcol += incr;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001336 mb_ptr_adv(ptr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001337 }
1338 }
1339 if (start != NULL)
1340 *start = vcol + head;
1341 if (end != NULL)
1342 *end = vcol + incr - 1;
1343 if (cursor != NULL)
1344 {
1345 if (*ptr == TAB
1346 && (State & NORMAL)
1347 && !wp->w_p_list
1348 && !virtual_active()
1349#ifdef FEAT_VISUAL
1350 && !(VIsual_active
1351 && (*p_sel == 'e' || ltoreq(*pos, VIsual)))
1352#endif
1353 )
1354 *cursor = vcol + incr - 1; /* cursor at end */
1355 else
1356 *cursor = vcol + head; /* cursor at start */
1357 }
1358}
1359
1360/*
1361 * Get virtual cursor column in the current window, pretending 'list' is off.
1362 */
1363 colnr_T
1364getvcol_nolist(posp)
1365 pos_T *posp;
1366{
1367 int list_save = curwin->w_p_list;
1368 colnr_T vcol;
1369
1370 curwin->w_p_list = FALSE;
1371 getvcol(curwin, posp, NULL, &vcol, NULL);
1372 curwin->w_p_list = list_save;
1373 return vcol;
1374}
1375
1376#if defined(FEAT_VIRTUALEDIT) || defined(PROTO)
1377/*
1378 * Get virtual column in virtual mode.
1379 */
1380 void
1381getvvcol(wp, pos, start, cursor, end)
1382 win_T *wp;
1383 pos_T *pos;
1384 colnr_T *start;
1385 colnr_T *cursor;
1386 colnr_T *end;
1387{
1388 colnr_T col;
1389 colnr_T coladd;
1390 colnr_T endadd;
1391# ifdef FEAT_MBYTE
1392 char_u *ptr;
1393# endif
1394
1395 if (virtual_active())
1396 {
1397 /* For virtual mode, only want one value */
1398 getvcol(wp, pos, &col, NULL, NULL);
1399
1400 coladd = pos->coladd;
1401 endadd = 0;
1402# ifdef FEAT_MBYTE
1403 /* Cannot put the cursor on part of a wide character. */
1404 ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001405 if (pos->col < (colnr_T)STRLEN(ptr))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001406 {
1407 int c = (*mb_ptr2char)(ptr + pos->col);
1408
1409 if (c != TAB && vim_isprintc(c))
1410 {
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00001411 endadd = (colnr_T)(char2cells(c) - 1);
Bram Moolenaara5792f52005-11-23 21:25:05 +00001412 if (coladd > endadd) /* past end of line */
1413 endadd = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001414 else
1415 coladd = 0;
1416 }
1417 }
1418# endif
1419 col += coladd;
1420 if (start != NULL)
1421 *start = col;
1422 if (cursor != NULL)
1423 *cursor = col;
1424 if (end != NULL)
1425 *end = col + endadd;
1426 }
1427 else
1428 getvcol(wp, pos, start, cursor, end);
1429}
1430#endif
1431
1432#if defined(FEAT_VISUAL) || defined(PROTO)
1433/*
1434 * Get the leftmost and rightmost virtual column of pos1 and pos2.
1435 * Used for Visual block mode.
1436 */
1437 void
1438getvcols(wp, pos1, pos2, left, right)
1439 win_T *wp;
1440 pos_T *pos1, *pos2;
1441 colnr_T *left, *right;
1442{
1443 colnr_T from1, from2, to1, to2;
1444
1445 if (ltp(pos1, pos2))
1446 {
1447 getvvcol(wp, pos1, &from1, NULL, &to1);
1448 getvvcol(wp, pos2, &from2, NULL, &to2);
1449 }
1450 else
1451 {
1452 getvvcol(wp, pos2, &from1, NULL, &to1);
1453 getvvcol(wp, pos1, &from2, NULL, &to2);
1454 }
1455 if (from2 < from1)
1456 *left = from2;
1457 else
1458 *left = from1;
1459 if (to2 > to1)
1460 {
1461 if (*p_sel == 'e' && from2 - 1 >= to1)
1462 *right = from2 - 1;
1463 else
1464 *right = to2;
1465 }
1466 else
1467 *right = to1;
1468}
1469#endif
1470
1471/*
1472 * skipwhite: skip over ' ' and '\t'.
1473 */
1474 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001475skipwhite(q)
1476 char_u *q;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001477{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001478 char_u *p = q;
1479
Bram Moolenaar071d4272004-06-13 20:20:40 +00001480 while (vim_iswhite(*p)) /* skip to next non-white */
1481 ++p;
1482 return p;
1483}
1484
1485/*
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001486 * skip over digits
Bram Moolenaar071d4272004-06-13 20:20:40 +00001487 */
1488 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001489skipdigits(q)
1490 char_u *q;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001491{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001492 char_u *p = q;
1493
Bram Moolenaar071d4272004-06-13 20:20:40 +00001494 while (VIM_ISDIGIT(*p)) /* skip to next non-digit */
1495 ++p;
1496 return p;
1497}
1498
Bram Moolenaarc4956c82006-03-12 21:58:43 +00001499#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) || defined(PROTO)
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001500/*
1501 * skip over digits and hex characters
1502 */
1503 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001504skiphex(q)
1505 char_u *q;
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001506{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001507 char_u *p = q;
1508
Bram Moolenaar75c50c42005-06-04 22:06:24 +00001509 while (vim_isxdigit(*p)) /* skip to next non-digit */
1510 ++p;
1511 return p;
1512}
1513#endif
1514
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001515#if defined(FEAT_EX_EXTRA) || defined(PROTO)
1516/*
1517 * skip to digit (or NUL after the string)
1518 */
1519 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001520skiptodigit(q)
1521 char_u *q;
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001522{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001523 char_u *p = q;
1524
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001525 while (*p != NUL && !VIM_ISDIGIT(*p)) /* skip to next digit */
1526 ++p;
1527 return p;
1528}
1529
1530/*
1531 * skip to hex character (or NUL after the string)
1532 */
1533 char_u *
Bram Moolenaar1387a602008-07-24 19:31:11 +00001534skiptohex(q)
1535 char_u *q;
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001536{
Bram Moolenaar1387a602008-07-24 19:31:11 +00001537 char_u *p = q;
1538
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001539 while (*p != NUL && !vim_isxdigit(*p)) /* skip to next digit */
1540 ++p;
1541 return p;
1542}
1543#endif
1544
Bram Moolenaar071d4272004-06-13 20:20:40 +00001545/*
1546 * Variant of isdigit() that can handle characters > 0x100.
1547 * We don't use isdigit() here, because on some systems it also considers
1548 * superscript 1 to be a digit.
1549 * Use the VIM_ISDIGIT() macro for simple arguments.
1550 */
1551 int
1552vim_isdigit(c)
1553 int c;
1554{
1555 return (c >= '0' && c <= '9');
1556}
1557
1558/*
1559 * Variant of isxdigit() that can handle characters > 0x100.
1560 * We don't use isxdigit() here, because on some systems it also considers
1561 * superscript 1 to be a digit.
1562 */
1563 int
1564vim_isxdigit(c)
1565 int c;
1566{
1567 return (c >= '0' && c <= '9')
1568 || (c >= 'a' && c <= 'f')
1569 || (c >= 'A' && c <= 'F');
1570}
1571
Bram Moolenaar78622822005-08-23 21:00:13 +00001572#if defined(FEAT_MBYTE) || defined(PROTO)
1573/*
1574 * Vim's own character class functions. These exist because many library
1575 * islower()/toupper() etc. do not work properly: they crash when used with
1576 * invalid values or can't handle latin1 when the locale is C.
1577 * Speed is most important here.
1578 */
1579#define LATIN1LOWER 'l'
1580#define LATIN1UPPER 'U'
1581
1582/* !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]%_'abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ */
Bram Moolenaar6e7c7f32005-08-24 22:16:11 +00001583static char_u latin1flags[257] = " UUUUUUUUUUUUUUUUUUUUUUUUUU llllllllllllllllllllllllll UUUUUUUUUUUUUUUUUUUUUUU UUUUUUUllllllllllllllllllllllll llllllll";
1584static char_u latin1upper[257] = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ÷ØÙÚÛÜÝÞÿ";
1585static char_u latin1lower[257] = " !\"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿àáâãäåæçèéêëìíîïðñòóôõö×øùúûüýþßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ";
Bram Moolenaar78622822005-08-23 21:00:13 +00001586
1587 int
1588vim_islower(c)
1589 int c;
1590{
1591 if (c <= '@')
1592 return FALSE;
1593 if (c >= 0x80)
1594 {
1595 if (enc_utf8)
1596 return utf_islower(c);
1597 if (c >= 0x100)
1598 {
1599#ifdef HAVE_ISWLOWER
1600 if (has_mbyte)
1601 return iswlower(c);
1602#endif
1603 /* islower() can't handle these chars and may crash */
1604 return FALSE;
1605 }
1606 if (enc_latin1like)
1607 return (latin1flags[c] & LATIN1LOWER) == LATIN1LOWER;
1608 }
1609 return islower(c);
1610}
1611
1612 int
1613vim_isupper(c)
1614 int c;
1615{
1616 if (c <= '@')
1617 return FALSE;
1618 if (c >= 0x80)
1619 {
1620 if (enc_utf8)
1621 return utf_isupper(c);
1622 if (c >= 0x100)
1623 {
1624#ifdef HAVE_ISWUPPER
1625 if (has_mbyte)
1626 return iswupper(c);
1627#endif
1628 /* islower() can't handle these chars and may crash */
1629 return FALSE;
1630 }
1631 if (enc_latin1like)
1632 return (latin1flags[c] & LATIN1UPPER) == LATIN1UPPER;
1633 }
1634 return isupper(c);
1635}
1636
1637 int
1638vim_toupper(c)
1639 int c;
1640{
1641 if (c <= '@')
1642 return c;
1643 if (c >= 0x80)
1644 {
1645 if (enc_utf8)
1646 return utf_toupper(c);
1647 if (c >= 0x100)
1648 {
1649#ifdef HAVE_TOWUPPER
1650 if (has_mbyte)
1651 return towupper(c);
1652#endif
1653 /* toupper() can't handle these chars and may crash */
1654 return c;
1655 }
1656 if (enc_latin1like)
1657 return latin1upper[c];
1658 }
1659 return TOUPPER_LOC(c);
1660}
1661
1662 int
1663vim_tolower(c)
1664 int c;
1665{
1666 if (c <= '@')
1667 return c;
1668 if (c >= 0x80)
1669 {
1670 if (enc_utf8)
1671 return utf_tolower(c);
1672 if (c >= 0x100)
1673 {
1674#ifdef HAVE_TOWLOWER
1675 if (has_mbyte)
1676 return towlower(c);
1677#endif
1678 /* tolower() can't handle these chars and may crash */
1679 return c;
1680 }
1681 if (enc_latin1like)
1682 return latin1lower[c];
1683 }
1684 return TOLOWER_LOC(c);
1685}
1686#endif
1687
Bram Moolenaar071d4272004-06-13 20:20:40 +00001688/*
1689 * skiptowhite: skip over text until ' ' or '\t' or NUL.
1690 */
1691 char_u *
1692skiptowhite(p)
1693 char_u *p;
1694{
1695 while (*p != ' ' && *p != '\t' && *p != NUL)
1696 ++p;
1697 return p;
1698}
1699
1700#if defined(FEAT_LISTCMDS) || defined(FEAT_SIGNS) || defined(FEAT_SNIFF) \
1701 || defined(PROTO)
1702/*
1703 * skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
1704 */
1705 char_u *
1706skiptowhite_esc(p)
1707 char_u *p;
1708{
1709 while (*p != ' ' && *p != '\t' && *p != NUL)
1710 {
1711 if ((*p == '\\' || *p == Ctrl_V) && *(p + 1) != NUL)
1712 ++p;
1713 ++p;
1714 }
1715 return p;
1716}
1717#endif
1718
1719/*
1720 * Getdigits: Get a number from a string and skip over it.
1721 * Note: the argument is a pointer to a char_u pointer!
1722 */
1723 long
1724getdigits(pp)
1725 char_u **pp;
1726{
1727 char_u *p;
1728 long retval;
1729
1730 p = *pp;
1731 retval = atol((char *)p);
1732 if (*p == '-') /* skip negative sign */
1733 ++p;
1734 p = skipdigits(p); /* skip to next non-digit */
1735 *pp = p;
1736 return retval;
1737}
1738
1739/*
1740 * Return TRUE if "lbuf" is empty or only contains blanks.
1741 */
1742 int
1743vim_isblankline(lbuf)
1744 char_u *lbuf;
1745{
1746 char_u *p;
1747
1748 p = skipwhite(lbuf);
1749 return (*p == NUL || *p == '\r' || *p == '\n');
1750}
1751
1752/*
1753 * Convert a string into a long and/or unsigned long, taking care of
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00001754 * hexadecimal and octal numbers. Accepts a '-' sign.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001755 * If "hexp" is not NULL, returns a flag to indicate the type of the number:
1756 * 0 decimal
1757 * '0' octal
1758 * 'X' hex
1759 * 'x' hex
1760 * If "len" is not NULL, the length of the number in characters is returned.
1761 * If "nptr" is not NULL, the signed result is returned in it.
1762 * If "unptr" is not NULL, the unsigned result is returned in it.
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001763 * If "dooct" is non-zero recognize octal numbers, when > 1 always assume
1764 * octal number.
Bram Moolenaar97b2ad32006-03-18 21:40:56 +00001765 * If "dohex" is non-zero recognize hex numbers, when > 1 always assume
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001766 * hex number.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001767 */
1768 void
1769vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr)
1770 char_u *start;
1771 int *hexp; /* return: type of number 0 = decimal, 'x'
1772 or 'X' is hex, '0' = octal */
1773 int *len; /* return: detected length of number */
1774 int dooct; /* recognize octal number */
1775 int dohex; /* recognize hex number */
1776 long *nptr; /* return: signed result */
1777 unsigned long *unptr; /* return: unsigned result */
1778{
1779 char_u *ptr = start;
1780 int hex = 0; /* default is decimal */
1781 int negative = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001782 unsigned long un = 0;
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001783 int n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001784
1785 if (ptr[0] == '-')
1786 {
1787 negative = TRUE;
1788 ++ptr;
1789 }
1790
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001791 /* Recognize hex and octal. */
1792 if (ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001793 {
1794 hex = ptr[1];
1795 if (dohex && (hex == 'X' || hex == 'x') && vim_isxdigit(ptr[2]))
1796 ptr += 2; /* hexadecimal */
1797 else
1798 {
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001799 hex = 0; /* default is decimal */
1800 if (dooct)
1801 {
1802 /* Don't interpret "0", "08" or "0129" as octal. */
1803 for (n = 1; VIM_ISDIGIT(ptr[n]); ++n)
1804 {
1805 if (ptr[n] > '7')
1806 {
1807 hex = 0; /* can't be octal */
1808 break;
1809 }
1810 if (ptr[n] > '0')
1811 hex = '0'; /* assume octal */
1812 }
1813 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001814 }
1815 }
1816
1817 /*
1818 * Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
1819 */
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001820 if (hex == '0' || dooct > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001821 {
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001822 /* octal */
1823 while ('0' <= *ptr && *ptr <= '7')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001824 {
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001825 un = 8 * un + (unsigned long)(*ptr - '0');
1826 ++ptr;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001827 }
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001828 }
1829 else if (hex != 0 || dohex > 1)
1830 {
1831 /* hex */
1832 while (vim_isxdigit(*ptr))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001833 {
Bram Moolenaar5c06f8b2005-05-31 22:14:58 +00001834 un = 16 * un + (unsigned long)hex2nr(*ptr);
1835 ++ptr;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001836 }
1837 }
1838 else
1839 {
1840 /* decimal */
1841 while (VIM_ISDIGIT(*ptr))
1842 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001843 un = 10 * un + (unsigned long)(*ptr - '0');
1844 ++ptr;
1845 }
1846 }
1847
Bram Moolenaar071d4272004-06-13 20:20:40 +00001848 if (hexp != NULL)
1849 *hexp = hex;
1850 if (len != NULL)
1851 *len = (int)(ptr - start);
1852 if (nptr != NULL)
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00001853 {
1854 if (negative) /* account for leading '-' for decimal numbers */
1855 *nptr = -(long)un;
1856 else
1857 *nptr = (long)un;
1858 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001859 if (unptr != NULL)
1860 *unptr = un;
1861}
1862
1863/*
1864 * Return the value of a single hex character.
1865 * Only valid when the argument is '0' - '9', 'A' - 'F' or 'a' - 'f'.
1866 */
1867 int
1868hex2nr(c)
1869 int c;
1870{
1871 if (c >= 'a' && c <= 'f')
1872 return c - 'a' + 10;
1873 if (c >= 'A' && c <= 'F')
1874 return c - 'A' + 10;
1875 return c - '0';
1876}
1877
1878#if defined(FEAT_TERMRESPONSE) \
1879 || (defined(FEAT_GUI_GTK) && defined(FEAT_WINDOWS)) || defined(PROTO)
1880/*
1881 * Convert two hex characters to a byte.
1882 * Return -1 if one of the characters is not hex.
1883 */
1884 int
1885hexhex2nr(p)
1886 char_u *p;
1887{
1888 if (!vim_isxdigit(p[0]) || !vim_isxdigit(p[1]))
1889 return -1;
1890 return (hex2nr(p[0]) << 4) + hex2nr(p[1]);
1891}
1892#endif
1893
1894/*
1895 * Return TRUE if "str" starts with a backslash that should be removed.
1896 * For MS-DOS, WIN32 and OS/2 this is only done when the character after the
1897 * backslash is not a normal file name character.
1898 * '$' is a valid file name character, we don't remove the backslash before
1899 * it. This means it is not possible to use an environment variable after a
1900 * backslash. "C:\$VIM\doc" is taken literally, only "$VIM\doc" works.
1901 * Although "\ name" is valid, the backslash in "Program\ files" must be
1902 * removed. Assume a file name doesn't start with a space.
1903 * For multi-byte names, never remove a backslash before a non-ascii
1904 * character, assume that all multi-byte characters are valid file name
1905 * characters.
1906 */
1907 int
1908rem_backslash(str)
1909 char_u *str;
1910{
1911#ifdef BACKSLASH_IN_FILENAME
1912 return (str[0] == '\\'
1913# ifdef FEAT_MBYTE
1914 && str[1] < 0x80
1915# endif
1916 && (str[1] == ' '
1917 || (str[1] != NUL
1918 && str[1] != '*'
1919 && str[1] != '?'
1920 && !vim_isfilec(str[1]))));
1921#else
1922 return (str[0] == '\\' && str[1] != NUL);
1923#endif
1924}
1925
1926/*
1927 * Halve the number of backslashes in a file name argument.
1928 * For MS-DOS we only do this if the character after the backslash
1929 * is not a normal file character.
1930 */
1931 void
1932backslash_halve(p)
1933 char_u *p;
1934{
1935 for ( ; *p; ++p)
1936 if (rem_backslash(p))
Bram Moolenaar446cb832008-06-24 21:56:24 +00001937 STRMOVE(p, p + 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001938}
1939
1940/*
1941 * backslash_halve() plus save the result in allocated memory.
1942 */
1943 char_u *
1944backslash_halve_save(p)
1945 char_u *p;
1946{
1947 char_u *res;
1948
1949 res = vim_strsave(p);
1950 if (res == NULL)
1951 return p;
1952 backslash_halve(res);
1953 return res;
1954}
1955
1956#if (defined(EBCDIC) && defined(FEAT_POSTSCRIPT)) || defined(PROTO)
1957/*
1958 * Table for EBCDIC to ASCII conversion unashamedly taken from xxd.c!
1959 * The first 64 entries have been added to map control characters defined in
1960 * ascii.h
1961 */
1962static char_u ebcdic2ascii_tab[256] =
1963{
1964 0000, 0001, 0002, 0003, 0004, 0011, 0006, 0177,
1965 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
1966 0020, 0021, 0022, 0023, 0024, 0012, 0010, 0027,
1967 0030, 0031, 0032, 0033, 0033, 0035, 0036, 0037,
1968 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
1969 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
1970 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
1971 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
1972 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
1973 0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
1974 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
1975 0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
1976 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
1977 0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
1978 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
1979 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
1980 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
1981 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
1982 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
1983 0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
1984 0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
1985 0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
1986 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
1987 0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
1988 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
1989 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
1990 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
1991 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
1992 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
1993 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
1994 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
1995 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377
1996};
1997
1998/*
1999 * Convert a buffer worth of characters from EBCDIC to ASCII. Only useful if
2000 * wanting 7-bit ASCII characters out the other end.
2001 */
2002 void
2003ebcdic2ascii(buffer, len)
2004 char_u *buffer;
2005 int len;
2006{
2007 int i;
2008
2009 for (i = 0; i < len; i++)
2010 buffer[i] = ebcdic2ascii_tab[buffer[i]];
2011}
2012#endif