Browse Source

Added a handy new method: XmlElement::createNewChildElement().

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
1d1fc5aa4c
5 changed files with 107 additions and 70 deletions
  1. +82
    -68
      extras/amalgamator/juce_AmalgamatorMain.cpp
  2. +1
    -1
      src/io/streams/juce_MemoryOutputStream.cpp
  3. +1
    -1
      src/io/streams/juce_MemoryOutputStream.h
  4. +7
    -0
      src/text/juce_XmlElement.cpp
  5. +16
    -0
      src/text/juce_XmlElement.h

+ 82
- 68
extras/amalgamator/juce_AmalgamatorMain.cpp View File

@@ -28,6 +28,8 @@
//==============================================================================
static const char* newLine = "\n";
static bool matchesWildcard (const String& filename, const StringArray& wildcards)
{
for (int i = wildcards.size(); --i >= 0;)
@@ -67,16 +69,44 @@ static bool canFileBeReincluded (const File& f)
return true;
}
static int64 calculateStreamHashCode (InputStream& in)
{
int64 t = 0;
const int bufferSize = 4096;
HeapBlock <uint8> buffer;
buffer.malloc (bufferSize);
for (;;)
{
const int num = in.read (buffer, bufferSize);
if (num <= 0)
break;
for (int i = 0; i < num; ++i)
t = t * 65599 + buffer[i];
}
return t;
}
static int64 calculateFileHashCode (const File& file)
{
ScopedPointer <FileInputStream> stream (file.createInputStream());
return stream != 0 ? calculateStreamHashCode (*stream) : 0;
}
//==============================================================================
static bool parseFile (const File& rootFolder,
const File& newTargetFile,
StringArray& dest,
OutputStream& dest,
const File& file,
StringArray& alreadyIncludedFiles,
const StringArray& includesToIgnore,
const StringArray& wildcards,
const bool isOuterFile,
const bool stripUnnecessaryStuff)
const bool isOuterFile)
{
if (! file.exists())
{
@@ -84,30 +114,27 @@ static bool parseFile (const File& rootFolder,
return false;
}
String content (file.loadFileAsString());
StringArray lines;
lines.addLines (file.loadFileAsString());
if (stripUnnecessaryStuff && ! isOuterFile)
if (lines.size() == 0)
{
if (content.startsWith (T("/*")))
content = content.fromFirstOccurrenceOf (T("*/"), false, false).trimStart();
content = content.replace (T("\r\n\r\n\r\n"), T("\r\n\r\n"));
std::cout << "!! ERROR - input file was empty: " << (const char*) file.getFullPathName();
return false;
}
StringArray lines;
lines.addLines (content);
while (lines.size() > 0 && lines[0].trim().isEmpty())
lines.remove (0);
bool lastLineWasBlank = true;
for (int i = 0; i < lines.size(); ++i)
{
String line (lines[i]);
String trimmed (line.trimStart());
if ((! isOuterFile) && line.contains (T("//================================================================")))
if ((! isOuterFile) && trimmed.startsWith (T("//================================================================")))
line = String::empty;
if (line.trimStart().startsWithChar (T('#'))
&& line.removeCharacters (T(" \t")).startsWithIgnoreCase (T("#include\"")))
if (trimmed.startsWithChar (T('#'))
&& trimmed.removeCharacters (T(" \t")).startsWithIgnoreCase (T("#include\"")))
{
const int endOfInclude = line.indexOfChar (line.indexOfChar (T('\"')) + 1, T('\"')) + 1;
const String lineUpToEndOfInclude (line.substring (0, endOfInclude));
@@ -117,8 +144,7 @@ static bool parseFile (const File& rootFolder,
.upToLastOccurrenceOf (T("\""), false, false));
const File targetFile (file.getSiblingFile (filename));
if (targetFile.exists()
&& targetFile.isAChildOf (rootFolder))
if (targetFile.exists() && targetFile.isAChildOf (rootFolder))
{
if (matchesWildcard (filename.replaceCharacter (T('\\'), T('/')), wildcards)
&& ! includesToIgnore.contains (targetFile.getFileName()))
@@ -129,45 +155,36 @@ static bool parseFile (const File& rootFolder,
if (! canFileBeReincluded (targetFile))
alreadyIncludedFiles.add (targetFile.getFullPathName());
dest.add (String::empty);
dest.add (T("/********* Start of inlined file: ")
+ targetFile.getFileName()
+ T(" *********/"));
dest << newLine << "/*** Start of inlined file: " << targetFile.getFileName() << " ***/" << newLine;
if (! parseFile (rootFolder, newTargetFile,
dest, targetFile, alreadyIncludedFiles, includesToIgnore,
wildcards, false, stripUnnecessaryStuff))
wildcards, false))
{
return false;
}
dest.add (T("/********* End of inlined file: ")
+ targetFile.getFileName()
+ T(" *********/"));
dest.add (String::empty);
dest << "/*** End of inlined file: " << targetFile.getFileName() << " ***/" << newLine << newLine;
line = lineAfterInclude;
}
else
{
if (stripUnnecessaryStuff)
line = String::empty;
else
line = T("/* ") + lineUpToEndOfInclude + T(" */") + lineAfterInclude;
line = String::empty;
}
}
else
{
line = lineUpToEndOfInclude.upToFirstOccurrenceOf (T("\""), true, false)
+ targetFile.getRelativePathFrom (newTargetFile.getParentDirectory())
.replaceCharacter (T('\\'), T('/'))
+ T("\"")
+ lineAfterInclude;
+ targetFile.getRelativePathFrom (newTargetFile.getParentDirectory())
.replaceCharacter (T('\\'), T('/'))
+ T("\"")
+ lineAfterInclude;
}
}
}
if (line.trimStart().startsWith (T("/*")))
if (trimmed.startsWith (T("/*")) && (i > 10 || ! isOuterFile))
{
int originalI = i;
String originalLine = line;
@@ -228,7 +245,10 @@ static bool parseFile (const File& rootFolder,
}
}
dest.add (line);
if (line.isNotEmpty() || ! lastLineWasBlank)
dest << line << newLine;
lastLineWasBlank = line.isEmpty();
}
return true;
@@ -236,8 +256,7 @@ static bool parseFile (const File& rootFolder,
//==============================================================================
static bool munge (const File& templateFile, const File& targetFile, const String& wildcard,
const bool stripUnnecessaryStuff, StringArray& alreadyIncludedFiles,
const StringArray& includesToIgnore)
StringArray& alreadyIncludedFiles, const StringArray& includesToIgnore)
{
if (! templateFile.existsAsFile())
{
@@ -245,45 +264,43 @@ static bool munge (const File& templateFile, const File& targetFile, const Strin
return false;
}
StringArray lines, wildcards;
StringArray wildcards;
wildcards.addTokens (wildcard, T(";,"), T("'\""));
wildcards.trim();
wildcards.removeEmptyStrings();
std::cout << "Building: " << (const char*) targetFile.getFullPathName() << "...\n";
TemporaryFile temp (targetFile);
ScopedPointer <FileOutputStream> out (temp.getFile().createOutputStream (1024 * 128));
if (out == 0)
{
std::cout << "\n!! ERROR - couldn't write to the target file: "
<< (const char*) temp.getFile().getFullPathName() << "\n\n";
return false;
}
if (! parseFile (targetFile.getParentDirectory(),
targetFile,
lines, templateFile,
*out, templateFile,
alreadyIncludedFiles,
includesToIgnore,
wildcards,
true, stripUnnecessaryStuff))
true))
{
return false;
}
std::cout << "Building: " << (const char*) targetFile.getFullPathName() << "...\n";
for (int i = 0; i < lines.size() - 2; ++i)
{
if (lines[i].isEmpty() && lines[i + 1].isEmpty())
{
lines.remove (i + 1);
--i;
}
}
MemoryBlock newData, oldData;
const String newText (lines.joinIntoString (T("\n")) + T("\n"));
newData.append ((const char*) newText, (int) strlen ((const char*) newText));
targetFile.loadFileAsData (oldData);
out = 0;
if (oldData == newData)
if (calculateFileHashCode (targetFile) == calculateFileHashCode (temp.getFile()))
{
std::cout << "(No need to write - new file is identical)\n";
std::cout << " -- No need to write - new file is identical\n";
return true;
}
if (! targetFile.replaceWithData (newData.getData(), newData.getSize()))
if (! temp.overwriteTargetFileWithTemporary())
{
std::cout << "\n!! ERROR - couldn't write to the target file: "
<< (const char*) targetFile.getFullPathName() << "\n\n";
@@ -328,16 +345,15 @@ static void mungeJuce (const File& juceFolder)
return;
}
const File hppTemplate (juceFolder.getChildFile (T("src/juce_amalgamated_template.h")));
const File cppTemplate (juceFolder.getChildFile (T("src/juce_amalgamated_template.cpp")));
const File hppTemplate (juceFolder.getChildFile (T("amalgamation/juce_amalgamated_template.h")));
const File cppTemplate (juceFolder.getChildFile (T("amalgamation/juce_amalgamated_template.cpp")));
const File hppTarget (juceFolder.getChildFile (T("juce_amalgamated.h")));
const File cppTarget (juceFolder.getChildFile (T("juce_amalgamated.cpp")));
StringArray alreadyIncludedFiles, includesToIgnore;
if (! munge (hppTemplate, hppTarget,
"*.h", true, alreadyIncludedFiles, includesToIgnore))
if (! munge (hppTemplate, hppTarget, "*.h", alreadyIncludedFiles, includesToIgnore))
{
return;
}
@@ -345,9 +361,7 @@ static void mungeJuce (const File& juceFolder)
findAllFilesIncludedIn (hppTemplate, alreadyIncludedFiles);
includesToIgnore.add (hppTarget.getFileName());
munge (cppTemplate, cppTarget,
"*.cpp;*.c;*.h;*.mm;*.m", true, alreadyIncludedFiles,
includesToIgnore);
munge (cppTemplate, cppTarget, "*.cpp;*.c;*.h;*.mm;*.m", alreadyIncludedFiles, includesToIgnore);
}
//==============================================================================
@@ -366,7 +380,7 @@ int main (int argc, char* argv[])
const String wildcard (String (argv[3]).unquoted());
StringArray alreadyIncludedFiles, includesToIgnore;
munge (templateFile, targetFile, wildcard, false, alreadyIncludedFiles, includesToIgnore);
munge (templateFile, targetFile, wildcard, alreadyIncludedFiles, includesToIgnore);
}
else if (argc == 2)
{


+ 1
- 1
src/io/streams/juce_MemoryOutputStream.cpp View File

@@ -86,7 +86,7 @@ bool MemoryOutputStream::write (const void* buffer, int howMany)
return true;
}
const char* MemoryOutputStream::getData() throw()
const char* MemoryOutputStream::getData() const throw()
{
if (data->getSize() > size)
((char*) data->getData()) [size] = 0;


+ 1
- 1
src/io/streams/juce_MemoryOutputStream.h View File

@@ -65,7 +65,7 @@ public:
@see getDataSize
*/
const char* getData() throw();
const char* getData() const throw();
/** Returns the number of bytes of data that have been written to the stream.


+ 7
- 0
src/text/juce_XmlElement.cpp View File

@@ -820,6 +820,13 @@ void XmlElement::insertChildElement (XmlElement* const newNode,
}
}
XmlElement* XmlElement::createNewChildElement (const String& tagName)
{
XmlElement* const newElement = new XmlElement (tagName);
addChildElement (newElement);
return newElement;
}
bool XmlElement::replaceChildElement (XmlElement* const currentChildElement,
XmlElement* const newNode) throw()
{


+ 16
- 0
src/text/juce_XmlElement.h View File

@@ -507,6 +507,22 @@ public:
void insertChildElement (XmlElement* const newChildNode,
int indexToInsertAt) throw();
/** Creates a new element with the given name and returns it, after adding it
as a child element.
This is a handy method that means that instead of writing this:
@code
XmlElement* newElement = new XmlElement ("foobar");
myParentElement->addChildElement (newElement);
@endcode
..you could just write this:
@code
XmlElement* newElement = myParentElement->createNewChildElement ("foobar");
@endcode
*/
XmlElement* createNewChildElement (const String& tagName);
/** Replaces one of this element's children with another node.
If the current element passed-in isn't actually a child of this element,


Loading…
Cancel
Save