1 #ifndef NVIM_ASCII_H
2 #define NVIM_ASCII_H
3 
4 #include <stdbool.h>
5 
6 #include "nvim/func_attr.h"
7 #include "nvim/macros.h"
8 #include "nvim/os/os_defs.h"
9 
10 // Definitions of various common control characters.
11 
12 #define CharOrd(x)      ((uint8_t)(x) < 'a' \
13                          ? (uint8_t)(x) - 'A' \
14                          : (uint8_t)(x) - 'a')
15 #define CharOrdLow(x)   ((uint8_t)(x) - 'a')
16 #define CharOrdUp(x)    ((uint8_t)(x) - 'A')
17 #define ROT13(c, a)     (((((c) - (a)) + 13) % 26) + (a))
18 
19 #define NUL             '\000'
20 #define BELL            '\007'
21 #define BS              '\010'
22 #define TAB             '\011'
23 #define NL              '\012'
24 #define NL_STR          "\012"
25 #define FF              '\014'
26 #define CAR             '\015'  // CR is used by Mac OS X
27 #define ESC             '\033'
28 #define ESC_STR         "\033"
29 #define DEL             0x7f
30 #define DEL_STR         "\177"
31 #define CSI             0x9b    // Control Sequence Introducer
32 #define CSI_STR         "\233"
33 #define DCS             0x90    // Device Control String
34 #define STERM           0x9c    // String Terminator
35 
36 #define POUND           0xA3
37 
38 #define Ctrl_chr(x)     (TOUPPER_ASC(x) ^ 0x40)  // '?' -> DEL, '@' -> ^@, etc.
39 #define Meta(x)         ((x) | 0x80)
40 
41 #define CTRL_F_STR      "\006"
42 #define CTRL_H_STR      "\010"
43 #define CTRL_V_STR      "\026"
44 
45 #define Ctrl_AT         0   // @
46 #define Ctrl_A          1
47 #define Ctrl_B          2
48 #define Ctrl_C          3
49 #define Ctrl_D          4
50 #define Ctrl_E          5
51 #define Ctrl_F          6
52 #define Ctrl_G          7
53 #define Ctrl_H          8
54 #define Ctrl_I          9
55 #define Ctrl_J          10
56 #define Ctrl_K          11
57 #define Ctrl_L          12
58 #define Ctrl_M          13
59 #define Ctrl_N          14
60 #define Ctrl_O          15
61 #define Ctrl_P          16
62 #define Ctrl_Q          17
63 #define Ctrl_R          18
64 #define Ctrl_S          19
65 #define Ctrl_T          20
66 #define Ctrl_U          21
67 #define Ctrl_V          22
68 #define Ctrl_W          23
69 #define Ctrl_X          24
70 #define Ctrl_Y          25
71 #define Ctrl_Z          26
72 // CTRL- [ Left Square Bracket == ESC
73 #define Ctrl_BSL        28  // \ BackSLash
74 #define Ctrl_RSB        29  // ] Right Square Bracket
75 #define Ctrl_HAT        30  // ^
76 #define Ctrl__          31
77 
78 
79 // Character that separates dir names in a path.
80 #ifdef BACKSLASH_IN_FILENAME
81 # define PATHSEP        psepc
82 # define PATHSEPSTR     pseps
83 #else
84 # define PATHSEP        '/'
85 # define PATHSEPSTR     "/"
86 #endif
87 
88 static inline bool ascii_iswhite(int)
89   REAL_FATTR_CONST
90   REAL_FATTR_ALWAYS_INLINE;
91 
92 static inline bool ascii_iswhite_or_nul(int)
93   REAL_FATTR_CONST
94   REAL_FATTR_ALWAYS_INLINE;
95 
96 static inline bool ascii_isdigit(int)
97   REAL_FATTR_CONST
98   REAL_FATTR_ALWAYS_INLINE;
99 
100 static inline bool ascii_isxdigit(int)
101   REAL_FATTR_CONST
102   REAL_FATTR_ALWAYS_INLINE;
103 
104 static inline bool ascii_isident(int)
105   REAL_FATTR_CONST
106   REAL_FATTR_ALWAYS_INLINE;
107 
108 static inline bool ascii_isbdigit(int)
109   REAL_FATTR_CONST
110   REAL_FATTR_ALWAYS_INLINE;
111 
112 static inline bool ascii_isspace(int)
113   REAL_FATTR_CONST
114   REAL_FATTR_ALWAYS_INLINE;
115 
116 /// Checks if `c` is a space or tab character.
117 ///
118 /// @see {ascii_isdigit}
ascii_iswhite(int c)119 static inline bool ascii_iswhite(int c)
120 {
121   return c == ' ' || c == '\t';
122 }
123 
124 /// Checks if `c` is a space or tab character or NUL.
125 ///
126 /// @see {ascii_isdigit}
ascii_iswhite_or_nul(int c)127 static inline bool ascii_iswhite_or_nul(int c)
128 {
129   return ascii_iswhite(c) || c == NUL;
130 }
131 
132 /// Check whether character is a decimal digit.
133 ///
134 /// Library isdigit() function is officially locale-dependent and, for
135 /// example, returns true for superscript 1 (¹) in locales where encoding
136 /// contains it in lower 8 bits. Also avoids crashes in case c is below
137 /// 0 or above 255: library functions are officially defined as accepting
138 /// only EOF and unsigned char values (otherwise it is undefined behaviour)
139 /// what may be used for some optimizations (e.g. simple `return
140 /// isdigit_table[c];`).
ascii_isdigit(int c)141 static inline bool ascii_isdigit(int c)
142 {
143   return c >= '0' && c <= '9';
144 }
145 
146 /// Checks if `c` is a hexadecimal digit, that is, one of 0-9, a-f, A-F.
147 ///
148 /// @see {ascii_isdigit}
ascii_isxdigit(int c)149 static inline bool ascii_isxdigit(int c)
150 {
151   return (c >= '0' && c <= '9')
152          || (c >= 'a' && c <= 'f')
153          || (c >= 'A' && c <= 'F');
154 }
155 
156 /// Checks if `c` is an “identifier” character
157 ///
158 /// That is, whether it is alphanumeric character or underscore.
ascii_isident(int c)159 static inline bool ascii_isident(int c)
160 {
161   return ASCII_ISALNUM(c) || c == '_';
162 }
163 
164 /// Checks if `c` is a binary digit, that is, 0-1.
165 ///
166 /// @see {ascii_isdigit}
ascii_isbdigit(int c)167 static inline bool ascii_isbdigit(int c)
168 {
169   return (c == '0' || c == '1');
170 }
171 
172 /// Checks if `c` is an octal digit, that is, 0-7.
173 ///
174 /// @see {ascii_isdigit}
ascii_isodigit(int c)175 static inline bool ascii_isodigit(int c)
176 {
177   return (c >= '0' && c <= '7');
178 }
179 
180 /// Checks if `c` is a white-space character, that is,
181 /// one of \f, \n, \r, \t, \v.
182 ///
183 /// @see {ascii_isdigit}
ascii_isspace(int c)184 static inline bool ascii_isspace(int c)
185 {
186   return (c >= 9 && c <= 13) || c == ' ';
187 }
188 
189 #endif  // NVIM_ASCII_H
190