diff options
Diffstat (limited to 'scintilla/lexlib')
-rw-r--r-- | scintilla/lexlib/Accessor.cxx | 79 | ||||
-rw-r--r-- | scintilla/lexlib/Accessor.h | 35 | ||||
-rw-r--r-- | scintilla/lexlib/CharacterSet.cxx | 61 | ||||
-rw-r--r-- | scintilla/lexlib/CharacterSet.h | 149 | ||||
-rw-r--r-- | scintilla/lexlib/LexAccessor.h | 175 | ||||
-rw-r--r-- | scintilla/lexlib/LexerBase.cxx | 92 | ||||
-rw-r--r-- | scintilla/lexlib/LexerBase.h | 41 | ||||
-rw-r--r-- | scintilla/lexlib/LexerModule.cxx | 121 | ||||
-rw-r--r-- | scintilla/lexlib/LexerModule.h | 82 | ||||
-rw-r--r-- | scintilla/lexlib/LexerNoExceptions.cxx | 68 | ||||
-rw-r--r-- | scintilla/lexlib/LexerNoExceptions.h | 32 | ||||
-rw-r--r-- | scintilla/lexlib/LexerSimple.cxx | 57 | ||||
-rw-r--r-- | scintilla/lexlib/LexerSimple.h | 30 | ||||
-rw-r--r-- | scintilla/lexlib/OptionSet.h | 140 | ||||
-rw-r--r-- | scintilla/lexlib/PropSetSimple.cxx | 169 | ||||
-rw-r--r-- | scintilla/lexlib/PropSetSimple.h | 33 | ||||
-rw-r--r-- | scintilla/lexlib/StyleContext.cxx | 56 | ||||
-rw-r--r-- | scintilla/lexlib/StyleContext.h | 168 | ||||
-rw-r--r-- | scintilla/lexlib/WordList.cxx | 200 | ||||
-rw-r--r-- | scintilla/lexlib/WordList.h | 41 |
20 files changed, 1829 insertions, 0 deletions
diff --git a/scintilla/lexlib/Accessor.cxx b/scintilla/lexlib/Accessor.cxx new file mode 100644 index 0000000..c180665 --- /dev/null +++ b/scintilla/lexlib/Accessor.cxx @@ -0,0 +1,79 @@ +// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+Accessor::Accessor(IDocument *pAccess_, PropSetSimple *pprops_) : LexAccessor(pAccess_), pprops(pprops_) {
+}
+
+int Accessor::GetPropertyInt(const char *key, int defaultValue) {
+ return pprops->GetInt(key, defaultValue);
+}
+
+int Accessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
+ int end = Length();
+ int spaceFlags = 0;
+
+ // Determines the indentation level of the current line and also checks for consistent
+ // indentation compared to the previous line.
+ // Indentation is judged consistent when the indentation whitespace of each line lines
+ // the same or the indentation of one line is a prefix of the other.
+
+ int pos = LineStart(line);
+ char ch = (*this)[pos];
+ int indent = 0;
+ bool inPrevPrefix = line > 0;
+ int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
+ while ((ch == ' ' || ch == '\t') && (pos < end)) {
+ if (inPrevPrefix) {
+ char chPrev = (*this)[posPrev++];
+ if (chPrev == ' ' || chPrev == '\t') {
+ if (chPrev != ch)
+ spaceFlags |= wsInconsistent;
+ } else {
+ inPrevPrefix = false;
+ }
+ }
+ if (ch == ' ') {
+ spaceFlags |= wsSpace;
+ indent++;
+ } else { // Tab
+ spaceFlags |= wsTab;
+ if (spaceFlags & wsSpace)
+ spaceFlags |= wsSpaceTab;
+ indent = (indent / 8 + 1) * 8;
+ }
+ ch = (*this)[++pos];
+ }
+
+ *flags = spaceFlags;
+ indent += SC_FOLDLEVELBASE;
+ // if completely empty line or the start of a comment...
+ if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
+ (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)))
+ return indent | SC_FOLDLEVELWHITEFLAG;
+ else
+ return indent;
+}
diff --git a/scintilla/lexlib/Accessor.h b/scintilla/lexlib/Accessor.h new file mode 100644 index 0000000..74d42e0 --- /dev/null +++ b/scintilla/lexlib/Accessor.h @@ -0,0 +1,35 @@ +// Scintilla source code edit control
+/** @file Accessor.h
+ ** Interfaces between Scintilla and lexers.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef ACCESSOR_H
+#define ACCESSOR_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8};
+
+class Accessor;
+class WordList;
+class PropSetSimple;
+
+typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len);
+
+class Accessor : public LexAccessor {
+public:
+ PropSetSimple *pprops;
+ Accessor(IDocument *pAccess_, PropSetSimple *pprops_);
+ int GetPropertyInt(const char *, int defaultValue=0);
+ int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/scintilla/lexlib/CharacterSet.cxx b/scintilla/lexlib/CharacterSet.cxx new file mode 100644 index 0000000..86e08a1 --- /dev/null +++ b/scintilla/lexlib/CharacterSet.cxx @@ -0,0 +1,61 @@ +// Scintilla source code edit control
+/** @file CharacterSet.cxx
+ ** Simple case functions for ASCII.
+ ** Lexer infrastructure.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "CharacterSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+int CompareCaseInsensitive(const char *a, const char *b) {
+ while (*a && *b) {
+ if (*a != *b) {
+ char upperA = MakeUpperCase(*a);
+ char upperB = MakeUpperCase(*b);
+ if (upperA != upperB)
+ return upperA - upperB;
+ }
+ a++;
+ b++;
+ }
+ // Either *a or *b is nul
+ return *a - *b;
+}
+
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
+ while (*a && *b && len) {
+ if (*a != *b) {
+ char upperA = MakeUpperCase(*a);
+ char upperB = MakeUpperCase(*b);
+ if (upperA != upperB)
+ return upperA - upperB;
+ }
+ a++;
+ b++;
+ len--;
+ }
+ if (len == 0)
+ return 0;
+ else
+ // Either *a or *b is nul
+ return *a - *b;
+}
+
+#ifdef SCI_NAMESPACE
+}
+#endif
diff --git a/scintilla/lexlib/CharacterSet.h b/scintilla/lexlib/CharacterSet.h new file mode 100644 index 0000000..2ac21c5 --- /dev/null +++ b/scintilla/lexlib/CharacterSet.h @@ -0,0 +1,149 @@ +// Scintilla source code edit control
+/** @file CharacterSet.h
+ ** Encapsulates a set of characters. Used to test if a character is within a set.
+ **/
+// Copyright 2007 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef CHARACTERSET_H
+#define CHARACTERSET_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class CharacterSet {
+ int size;
+ bool valueAfter;
+ bool *bset;
+public:
+ enum setBase {
+ setNone=0,
+ setLower=1,
+ setUpper=2,
+ setDigits=4,
+ setAlpha=setLower|setUpper,
+ setAlphaNum=setAlpha|setDigits
+ };
+ CharacterSet(setBase base=setNone, const char *initialSet="", int size_=0x80, bool valueAfter_=false) {
+ size = size_;
+ valueAfter = valueAfter_;
+ bset = new bool[size];
+ for (int i=0; i < size; i++) {
+ bset[i] = false;
+ }
+ AddString(initialSet);
+ if (base & setLower)
+ AddString("abcdefghijklmnopqrstuvwxyz");
+ if (base & setUpper)
+ AddString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ if (base & setDigits)
+ AddString("0123456789");
+ }
+ ~CharacterSet() {
+ delete []bset;
+ bset = 0;
+ size = 0;
+ }
+ void Add(int val) {
+ assert(val >= 0);
+ assert(val < size);
+ bset[val] = true;
+ }
+ void AddString(const char *CharacterSet) {
+ for (const char *cp=CharacterSet; *cp; cp++) {
+ int val = static_cast<unsigned char>(*cp);
+ assert(val >= 0);
+ assert(val < size);
+ bset[val] = true;
+ }
+ }
+ bool Contains(int val) const {
+ assert(val >= 0);
+ if (val < 0) return false;
+ return (val < size) ? bset[val] : valueAfter;
+ }
+};
+
+// Functions for classifying characters
+
+inline bool IsASpace(int ch) {
+ return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+inline bool IsASpaceOrTab(int ch) {
+ return (ch == ' ') || (ch == '\t');
+}
+
+inline bool IsADigit(int ch) {
+ return (ch >= '0') && (ch <= '9');
+}
+
+inline bool IsADigit(int ch, int base) {
+ if (base <= 10) {
+ return (ch >= '0') && (ch < '0' + base);
+ } else {
+ return ((ch >= '0') && (ch <= '9')) ||
+ ((ch >= 'A') && (ch < 'A' + base - 10)) ||
+ ((ch >= 'a') && (ch < 'a' + base - 10));
+ }
+}
+
+inline bool IsASCII(int ch) {
+ return ch < 0x80;
+}
+
+inline bool IsAlphaNumeric(int ch) {
+ return
+ ((ch >= '0') && (ch <= '9')) ||
+ ((ch >= 'a') && (ch <= 'z')) ||
+ ((ch >= 'A') && (ch <= 'Z'));
+}
+
+/**
+ * Check if a character is a space.
+ * This is ASCII specific but is safe with chars >= 0x80.
+ */
+inline bool isspacechar(int ch) {
+ return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+inline bool iswordchar(int ch) {
+ return IsASCII(ch) && (IsAlphaNumeric(ch) || ch == '.' || ch == '_');
+}
+
+inline bool iswordstart(int ch) {
+ return IsASCII(ch) && (IsAlphaNumeric(ch) || ch == '_');
+}
+
+inline bool isoperator(int ch) {
+ if (IsASCII(ch) && IsAlphaNumeric(ch))
+ return false;
+ // '.' left out as it is used to make up numbers
+ if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
+ ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
+ ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
+ ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
+ ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
+ ch == '?' || ch == '!' || ch == '.' || ch == '~')
+ return true;
+ return false;
+}
+
+// Simple case functions for ASCII.
+
+inline char MakeUpperCase(char ch) {
+ if (ch < 'a' || ch > 'z')
+ return ch;
+ else
+ return static_cast<char>(ch - 'a' + 'A');
+}
+
+int CompareCaseInsensitive(const char *a, const char *b);
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/scintilla/lexlib/LexAccessor.h b/scintilla/lexlib/LexAccessor.h new file mode 100644 index 0000000..0ad7bc1 --- /dev/null +++ b/scintilla/lexlib/LexAccessor.h @@ -0,0 +1,175 @@ +// Scintilla source code edit control
+/** @file LexAccessor.h
+ ** Interfaces between Scintilla and lexers.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXACCESSOR_H
+#define LEXACCESSOR_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class LexAccessor {
+private:
+ IDocument *pAccess;
+ enum {extremePosition=0x7FFFFFFF};
+ /** @a bufferSize is a trade off between time taken to copy the characters
+ * and retrieval overhead.
+ * @a slopSize positions the buffer before the desired position
+ * in case there is some backtracking. */
+ enum {bufferSize=4000, slopSize=bufferSize/8};
+ char buf[bufferSize+1];
+ int startPos;
+ int endPos;
+ int codePage;
+ int lenDoc;
+ int mask;
+ char styleBuf[bufferSize];
+ int validLen;
+ char chFlags;
+ char chWhile;
+ unsigned int startSeg;
+ int startPosStyling;
+
+ void Fill(int position) {
+ startPos = position - slopSize;
+ if (startPos + bufferSize > lenDoc)
+ startPos = lenDoc - bufferSize;
+ if (startPos < 0)
+ startPos = 0;
+ endPos = startPos + bufferSize;
+ if (endPos > lenDoc)
+ endPos = lenDoc;
+
+ pAccess->GetCharRange(buf, startPos, endPos-startPos);
+ buf[endPos-startPos] = '\0';
+ }
+
+public:
+ LexAccessor(IDocument *pAccess_) :
+ pAccess(pAccess_), startPos(extremePosition), endPos(0),
+ codePage(pAccess->CodePage()), lenDoc(pAccess->Length()),
+ mask(127), validLen(0), chFlags(0), chWhile(0),
+ startSeg(0), startPosStyling(0) {
+ }
+ char operator[](int position) {
+ if (position < startPos || position >= endPos) {
+ Fill(position);
+ }
+ return buf[position - startPos];
+ }
+ /** Safe version of operator[], returning a defined value for invalid position. */
+ char SafeGetCharAt(int position, char chDefault=' ') {
+ if (position < startPos || position >= endPos) {
+ Fill(position);
+ if (position < startPos || position >= endPos) {
+ // Position is outside range of document
+ return chDefault;
+ }
+ }
+ return buf[position - startPos];
+ }
+ bool IsLeadByte(char ch) {
+ return pAccess->IsDBCSLeadByte(ch);
+ }
+
+ bool Match(int pos, const char *s) {
+ for (int i=0; *s; i++) {
+ if (*s != SafeGetCharAt(pos+i))
+ return false;
+ s++;
+ }
+ return true;
+ }
+ char StyleAt(int position) {
+ return static_cast<char>(pAccess->StyleAt(position) & mask);
+ }
+ int GetLine(int position) {
+ return pAccess->LineFromPosition(position);
+ }
+ int LineStart(int line) {
+ return pAccess->LineStart(line);
+ }
+ int LevelAt(int line) {
+ return pAccess->GetLevel(line);
+ }
+ int Length() const {
+ return lenDoc;
+ }
+ void Flush() {
+ startPos = extremePosition;
+ if (validLen > 0) {
+ pAccess->SetStyles(validLen, styleBuf);
+ startPosStyling += validLen;
+ validLen = 0;
+ }
+ }
+ int GetLineState(int line) {
+ return pAccess->GetLineState(line);
+ }
+ int SetLineState(int line, int state) {
+ return pAccess->SetLineState(line, state);
+ }
+ // Style setting
+ void StartAt(unsigned int start, char chMask=31) {
+ // Store the mask specified for use with StyleAt.
+ mask = chMask;
+ pAccess->StartStyling(start, chMask);
+ startPosStyling = start;
+ }
+ void SetFlags(char chFlags_, char chWhile_) {
+ chFlags = chFlags_;
+ chWhile = chWhile_;
+ }
+ unsigned int GetStartSegment() const {
+ return startSeg;
+ }
+ void StartSegment(unsigned int pos) {
+ startSeg = pos;
+ }
+ void ColourTo(unsigned int pos, int chAttr) {
+ // Only perform styling if non empty range
+ if (pos != startSeg - 1) {
+ assert(pos >= startSeg);
+ if (pos < startSeg) {
+ return;
+ }
+
+ if (validLen + (pos - startSeg + 1) >= bufferSize)
+ Flush();
+ if (validLen + (pos - startSeg + 1) >= bufferSize) {
+ // Too big for buffer so send directly
+ pAccess->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
+ } else {
+ if (chAttr != chWhile)
+ chFlags = 0;
+ chAttr |= chFlags;
+ for (unsigned int i = startSeg; i <= pos; i++) {
+ assert((startPosStyling + validLen) < Length());
+ styleBuf[validLen++] = static_cast<char>(chAttr);
+ }
+ }
+ }
+ startSeg = pos+1;
+ }
+ void SetLevel(int line, int level) {
+ pAccess->SetLevel(line, level);
+ }
+ void IndicatorFill(int start, int end, int indicator, int value) {
+ pAccess->DecorationSetCurrentIndicator(indicator);
+ pAccess->DecorationFillRange(start, value, end - start);
+ }
+
+ void ChangeLexerState(int start, int end) {
+ pAccess->ChangeLexerState(start, end);
+ }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/scintilla/lexlib/LexerBase.cxx b/scintilla/lexlib/LexerBase.cxx new file mode 100644 index 0000000..e2791ec --- /dev/null +++ b/scintilla/lexlib/LexerBase.cxx @@ -0,0 +1,92 @@ +// Scintilla source code edit control
+/** @file LexerSimple.cxx
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerBase::LexerBase() {
+ for (int wl = 0; wl < numWordLists; wl++)
+ keyWordLists[wl] = new WordList;
+ keyWordLists[numWordLists] = 0;
+}
+
+LexerBase::~LexerBase() {
+ for (int wl = 0; wl < numWordLists; wl++) {
+ delete keyWordLists[wl];
+ keyWordLists[wl] = 0;
+ }
+ keyWordLists[numWordLists] = 0;
+}
+
+void SCI_METHOD LexerBase::Release() {
+ delete this;
+}
+
+int SCI_METHOD LexerBase::Version() const {
+ return lvOriginal;
+}
+
+const char * SCI_METHOD LexerBase::PropertyNames() {
+ return "";
+}
+
+int SCI_METHOD LexerBase::PropertyType(const char *) {
+ return SC_TYPE_BOOLEAN;
+}
+
+const char * SCI_METHOD LexerBase::DescribeProperty(const char *) {
+ return "";
+}
+
+int SCI_METHOD LexerBase::PropertySet(const char *key, const char *val) {
+ const char *valOld = props.Get(key);
+ if (strcmp(val, valOld) != 0) {
+ props.Set(key, val);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+const char * SCI_METHOD LexerBase::DescribeWordListSets() {
+ return "";
+}
+
+int SCI_METHOD LexerBase::WordListSet(int n, const char *wl) {
+ if (n < numWordLists) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*keyWordLists[n] != wlNew) {
+ keyWordLists[n]->Set(wl);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+void * SCI_METHOD LexerBase::PrivateCall(int, void *) {
+ return 0;
+}
diff --git a/scintilla/lexlib/LexerBase.h b/scintilla/lexlib/LexerBase.h new file mode 100644 index 0000000..0d38bc4 --- /dev/null +++ b/scintilla/lexlib/LexerBase.h @@ -0,0 +1,41 @@ +// Scintilla source code edit control
+/** @file LexerBase.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERBASE_H
+#define LEXERBASE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerBase : public ILexer {
+protected:
+ PropSetSimple props;
+ enum {numWordLists=KEYWORDSET_MAX+1};
+ WordList *keyWordLists[numWordLists+1];
+public:
+ LexerBase();
+ ~LexerBase();
+ void SCI_METHOD Release();
+ int SCI_METHOD Version() const;
+ const char * SCI_METHOD PropertyNames();
+ int SCI_METHOD PropertyType(const char *name);
+ const char * SCI_METHOD DescribeProperty(const char *name);
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets();
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+ void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+ void * SCI_METHOD PrivateCall(int operation, void *pointer);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/scintilla/lexlib/LexerModule.cxx b/scintilla/lexlib/LexerModule.cxx new file mode 100644 index 0000000..4b1aa6d --- /dev/null +++ b/scintilla/lexlib/LexerModule.cxx @@ -0,0 +1,121 @@ +// Scintilla source code edit control
+/** @file LexerModule.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <string>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerSimple.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerModule::LexerModule(int language_,
+ LexerFunction fnLexer_,
+ const char *languageName_,
+ LexerFunction fnFolder_,
+ const char *const wordListDescriptions_[],
+ int styleBits_) :
+ language(language_),
+ fnLexer(fnLexer_),
+ fnFolder(fnFolder_),
+ fnFactory(0),
+ wordListDescriptions(wordListDescriptions_),
+ styleBits(styleBits_),
+ languageName(languageName_) {
+}
+
+LexerModule::LexerModule(int language_,
+ LexerFactoryFunction fnFactory_,
+ const char *languageName_,
+ const char * const wordListDescriptions_[],
+ int styleBits_) :
+ language(language_),
+ fnLexer(0),
+ fnFolder(0),
+ fnFactory(fnFactory_),
+ wordListDescriptions(wordListDescriptions_),
+ styleBits(styleBits_),
+ languageName(languageName_) {
+}
+
+int LexerModule::GetNumWordLists() const {
+ if (wordListDescriptions == NULL) {
+ return -1;
+ } else {
+ int numWordLists = 0;
+
+ while (wordListDescriptions[numWordLists]) {
+ ++numWordLists;
+ }
+
+ return numWordLists;
+ }
+}
+
+const char *LexerModule::GetWordListDescription(int index) const {
+ static const char *emptyStr = "";
+
+ assert(index < GetNumWordLists());
+ if (index >= GetNumWordLists()) {
+ return emptyStr;
+ } else {
+ return wordListDescriptions[index];
+ }
+}
+
+int LexerModule::GetStyleBitsNeeded() const {
+ return styleBits;
+}
+
+ILexer *LexerModule::Create() const {
+ if (fnFactory)
+ return fnFactory();
+ else
+ return new LexerSimple(this);
+}
+
+void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const {
+ if (fnLexer)
+ fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler);
+}
+
+void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const {
+ if (fnFolder) {
+ int lineCurrent = styler.GetLine(startPos);
+ // Move back one line in case deletion wrecked current line fold state
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ int newStartPos = styler.LineStart(lineCurrent);
+ lengthDoc += startPos - newStartPos;
+ startPos = newStartPos;
+ initStyle = 0;
+ if (startPos > 0) {
+ initStyle = styler.StyleAt(startPos - 1);
+ }
+ }
+ fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler);
+ }
+}
diff --git a/scintilla/lexlib/LexerModule.h b/scintilla/lexlib/LexerModule.h new file mode 100644 index 0000000..22f4a60 --- /dev/null +++ b/scintilla/lexlib/LexerModule.h @@ -0,0 +1,82 @@ +// Scintilla source code edit control
+/** @file LexerModule.h
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERMODULE_H
+#define LEXERMODULE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class Accessor;
+class WordList;
+
+typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
+ WordList *keywordlists[], Accessor &styler);
+typedef ILexer *(*LexerFactoryFunction)();
+
+/**
+ * A LexerModule is responsible for lexing and folding a particular language.
+ * The class maintains a list of LexerModules which can be searched to find a
+ * module appropriate to a particular language.
+ */
+class LexerModule {
+protected:
+ int language;
+ LexerFunction fnLexer;
+ LexerFunction fnFolder;
+ LexerFactoryFunction fnFactory;
+ const char * const * wordListDescriptions;
+ int styleBits;
+
+public:
+ const char *languageName;
+ LexerModule(int language_,
+ LexerFunction fnLexer_,
+ const char *languageName_=0,
+ LexerFunction fnFolder_=0,
+ const char * const wordListDescriptions_[] = NULL,
+ int styleBits_=5);
+ LexerModule(int language_,
+ LexerFactoryFunction fnFactory_,
+ const char *languageName_,
+ const char * const wordListDescriptions_[] = NULL,
+ int styleBits_=8);
+ virtual ~LexerModule() {
+ }
+ int GetLanguage() const { return language; }
+
+ // -1 is returned if no WordList information is available
+ int GetNumWordLists() const;
+ const char *GetWordListDescription(int index) const;
+
+ int GetStyleBitsNeeded() const;
+
+ ILexer *Create() const;
+
+ virtual void Lex(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const;
+ virtual void Fold(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const;
+
+ friend class Catalogue;
+};
+
+inline int Maximum(int a, int b) {
+ return (a > b) ? a : b;
+}
+
+// Shut up annoying Visual C++ warnings:
+#ifdef _MSC_VER
+#pragma warning(disable: 4244 4309 4514 4710)
+#endif
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/scintilla/lexlib/LexerNoExceptions.cxx b/scintilla/lexlib/LexerNoExceptions.cxx new file mode 100644 index 0000000..e179a74 --- /dev/null +++ b/scintilla/lexlib/LexerNoExceptions.cxx @@ -0,0 +1,68 @@ +// Scintilla source code edit control
+/** @file LexerNoExceptions.cxx
+ ** A simple lexer with no state which does not throw exceptions so can be used in an external lexer.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerNoExceptions.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+int SCI_METHOD LexerNoExceptions::PropertySet(const char *key, const char *val) {
+ try {
+ return LexerBase::PropertySet(key, val);
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerNoExceptions::WordListSet(int n, const char *wl) {
+ try {
+ return LexerBase::WordListSet(n, wl);
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ }
+ return -1;
+}
+
+void SCI_METHOD LexerNoExceptions::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ try {
+ Accessor astyler(pAccess, &props);
+ Lexer(startPos, length, initStyle, pAccess, astyler);
+ astyler.Flush();
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ pAccess->SetErrorStatus(SC_STATUS_FAILURE);
+ }
+}
+void SCI_METHOD LexerNoExceptions::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ try {
+ Accessor astyler(pAccess, &props);
+ Folder(startPos, length, initStyle, pAccess, astyler);
+ astyler.Flush();
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ pAccess->SetErrorStatus(SC_STATUS_FAILURE);
+ }
+}
diff --git a/scintilla/lexlib/LexerNoExceptions.h b/scintilla/lexlib/LexerNoExceptions.h new file mode 100644 index 0000000..90219c8 --- /dev/null +++ b/scintilla/lexlib/LexerNoExceptions.h @@ -0,0 +1,32 @@ +// Scintilla source code edit control
+/** @file LexerNoExceptions.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LexerNoExceptions_H
+#define LexerNoExceptions_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerNoExceptions : public LexerBase {
+public:
+ // TODO Also need to prevent exceptions in constructor and destructor
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *);
+
+ virtual void Lexer(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0;
+ virtual void Folder(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/scintilla/lexlib/LexerSimple.cxx b/scintilla/lexlib/LexerSimple.cxx new file mode 100644 index 0000000..f1b5362 --- /dev/null +++ b/scintilla/lexlib/LexerSimple.cxx @@ -0,0 +1,57 @@ +// Scintilla source code edit control
+/** @file LexerSimple.cxx
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <string>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerSimple.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerSimple::LexerSimple(const LexerModule *module_) : module(module_) {
+ for (int wl = 0; wl < module->GetNumWordLists(); wl++) {
+ if (!wordLists.empty())
+ wordLists += "\n";
+ wordLists += module->GetWordListDescription(wl);
+ }
+}
+
+const char * SCI_METHOD LexerSimple::DescribeWordListSets() {
+ return wordLists.c_str();
+}
+
+void SCI_METHOD LexerSimple::Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) {
+ Accessor astyler(pAccess, &props);
+ module->Lex(startPos, lengthDoc, initStyle, keyWordLists, astyler);
+ astyler.Flush();
+}
+
+void SCI_METHOD LexerSimple::Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) {
+ if (props.GetInt("fold")) {
+ Accessor astyler(pAccess, &props);
+ module->Fold(startPos, lengthDoc, initStyle, keyWordLists, astyler);
+ astyler.Flush();
+ }
+}
diff --git a/scintilla/lexlib/LexerSimple.h b/scintilla/lexlib/LexerSimple.h new file mode 100644 index 0000000..6c79db4 --- /dev/null +++ b/scintilla/lexlib/LexerSimple.h @@ -0,0 +1,30 @@ +// Scintilla source code edit control
+/** @file LexerSimple.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERSIMPLE_H
+#define LEXERSIMPLE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerSimple : public LexerBase {
+ const LexerModule *module;
+ std::string wordLists;
+public:
+ LexerSimple(const LexerModule *module_);
+ const char * SCI_METHOD DescribeWordListSets();
+ void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/scintilla/lexlib/OptionSet.h b/scintilla/lexlib/OptionSet.h new file mode 100644 index 0000000..1969173 --- /dev/null +++ b/scintilla/lexlib/OptionSet.h @@ -0,0 +1,140 @@ +// Scintilla source code edit control
+/** @file OptionSet.h
+ ** Manage descriptive information about an options struct for a lexer.
+ ** Hold the names, positions, and descriptions of boolean, integer and string options and
+ ** allow setting options and retrieving metadata about the options.
+ **/
+// Copyright 2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef OPTIONSET_H
+#define OPTIONSET_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+template <typename T>
+class OptionSet {
+ typedef T Target;
+ typedef bool T::*plcob;
+ typedef int T::*plcoi;
+ typedef std::string T::*plcos;
+ struct Option {
+ int opType;
+ union {
+ plcob pb;
+ plcoi pi;
+ plcos ps;
+ };
+ std::string description;
+ Option() :
+ opType(SC_TYPE_BOOLEAN), pb(0), description("") {
+ }
+ Option(plcob pb_, std::string description_="") :
+ opType(SC_TYPE_BOOLEAN), pb(pb_), description(description_) {
+ }
+ Option(plcoi pi_, std::string description_) :
+ opType(SC_TYPE_INTEGER), pi(pi_), description(description_) {
+ }
+ Option(plcos ps_, std::string description_) :
+ opType(SC_TYPE_STRING), ps(ps_), description(description_) {
+ }
+ bool Set(T *base, const char *val) {
+ switch (opType) {
+ case SC_TYPE_BOOLEAN: {
+ bool option = atoi(val) != 0;
+ if ((*base).*pb != option) {
+ (*base).*pb = option;
+ return true;
+ }
+ break;
+ }
+ case SC_TYPE_INTEGER: {
+ int option = atoi(val);
+ if ((*base).*pi != option) {
+ (*base).*pi = option;
+ return true;
+ }
+ break;
+ }
+ case SC_TYPE_STRING: {
+ if ((*base).*ps != val) {
+ (*base).*ps = val;
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+ }
+ };
+ typedef std::map<std::string, Option> OptionMap;
+ OptionMap nameToDef;
+ std::string names;
+ std::string wordLists;
+
+ void AppendName(const char *name) {
+ if (!names.empty())
+ names += "\n";
+ names += name;
+ }
+public:
+ void DefineProperty(const char *name, plcob pb, std::string description="") {
+ nameToDef[name] = Option(pb, description);
+ AppendName(name);
+ }
+ void DefineProperty(const char *name, plcoi pi, std::string description="") {
+ nameToDef[name] = Option(pi, description);
+ AppendName(name);
+ }
+ void DefineProperty(const char *name, plcos ps, std::string description="") {
+ nameToDef[name] = Option(ps, description);
+ AppendName(name);
+ }
+ const char *PropertyNames() {
+ return names.c_str();
+ }
+ int PropertyType(const char *name) {
+ typename OptionMap::iterator it = nameToDef.find(name);
+ if (it != nameToDef.end()) {
+ return it->second.opType;
+ }
+ return SC_TYPE_BOOLEAN;
+ }
+ const char *DescribeProperty(const char *name) {
+ typename OptionMap::iterator it = nameToDef.find(name);
+ if (it != nameToDef.end()) {
+ return it->second.description.c_str();
+ }
+ return "";
+ }
+
+ bool PropertySet(T *base, const char *name, const char *val) {
+ typename OptionMap::iterator it = nameToDef.find(name);
+ if (it != nameToDef.end()) {
+ return it->second.Set(base, val);
+ }
+ return false;
+ }
+
+ void DefineWordListSets(const char * const wordListDescriptions[]) {
+ if (wordListDescriptions) {
+ for (size_t wl = 0; wordListDescriptions[wl]; wl++) {
+ if (!wordLists.empty())
+ wordLists += "\n";
+ wordLists += wordListDescriptions[wl];
+ }
+ }
+ }
+
+ const char *DescribeWordListSets() {
+ return wordLists.c_str();
+ }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/scintilla/lexlib/PropSetSimple.cxx b/scintilla/lexlib/PropSetSimple.cxx new file mode 100644 index 0000000..9bd4e5c --- /dev/null +++ b/scintilla/lexlib/PropSetSimple.cxx @@ -0,0 +1,169 @@ +// SciTE - Scintilla based Text Editor
+/** @file PropSetSimple.cxx
+ ** A Java style properties file module.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// Maintain a dictionary of properties
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef _MSC_VER
+// Visual C++ doesn't like unreachable code or long decorated names in its own headers.
+#pragma warning(disable: 4018 4100 4245 4511 4512 4663 4702 4786)
+#endif
+
+#include <string>
+#include <map>
+
+#include "PropSetSimple.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+typedef std::map<std::string, std::string> mapss;
+
+PropSetSimple::PropSetSimple() {
+ mapss *props = new mapss;
+ impl = static_cast<void *>(props);
+}
+
+PropSetSimple::~PropSetSimple() {
+ mapss *props = static_cast<mapss *>(impl);
+ delete props;
+ impl = 0;
+}
+
+void PropSetSimple::Set(const char *key, const char *val, int lenKey, int lenVal) {
+ mapss *props = static_cast<mapss *>(impl);
+ if (!*key) // Empty keys are not supported
+ return;
+ if (lenKey == -1)
+ lenKey = static_cast<int>(strlen(key));
+ if (lenVal == -1)
+ lenVal = static_cast<int>(strlen(val));
+ (*props)[std::string(key, lenKey)] = std::string(val, lenVal);
+}
+
+static bool IsASpaceCharacter(unsigned int ch) {
+ return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+void PropSetSimple::Set(const char *keyVal) {
+ while (IsASpaceCharacter(*keyVal))
+ keyVal++;
+ const char *endVal = keyVal;
+ while (*endVal && (*endVal != '\n'))
+ endVal++;
+ const char *eqAt = strchr(keyVal, '=');
+ if (eqAt) {
+ Set(keyVal, eqAt + 1, eqAt-keyVal, endVal - eqAt - 1);
+ } else if (*keyVal) { // No '=' so assume '=1'
+ Set(keyVal, "1", endVal-keyVal, 1);
+ }
+}
+
+void PropSetSimple::SetMultiple(const char *s) {
+ const char *eol = strchr(s, '\n');
+ while (eol) {
+ Set(s);
+ s = eol + 1;
+ eol = strchr(s, '\n');
+ }
+ Set(s);
+}
+
+const char *PropSetSimple::Get(const char *key) const {
+ mapss *props = static_cast<mapss *>(impl);
+ mapss::const_iterator keyPos = props->find(std::string(key));
+ if (keyPos != props->end()) {
+ return keyPos->second.c_str();
+ } else {
+ return "";
+ }
+}
+
+// There is some inconsistency between GetExpanded("foo") and Expand("$(foo)").
+// A solution is to keep a stack of variables that have been expanded, so that
+// recursive expansions can be skipped. For now I'll just use the C++ stack
+// for that, through a recursive function and a simple chain of pointers.
+
+struct VarChain {
+ VarChain(const char *var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {}
+
+ bool contains(const char *testVar) const {
+ return (var && (0 == strcmp(var, testVar)))
+ || (link && link->contains(testVar));
+ }
+
+ const char *var;
+ const VarChain *link;
+};
+
+static int ExpandAllInPlace(const PropSetSimple &props, std::string &withVars, int maxExpands, const VarChain &blankVars) {
+ size_t varStart = withVars.find("$(");
+ while ((varStart != std::string::npos) && (maxExpands > 0)) {
+ size_t varEnd = withVars.find(")", varStart+2);
+ if (varEnd == std::string::npos) {
+ break;
+ }
+
+ // For consistency, when we see '$(ab$(cde))', expand the inner variable first,
+ // regardless whether there is actually a degenerate variable named 'ab$(cde'.
+ size_t innerVarStart = withVars.find("$(", varStart+2);
+ while ((innerVarStart != std::string::npos) && (innerVarStart > varStart) && (innerVarStart < varEnd)) {
+ varStart = innerVarStart;
+ innerVarStart = withVars.find("$(", varStart+2);
+ }
+
+ std::string var(withVars.c_str(), varStart + 2, varEnd - varStart - 2);
+ std::string val = props.Get(var.c_str());
+
+ if (blankVars.contains(var.c_str())) {
+ val = ""; // treat blankVar as an empty string (e.g. to block self-reference)
+ }
+
+ if (--maxExpands >= 0) {
+ maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars));
+ }
+
+ withVars.erase(varStart, varEnd-varStart+1);
+ withVars.insert(varStart, val.c_str(), val.length());
+
+ varStart = withVars.find("$(");
+ }
+
+ return maxExpands;
+}
+
+char *PropSetSimple::Expanded(const char *key) const {
+ std::string val = Get(key);
+ ExpandAllInPlace(*this, val, 100, VarChain(key));
+ char *ret = new char [val.size() + 1];
+ strcpy(ret, val.c_str());
+ return ret;
+}
+
+int PropSetSimple::GetExpanded(const char *key, char *result) const {
+ char *val = Expanded(key);
+ const int n = strlen(val);
+ if (result) {
+ strcpy(result, val);
+ }
+ delete []val;
+ return n; // Not including NUL
+}
+
+int PropSetSimple::GetInt(const char *key, int defaultValue) const {
+ char *val = Expanded(key);
+ if (val) {
+ int retVal = val[0] ? atoi(val) : defaultValue;
+ delete []val;
+ return retVal;
+ }
+ return defaultValue;
+}
diff --git a/scintilla/lexlib/PropSetSimple.h b/scintilla/lexlib/PropSetSimple.h new file mode 100644 index 0000000..ca91b63 --- /dev/null +++ b/scintilla/lexlib/PropSetSimple.h @@ -0,0 +1,33 @@ +// Scintilla source code edit control
+/** @file PropSetSimple.h
+ ** A basic string to string map.
+ **/
+// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef PROPSETSIMPLE_H
+#define PROPSETSIMPLE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class PropSetSimple {
+ void *impl;
+ void Set(const char *keyVal);
+public:
+ PropSetSimple();
+ virtual ~PropSetSimple();
+ void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1);
+ void SetMultiple(const char *);
+ const char *Get(const char *key) const;
+ char *Expanded(const char *key) const;
+ int GetExpanded(const char *key, char *result) const;
+ int GetInt(const char *key, int defaultValue=0) const;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/scintilla/lexlib/StyleContext.cxx b/scintilla/lexlib/StyleContext.cxx new file mode 100644 index 0000000..3db04e3 --- /dev/null +++ b/scintilla/lexlib/StyleContext.cxx @@ -0,0 +1,56 @@ +// Scintilla source code edit control
+/** @file StyleContext.cxx
+ ** Lexer infrastructure.
+ **/
+// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
+// This file is in the public domain.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "ILexer.h"
+
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static void getRange(unsigned int start,
+ unsigned int end,
+ LexAccessor &styler,
+ char *s,
+ unsigned int len) {
+ unsigned int i = 0;
+ while ((i < end - start + 1) && (i < len-1)) {
+ s[i] = styler[start + i];
+ i++;
+ }
+ s[i] = '\0';
+}
+
+void StyleContext::GetCurrent(char *s, unsigned int len) {
+ getRange(styler.GetStartSegment(), currentPos - 1, styler, s, len);
+}
+
+static void getRangeLowered(unsigned int start,
+ unsigned int end,
+ LexAccessor &styler,
+ char *s,
+ unsigned int len) {
+ unsigned int i = 0;
+ while ((i < end - start + 1) && (i < len-1)) {
+ s[i] = static_cast<char>(tolower(styler[start + i]));
+ i++;
+ }
+ s[i] = '\0';
+}
+
+void StyleContext::GetCurrentLowered(char *s, unsigned int len) {
+ getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len);
+}
diff --git a/scintilla/lexlib/StyleContext.h b/scintilla/lexlib/StyleContext.h new file mode 100644 index 0000000..c3f85e3 --- /dev/null +++ b/scintilla/lexlib/StyleContext.h @@ -0,0 +1,168 @@ +// Scintilla source code edit control
+/** @file StyleContext.cxx
+ ** Lexer infrastructure.
+ **/
+// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
+// This file is in the public domain.
+
+#ifndef STYLECONTEXT_H
+#define STYLECONTEXT_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+static inline int MakeLowerCase(int ch) {
+ if (ch < 'A' || ch > 'Z')
+ return ch;
+ else
+ return ch - 'A' + 'a';
+}
+
+// All languages handled so far can treat all characters >= 0x80 as one class
+// which just continues the current token or starts an identifier if in default.
+// DBCS treated specially as the second character can be < 0x80 and hence
+// syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
+class StyleContext {
+ LexAccessor &styler;
+ unsigned int endPos;
+ StyleContext &operator=(const StyleContext &);
+ void GetNextChar(unsigned int pos) {
+ chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
+ if (styler.IsLeadByte(static_cast<char>(chNext))) {
+ chNext = chNext << 8;
+ chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
+ }
+ // End of line?
+ // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win)
+ // or on LF alone (Unix). Avoid triggering two times on Dos/Win.
+ atLineEnd = (ch == '\r' && chNext != '\n') ||
+ (ch == '\n') ||
+ (currentPos >= endPos);
+ }
+
+public:
+ unsigned int currentPos;
+ bool atLineStart;
+ bool atLineEnd;
+ int state;
+ int chPrev;
+ int ch;
+ int chNext;
+
+ StyleContext(unsigned int startPos, unsigned int length,
+ int initStyle, LexAccessor &styler_, char chMask=31) :
+ styler(styler_),
+ endPos(startPos + length),
+ currentPos(startPos),
+ atLineStart(true),
+ atLineEnd(false),
+ state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
+ chPrev(0),
+ ch(0),
+ chNext(0) {
+ styler.StartAt(startPos, chMask);
+ styler.StartSegment(startPos);
+ unsigned int pos = currentPos;
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
+ if (styler.IsLeadByte(static_cast<char>(ch))) {
+ pos++;
+ ch = ch << 8;
+ ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos));
+ }
+ GetNextChar(pos);
+ }
+ void Complete() {
+ styler.ColourTo(currentPos - 1, state);
+ styler.Flush();
+ }
+ bool More() const {
+ return currentPos < endPos;
+ }
+ void Forward() {
+ if (currentPos < endPos) {
+ atLineStart = atLineEnd;
+ chPrev = ch;
+ currentPos++;
+ if (ch >= 0x100)
+ currentPos++;
+ ch = chNext;
+ GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0));
+ } else {
+ atLineStart = false;
+ chPrev = ' ';
+ ch = ' ';
+ chNext = ' ';
+ atLineEnd = true;
+ }
+ }
+ void Forward(int nb) {
+ for (int i = 0; i < nb; i++) {
+ Forward();
+ }
+ }
+ void ChangeState(int state_) {
+ state = state_;
+ }
+ void SetState(int state_) {
+ styler.ColourTo(currentPos - 1, state);
+ state = state_;
+ }
+ void ForwardSetState(int state_) {
+ Forward();
+ styler.ColourTo(currentPos - 1, state);
+ state = state_;
+ }
+ int LengthCurrent() {
+ return currentPos - styler.GetStartSegment();
+ }
+ int GetRelative(int n) {
+ return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n));
+ }
+ bool Match(char ch0) const {
+ return ch == static_cast<unsigned char>(ch0);
+ }
+ bool Match(char ch0, char ch1) const {
+ return (ch == static_cast<unsigned char>(ch0)) && (chNext == static_cast<unsigned char>(ch1));
+ }
+ bool Match(const char *s) {
+ if (ch != static_cast<unsigned char>(*s))
+ return false;
+ s++;
+ if (!*s)
+ return true;
+ if (chNext != static_cast<unsigned char>(*s))
+ return false;
+ s++;
+ for (int n=2; *s; n++) {
+ if (*s != styler.SafeGetCharAt(currentPos+n))
+ return false;
+ s++;
+ }
+ return true;
+ }
+ bool MatchIgnoreCase(const char *s) {
+ if (MakeLowerCase(ch) != static_cast<unsigned char>(*s))
+ return false;
+ s++;
+ if (MakeLowerCase(chNext) != static_cast<unsigned char>(*s))
+ return false;
+ s++;
+ for (int n=2; *s; n++) {
+ if (static_cast<unsigned char>(*s) !=
+ MakeLowerCase(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n))))
+ return false;
+ s++;
+ }
+ return true;
+ }
+ // Non-inline
+ void GetCurrent(char *s, unsigned int len);
+ void GetCurrentLowered(char *s, unsigned int len);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/scintilla/lexlib/WordList.cxx b/scintilla/lexlib/WordList.cxx new file mode 100644 index 0000000..585cda9 --- /dev/null +++ b/scintilla/lexlib/WordList.cxx @@ -0,0 +1,200 @@ +// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "WordList.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+/**
+ * Creates an array that points into each word in the string and puts \0 terminators
+ * after each word.
+ */
+static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
+ int prev = '\n';
+ int words = 0;
+ // For rapid determination of whether a character is a separator, build
+ // a look up table.
+ bool wordSeparator[256];
+ for (int i=0; i<256; i++) {
+ wordSeparator[i] = false;
+ }
+ wordSeparator['\r'] = true;
+ wordSeparator['\n'] = true;
+ if (!onlyLineEnds) {
+ wordSeparator[' '] = true;
+ wordSeparator['\t'] = true;
+ }
+ for (int j = 0; wordlist[j]; j++) {
+ int curr = static_cast<unsigned char>(wordlist[j]);
+ if (!wordSeparator[curr] && wordSeparator[prev])
+ words++;
+ prev = curr;
+ }
+ char **keywords = new char *[words + 1];
+ if (keywords) {
+ words = 0;
+ prev = '\0';
+ size_t slen = strlen(wordlist);
+ for (size_t k = 0; k < slen; k++) {
+ if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
+ if (!prev) {
+ keywords[words] = &wordlist[k];
+ words++;
+ }
+ } else {
+ wordlist[k] = '\0';
+ }
+ prev = wordlist[k];
+ }
+ keywords[words] = &wordlist[slen];
+ *len = words;
+ } else {
+ *len = 0;
+ }
+ return keywords;
+}
+
+bool WordList::operator!=(const WordList &other) const {
+ if (len != other.len)
+ return true;
+ for (int i=0; i<len; i++) {
+ if (strcmp(words[i], other.words[i]) != 0)
+ return true;
+ }
+ return false;
+}
+
+void WordList::Clear() {
+ if (words) {
+ delete []list;
+ delete []words;
+ }
+ words = 0;
+ list = 0;
+ len = 0;
+}
+
+extern "C" int cmpString(const void *a1, const void *a2) {
+ // Can't work out the correct incantation to use modern casts here
+ return strcmp(*(char **)(a1), *(char **)(a2));
+}
+
+static void SortWordList(char **words, unsigned int len) {
+ qsort(reinterpret_cast<void *>(words), len, sizeof(*words),
+ cmpString);
+}
+
+void WordList::Set(const char *s) {
+ Clear();
+ list = new char[strlen(s) + 1];
+ strcpy(list, s);
+ words = ArrayFromWordList(list, &len, onlyLineEnds);
+ SortWordList(words, len);
+ for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
+ starts[k] = -1;
+ for (int l = len - 1; l >= 0; l--) {
+ unsigned char indexChar = words[l][0];
+ starts[indexChar] = l;
+ }
+}
+
+bool WordList::InList(const char *s) const {
+ if (0 == words)
+ return false;
+ unsigned char firstChar = s[0];
+ int j = starts[firstChar];
+ if (j >= 0) {
+ while ((unsigned char)words[j][0] == firstChar) {
+ if (s[1] == words[j][1]) {
+ const char *a = words[j] + 1;
+ const char *b = s + 1;
+ while (*a && *a == *b) {
+ a++;
+ b++;
+ }
+ if (!*a && !*b)
+ return true;
+ }
+ j++;
+ }
+ }
+ j = starts['^'];
+ if (j >= 0) {
+ while (words[j][0] == '^') {
+ const char *a = words[j] + 1;
+ const char *b = s;
+ while (*a && *a == *b) {
+ a++;
+ b++;
+ }
+ if (!*a)
+ return true;
+ j++;
+ }
+ }
+ return false;
+}
+
+/** similar to InList, but word s can be a substring of keyword.
+ * eg. the keyword define is defined as def~ine. This means the word must start
+ * with def to be a keyword, but also defi, defin and define are valid.
+ * The marker is ~ in this case.
+ */
+bool WordList::InListAbbreviated(const char *s, const char marker) const {
+ if (0 == words)
+ return false;
+ unsigned char firstChar = s[0];
+ int j = starts[firstChar];
+ if (j >= 0) {
+ while (words[j][0] == firstChar) {
+ bool isSubword = false;
+ int start = 1;
+ if (words[j][1] == marker) {
+ isSubword = true;
+ start++;
+ }
+ if (s[1] == words[j][start]) {
+ const char *a = words[j] + start;
+ const char *b = s + 1;
+ while (*a && *a == *b) {
+ a++;
+ if (*a == marker) {
+ isSubword = true;
+ a++;
+ }
+ b++;
+ }
+ if ((!*a || isSubword) && !*b)
+ return true;
+ }
+ j++;
+ }
+ }
+ j = starts['^'];
+ if (j >= 0) {
+ while (words[j][0] == '^') {
+ const char *a = words[j] + 1;
+ const char *b = s;
+ while (*a && *a == *b) {
+ a++;
+ b++;
+ }
+ if (!*a)
+ return true;
+ j++;
+ }
+ }
+ return false;
+}
diff --git a/scintilla/lexlib/WordList.h b/scintilla/lexlib/WordList.h new file mode 100644 index 0000000..4ce0246 --- /dev/null +++ b/scintilla/lexlib/WordList.h @@ -0,0 +1,41 @@ +// Scintilla source code edit control
+/** @file WordList.h
+ ** Hold a list of words.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef WORDLIST_H
+#define WORDLIST_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+/**
+ */
+class WordList {
+public:
+ // Each word contains at least one character - a empty word acts as sentinel at the end.
+ char **words;
+ char *list;
+ int len;
+ bool onlyLineEnds; ///< Delimited by any white space or only line ends
+ int starts[256];
+ WordList(bool onlyLineEnds_ = false) :
+ words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_)
+ {}
+ ~WordList() { Clear(); }
+ operator bool() const { return len ? true : false; }
+ bool operator!=(const WordList &other) const;
+ void Clear();
+ void Set(const char *s);
+ bool InList(const char *s) const;
+ bool InListAbbreviated(const char *s, const char marker) const;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
|