| @@ -513,7 +513,7 @@ protected: | |||
| { | |||
| if (value.isNotEmpty()) | |||
| mo << " VALUE \"" << name << "\", \"" | |||
| << CodeHelpers::addEscapeChars (value) << "\\0\"" << newLine; | |||
| << CppTokeniserFunctions::addEscapeChars (value) << "\\0\"" << newLine; | |||
| } | |||
| static String getCommaSeparatedVersionNumber (const String& version) | |||
| @@ -435,8 +435,8 @@ private: | |||
| << newLine | |||
| << "namespace ProjectInfo" << newLine | |||
| << "{" << newLine | |||
| << " const char* const projectName = " << CodeHelpers::addEscapeChars (project.getTitle()).quoted() << ";" << newLine | |||
| << " const char* const versionString = " << CodeHelpers::addEscapeChars (project.getVersionString()).quoted() << ";" << newLine | |||
| << " const char* const projectName = " << CppTokeniserFunctions::addEscapeChars (project.getTitle()).quoted() << ";" << newLine | |||
| << " const char* const versionString = " << CppTokeniserFunctions::addEscapeChars (project.getVersionString()).quoted() << ";" << newLine | |||
| << " const int versionNumber = " << project.getVersionAsHex() << ";" << newLine | |||
| << "}" << newLine | |||
| << newLine | |||
| @@ -128,12 +128,12 @@ namespace | |||
| String valueToStringLiteral (const var& v) | |||
| { | |||
| return CodeHelpers::addEscapeChars (v.toString()).quoted(); | |||
| return CppTokeniserFunctions::addEscapeChars (v.toString()).quoted(); | |||
| } | |||
| String valueToCharLiteral (const var& v) | |||
| { | |||
| return CodeHelpers::addEscapeChars (v.toString().trim().substring (0, 4)).quoted ('\''); | |||
| return CppTokeniserFunctions::addEscapeChars (v.toString().trim().substring (0, 4)).quoted ('\''); | |||
| } | |||
| void writePluginCharacteristicsFile (ProjectSaver& projectSaver) | |||
| @@ -212,8 +212,8 @@ namespace | |||
| String createEscapedStringForVersion (ProjectExporter& exporter, const String& text) | |||
| { | |||
| // (VS10 automatically adds escape characters to the quotes for this definition) | |||
| return exporter.getVisualStudioVersion() < 10 ? CodeHelpers::addEscapeChars (text.quoted()) | |||
| : CodeHelpers::addEscapeChars (text).quoted(); | |||
| return exporter.getVisualStudioVersion() < 10 ? CppTokeniserFunctions::addEscapeChars (text.quoted()) | |||
| : CppTokeniserFunctions::addEscapeChars (text).quoted(); | |||
| } | |||
| String createRebasedPath (ProjectExporter& exporter, const RelativePath& path) | |||
| @@ -341,7 +341,7 @@ struct NewProjectWizardClasses | |||
| : "jucer_MainTemplate_NoWindow_cpp") | |||
| .replace ("APPHEADERS", appHeaders, false) | |||
| .replace ("APPCLASSNAME", CodeHelpers::makeValidIdentifier (appTitle + "Application", false, true, false), false) | |||
| .replace ("APPNAME", CodeHelpers::addEscapeChars (appTitle), false) | |||
| .replace ("APPNAME", CppTokeniserFunctions::addEscapeChars (appTitle), false) | |||
| .replace ("CONTENTCOMPCLASS", contentCompName, false) | |||
| .replace ("ALLOWMORETHANONEINSTANCE", "true", false); | |||
| @@ -102,87 +102,6 @@ namespace CodeHelpers | |||
| return n; | |||
| } | |||
| static void writeEscapeChars (OutputStream& out, const char* utf8, const int numBytes, | |||
| const int maxCharsOnLine, const bool breakAtNewLines, | |||
| const bool replaceSingleQuotes, const bool allowStringBreaks) | |||
| { | |||
| int charsOnLine = 0; | |||
| bool lastWasHexEscapeCode = false; | |||
| for (int i = 0; i < numBytes || numBytes < 0; ++i) | |||
| { | |||
| const unsigned char c = (unsigned char) utf8[i]; | |||
| bool startNewLine = false; | |||
| switch (c) | |||
| { | |||
| case '\t': out << "\\t"; lastWasHexEscapeCode = false; charsOnLine += 2; break; | |||
| case '\r': out << "\\r"; lastWasHexEscapeCode = false; charsOnLine += 2; break; | |||
| case '\n': out << "\\n"; lastWasHexEscapeCode = false; charsOnLine += 2; startNewLine = breakAtNewLines; break; | |||
| case '\\': out << "\\\\"; lastWasHexEscapeCode = false; charsOnLine += 2; break; | |||
| case '\"': out << "\\\""; lastWasHexEscapeCode = false; charsOnLine += 2; break; | |||
| case 0: | |||
| if (numBytes < 0) | |||
| return; | |||
| out << "\\0"; | |||
| lastWasHexEscapeCode = true; | |||
| charsOnLine += 2; | |||
| break; | |||
| case '\'': | |||
| if (replaceSingleQuotes) | |||
| { | |||
| out << "\\\'"; | |||
| lastWasHexEscapeCode = false; | |||
| charsOnLine += 2; | |||
| break; | |||
| } | |||
| // deliberate fall-through... | |||
| default: | |||
| if (c >= 32 && c < 127 && ! (lastWasHexEscapeCode // (have to avoid following a hex escape sequence with a valid hex digit) | |||
| && CharacterFunctions::getHexDigitValue (c) >= 0)) | |||
| { | |||
| out << (char) c; | |||
| lastWasHexEscapeCode = false; | |||
| ++charsOnLine; | |||
| } | |||
| else if (allowStringBreaks && lastWasHexEscapeCode && c >= 32 && c < 127) | |||
| { | |||
| out << "\"\"" << (char) c; | |||
| lastWasHexEscapeCode = false; | |||
| charsOnLine += 3; | |||
| } | |||
| else | |||
| { | |||
| out << (c < 16 ? "\\x0" : "\\x") << String::toHexString ((int) c); | |||
| lastWasHexEscapeCode = true; | |||
| charsOnLine += 4; | |||
| } | |||
| break; | |||
| } | |||
| if ((startNewLine || (maxCharsOnLine > 0 && charsOnLine >= maxCharsOnLine)) | |||
| && (numBytes < 0 || i < numBytes - 1)) | |||
| { | |||
| charsOnLine = 0; | |||
| out << "\"" << newLine << "\""; | |||
| lastWasHexEscapeCode = false; | |||
| } | |||
| } | |||
| } | |||
| String addEscapeChars (const String& s) | |||
| { | |||
| MemoryOutputStream out; | |||
| writeEscapeChars (out, s.toRawUTF8(), -1, -1, false, true, true); | |||
| return out.toUTF8(); | |||
| } | |||
| String createIncludeStatement (const File& includeFile, const File& targetFile) | |||
| { | |||
| return createIncludeStatement (FileHelpers::unixStylePath (FileHelpers::getRelativePathFrom (includeFile, targetFile.getParentDirectory()))); | |||
| @@ -258,7 +177,7 @@ namespace CodeHelpers | |||
| } | |||
| for (int i = 0; i < lines.size(); ++i) | |||
| lines.getReference(i) = addEscapeChars (lines.getReference(i)); | |||
| lines.getReference(i) = CppTokeniserFunctions::addEscapeChars (lines.getReference(i)); | |||
| lines.removeEmptyStrings(); | |||
| @@ -424,8 +343,8 @@ namespace CodeHelpers | |||
| else | |||
| { | |||
| out << "\""; | |||
| writeEscapeChars (out, (const char*) data, (int) mb.getSize(), | |||
| maxCharsOnLine, breakAtNewLines, false, allowStringBreaks); | |||
| CppTokeniserFunctions::writeEscapeChars (out, (const char*) data, (int) mb.getSize(), | |||
| maxCharsOnLine, breakAtNewLines, false, allowStringBreaks); | |||
| out << "\";"; | |||
| } | |||
| } | |||
| @@ -31,7 +31,6 @@ namespace CodeHelpers | |||
| { | |||
| String indent (const String& code, const int numSpaces, bool indentFirstLine); | |||
| String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates); | |||
| String addEscapeChars (const String& text); | |||
| String createIncludeStatement (const File& includedFile, const File& targetFile); | |||
| String createIncludeStatement (const String& includePath); | |||
| String makeHeaderGuardName (const File& file); | |||
| @@ -535,6 +535,106 @@ struct CppTokeniserFunctions | |||
| String::CharPointerType t; | |||
| int numChars; | |||
| }; | |||
| //============================================================================== | |||
| /** Takes a UTF8 string and writes it to a stream using standard C++ escape sequences for any | |||
| non-ascii bytes. | |||
| Although not strictly a tokenising function, this is still a function that often comes in | |||
| handy when working with C++ code! | |||
| Note that addEscapeChars() is easier to use than this function if you're working with Strings. | |||
| @see addEscapeChars | |||
| */ | |||
| static void writeEscapeChars (OutputStream& out, const char* utf8, const int numBytesToRead, | |||
| const int maxCharsOnLine, const bool breakAtNewLines, | |||
| const bool replaceSingleQuotes, const bool allowStringBreaks) | |||
| { | |||
| int charsOnLine = 0; | |||
| bool lastWasHexEscapeCode = false; | |||
| for (int i = 0; i < numBytesToRead || numBytesToRead < 0; ++i) | |||
| { | |||
| const unsigned char c = (unsigned char) utf8[i]; | |||
| bool startNewLine = false; | |||
| switch (c) | |||
| { | |||
| case '\t': out << "\\t"; lastWasHexEscapeCode = false; charsOnLine += 2; break; | |||
| case '\r': out << "\\r"; lastWasHexEscapeCode = false; charsOnLine += 2; break; | |||
| case '\n': out << "\\n"; lastWasHexEscapeCode = false; charsOnLine += 2; startNewLine = breakAtNewLines; break; | |||
| case '\\': out << "\\\\"; lastWasHexEscapeCode = false; charsOnLine += 2; break; | |||
| case '\"': out << "\\\""; lastWasHexEscapeCode = false; charsOnLine += 2; break; | |||
| case 0: | |||
| if (numBytesToRead < 0) | |||
| return; | |||
| out << "\\0"; | |||
| lastWasHexEscapeCode = true; | |||
| charsOnLine += 2; | |||
| break; | |||
| case '\'': | |||
| if (replaceSingleQuotes) | |||
| { | |||
| out << "\\\'"; | |||
| lastWasHexEscapeCode = false; | |||
| charsOnLine += 2; | |||
| break; | |||
| } | |||
| // deliberate fall-through... | |||
| default: | |||
| if (c >= 32 && c < 127 && ! (lastWasHexEscapeCode // (have to avoid following a hex escape sequence with a valid hex digit) | |||
| && CharacterFunctions::getHexDigitValue (c) >= 0)) | |||
| { | |||
| out << (char) c; | |||
| lastWasHexEscapeCode = false; | |||
| ++charsOnLine; | |||
| } | |||
| else if (allowStringBreaks && lastWasHexEscapeCode && c >= 32 && c < 127) | |||
| { | |||
| out << "\"\"" << (char) c; | |||
| lastWasHexEscapeCode = false; | |||
| charsOnLine += 3; | |||
| } | |||
| else | |||
| { | |||
| out << (c < 16 ? "\\x0" : "\\x") << String::toHexString ((int) c); | |||
| lastWasHexEscapeCode = true; | |||
| charsOnLine += 4; | |||
| } | |||
| break; | |||
| } | |||
| if ((startNewLine || (maxCharsOnLine > 0 && charsOnLine >= maxCharsOnLine)) | |||
| && (numBytesToRead < 0 || i < numBytesToRead - 1)) | |||
| { | |||
| charsOnLine = 0; | |||
| out << "\"" << newLine << "\""; | |||
| lastWasHexEscapeCode = false; | |||
| } | |||
| } | |||
| } | |||
| /** Takes a string and returns a version of it where standard C++ escape sequences have been | |||
| used to replace any non-ascii bytes. | |||
| Although not strictly a tokenising function, this is still a function that often comes in | |||
| handy when working with C++ code! | |||
| @see writeEscapeChars | |||
| */ | |||
| static String addEscapeChars (StringRef s) | |||
| { | |||
| MemoryOutputStream out; | |||
| writeEscapeChars (out, s.text, -1, -1, false, true, true); | |||
| return out.toUTF8(); | |||
| } | |||
| }; | |||