1typedef unsigned int source_location; 2typedef source_location location_t; 3extern void error_at (location_t, const char *, ...) 4 __attribute__ ((__format__ (__gcc_tdiag__, 2, 3))) 5 __attribute__ ((__nonnull__ (2))); 6 7class Lex 8{ 9 static int fetch_char (const char *str, unsigned int *value); 10 location_t location () const; 11 const char *advance_one_utf8_char (const char *, unsigned int *, bool *); 12 const char *advance_one_char (const char *, bool, unsigned int *, bool *); 13 int lineoff_; 14 int lineno_; 15}; 16 17int 18Lex::fetch_char (const char *p, unsigned int *value) 19{ 20 unsigned char c = *p; 21 if (c <= 0x7f) 22 { 23 return 1; 24 } 25 else if ((c & 0xe0) == 0xc0 && (p[1] & 0xc0) == 0x80) 26 { 27 *value = (((c & 0x1f) << 6) + (p[1] & 0x3f)); 28 } 29 { 30 *value = (((c & 0xf) << 12) + (p[2] & 0x3f)); 31 } 32} 33 34const char * 35Lex::advance_one_utf8_char (const char *p, unsigned int *value, 36 bool * issued_error) 37{ 38 *issued_error = false; 39 if (*p == '\0') 40 { 41 *issued_error = true; 42 return p + 1; 43 } 44 int adv = Lex::fetch_char (p, value); 45 if (*value == 0xfeff && (this->lineno_ != 1 || this->lineoff_ != 0)) 46 { 47 *issued_error = true; 48 } 49 return p + adv; 50} 51 52const char * 53Lex::advance_one_char (const char *p, bool is_single_quote, 54 unsigned int *value, bool * is_character) 55{ 56 { 57 bool issued_error; 58 const char *ret = this->advance_one_utf8_char (p, value, &issued_error); 59 if (is_single_quote 60 && (*value == '\'' || *value == '\n') && !issued_error) 61 error_at (this->location (), "invalid character literal"); 62 } 63} 64