static int c;
token_t lexer_token;
+symbol_t *symbol_L;
static FILE *input;
static char buf[1024 + MAX_PUTBACK];
static const char *bufend;
lexer_token.source_position.linenr++; \
code;
-static inline void eat(char c_type)
-{
- assert(c == c_type);
- next_char();
-}
+#define eat(c_type) do { assert(c == c_type); next_char(); } while(0)
static void maybe_concat_lines(void)
{
{
next_real_char();
+#if 0
/* filter trigraphs */
if(UNLIKELY(c == '\\')) {
maybe_concat_lines();
}
end_of_next_char:
+#endif
+ (void) maybe_concat_lines;
#ifdef DEBUG_CHARS
printf("nchar '%c'\n", c);
#else
}
}
-static int parse_octal_sequence(void)
+static inline int is_octal_digit(int chr)
{
- int value = 0;
- while(1) {
- if(c < '0' || c > '7')
- break;
- value = 8 * value + c - '0';
- next_char();
- }
+ return '0' <= chr && chr <= '7';
+}
+static int parse_octal_sequence(const int first_digit)
+{
+ assert(is_octal_digit(first_digit));
+ int value = first_digit - '0';
+ if (!is_octal_digit(c)) return value;
+ value = 8 * value + c - '0';
+ next_char();
+ if (!is_octal_digit(c)) return value;
+ value = 8 * value + c - '0';
+ next_char();
return value;
}
switch(ec) {
case '"': return '"';
- case '\'': return'\'';
+ case '\'': return '\'';
case '\\': return '\\';
case '?': return '\?';
case 'a': return '\a';
case '5':
case '6':
case '7':
- return parse_octal_sequence();
+ return parse_octal_sequence(ec);
case EOF:
parse_error("reached end of file while parsing escape sequence");
return EOF;
}
}
-static void parse_preprocessor_directive()
+static void parse_preprocessor_directive(void)
{
next_pp_token();
SYMBOL_CHARS
parse_symbol();
+ /* might be a wide string ( L"string" ) */
+ if(c == '"' && (lexer_token.type == T_IDENTIFIER &&
+ lexer_token.v.symbol == symbol_L)) {
+ parse_string_literal();
+ return;
+ }
return;
DIGITS
lexer_token.source_position.linenr = 0;
lexer_token.source_position.input_name = input_name;
+ symbol_L = symbol_table_insert("L");
+
/* place a virtual \n at the beginning so the lexer knows that we're
* at the beginning of a line */
c = '\n';