#include #include #include #include "errors.h" #include "lex-string.h" #include "string16.h" static uint16 parseInteger( const char *&str, const unsigned base, unsigned maxDigits ) { uint16 result = 0; while (maxDigits--) { unsigned digit = *str; if (isdigit( digit )) digit -= '0'; else if (islower( digit )) digit -= 'a' - 10; else if (isupper( digit )) digit -= 'A' - 10; else return result; if (digit < base) { ++str; result *= base; result += digit; } else return result; } return result; } static uint16 convert( const char *&str, const SourcePosn &position ) { switch (*str) { case '\\': switch (*++str) { case 'n': ++str; return '\n'; case 'b': ++str; return '\b'; case 'r': ++str; return '\r'; case 't': ++str; return '\t'; case 'f': ++str; return '\f'; case '\\': case '"': case '\'': return *str++; case '0': case '1': case '2': case '3': return parseInteger( str, 8, 3 ); case '4': case '5': case '6': case '7': return parseInteger( str, 8, 2 ); case 'u': { do str++; while (*str == 'u'); const char * const before = str; const uint16 result = parseInteger( str, 16, 4 ); // require exactly four hex digits if (str - before == 4) return result; } default: Error(position) << "illegal escape sequence in literal: \"" << (str - 1) << '\"' << endl; return '?'; } default: return *str++; } } uint16 convertCharacter( char *str, size_t length, const SourcePosn &position ) { const char *frozen = str; str[ length ] = '\0'; return convert( frozen, position ); } const string16 convertString( char* str, size_t length, const SourcePosn &position ) { const char *frozen = str; str[ length ] = '\0'; string16 result; result.reserve( length ); const char * const end = frozen + length; while (frozen < end) result += convert( frozen, position ); return result; }