35
static int chartab_initialized = FALSE;
35
static bool chartab_initialized = false;
37
// b_chartab[] is an array of 32 bytes, each bit representing one of the
37
// b_chartab[] is an array with 256 bits, each bit representing one of the
38
38
// characters 0-255.
39
39
#define SET_CHARTAB(buf, c) \
40
(buf)->b_chartab[(unsigned)(c) >> 3] |= (1 << ((c) & 0x7))
40
(buf)->b_chartab[(unsigned)(c) >> 6] |= (1ull << ((c) & 0x3f))
41
41
#define RESET_CHARTAB(buf, c) \
42
(buf)->b_chartab[(unsigned)(c) >> 3] &= ~(1 << ((c) & 0x7))
42
(buf)->b_chartab[(unsigned)(c) >> 6] &= ~(1ull << ((c) & 0x3f))
43
43
#define GET_CHARTAB(buf, c) \
44
((buf)->b_chartab[(unsigned)(c) >> 3] & (1 << ((c) & 0x7)))
44
((buf)->b_chartab[(unsigned)(c) >> 6] & (1ull << ((c) & 0x3f)))
46
46
/// Fill chartab[]. Also fills curbuf->b_chartab[] with flags for keyword
47
47
/// characters for current buffer.
69
69
/// an error, OK otherwise.
70
70
int init_chartab(void)
72
return buf_init_chartab(curbuf, TRUE);
72
return buf_init_chartab(curbuf, true);
75
75
/// Helper for init_chartab
77
/// @param global FALSE: only set buf->b_chartab[]
77
/// @param global false: only set buf->b_chartab[]
79
79
/// @return FAIL if 'iskeyword', 'isident', 'isfname' or 'isprint' option has
80
80
/// an error, OK otherwise.
91
91
// Set the default size for printable characters:
92
92
// From <Space> to '~' is 1 (printable), others are 2 (not printable).
93
// This also inits all 'isident' and 'isfname' flags to FALSE.
93
// This also inits all 'isident' and 'isfname' flags to false.
244
244
|| (p_altkeymap && (F_isalpha(c) || F_isdigit(c))))
245
245
&& !(enc_dbcs && (MB_BYTE2LEN(c) == 2))) {
247
chartab[c] = (chartab[c] & ~CT_CELL_MASK)
248
+ ((dy_flags & DY_UHEX) ? 4 : 2);
249
chartab[c] &= ~CT_PRINT_CHAR;
247
chartab[c] = (uint8_t)((chartab[c] & ~CT_CELL_MASK)
248
+ ((dy_flags & DY_UHEX) ? 4 : 2));
249
chartab[c] &= (uint8_t)~CT_PRINT_CHAR;
251
chartab[c] = (chartab[c] & ~CT_CELL_MASK) + 1;
251
chartab[c] = (uint8_t)((chartab[c] & ~CT_CELL_MASK) + 1);
252
252
chartab[c] |= CT_PRINT_CHAR;
255
255
} else if (i == 2) {
256
256
// (re)set fname flag
258
chartab[c] &= ~CT_FNAME_CHAR;
258
chartab[c] &= (uint8_t)~CT_FNAME_CHAR;
260
260
chartab[c] |= CT_FNAME_CHAR;
477
478
i += (*mb_ptr2len)(STR_PTR(i));
479
480
if (buf == NULL) {
480
GA_CHAR(i) = TOLOWER_LOC(GA_CHAR(i));
481
GA_CHAR(i) = (char_u)TOLOWER_LOC(GA_CHAR(i));
482
buf[i] = TOLOWER_LOC(buf[i]);
483
buf[i] = (char_u)TOLOWER_LOC(buf[i]);
494
495
// Catch 22: chartab[] can't be initialized before the options are
495
496
// initialized, and initializing options may cause transchar() to be called!
496
// When chartab_initialized == FALSE don't use chartab[].
497
// When chartab_initialized == false don't use chartab[].
497
498
// Does NOT work for multi-byte characters, c must be <= 255.
498
499
// Also doesn't work for the first byte of a multi-byte, "c" must be a
518
519
if ((!chartab_initialized && (((c >= ' ') && (c <= '~')) || F_ischar(c)))
519
520
|| ((c < 256) && vim_isprintc_strict(c))) {
520
521
// printable character
521
transchar_buf[i] = c;
522
transchar_buf[i] = (char_u)c;
522
523
transchar_buf[i + 1] = NUL;
524
525
transchar_nonprint(transchar_buf + i, c);
595
buf[++i] = nr2hex((unsigned)c >> 12);
596
buf[++i] = nr2hex((unsigned)c >> 8);
596
buf[++i] = (char_u)nr2hex((unsigned)c >> 12);
597
buf[++i] = (char_u)nr2hex((unsigned)c >> 8);
598
buf[++i] = nr2hex((unsigned)c >> 4);
599
buf[++i] = nr2hex((unsigned)c);
599
buf[++i] = (char_u)(nr2hex((unsigned)c >> 4));
600
buf[++i] = (char_u)(nr2hex((unsigned)c));
734
735
/// @return Number of characters.
735
736
#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
736
737
if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) { \
738
ts = (buf)->b_p_ts; \
739
return (int)(ts - (col % ts)); \
738
const int ts = (int) (buf)->b_p_ts; \
739
return (ts - (int)(col % ts)); \
741
741
return ptr2cells(p); \
799
799
return (unsigned int)col;
802
/// Return TRUE if 'c' is a normal identifier character:
802
/// Check that "c" is a normal identifier character:
804
803
/// Letters and characters from the 'isident' option.
808
/// @return TRUE if 'c' is a normal identifier character.
805
/// @param c character to check
806
bool vim_isIDc(int c)
807
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
811
809
return c > 0 && c < 0x100 && (chartab[c] & CT_ID_CHAR);
814
/// return TRUE if 'c' is a keyword character: Letters and characters from
815
/// 'iskeyword' option for current buffer.
812
/// Check that "c" is a keyword character:
813
/// Letters and characters from 'iskeyword' option for current buffer.
817
814
/// For multi-byte characters mb_get_class() is used (builtin rules).
821
/// @return TRUE if 'c' is a keyword character.
822
int vim_iswordc(int c)
816
/// @param c character to check
817
bool vim_iswordc(int c)
818
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
824
820
return vim_iswordc_buf(c, curbuf);
827
int vim_iswordc_buf(int c, buf_T *buf)
823
/// Check that "c" is a keyword character:
824
/// Letters and characters from 'iskeyword' option for given buffer.
825
/// For multi-byte characters mb_get_class() is used (builtin rules).
827
/// @param c character to check
828
/// @param buf buffer whose keywords to use
829
bool vim_iswordc_buf(int c, buf_T *buf)
830
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(2)
829
832
if (c >= 0x100) {
830
833
if (enc_dbcs != 0) {
841
844
/// Just like vim_iswordc() but uses a pointer to the (multi-byte) character.
846
/// @param p pointer to the multi-byte character
845
/// @return TRUE if 'p' points to a keyword character.
846
int vim_iswordp(char_u *p)
848
/// @return true if "p" points to a keyword character.
849
bool vim_iswordp(char_u *p)
850
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
848
852
if (has_mbyte && (MB_BYTE2LEN(*p) > 1)) {
849
853
return mb_get_class(p) >= 2;
851
855
return GET_CHARTAB(curbuf, *p) != 0;
854
int vim_iswordp_buf(char_u *p, buf_T *buf)
858
/// Just like vim_iswordc_buf() but uses a pointer to the (multi-byte)
861
/// @param p pointer to the multi-byte character
862
/// @param buf buffer whose keywords to use
864
/// @return true if "p" points to a keyword character.
865
bool vim_iswordp_buf(char_u *p, buf_T *buf)
866
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
856
868
if (has_mbyte && (MB_BYTE2LEN(*p) > 1)) {
857
869
return mb_get_class(p) >= 2;
859
871
return GET_CHARTAB(buf, *p) != 0;
862
/// return TRUE if 'c' is a valid file-name character
874
/// Check that "c" is a valid file-name character.
863
875
/// Assume characters above 0x100 are valid (multi-byte).
867
/// @return TRUE if 'c' is a valid file name character.
868
int vim_isfilec(int c)
877
/// @param c character to check
878
bool vim_isfilec(int c)
879
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
870
881
return c >= 0x100 || (c > 0 && (chartab[c] & CT_FNAME_CHAR));
873
/// return TRUE if 'c' is a valid file-name character or a wildcard character
884
/// Check that "c" is a valid file-name character or a wildcard character
874
885
/// Assume characters above 0x100 are valid (multi-byte).
875
886
/// Explicitly interpret ']' as a wildcard character as path_has_wildcard("]")
876
887
/// returns false.
880
/// @return TRUE if 'c' is a valid file-name character or wildcard character.
881
int vim_isfilec_or_wc(int c)
889
/// @param c character to check
890
bool vim_isfilec_or_wc(int c)
891
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
884
894
buf[0] = (char_u)c;
886
896
return vim_isfilec(c) || c == ']' || path_has_wildcard(buf);
889
/// return TRUE if 'c' is a printable character
890
/// Assume characters above 0x100 are printable (multi-byte), except for
895
/// @return TRUE if 'c' a printable character.
896
int vim_isprintc(int c)
899
/// Check that "c" is a printable character.
900
/// Assume characters above 0x100 are printable for double-byte encodings.
902
/// @param c character to check
903
bool vim_isprintc(int c)
904
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
898
906
if (enc_utf8 && (c >= 0x100)) {
899
907
return utf_printable(c);
901
909
return c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR));
904
/// Strict version of vim_isprintc(c), don't return TRUE if "c" is the head
912
/// Strict version of vim_isprintc(c), don't return true if "c" is the head
905
913
/// byte of a double-byte character.
915
/// @param c character to check
909
/// @return TRUE if 'c' is a printable character.
910
int vim_isprintc_strict(int c)
917
/// @return true if "c" is a printable character.
918
bool vim_isprintc_strict(int c)
919
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
912
921
if ((enc_dbcs != 0) && (c < 0x100) && (MB_BYTE2LEN(c) > 1)) {
916
925
if (enc_utf8 && (c >= 0x100)) {
1147
/// Return TRUE if virtual column "vcol" is in the rightmost column of window
1153
/// @return TRUE if the virtual column is in the rightmost column.
1154
int in_win_border(win_T *wp, colnr_T vcol)
1156
/// Check that virtual column "vcol" is in the rightmost column of window "wp".
1158
/// @param wp window
1159
/// @param vcol column number
1160
bool in_win_border(win_T *wp, colnr_T vcol)
1161
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1)
1156
1163
int width1; // width of first line (after line number)
1157
1164
int width2; // width of further lines
1159
1166
if (wp->w_width == 0) {
1160
1167
// there is no border
1163
1170
width1 = wp->w_width - win_col_off(wp);
1165
1172
if ((int)vcol < width1 - 1) {
1169
1176
if ((int)vcol == width1 - 1) {
1172
1179
width2 = width1 + win_col_off2(wp);
1174
1181
if (width2 <= 0) {
1177
1184
return (vcol - width1) % width2 == width2 - 1;
1198
1205
char_u *line; // start of the line
1201
int ts = wp->w_buffer->b_p_ts;
1208
int ts = (int)wp->w_buffer->b_p_ts;
1205
line = ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
1212
line = ptr = ml_get_buf(wp->w_buffer, pos->lnum, false);
1207
1214
if (pos->col == MAXCOL) {
1208
1215
// continue until the NUL
1322
1329
int list_save = curwin->w_p_list;
1325
curwin->w_p_list = FALSE;
1332
curwin->w_p_list = false;
1326
1333
getvcol(curwin, posp, NULL, &vcol, NULL);
1327
1334
curwin->w_p_list = list_save;
1353
1360
// Cannot put the cursor on part of a wide character.
1354
ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
1361
ptr = ml_get_buf(wp->w_buffer, pos->lnum, false);
1356
1363
if (pos->col < (colnr_T)STRLEN(ptr)) {
1357
1364
int c = (*mb_ptr2char)(ptr + pos->col);
1571
1578
"\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee"
1572
1579
"\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
1574
int vim_islower(int c)
1581
/// Check that the character is lower-case
1583
/// @param c character to check
1584
bool vim_islower(int c)
1585
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
1576
1587
if (c <= '@') {
1580
1591
if (c >= 0x80) {
1744
1759
return (long)number;
1747
/// Return TRUE if "lbuf" is empty or only contains blanks.
1751
/// @return TRUE if `lbuf` is empty or only contains blanks.
1752
int vim_isblankline(char_u *lbuf)
1762
/// Check that "lbuf" is empty or only contains blanks.
1764
/// @param lbuf line buffer to check
1765
bool vim_isblankline(char_u *lbuf)
1754
1767
char_u *p = skipwhite(lbuf);
1755
1768
return *p == NUL || *p == '\r' || *p == '\n';
1922
1935
return c - '0';
1925
/// Return true if "str" starts with a backslash that should be removed.
1926
/// For WIN32 this is only done when the character after the
1938
/// Check that "str" starts with a backslash that should be removed.
1939
/// For Windows this is only done when the character after the
1927
1940
/// backslash is not a normal file name character.
1928
1941
/// '$' is a valid file name character, we don't remove the backslash before
1929
1942
/// it. This means it is not possible to use an environment variable after a
1934
1947
/// character, assume that all multi-byte characters are valid file name
1935
1948
/// characters.
1939
/// @return true if `str` starts with a backslash that should be removed.
1950
/// @param str file path string to check
1940
1951
bool rem_backslash(const char_u *str)
1952
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
1942
1954
#ifdef BACKSLASH_IN_FILENAME
1943
1955
return str[0] == '\\'