|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2015 - ROLI Ltd.
-
- Permission is granted to use this software under the terms of either:
- a) the GPL v2 (or any later version)
- b) the Affero GPL v3
-
- Details of these licenses can be found at: www.gnu.org/licenses
-
- JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- ------------------------------------------------------------------------------
-
- To release a closed-source product which uses JUCE, commercial licenses are
- available: visit www.juce.com for more information.
-
- ==============================================================================
- */
-
- struct CppParserHelpers
- {
- static bool parseHexInt (const String& text, int64& result)
- {
- CppTokeniserFunctions::StringIterator i (text);
-
- if (CppTokeniserFunctions::parseHexLiteral (i))
- {
- result = text.fromFirstOccurrenceOf ("x", false, true).getHexValue64();
- return true;
- }
-
- return false;
- }
-
- static bool parseOctalInt (const String& text, int64& result)
- {
- CppTokeniserFunctions::StringIterator it (text);
-
- if (CppTokeniserFunctions::parseOctalLiteral (it))
- {
- result = 0;
-
- for (int i = 0; i < text.length(); ++i)
- {
- const int digit = text[i] - '0';
-
- if (digit < 0 || digit > 7)
- break;
-
- result = result * 8 + digit;
- }
-
- return true;
- }
-
- return false;
- }
-
- static bool parseDecimalInt (const String& text, int64& result)
- {
- CppTokeniserFunctions::StringIterator i (text);
-
- if (CppTokeniserFunctions::parseDecimalLiteral (i))
- {
- result = text.getLargeIntValue();
- return true;
- }
-
- return false;
- }
-
- static bool parseInt (const String& text, int64& result)
- {
- return parseHexInt (text, result)
- || parseOctalInt (text, result)
- || parseDecimalInt (text, result);
- }
-
- static bool parseFloat (const String& text, double& result)
- {
- CppTokeniserFunctions::StringIterator i (text);
-
- if (CppTokeniserFunctions::parseFloatLiteral (i))
- {
- result = text.getDoubleValue();
- return true;
- }
-
- return false;
- }
-
- static int parseSingleToken (const String& text)
- {
- if (text.isEmpty())
- return CPlusPlusCodeTokeniser::tokenType_error;
-
- CppTokeniserFunctions::StringIterator i (text);
- i.skipWhitespace();
- const int tok = CppTokeniserFunctions::readNextToken (i);
- i.skipWhitespace();
- i.skip();
- return i.isEOF() ? tok : CPlusPlusCodeTokeniser::tokenType_error;
- }
-
- static String getIntegerSuffix (const String& s) { return s.retainCharacters ("lLuU"); }
- static String getFloatSuffix (const String& s) { return s.retainCharacters ("fF"); }
-
- static String getReplacementStringInSameFormat (const String& old, double newValue)
- {
- {
- CppTokeniserFunctions::StringIterator i (old);
-
- if (CppTokeniserFunctions::parseFloatLiteral (i))
- {
- String s (newValue);
-
- if (! s.containsChar ('.'))
- s += ".0";
-
- return s + getFloatSuffix (old);
- }
- }
-
- return getReplacementStringInSameFormat (old, (int64) newValue);
- }
-
- static String getReplacementStringInSameFormat (const String& old, int64 newValue)
- {
- {
- CppTokeniserFunctions::StringIterator i (old);
-
- if (CppTokeniserFunctions::parseHexLiteral (i))
- {
- String s ("0x" + String::toHexString (newValue) + getIntegerSuffix (old));
-
- if (old.toUpperCase() == old)
- s = s.toUpperCase();
-
- return s;
- }
- }
-
- {
- CppTokeniserFunctions::StringIterator i (old);
-
- if (CppTokeniserFunctions::parseDecimalLiteral (i))
- return String (newValue) + getIntegerSuffix (old);
- }
-
- return old;
- }
-
- // Given a type name which could be a smart pointer or other pointer/ref, this extracts
- // the essential class name of the thing that it points to.
- static String getSignificantClass (String cls)
- {
- int firstAngleBracket = cls.indexOfChar ('<');
-
- if (firstAngleBracket > 0)
- cls = cls.substring (firstAngleBracket + 1).upToLastOccurrenceOf (">", false, false).trim();
-
- while (cls.endsWithChar ('*') || cls.endsWithChar ('&'))
- cls = cls.dropLastCharacters (1).trim();
-
- return cls;
- }
-
- //==============================================================================
- struct ValidCppIdentifierRestriction : public TextEditor::InputFilter
- {
- ValidCppIdentifierRestriction (bool allowTemplatesAndNamespaces)
- : className (allowTemplatesAndNamespaces) {}
-
- String filterNewText (TextEditor& ed, const String& text)
- {
- String allowedChars ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_");
- if (className)
- allowedChars += "<>:";
-
- if (ed.getHighlightedRegion().getStart() > 0)
- allowedChars += "0123456789";
-
- String s = text.retainCharacters (allowedChars);
-
- if (CPlusPlusCodeTokeniser::isReservedKeyword (ed.getText().replaceSection (ed.getHighlightedRegion().getStart(),
- ed.getHighlightedRegion().getLength(),
- s)))
- return String();
-
- return s;
- }
-
- bool className;
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValidCppIdentifierRestriction)
- };
- };
-
- //==============================================================================
- struct CodeChange
- {
- CodeChange (Range<int> r, const String& t) : range (r), text (t)
- {
- }
-
- bool mergeWith (const CodeChange& next)
- {
- if (text.isEmpty())
- {
- if (next.text.isNotEmpty()
- && next.range.isEmpty()
- && next.range.getStart() == range.getStart())
- {
- text = next.text;
- return true;
- }
-
- if (next.text.isEmpty())
- {
- Range<int> nextRange (next.range);
-
- if (nextRange.getStart() >= range.getStart())
- nextRange += range.getLength();
- else if (nextRange.getEnd() > range.getStart())
- nextRange.setEnd (nextRange.getEnd() + range.getLength());
-
- if (range.intersects (nextRange)
- || range.getEnd() == nextRange.getStart()
- || range.getStart() == nextRange.getEnd())
- {
- range = range.getUnionWith (nextRange);
- return true;
- }
- }
- }
- else if (next.text.isEmpty())
- {
- if (next.range.getEnd() == range.getStart())
- {
- range.setStart (next.range.getStart());
- return true;
- }
-
- if (next.range.getStart() == range.getStart() + text.length())
- {
- range.setLength (range.getLength() + next.range.getLength());
- return true;
- }
- }
-
- return false;
- }
-
- void addToList (Array<CodeChange>& list) const
- {
- if (list.size() == 0 || ! list.getReference (list.size() - 1).mergeWith (*this))
- list.add (*this);
- }
-
- Range<int> range;
- String text;
- };
-
- //==============================================================================
- static inline String concatenateListOfStrings (const StringArray& s)
- {
- return s.joinIntoString ("\x01");
- }
-
- static inline StringArray separateJoinedStrings (const String& s)
- {
- return StringArray::fromTokens (s, "\x01", juce::StringRef());
- }
|