From c8bf8cd41e79a7da4db11e4eda945372398f7f56 Mon Sep 17 00:00:00 2001 From: jules Date: Fri, 4 Jul 2014 17:53:31 +0100 Subject: [PATCH] Moved some C++ escaping functions from the Introjucer into CppTokeniserFunctions. --- .../Project Saving/jucer_ProjectExport_MSVC.h | 2 +- .../Project Saving/jucer_ProjectSaver.h | 4 +- .../Source/Project/jucer_AudioPluginModule.h | 8 +- .../Source/Project/jucer_NewProjectWizard.cpp | 2 +- .../Source/Utility/jucer_CodeHelpers.cpp | 87 +-------------- .../Source/Utility/jucer_CodeHelpers.h | 1 - .../juce_CPlusPlusCodeTokeniserFunctions.h | 100 ++++++++++++++++++ 7 files changed, 111 insertions(+), 93 deletions(-) diff --git a/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h b/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h index d8676cd5c5..d66d97b1c8 100644 --- a/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h +++ b/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h @@ -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) diff --git a/extras/Introjucer/Source/Project Saving/jucer_ProjectSaver.h b/extras/Introjucer/Source/Project Saving/jucer_ProjectSaver.h index f64ba99e97..73508cc429 100644 --- a/extras/Introjucer/Source/Project Saving/jucer_ProjectSaver.h +++ b/extras/Introjucer/Source/Project Saving/jucer_ProjectSaver.h @@ -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 diff --git a/extras/Introjucer/Source/Project/jucer_AudioPluginModule.h b/extras/Introjucer/Source/Project/jucer_AudioPluginModule.h index da23c82eb9..8934791e7a 100644 --- a/extras/Introjucer/Source/Project/jucer_AudioPluginModule.h +++ b/extras/Introjucer/Source/Project/jucer_AudioPluginModule.h @@ -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) diff --git a/extras/Introjucer/Source/Project/jucer_NewProjectWizard.cpp b/extras/Introjucer/Source/Project/jucer_NewProjectWizard.cpp index f2e33d2dbb..b3696b2aa3 100644 --- a/extras/Introjucer/Source/Project/jucer_NewProjectWizard.cpp +++ b/extras/Introjucer/Source/Project/jucer_NewProjectWizard.cpp @@ -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); diff --git a/extras/Introjucer/Source/Utility/jucer_CodeHelpers.cpp b/extras/Introjucer/Source/Utility/jucer_CodeHelpers.cpp index 9923751de4..57b6bdc46e 100644 --- a/extras/Introjucer/Source/Utility/jucer_CodeHelpers.cpp +++ b/extras/Introjucer/Source/Utility/jucer_CodeHelpers.cpp @@ -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 << "\";"; } } diff --git a/extras/Introjucer/Source/Utility/jucer_CodeHelpers.h b/extras/Introjucer/Source/Utility/jucer_CodeHelpers.h index d3f63b49ae..6c4a55cdcb 100644 --- a/extras/Introjucer/Source/Utility/jucer_CodeHelpers.h +++ b/extras/Introjucer/Source/Utility/jucer_CodeHelpers.h @@ -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); diff --git a/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h b/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h index a3a09f2642..93ba37f37d 100644 --- a/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h +++ b/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h @@ -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(); + } };