aboutsummaryrefslogtreecommitdiffstats
path: root/src/syntax.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/syntax.c')
-rw-r--r--src/syntax.c272
1 files changed, 200 insertions, 72 deletions
diff --git a/src/syntax.c b/src/syntax.c
index ea15cf68c43..6d52d115889 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -20,6 +20,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21#include <config.h> 21#include <config.h>
22 22
23#define SYNTAX_INLINE EXTERN_INLINE
24
23#include <sys/types.h> 25#include <sys/types.h>
24 26
25#include "lisp.h" 27#include "lisp.h"
@@ -58,54 +60,86 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
58 For style c (like the nested flag), the flag can be placed on any of 60 For style c (like the nested flag), the flag can be placed on any of
59 the chars. */ 61 the chars. */
60 62
61/* These macros extract specific flags from an integer 63/* These functions extract specific flags from an integer
62 that holds the syntax code and the flags. */ 64 that holds the syntax code and the flags. */
63 65
64#define SYNTAX_FLAGS_COMSTART_FIRST(flags) (((flags) >> 16) & 1) 66static bool
65 67SYNTAX_FLAGS_COMSTART_FIRST (int flags)
66#define SYNTAX_FLAGS_COMSTART_SECOND(flags) (((flags) >> 17) & 1) 68{
67 69 return (flags >> 16) & 1;
68#define SYNTAX_FLAGS_COMEND_FIRST(flags) (((flags) >> 18) & 1) 70}
69 71static bool
70#define SYNTAX_FLAGS_COMEND_SECOND(flags) (((flags) >> 19) & 1) 72SYNTAX_FLAGS_COMSTART_SECOND (int flags)
71 73{
72#define SYNTAX_FLAGS_PREFIX(flags) (((flags) >> 20) & 1) 74 return (flags >> 17) & 1;
75}
76static bool
77SYNTAX_FLAGS_COMEND_FIRST (int flags)
78{
79 return (flags >> 18) & 1;
80}
81static bool
82SYNTAX_FLAGS_COMEND_SECOND (int flags)
83{
84 return (flags >> 19) & 1;
85}
86static bool
87SYNTAX_FLAGS_PREFIX (int flags)
88{
89 return (flags >> 20) & 1;
90}
91static bool
92SYNTAX_FLAGS_COMMENT_STYLEB (int flags)
93{
94 return (flags >> 21) & 1;
95}
96static bool
97SYNTAX_FLAGS_COMMENT_STYLEC (int flags)
98{
99 return (flags >> 23) & 1;
100}
101static int
102SYNTAX_FLAGS_COMMENT_STYLEC2 (int flags)
103{
104 return (flags >> 22) & 2; /* SYNTAX_FLAGS_COMMENT_STYLEC (flags) * 2 */
105}
106static bool
107SYNTAX_FLAGS_COMMENT_NESTED (int flags)
108{
109 return (flags >> 22) & 1;
110}
73 111
74#define SYNTAX_FLAGS_COMMENT_STYLEB(flags) (((flags) >> 21) & 1)
75#define SYNTAX_FLAGS_COMMENT_STYLEC(flags) (((flags) >> 23) & 1)
76#define SYNTAX_FLAGS_COMMENT_STYLEC2(flags) (((flags) >> 22) & 2) /* C * 2 */
77/* FLAGS should be the flags of the main char of the comment marker, e.g. 112/* FLAGS should be the flags of the main char of the comment marker, e.g.
78 the second for comstart and the first for comend. */ 113 the second for comstart and the first for comend. */
79#define SYNTAX_FLAGS_COMMENT_STYLE(flags, other_flags) \ 114static int
80 (SYNTAX_FLAGS_COMMENT_STYLEB (flags) \ 115SYNTAX_FLAGS_COMMENT_STYLE (int flags, int other_flags)
81 | SYNTAX_FLAGS_COMMENT_STYLEC2 (flags) \ 116{
82 | SYNTAX_FLAGS_COMMENT_STYLEC2 (other_flags)) 117 return (SYNTAX_FLAGS_COMMENT_STYLEB (flags)
83 118 | SYNTAX_FLAGS_COMMENT_STYLEC2 (flags)
84#define SYNTAX_FLAGS_COMMENT_NESTED(flags) (((flags) >> 22) & 1) 119 | SYNTAX_FLAGS_COMMENT_STYLEC2 (other_flags));
120}
85 121
86/* These macros extract a particular flag for a given character. */ 122/* Extract a particular flag for a given character. */
87 123
88#define SYNTAX_COMEND_FIRST(c) \ 124static bool
89 (SYNTAX_FLAGS_COMEND_FIRST (SYNTAX_WITH_FLAGS (c))) 125SYNTAX_COMEND_FIRST (int c)
90#define SYNTAX_PREFIX(c) (SYNTAX_FLAGS_PREFIX (SYNTAX_WITH_FLAGS (c))) 126{
127 return SYNTAX_FLAGS_COMEND_FIRST (SYNTAX_WITH_FLAGS (c));
128}
91 129
92/* We use these constants in place for comment-style and 130/* We use these constants in place for comment-style and
93 string-ender-char to distinguish comments/strings started by 131 string-ender-char to distinguish comments/strings started by
94 comment_fence and string_fence codes. */ 132 comment_fence and string_fence codes. */
95 133
96#define ST_COMMENT_STYLE (256 + 1) 134enum
97#define ST_STRING_STYLE (256 + 2) 135 {
136 ST_COMMENT_STYLE = 256 + 1,
137 ST_STRING_STYLE = 256 + 2
138 };
98 139
99static Lisp_Object Qsyntax_table_p; 140static Lisp_Object Qsyntax_table_p;
100static Lisp_Object Qsyntax_table, Qscan_error; 141static Lisp_Object Qsyntax_table, Qscan_error;
101 142
102#ifndef __GNUC__
103/* Used as a temporary in SYNTAX_ENTRY and other macros in syntax.h,
104 if not compiled with GCC. No need to mark it, since it is used
105 only very temporarily. */
106Lisp_Object syntax_temp;
107#endif
108
109/* This is the internal form of the parse state used in parse-partial-sexp. */ 143/* This is the internal form of the parse state used in parse-partial-sexp. */
110 144
111struct lisp_parse_state 145struct lisp_parse_state
@@ -162,14 +196,107 @@ bset_syntax_table (struct buffer *b, Lisp_Object val)
162bool 196bool
163syntax_prefix_flag_p (int c) 197syntax_prefix_flag_p (int c)
164{ 198{
165 return SYNTAX_PREFIX (c); 199 return SYNTAX_FLAGS_PREFIX (SYNTAX_WITH_FLAGS (c));
166} 200}
167 201
168struct gl_state_s gl_state; /* Global state of syntax parser. */ 202struct gl_state_s gl_state; /* Global state of syntax parser. */
169 203
170#define INTERVALS_AT_ONCE 10 /* 1 + max-number of intervals 204enum { INTERVALS_AT_ONCE = 10 }; /* 1 + max-number of intervals
171 to scan to property-change. */ 205 to scan to property-change. */
172 206
207/* Set the syntax entry VAL for char C in table TABLE. */
208
209static void
210SET_RAW_SYNTAX_ENTRY (Lisp_Object table, int c, Lisp_Object val)
211{
212 CHAR_TABLE_SET (table, c, val);
213}
214
215/* Set the syntax entry VAL for char-range RANGE in table TABLE.
216 RANGE is a cons (FROM . TO) specifying the range of characters. */
217
218static void
219SET_RAW_SYNTAX_ENTRY_RANGE (Lisp_Object table, Lisp_Object range,
220 Lisp_Object val)
221{
222 Fset_char_table_range (table, range, val);
223}
224
225/* Extract the information from the entry for character C
226 in the current syntax table. */
227
228static Lisp_Object
229SYNTAX_MATCH (int c)
230{
231 Lisp_Object ent = SYNTAX_ENTRY (c);
232 return CONSP (ent) ? XCDR (ent) : Qnil;
233}
234
235/* This should be called with FROM at the start of forward
236 search, or after the last position of the backward search. It
237 makes sure that the first char is picked up with correct table, so
238 one does not need to call UPDATE_SYNTAX_TABLE immediately after the
239 call.
240 Sign of COUNT gives the direction of the search.
241 */
242
243static void
244SETUP_SYNTAX_TABLE (ptrdiff_t from, ptrdiff_t count)
245{
246 SETUP_BUFFER_SYNTAX_TABLE ();
247 gl_state.b_property = BEGV;
248 gl_state.e_property = ZV + 1;
249 gl_state.object = Qnil;
250 gl_state.offset = 0;
251 if (parse_sexp_lookup_properties)
252 if (count > 0 || from > BEGV)
253 update_syntax_table (count > 0 ? from : from - 1, count, 1, Qnil);
254}
255
256/* Same as above, but in OBJECT. If OBJECT is nil, use current buffer.
257 If it is t (which is only used in fast_c_string_match_ignore_case),
258 ignore properties altogether.
259
260 This is meant for regex.c to use. For buffers, regex.c passes arguments
261 to the UPDATE_SYNTAX_TABLE functions which are relative to BEGV.
262 So if it is a buffer, we set the offset field to BEGV. */
263
264void
265SETUP_SYNTAX_TABLE_FOR_OBJECT (Lisp_Object object,
266 ptrdiff_t from, ptrdiff_t count)
267{
268 SETUP_BUFFER_SYNTAX_TABLE ();
269 gl_state.object = object;
270 if (BUFFERP (gl_state.object))
271 {
272 struct buffer *buf = XBUFFER (gl_state.object);
273 gl_state.b_property = 1;
274 gl_state.e_property = BUF_ZV (buf) - BUF_BEGV (buf) + 1;
275 gl_state.offset = BUF_BEGV (buf) - 1;
276 }
277 else if (NILP (gl_state.object))
278 {
279 gl_state.b_property = 1;
280 gl_state.e_property = ZV - BEGV + 1;
281 gl_state.offset = BEGV - 1;
282 }
283 else if (EQ (gl_state.object, Qt))
284 {
285 gl_state.b_property = 0;
286 gl_state.e_property = PTRDIFF_MAX;
287 gl_state.offset = 0;
288 }
289 else
290 {
291 gl_state.b_property = 0;
292 gl_state.e_property = 1 + SCHARS (gl_state.object);
293 gl_state.offset = 0;
294 }
295 if (parse_sexp_lookup_properties)
296 update_syntax_table (from + gl_state.offset - (count <= 0),
297 count, 1, gl_state.object);
298}
299
173/* Update gl_state to an appropriate interval which contains CHARPOS. The 300/* Update gl_state to an appropriate interval which contains CHARPOS. The
174 sign of COUNT give the relative position of CHARPOS wrt the previously 301 sign of COUNT give the relative position of CHARPOS wrt the previously
175 valid interval. If INIT, only [be]_property fields of gl_state are 302 valid interval. If INIT, only [be]_property fields of gl_state are
@@ -1751,7 +1878,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
1751 } 1878 }
1752 1879
1753 immediate_quit = 1; 1880 immediate_quit = 1;
1754 /* This code may look up syntax tables using macros that rely on the 1881 /* This code may look up syntax tables using functions that rely on the
1755 gl_state object. To make sure this object is not out of date, 1882 gl_state object. To make sure this object is not out of date,
1756 let's initialize it manually. 1883 let's initialize it manually.
1757 We ignore syntax-table text-properties for now, since that's 1884 We ignore syntax-table text-properties for now, since that's
@@ -2426,11 +2553,13 @@ between them, return t; otherwise return nil. */)
2426} 2553}
2427 2554
2428/* Return syntax code of character C if C is an ASCII character 2555/* Return syntax code of character C if C is an ASCII character
2429 or `multibyte_symbol_p' is zero. Otherwise, return Ssymbol. */ 2556 or if MULTIBYTE_SYMBOL_P is false. Otherwise, return Ssymbol. */
2430 2557
2431#define SYNTAX_WITH_MULTIBYTE_CHECK(c) \ 2558static enum syntaxcode
2432 ((ASCII_CHAR_P (c) || !multibyte_symbol_p) \ 2559syntax_multibyte (int c, bool multibyte_symbol_p)
2433 ? SYNTAX (c) : Ssymbol) 2560{
2561 return ASCII_CHAR_P (c) || !multibyte_symbol_p ? SYNTAX (c) : Ssymbol;
2562}
2434 2563
2435static Lisp_Object 2564static Lisp_Object
2436scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) 2565scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
@@ -2441,7 +2570,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2441 int stringterm; 2570 int stringterm;
2442 bool quoted; 2571 bool quoted;
2443 bool mathexit = 0; 2572 bool mathexit = 0;
2444 enum syntaxcode code, temp_code, c_code; 2573 enum syntaxcode code;
2445 EMACS_INT min_depth = depth; /* Err out if depth gets less than this. */ 2574 EMACS_INT min_depth = depth; /* Err out if depth gets less than this. */
2446 int comstyle = 0; /* style of comment encountered */ 2575 int comstyle = 0; /* style of comment encountered */
2447 bool comnested = 0; /* whether the comment is nestable or not */ 2576 bool comnested = 0; /* whether the comment is nestable or not */
@@ -2473,7 +2602,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2473 UPDATE_SYNTAX_TABLE_FORWARD (from); 2602 UPDATE_SYNTAX_TABLE_FORWARD (from);
2474 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2603 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2475 syntax = SYNTAX_WITH_FLAGS (c); 2604 syntax = SYNTAX_WITH_FLAGS (c);
2476 code = SYNTAX_WITH_MULTIBYTE_CHECK (c); 2605 code = syntax_multibyte (c, multibyte_symbol_p);
2477 comstart_first = SYNTAX_FLAGS_COMSTART_FIRST (syntax); 2606 comstart_first = SYNTAX_FLAGS_COMSTART_FIRST (syntax);
2478 comnested = SYNTAX_FLAGS_COMMENT_NESTED (syntax); 2607 comnested = SYNTAX_FLAGS_COMMENT_NESTED (syntax);
2479 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0); 2608 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0);
@@ -2519,10 +2648,8 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2519 { 2648 {
2520 UPDATE_SYNTAX_TABLE_FORWARD (from); 2649 UPDATE_SYNTAX_TABLE_FORWARD (from);
2521 2650
2522 /* Some compilers can't handle this inside the switch. */
2523 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2651 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2524 c_code = SYNTAX_WITH_MULTIBYTE_CHECK (c); 2652 switch (syntax_multibyte (c, multibyte_symbol_p))
2525 switch (c_code)
2526 { 2653 {
2527 case Scharquote: 2654 case Scharquote:
2528 case Sescape: 2655 case Sescape:
@@ -2594,18 +2721,17 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2594 stringterm = FETCH_CHAR_AS_MULTIBYTE (temp_pos); 2721 stringterm = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
2595 while (1) 2722 while (1)
2596 { 2723 {
2724 enum syntaxcode c_code;
2597 if (from >= stop) 2725 if (from >= stop)
2598 goto lose; 2726 goto lose;
2599 UPDATE_SYNTAX_TABLE_FORWARD (from); 2727 UPDATE_SYNTAX_TABLE_FORWARD (from);
2600 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2728 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2729 c_code = syntax_multibyte (c, multibyte_symbol_p);
2601 if (code == Sstring 2730 if (code == Sstring
2602 ? (c == stringterm 2731 ? c == stringterm && c_code == Sstring
2603 && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring) 2732 : c_code == Sstring_fence)
2604 : SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring_fence)
2605 break; 2733 break;
2606 2734
2607 /* Some compilers can't handle this inside the switch. */
2608 c_code = SYNTAX_WITH_MULTIBYTE_CHECK (c);
2609 switch (c_code) 2735 switch (c_code)
2610 { 2736 {
2611 case Scharquote: 2737 case Scharquote:
@@ -2644,7 +2770,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2644 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2770 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2645 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2771 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2646 syntax= SYNTAX_WITH_FLAGS (c); 2772 syntax= SYNTAX_WITH_FLAGS (c);
2647 code = SYNTAX_WITH_MULTIBYTE_CHECK (c); 2773 code = syntax_multibyte (c, multibyte_symbol_p);
2648 if (depth == min_depth) 2774 if (depth == min_depth)
2649 last_good = from; 2775 last_good = from;
2650 comstyle = 0; 2776 comstyle = 0;
@@ -2697,9 +2823,8 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2697 temp_pos--; 2823 temp_pos--;
2698 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1); 2824 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2699 c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos); 2825 c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
2700 temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1);
2701 /* Don't allow comment-end to be quoted. */ 2826 /* Don't allow comment-end to be quoted. */
2702 if (temp_code == Sendcomment) 2827 if (syntax_multibyte (c1, multibyte_symbol_p) == Sendcomment)
2703 goto done2; 2828 goto done2;
2704 quoted = char_quoted (from - 1, temp_pos); 2829 quoted = char_quoted (from - 1, temp_pos);
2705 if (quoted) 2830 if (quoted)
@@ -2709,11 +2834,12 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2709 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1); 2834 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2710 } 2835 }
2711 c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos); 2836 c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
2712 temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1); 2837 if (! quoted)
2713 if (! (quoted || temp_code == Sword 2838 switch (syntax_multibyte (c1, multibyte_symbol_p))
2714 || temp_code == Ssymbol 2839 {
2715 || temp_code == Squote)) 2840 case Sword: case Ssymbol: case Squote: break;
2716 goto done2; 2841 default: goto done2;
2842 }
2717 DEC_BOTH (from, from_byte); 2843 DEC_BOTH (from, from_byte);
2718 } 2844 }
2719 goto done2; 2845 goto done2;
@@ -2768,10 +2894,12 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2768 goto lose; 2894 goto lose;
2769 DEC_BOTH (from, from_byte); 2895 DEC_BOTH (from, from_byte);
2770 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2896 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2771 if (!char_quoted (from, from_byte) 2897 if (!char_quoted (from, from_byte))
2772 && (c = FETCH_CHAR_AS_MULTIBYTE (from_byte), 2898 {
2773 SYNTAX_WITH_MULTIBYTE_CHECK (c) == code)) 2899 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2774 break; 2900 if (syntax_multibyte (c, multibyte_symbol_p) == code)
2901 break;
2902 }
2775 } 2903 }
2776 if (code == Sstring_fence && !depth && sexpflag) goto done2; 2904 if (code == Sstring_fence && !depth && sexpflag) goto done2;
2777 break; 2905 break;
@@ -2784,11 +2912,14 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2784 goto lose; 2912 goto lose;
2785 DEC_BOTH (from, from_byte); 2913 DEC_BOTH (from, from_byte);
2786 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2914 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2787 if (!char_quoted (from, from_byte) 2915 if (!char_quoted (from, from_byte))
2788 && (stringterm 2916 {
2789 == (c = FETCH_CHAR_AS_MULTIBYTE (from_byte))) 2917 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2790 && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring) 2918 if (c == stringterm
2791 break; 2919 && (syntax_multibyte (c, multibyte_symbol_p)
2920 == Sstring))
2921 break;
2922 }
2792 } 2923 }
2793 if (!depth && sexpflag) goto done2; 2924 if (!depth && sexpflag) goto done2;
2794 break; 2925 break;
@@ -2894,7 +3025,7 @@ This includes chars with "quote" or "prefix" syntax (' or p). */)
2894 while (!char_quoted (pos, pos_byte) 3025 while (!char_quoted (pos, pos_byte)
2895 /* Previous statement updates syntax table. */ 3026 /* Previous statement updates syntax table. */
2896 && ((c = FETCH_CHAR_AS_MULTIBYTE (pos_byte), SYNTAX (c) == Squote) 3027 && ((c = FETCH_CHAR_AS_MULTIBYTE (pos_byte), SYNTAX (c) == Squote)
2897 || SYNTAX_PREFIX (c))) 3028 || syntax_prefix_flag_p (c)))
2898 { 3029 {
2899 opoint = pos; 3030 opoint = pos;
2900 opoint_byte = pos_byte; 3031 opoint_byte = pos_byte;
@@ -3117,10 +3248,8 @@ do { prev_from = from; \
3117 symstarted: 3248 symstarted:
3118 while (from < end) 3249 while (from < end)
3119 { 3250 {
3120 /* Some compilers can't handle this inside the switch. */
3121 int symchar = FETCH_CHAR_AS_MULTIBYTE (from_byte); 3251 int symchar = FETCH_CHAR_AS_MULTIBYTE (from_byte);
3122 enum syntaxcode symcharcode = SYNTAX (symchar); 3252 switch (SYNTAX (symchar))
3123 switch (symcharcode)
3124 { 3253 {
3125 case Scharquote: 3254 case Scharquote:
3126 case Sescape: 3255 case Sescape:
@@ -3206,7 +3335,6 @@ do { prev_from = from; \
3206 3335
3207 if (from >= end) goto done; 3336 if (from >= end) goto done;
3208 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 3337 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
3209 /* Some compilers can't handle this inside the switch. */
3210 c_code = SYNTAX (c); 3338 c_code = SYNTAX (c);
3211 3339
3212 /* Check C_CODE here so that if the char has 3340 /* Check C_CODE here so that if the char has