Do not strip the 0x prefix from the textual representation of hexadecimal constants.
[cparser] / preprocessor.c
index e3e65fb..2140145 100644 (file)
@@ -100,7 +100,7 @@ static const char       *printed_input_name = NULL;
 static source_position_t expansion_pos;
 static pp_definition_t  *current_expansion  = NULL;
 static strset_t          stringset;
-static preprocessor_token_kind_t last_token = TP_ERROR;
+static preprocessor_token_kind_t last_token;
 
 static searchpath_entry_t *searchpath;
 
@@ -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,10 +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;
        }
+       /* §6.4.4.4:8 footnote 64 */
+       parse_error("unknown escape sequence");
+       return EOF;
 }
 
 static const char *identify_string(char *string)
@@ -482,8 +485,7 @@ static void parse_string_literal(void)
                        source_position.input_name = pp_token.base.source_position.input_name;
                        source_position.lineno     = start_linenr;
                        errorf(&source_position, "string has no end");
-                       pp_token.kind = TP_ERROR;
-                       return;
+                       goto end_of_string;
                }
 
                case '"':
@@ -540,8 +542,7 @@ static void parse_wide_character_constant(void)
 
                case EOF:
                        parse_error("EOF while parsing character constant");
-                       pp_token.kind = TP_ERROR;
-                       return;
+                       goto end_of_wide_char_constant;
 
                default:
                        obstack_grow_symbol(&symbol_obstack, input.c);
@@ -586,8 +587,7 @@ static void parse_character_constant(void)
                        source_position.input_name = pp_token.base.source_position.input_name;
                        source_position.lineno     = start_linenr;
                        errorf(&source_position, "EOF while parsing character constant");
-                       pp_token.kind = TP_ERROR;
-                       return;
+                       goto end_of_char_constant;
                }
 
                case '\'':
@@ -825,7 +825,7 @@ static void skip_whitespace(void)
        }
 }
 
-static void eat_pp(int type)
+static void eat_pp(preprocessor_token_kind_t const type)
 {
        (void) type;
        assert(pp_token.kind == type);
@@ -1138,11 +1138,11 @@ restart:
                if (!ignore_unknown_chars) {
                        errorf(&pp_token.base.source_position,
                               "unknown character '%c' found\n", input.c);
-                       pp_token.kind = TP_ERROR;
+                       goto restart;
                } else {
                        pp_token.kind = input.c;
+                       return;
                }
-               return;
        }
 }