diff --git a/extras/Introjucer/Source/Application/jucer_CommandLine.cpp b/extras/Introjucer/Source/Application/jucer_CommandLine.cpp index 728a0a6fdd..f2a0b958a4 100644 --- a/extras/Introjucer/Source/Application/jucer_CommandLine.cpp +++ b/extras/Introjucer/Source/Application/jucer_CommandLine.cpp @@ -231,7 +231,7 @@ namespace } //============================================================================== - int showStatus (const StringArray& args) + static int showStatus (const StringArray& args) { hideDockIcon(); @@ -369,6 +369,101 @@ namespace return 0; } + //============================================================================== + static bool cleanWhitespace (const File& file, bool replaceTabs) + { + const String content (file.loadFileAsString()); + + if (content.contains ("%%") && content.contains ("//[")) + return true; // ignore introjucer GUI template files + + StringArray lines; + lines.addLines (content); + bool anyTabsRemoved = false; + + for (int i = 0; i < lines.size(); ++i) + { + String& line = lines.getReference(i); + + if (replaceTabs && line.containsChar ('\t')) + { + anyTabsRemoved = true; + + for (;;) + { + const int tabPos = line.indexOfChar ('\t'); + if (tabPos < 0) + break; + + const int spacesPerTab = 4; + const int spacesNeeded = spacesPerTab - (tabPos % spacesPerTab); + line = line.replaceSection (tabPos, 1, String::repeatedString (" ", spacesNeeded)); + } + } + + line = line.trimEnd(); + } + + if (replaceTabs && ! anyTabsRemoved) + return true; + + while (lines.size() > 10 && lines [lines.size() - 1].isEmpty()) + lines.remove (lines.size() - 1); + + const char* lineEnding = "\r\n"; + const String newText (lines.joinIntoString (lineEnding) + lineEnding); + + if (newText == content || newText == content + lineEnding) + return true; + + std::cout << (replaceTabs ? "Removing tabs in: " + : "Cleaning file: ") << file.getFullPathName() << std::endl; + + TemporaryFile temp (file); + + if (! temp.getFile().replaceWithText (newText, false, false)) + { + std::cout << "!!! ERROR Couldn't write to temp file!" << std::endl << std::endl; + return false; + } + + if (! temp.overwriteTargetFileWithTemporary()) + { + std::cout << "!!! ERROR Couldn't write to file!" << std::endl << std::endl; + return false; + } + + return true; + } + + static int cleanWhitespace (const StringArray& args, bool replaceTabs) + { + if (! checkArgumentCount (args, 2)) + return 1; + + const File targetFolder (getFile (args[1])); + + if (! targetFolder.exists()) + { + std::cout << "Could not find folder: " << args[1] << std::endl; + return 1; + } + + if (targetFolder.isDirectory()) + { + for (DirectoryIterator di (targetFolder, true, "*.cpp;*.h;*.hpp;*.c;*.cc;*.mm;*.m", File::findFiles); di.next();) + if (! cleanWhitespace (di.getFile(), replaceTabs)) + return 1; + } + else + { + if (! cleanWhitespace (targetFolder, replaceTabs)) + return 1; + } + + return 0; + } + //============================================================================== static int showHelp() { @@ -401,6 +496,12 @@ namespace << std::endl << " introjucer --buildallmodules target_folder module_folder" << std::endl << " Zips all modules in a given folder and creates an index for them." << std::endl + << std::endl + << " introjucer --trim-whitespace target_folder" << std::endl + << " Scans the given folder for C/C++ source files, and trims any trailing whitespace from their lines, as well as normalising their line-endings to CR-LF." << std::endl + << std::endl + << " introjucer --remove-tabs target_folder" << std::endl + << " Scans the given folder for C/C++ source files, and replaces any tab characters with 4 spaces." << std::endl << std::endl; return 0; @@ -426,6 +527,8 @@ int performCommandLine (const String& commandLine) if (matchArgument (command, "buildmodule")) return buildModules (args, false); if (matchArgument (command, "buildallmodules")) return buildModules (args, true); if (matchArgument (command, "status")) return showStatus (args); + if (matchArgument (command, "trim-whitespace")) return cleanWhitespace (args, false); + if (matchArgument (command, "remove-tabs")) return cleanWhitespace (args, true); return commandLineNotPerformed; }