Adapted cparser to CopyB lowering changes.
[cparser] / preprocessor.c
index 75b01d7..cc6308b 100644 (file)
@@ -195,8 +195,7 @@ static inline void next_real_char(void)
 {
        assert(input.bufpos <= input.bufend);
        if (input.bufpos >= input.bufend) {
-               size_t n = decode(input.input, input.buf + MAX_PUTBACK,
-                                 sizeof(input.buf)/sizeof(input.buf[0]) - MAX_PUTBACK);
+               size_t const n = decode(input.input, input.buf + MAX_PUTBACK, lengthof(input.buf) - MAX_PUTBACK);
                if (n == 0) {
                        input.c = EOF;
                        return;
@@ -362,50 +361,41 @@ static int digit_value(int digit)
  *
  * @param first_digit  the already read first digit
  */
-static int parse_octal_sequence(const int first_digit)
+static utf32 parse_octal_sequence(const utf32 first_digit)
 {
        assert(is_octal_digit(first_digit));
-       int value = digit_value(first_digit);
+       utf32 value = digit_value(first_digit);
        if (!is_octal_digit(input.c)) return value;
        value = 8 * value + digit_value(input.c);
        next_char();
        if (!is_octal_digit(input.c)) return value;
        value = 8 * value + digit_value(input.c);
        next_char();
+       return value;
 
-       if (char_is_signed) {
-               return (signed char) value;
-       } else {
-               return (unsigned char) value;
-       }
 }
 
 /**
  * Parses a hex character sequence.
  */
-static int parse_hex_sequence(void)
+static utf32 parse_hex_sequence(void)
 {
-       int value = 0;
+       utf32 value = 0;
        while (isxdigit(input.c)) {
                value = 16 * value + digit_value(input.c);
                next_char();
        }
-
-       if (char_is_signed) {
-               return (signed char) value;
-       } else {
-               return (unsigned char) value;
-       }
+       return value;
 }
 
 /**
  * Parse an escape sequence.
  */
-static int parse_escape_sequence(void)
+static utf32 parse_escape_sequence(void)
 {
        eat('\\');
 
-       int ec = input.c;
+       utf32 const ec = input.c;
        next_char();
 
        switch (ec) {
@@ -434,30 +424,23 @@ static int parse_escape_sequence(void)
        case EOF:
                parse_error("reached end of file while parsing escape sequence");
                return EOF;
-       default:
-               parse_error("unknown escape sequence");
+       /* \E is not documented, but handled, by GCC.  It is acceptable according
+        * to §6.11.4, whereas \e is not. */
+       case 'E':
+       case 'e':
+               if (c_mode & _GNUC)
+                       return 27;   /* hopefully 27 is ALWAYS the code for ESCAPE */
+               break;
+       case 'u':
+       case 'U':
+               parse_error("universal character parsing not implemented yet");
                return EOF;
+       default:
+               break;
        }
-}
-
-static void grow_symbol(utf32 const tc)
-{
-       struct obstack *const o  = &symbol_obstack;
-       if (tc < 0x80U) {
-               obstack_1grow(o, tc);
-       } else if (tc < 0x800) {
-               obstack_1grow(o, 0xC0 | (tc >> 6));
-               obstack_1grow(o, 0x80 | (tc & 0x3F));
-       } else if (tc < 0x10000) {
-               obstack_1grow(o, 0xE0 | ( tc >> 12));
-               obstack_1grow(o, 0x80 | ((tc >>  6) & 0x3F));
-               obstack_1grow(o, 0x80 | ( tc        & 0x3F));
-       } else {
-               obstack_1grow(o, 0xF0 | ( tc >> 18));
-               obstack_1grow(o, 0x80 | ((tc >> 12) & 0x3F));
-               obstack_1grow(o, 0x80 | ((tc >>  6) & 0x3F));
-               obstack_1grow(o, 0x80 | ( tc        & 0x3F));
-       }
+       /* §6.4.4.4:8 footnote 64 */
+       parse_error("unknown escape sequence");
+       return EOF;
 }
 
 static const char *identify_string(char *string)
@@ -511,7 +494,7 @@ static void parse_string_literal(void)
                        goto end_of_string;
 
                default:
-                       grow_symbol(input.c);
+                       obstack_grow_symbol(&symbol_obstack, input.c);
                        next_char();
                        break;
                }
@@ -545,7 +528,7 @@ static void parse_wide_character_constant(void)
                switch (input.c) {
                case '\\': {
                        const utf32 tc = parse_escape_sequence();
-                       grow_symbol(tc);
+                       obstack_grow_symbol(&symbol_obstack, tc);
                        break;
                }
 
@@ -564,7 +547,7 @@ static void parse_wide_character_constant(void)
                        return;
 
                default:
-                       grow_symbol(input.c);
+                       obstack_grow_symbol(&symbol_obstack, input.c);
                        next_char();
                        break;
                }