Compared files  

Left
C:\SDK\wxWidgets-2.6.2\contrib\src\stc\scintilla\src\LexRuby.cxx
Last modified2004-02-18 17:28:54.001 +0100
Size10.6 Kb (366 Lines)
EncodingLatin 1 - ANSI (CP1252) default
Right
C:\SDK\wxWidgets-2.6.3\contrib\src\stc\scintilla\src\LexRuby.cxx
Last modified2006-03-16 13:07:08.000 +0100
Size52.6 Kb (1543 Lines)
EncodingLatin 1 - ANSI (CP1252) default


   Comparison Statistics  

Detailed Statistics

All Changes
 BlocksLines
Unchanged5499
Inserted6214
Deleted325
Ignored00
Changed441472



   Comparison Details  

18 skipped lines
19U19U#include "Scintilla.h"
20U20U#include "SciLexer.h"
21U21U 
  22C#ifdef SCI_NAMESPACE
  23Cusing namespace Scintilla;
  24C#endif
  25C 
  26C//XXX Identical to Perl, put in common area
  27Cstatic inline bool isEOLChar(char ch) {
  28C    return (ch == '\r') || (ch == '\n');
  29C}
  30C 
  31C#define isSafeASCII(ch) ((unsigned int)(ch) <= 127)
55 skipped lines
  87C}
  88C 
  89C// Forward declarations
  90Cstatic bool keywordIsAmbiguous(const char *prevWord);
  91Cstatic bool keywordDoStartsLoop(int pos,
  92C                                Accessor &styler);
  93Cstatic bool keywordIsModifier(const char *word,
  94C                              int pos,
  95C                              Accessor &styler);
  96C 
22Cstatic void ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) { 97Cstatic int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
23U98U    char s[100];
  99C    unsigned int i, j;
24C    bool wordIsNumber = isdigit(styler[start]) != 0; 100C    unsigned int lim = end - start + 1; // num chars to copy
  101C    if (lim >= MAX_KEYWORD_LENGTH) {
  102C        lim = MAX_KEYWORD_LENGTH - 1;
  103C    }
25C    for (unsigned int i = 0; i < end - start + 1 && i < 30i++) { 104C    for (i = start, j = 0; j < limi++, j++) {
26C        s[i] = styler[start + i]; 105C        s[j] = styler[i];
27C        s[i + 1] = '\0';  
28U106U    }
  107C    s[j] = '\0';
29C    char chAttr = SCE_P_IDENTIFIER; 108C    int chAttr;
30U109U    if (0 == strcmp(prevWord, "class"))
31C        chAttr = SCE_P_CLASSNAME; 110C        chAttr = SCE_RB_CLASSNAME;
32U111U    else if (0 == strcmp(prevWord, "module"))
33C        chAttr = SCE_P_CLASSNAME; 112C        chAttr = SCE_RB_MODULE_NAME;
34U113U    else if (0 == strcmp(prevWord, "def"))
35C        chAttr = SCE_P_DEFNAME; 114C        chAttr = SCE_RB_DEFNAME;
36C    else if (wordIsNumber) 115C    else if (keywords.InList(s) && !followsDot(start - 1, styler)) {
37C        chAttr = SCE_P_NUMBER;  
38C    else if (keywords.InList(s)) 116C        if (keywordIsAmbiguous(s)
39C        chAttr = SCE_P_WORD; 117C            && keywordIsModifier(s, start, styler)) {
  118C             
  119C            // Demoted keywords are colored as keywords,
  120C            // but do not affect changes in indentation.
  121C            //
40C    // make sure that dot-qualifiers inside the word are lexed correct 122C            // Consider the word 'if':
  123C            // 1. <<if test ...>> : normal
  124C            // 2. <<stmt if test>> : demoted
41C    else for (unsigned int i = 0; i < end - star+ 1; i++) { 125C            // 3. <<lhs = if ...>> : normal: start a new indent level
42C        if (styler[start + i] == '.') { 126C            // 4. <<obj.if = 10>> : color as identifer, since it follows '.'
  127C             
  128C            chAttr = SCE_RB_WORD_DEMOTED;
  129C        } else {
  130C            chAttr = SCE_RB_WORD;
  131C        }
  132C    } else
  133C        chAttr = SCE_RB_IDENTIFIER;
43C        styler.ColourTo(start + i - 1, chAttr); 134C    styler.ColourTo(end, chAttr);
  135C    if (chAttr == SCE_RB_WORD) {
  136C        strcpy(prevWord, s);
  137C    } else {
  138C        prevWord[0] = 0;
  139C    }
  140C    return chAttr;
  141C}
  142C 
  143C 
  144C//XXX Identical to Perl, put in common area
  145Cstatic bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {
  146C    if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) {
  147C        return false;
  148C    }
  149C    while (*val) {
  150C        if (*val != styler[pos++]) {
44C        styler.ColourTo(start + i, SCE_P_OPERATOR); 151C        return false;
45U152U        }
  153A        val++;
46U154U    }
47C    styler.ColourTo(end, chAttr);  
48C    strcpy(prevWord, s); 155C    return true;
49U156U}
50U157U 
  158C// Do Ruby better -- find the end of the line, work back,
  159C// and then check for leading white space
  160C 
  161C// Precondition: the here-doc target can be indented
51Cstatic bool IsRbComment(Accessor &styler, int pos, int len{ 162Cstatic bool lookingAtHereDocDelim(Accessor     &styler,
  163C                                  int   pos,
  164C                                  int   lengthDoc,
  165C                                  const char   *HereDocDelim)
  166C{
  167C    if (!isMatch(styler, lengthDoc, pos, HereDocDelim)) {
  168C        return false;
  169C    }
  170C    while (--pos > 0) {
52C    return len>0 && styler[pos]=='#'; 171C        char ch = styler[pos];
  172C        if (isEOLChar(ch)) {
  173C            return true;
  174C        } else if (ch != ' ' && ch != '\t') {
  175C            return false;
  176C        }
  177C    }
  178C    return false;
53U179U}
54U180U 
  181C//XXX Identical to Perl, put in common area
55Cstatic bool IsRbStringStart(char ch, char chNextchar chNext2) { 182Cstatic char opposite(chach) {
56C    if (ch == '\'' || ch == '"') 183C    if (ch == '(')
57C        return true; 184C        return ')';
58C    if (ch == 'u' || ch == 'U') { 185C    if (ch == '[')
  186C        return ']';
59C        if (chNext == '"' || chNext == '\'') 187C    if (ch == '{')
60C        return true; 188C        return '}';
61C        if ((chNext == 'r' || chNext == 'R') && (chNext2 == '"' || chNext2 == '\'')) 189C    if (ch == '<')
  190C        return '>';
62C        return true; 191C    return ch;
63C    } 192C}
64C    if ((ch == 'r' || ch == 'R') && (chNext == '"' || chNext == '\'')) 193C 
65C        return true; 194C// Null transitions when we see we've reached the end
  195C// and need to relex the curr char.
66U196U 
  197Cstatic void redo_char(int &i, char &ch, char &chNext, char &chNext2,
  198C                      int &state) {
  199C    i--;
  200C    chNext2 = chNext;
  201C    chNext = ch;
67C    return false; 202C    state = SCE_RB_DEFAULT;
68U203U}
69U204U 
70Cstatic bool IsRbWordStart(char ch, char chNext, char chNext2) { 205Cstatic void advance_char(int &i, cha&ch, char &chNext, cha&chNext2) {
  206C    i++;
  207C    ch = chNext;
71C    return (iswordchar(ch) && !IsRbStringStart(ch, chNext, chNext2)); 208C    chNext = chNext2;
72U209U}
73U210U 
74C/* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */ 211C// precondition: startPos points to one after thEOL char
75Cstatic int GetRbStringState(Accessor &styler, int i, int *nextIndex) { 212Cstatic bool currLineContainsHereDelims(int& startPos,
76C    char ch = styler.SafeGetCharAt(i);  
77C    char chNext = styler.SafeGetCharAt(i + 1);  
78C   
79C    // Advance beyond r, u, or ur prefix, but bail if there are any unexpected chars  
80C    if (ch == 'r' || ch == 'R') {  
81C        i++;  
82C        ch = styler.SafeGetCharAt(i);  
83C        chNext = styler.SafeGetCharAt(i + 1); 213C                                       Accessor &styler) {
84C    }  
85C    else if (ch == 'u' || ch == 'U') {  
86C        if (chNext == 'r' || chNext == 'R') 214C    if (startPos <= 1)
87C        i += 2; 215C        return false;
88C        else  
89C        i += 1;  
90C        ch = styler.SafeGetCharAt(i);  
91C        chNext = styler.SafeGetCharAt(i + 1);  
92C    }  
93U216U 
  217C    int pos;
  218C    for (pos = startPos - 1; pos > 0; pos--) {
  219C        char ch = styler.SafeGetCharAt(pos);
94C    if (ch != '"' && ch != '\'') { 220C        if (isEOLChar(ch)) {
95C        *nextIndex = i + 1; 221C            // Leave the pointers where they are -- there are no
  222C            // here doc delims on the current line, even if
  223C            // the EOL isn't default style
  224C             
  225C            return false;
  226C        } else {
  227C            styler.Flush();
96C        return SCE_P_DEFAULT; 228C            if (actual_style(styler.StyleAt(pos)) == SCE_RB_HERE_DELIM) {
  229C                break;
  230C            }
  231C        }
  232C    }
  233C    if (pos == 0) {
  234C        return false;
  235C    }
  236C    // Update the pointers so we don't have to re-analyze the string
  237C    startPos = pos;
  238C    return true;
97C    } 239C}
98U240U 
99R    if (i>0 && styler.SafeGetCharAt(i-1) == '$') {  
100R        *nextIndex = i + 1;  
101R        return SCE_P_DEFAULT;  
102R    }  
103U241U 
  242Cstatic bool isEmptyLine(int pos,
  243C                        Accessor &styler) {
  244C    int spaceFlags = 0;
104C    if (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) { 245C    int lineCurrent = styler.GetLine(pos);
105C        *nextIndex = i + 3; 246C    int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
  247C    return (indentCurrent & SC_FOLDLEVELWHITEFLAG) != 0;
  248C}
  249C 
  250Cstatic bool RE_CanFollowKeyword(const char *keyword) {
  251C    if (!strcmp(keyword, "and")
  252C        || !strcmp(keyword, "begin")
  253C        || !strcmp(keyword, "break")
  254C        || !strcmp(keyword, "case")
  255C        || !strcmp(keyword, "do")
  256C        || !strcmp(keyword, "else")
3 skipped lines
  260C        || !strcmp(keyword, "return")
  261C        || !strcmp(keyword, "when")
  262C        || !strcmp(keyword, "unless")
  263C        || !strcmp(keyword, "until")
  264C        || !strcmp(keyword, "not")
  265C        || !strcmp(keyword, "or")) {
  266C        return true;
  267C    }
  268C    return false;
  269C}
106U270U 
107C        if (ch == '"') 271C// Look at chars up to but not including endPos
108C        return SCE_P_TRIPLEDOUBLE; 272C// Don't look at styles in case we're looking forward
109C        else  
110C        return SCE_P_TRIPLE;  
111C    } else {  
112C        *nextIndex = i + 1;  
113U273U 
  274Cstatic int skipWhitespace(int startPos,
  275C                           int endPos,
  276C                           Accessor &styler) {
  277C    for (int i = startPos; i < endPos; i++) {
  278C        if (!iswhitespace(styler[i])) {
  279C            return i;
  280C        }
  281C    }
  282C    return endPos;
  283C}
261 skipped lines
  545C    int lineStart;
  546C    for (lineStart = styler.GetLine(pos); lineStart > 0; lineStart--) {
  547C        // Now look at the style before the previous line's EOL
  548C        pos = styler.LineStart(lineStart) - 1;
  549C        if (pos <= 10) {
  550C            lineStart = 0;
  551C            break;
  552C        }
  553C        char ch = styler.SafeGetCharAt(pos);
  554C        char chPrev = styler.SafeGetCharAt(pos - 1);
114C        if (ch == '"') 555C        if (ch == '\n' && chPrev == '\r') {
  556C            pos--;
  557C        }
  558C        if (styler.SafeGetCharAt(pos - 1) == '\\') {
  559C            // Continuation line -- keep going
115C        return SCE_P_STRING; 560C        } else if (actual_style(styler.StyleAt(pos)) != SCE_RB_DEFAULT) {
  561C            // Part of multi-line construct -- keep going
116C        else 562C        } else if (currLineContainsHereDelims(pos, styler)) {
  563C            // Keep going, with pos and length now pointing
  564C            // at the end of the here-doc delimiter
  565C        } else if (skipWhiteSpace && isEmptyLine(pos, styler)) {
  566C            // Keep going
  567C        } else {
  568C            break;
  569C        }
  570C    }
  571C    pos = styler.LineStart(lineStart);
  572C    length += (startPos - pos);
  573C    startPos = pos;
117C        return SCE_P_CHARACTER; 574C    initStyle = SCE_RB_DEFAULT;
118C    }  
119U575U}
120U576U 
121U577Ustatic void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
122U578U           WordList *keywordlists[], Accessor &styler) {
123U579U 
  580C    // Lexer for Ruby often has to backtrack to start of current style to determine
  581C    // which characters are being used as quotes, how deeply nested is the
  582C    // start position and what the termination string is for here documents
  583C     
124C    int lengthDoc = startPos + length; 584C    WordList &keywords = *keywordlists[0];
125U585U 
126C    // Backtrack to previous line in case need to fix its tab whinging 586C    class HereDocCls {
127C    if (startPos > 0) { 587C    public:
128C        int lineCurrent = styler.GetLine(startPos); 588C        int State;
  589C        // States
  590C        // 0: '<<' encountered
  591C        // 1: collect the delimiter
  592C        // 1b: text between the end of the delimiter and the EOL
  593C        // 2: here doc text (lines after the delimiter)
  594C        char Quote;     // the char after '<<'
  595C        bool Quoted;// true if Quote in ('\'','"','`')
  596C        int DelimiterLength;// strlen(Delimiter)
  597C        char Delimiter[256];// the Delimiter, limit of 256: from Perl
  598C        bool CanBeIndented;
129C        if (lineCurrent > 0) { 599C        HereDocCls() {
130C        startPos = styler.LineStart(lineCurrent-1); 600C        State = 0;
131C        if (startPos == 0) 601C        DelimiterLength = 0;
132C        initStyle = SCE_P_DEFAULT; 602C        Delimiter[0] = '\0';
133C        else  
134C        initStyle = styler.StyleAt(startPos-1); 603C            CanBeIndented = false;
135U604U        }
136C    } 605C    };
  606C    HereDocCls HereDoc;   
137U607U 
138C    // Ruby uses a different mask because bad indentation is marked by oring with 32 608C    class QuoteCls {
  609C        public:
  610C        int  Count;
  611C        char Up;
  612C        char Down;
  613C        QuoteCls() {
  614C        this->New();
  615C        }
  616C        void New() {
  617C        Count = 0;
  618C        Up    = '\0';
  619C        Down  = '\0';
  620C        }
  621C        void Open(char u) {
  622C        Count++;
  623C        Up    = u;
  624C        Down  = opposite(Up);
  625C        }
  626C    };
139C    styler.StartAt(startPos, 127); 627C    QuoteCls Quote;
140U628U 
141C    WordList &keywords = *keywordlists[0]; 629C    int numDots = 0;  // For numbers --
  630C                      // Don't start lexing in the middle of a num
142U631U 
  632C    synchronizeDocStart(startPos, length, initStyle, styler, // ref args
  633C                        false);
  634C 
  635C    bool preferRE = true;
143C    int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level"); 636C    int state = initStyle;
  637C    int lengthDoc = startPos + length;
  638C 
144C    char prevWord[200]; 639C    char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
145U640U    prevWord[0] = '\0';
146U641U    if (length == 0)
147C        return ; 642C        return;
148U643U 
149C    int state = initStyle & 31; 644C    char chPrev = styler.SafeGetCharAt(startPos - 1);
150C  645C    char chNext = styler.SafeGetCharAt(startPos);
151C    int nextIndex = 0; 646C    // Ruby uses a different mask because bad indentation is marked by oring with 32
152C    char chPrev = ' ';  
153C    char chPrev2 = ' ';  
154C    char chNext = styler[startPos]; 647C    styler.StartAt(startPos, 127);
155U648U    styler.StartSegment(startPos);
156R    bool atStartLine = true;  
157R    int spaceFlags = 0;  
158R    for (int i = startPos; i < lengthDoc; i++) {  
159R   
160R        if (atStartLine) {  
10 skipped lines
171R        chFlags = (spaceFlags & wsTab) ? chBad : chGood;  
172R        }  
173R        styler.SetFlags(chFlags, static_cast<char>(state));  
174R        atStartLine = false;  
175R        }  
176U649U 
  650A    static int q_states[] = {SCE_RB_STRING_Q,
  651A                             SCE_RB_STRING_QQ,
  652A                             SCE_RB_STRING_QR,
  653A                             SCE_RB_STRING_QW,
  654A                             SCE_RB_STRING_QW,
  655A                             SCE_RB_STRING_QX};
  656A    static const char* q_chars = "qQrwWx";
  657A     
  658A    for (int i = startPos; i < lengthDoc; i++) {
177U659U        char ch = chNext;
178U660U        chNext = styler.SafeGetCharAt(i + 1);
179U661U        char chNext2 = styler.SafeGetCharAt(i + 2);
180U662U 
181C        if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {  
182C        if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) {  
183C        // Perform colourisation of white space and triple quoted strings at end of each line to allow  
184C        // tab marking to work inside white space and triple quoted strings  
185C        styler.ColourTo(i, state);  
186C        }  
187C        atStartLine = true;  
188C        }  
189C   
190C        if (styler.IsLeadByte(ch)) { 663C        if (styler.IsLeadByte(ch)) {
191C        chNext = styler.SafeGetCharAt(i + 2); 664C        chNext = chNext2;
192U665U        chPrev = ' ';
193R        chPrev2 = ' ';  
194U666U        i += 1;
195U667U        continue;
196U668U        }
  669A         
  670A        // skip on DOS/Windows
  671A        //No, don't, because some things will get tagged on,
  672A        // so we won't recognize keywords, for example
  673A#if 0
8 skipped lines
  682A        styler.ColourTo(i-1, state);
  683A            // Don't check for a missing quote, just jump into
  684A            // the here-doc state
  685A            state = SCE_RB_HERE_Q;
  686A        }
197U687U 
  688C        // Regular transitions
198C        if (state == SCE_P_STRINGEOL) { 689C        if (state == SCE_RB_DEFAULT) {
199C        if (ch != '\r' && ch != '\n') { 690C            if (isSafeDigit(ch)) {
200C        styler.ColourTo(i - 1, state); 691C            styler.ColourTo(i - 1, state);
201C        state = SCE_P_DEFAULT; 692C        state = SCE_RB_NUMBER;
202C        } 693C                numDots = 0;
203C        }  
204C        if (state == SCE_P_DEFAULT) {  
205C        if (IsRbWordStart(ch, chNext, chNext2)) { 694C            } else if (isHighBitChar(ch) || iswordstart(ch)) {
206C        styler.ColourTo(i - 1, state); 695C            styler.ColourTo(i - 1, state);
207C        state = SCE_P_WORD; 696C        state = SCE_RB_WORD;
208U697U        } else if (ch == '#') {
209U698U        styler.ColourTo(i - 1, state);
210C        state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE; 699C        state = SCE_RB_COMMENTLINE;
211C        } else if (ch == '=' && chNext == 'b') { 700C        } else if (ch == '=') {
212U701U        // =begin indicates the start of a comment (doc) block
  702C                if (i == 0 || isEOLChar(chPrev)
  703C                    && chNext == 'b'
  704C                    && styler.SafeGetCharAt(i + 2) == 'e'
  705C                    && styler.SafeGetCharAt(i + 3) == 'g'
  706C                    && styler.SafeGetCharAt(i + 4) == 'i'
213C        if(styler.SafeGetCharAt(i + 2) == 'e' && styler.SafeGetCharAt(i + 3) == 'g' && styler.SafeGetCharAt(i + 4) == 'i' && styler.SafeGetCharAt(i + 5) == 'n') { 707C                    && styler.SafeGetCharAt(i + 5) == 'n'
  708C                    && !isSafeWordcharOrHigh(styler.SafeGetCharAt(i + 6))) {
  709C                    styler.ColourTo(i - 1, state);
  710C                    state = SCE_RB_POD;
  711C        } else {
214U712U        styler.ColourTo(i - 1, state);
215C        state = SCE_P_TRIPLEDOUBLE; //SCE_C_COMMENT; 713C        styler.ColourTo(i, SCE_RB_OPERATOR);
  714C        preferRE = true;
216U715U        }
217C        }  else if (IsRbStringStart(ch, chNext, chNext2)) { 716C        } else if (ch == '"') {
218U717U        styler.ColourTo(i - 1, state);
219C        state = GetRbStringState(styler, i, &nextIndex); 718C        state = SCE_RB_STRING;
  719C        Quote.New();
  720C        Quote.Open(ch);
220C        if (nextIndex != i + 1) { 721C        } else if (ch == '\'') {
221C        i = nextIndex - 1; 722C                styler.ColourTo(i - 1, state);
222C        ch = ' '; 723C                state = SCE_RB_CHARACTER;
223C        chPrev = ' ';  
224C        chNext = styler.SafeGetCharAt(i + 1); 724C                Quote.New();
225C        } 725C                Quote.Open(ch);
226C        } else if (isoperator(ch)) { 726C        } else if (ch == '`') {
227U727U        styler.ColourTo(i - 1, state);
  728C        state = SCE_RB_BACKTICKS;
228C        styler.ColourTo(i, SCE_P_OPERATOR); 729C        Quote.New();
229C        } 730C        Quote.Open(ch);
230C        } else if (state == SCE_P_WORD) { 731C        } else if (ch == '@') {
231C        if (!iswordchar(ch)) { 732C                // Instance or class var
232C        ClassifyWordRb(styler.GetStartSegment(), i - 1, keywords, styler, prevWord); 733C        styler.ColourTo(i - 1, state);
  734C                if (chNext == '@') {
  735C                    state = SCE_RB_CLASS_VAR;
  736C                    advance_char(i, ch, chNext, chNext2); // pass by ref
  737C                } else {
233C        state = SCE_P_DEFAULT; 738C                    state = SCE_RB_INSTANCE_VAR;
  739C                }
234C        if (ch == '#') { 740C        } else if (ch == '$') {
  741C                // Check for a builtin global
  742C        styler.ColourTo(i - 1, state);
  743C                // Recognize it bit by bit
235C        state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE; 744C                state = SCE_RB_GLOBAL;
236C        } else if (IsRbStringStart(ch, chNext, chNext2)) { 745C            } else if (ch == '/' && preferRE) {
  746C                // Ambigous operator
237C        styler.ColourTo(i - 1, state); 747C        styler.ColourTo(i - 1, state);
238C        state = GetRbStringState(styler, i, &nextIndex); 748C        state = SCE_RB_REGEX;
  749C                Quote.New();
  750C                Quote.Open(ch);
239C        if (nextIndex != i + 1) { 751C        } else if (ch == '<' && chNext == '<' && chNext2 != '=') {
240C        i = nextIndex - 1; 752C 
241C        ch = ' '; 753C                // Recognise the '<<' symbol - either a here document or a binary op
  754C        styler.ColourTo(i - 1, state);
  755C                i++;
  756C                chNext = chNext2;
  757C        styler.ColourTo(i, SCE_RB_OPERATOR);
  758C 
  759C                if (! (strchr("\"\'`_-", chNext2) || isSafeAlpha(chNext2))) {
  760C                    // It's definitely not a here-doc,
  761C                    // based on Ruby's lexer/parser in the
  762C                    // heredoc_identifier routine.
  763C                    // Nothing else to do.
110 skipped lines
  874C            } else if (ch == '%') {
  875C                styler.ColourTo(i - 1, state);
  876C                bool have_string = false;
  877C                if (strchr(q_chars, chNext) && !isSafeWordcharOrHigh(chNext2)) {
  878C                    Quote.New();
  879C                    const char *hit = strchr(q_chars, chNext);
  880C                    if (hit != NULL) {
  881C                        state = q_states[hit - q_chars];
  882C                        Quote.Open(chNext2);
  883C                        i += 2;
242C        chPrev = ' '; 884C                        ch = chNext2;
243U885U        chNext = styler.SafeGetCharAt(i + 1);
  886A                        have_string = true;
  887A                    }
  888A                } else if (!isSafeWordcharOrHigh(chNext)) {
  889A                    // Ruby doesn't allow high bit chars here,
  890A                    // but the editor host might
166 skipped lines
  1057A        HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
  1058A        } else {
  1059A        styler.ColourTo(i - 1, state);
  1060A                        redo_char(i, ch, chNext, chNext2, state);
  1061A                        preferRE = false;
244U1062U        }
245C        } else if (isoperator(ch)) { 1063C                }
246C        styler.ColourTo(i, SCE_P_OPERATOR);  
247C        }  
248C        }  
249C        } else {  
250C        if (state == SCE_P_COMMENTLINE || state == SCE_P_COMMENTBLOCK) { 1064C        if (HereDoc.DelimiterLength >= static_cast<int>(sizeof(HereDoc.Delimiter)) - 1) {
251C        if (ch == '\r' || ch == '\n') {  
252U1065U        styler.ColourTo(i - 1, state);
253C        state = SCE_P_DEFAULT; 1066C        state = SCE_RB_ERROR;
254C        }  
255C        } else if (state == SCE_P_STRING) {  
256C        if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {  
257C        styler.ColourTo(i - 1, state);  
258C        state = SCE_P_STRINGEOL;  
259C        } else if (ch == '\\') {  
260C        if (chNext == '\"' || chNext == '\'' || chNext == '\\') {  
261C        i++;  
262C        ch = chNext;  
263C        chNext = styler.SafeGetCharAt(i + 1);  
264C        }  
265C        } else if (ch == '\"') {  
266C        styler.ColourTo(i, state);  
267C        state = SCE_P_DEFAULT; 1067C                    preferRE = false;
268U1068U        }
  1069C            }
  1070C        } else if (state == SCE_RB_HERE_Q) {
  1071C            // Not needed: HereDoc.State == 2
  1072C            // Indentable here docs: look backwards
  1073C            // Non-indentable: look forwards, like in Perl
  1074C            //
  1075C            // Why: so we can quickly resolve things like <<-" abc"
  1076C 
  1077C            if (!HereDoc.CanBeIndented) {
  1078C                if (isEOLChar(chPrev)
37 skipped lines
  1116C                        advance_char(i, ch, chNext, chNext2);
  1117C                    }
  1118C                    styler.ColourTo(i, state);
  1119C                    state = SCE_RB_DEFAULT;
  1120C                } else {
  1121C                    styler.ColourTo(i - 1, state);
  1122C                    redo_char(i, ch, chNext, chNext2, state); // pass by ref
  1123C                }
  1124C                preferRE = false;
  1125C            }
269C        } else if (state == SCE_P_CHARACTER) { 1126C        } else if (state == SCE_RB_POD) {
  1127C            // PODs end with ^=end\s, -- any whitespace can follow =end
  1128C            if (strchr(" \t\n\r", ch) != NULL
  1129C                && i > 5
  1130C                && isEOLChar(styler[i - 5])
270C        if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { 1131C                && isMatch(styler, lengthDoc, i - 4, "=end")) {
271C        styler.ColourTo(i - 1, state); 1132C                styler.ColourTo(i - 1, state);
272C        state = SCE_P_STRINGEOL; 1133C                state = SCE_RB_DEFAULT;
  1134C                preferRE = false;
  1135C            }
273C        } else if (ch == '\\') { 1136C        } else if (state == SCE_RB_REGEX || state == SCE_RB_STRING_QR) {
274C        if (chNext == '\"' || chNext == '\'' || chNext == '\\') { 1137C            if (ch == '\\' && Quote.Up != '\\') {
  1138C                // Skip one
  1139C                advance_char(i, ch, chNext, chNext2);
  1140C            } else if (ch == Quote.Down) {
  1141C                Quote.Count--;
  1142C                if (Quote.Count == 0) {
  1143C                    // Include the options
  1144C                    while (isSafeAlpha(chNext){
275C        i++; 1145C                        i++;
276U1146U        ch = chNext;
277C        chNext = styler.SafeGetCharAt(i + 1); 1147C                        chNext = styler.SafeGetCharAt(i + 1);
278C        } 1148C                    }
279C        } else if (ch == '\'') {  
280C        styler.ColourTo(i, state); 1149C                    styler.ColourTo(i, state);
281C        state = SCE_P_DEFAULT; 1150C                    state = SCE_RB_DEFAULT;
282C        } 1151C                    preferRE = false;
  1152C                }
283C        } else if (state == SCE_P_TRIPLE) { 1153C            } else if (ch == Quote.Up) {
  1154C                // Only if close quoter != open quoter
  1155C                Quote.Count++;
  1156C                 
284C        if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { 1157C            } else if (ch == '#' ) {
  1158C                //todo: distinguish comments from pound chars
  1159C                // for now, handle as comment
285C        styler.ColourTo(i, state); 1160C                styler.ColourTo(i - 1, state);
286C        state = SCE_P_DEFAULT; 1161C                bool inEscape = false;
287C        }  
288C        } else if (state == SCE_P_TRIPLEDOUBLE{ 1162C                while (++i < lengthDoc) {
289C        // =end terminates the comment block 1163C                    ch = styler.SafeGetCharAt(i);
290C        if (ch == 'd' && chPrev == 'n' && chPrev2 == 'e') { 1164C                    if (ch == '\\') {
291C        if  (styler.SafeGetCharAt(i - 3) == '=') { 1165C                        inEscape = true;
  1166C                    } else if (isEOLChar(ch)) {
  1167C                        // Comment inside a regex
292C        styler.ColourTo(i, state); 1168C                        styler.ColourTo(i - 1, SCE_RB_COMMENTLINE);
293C        state = SCE_P_DEFAULT; 1169C                        break;
294C        } 1170C                    } else if (inEscape) {
295C        } 1171C                        inEscape = false;  // don't look at char
  1172C                    } else if (ch == Quote.Down) {
  1173C                        // Have the regular handler deal with this
  1174C                        // to get trailing modifiers.
  1175C                        i--;
  1176C                        ch = styler[i];
  1177C        break;
  1178C                    }
  1179C                }
  1180C                chNext = styler.SafeGetCharAt(i + 1);
  1181C                chNext2 = styler.SafeGetCharAt(i + 2);
93 skipped lines
  1275C    while (--pos >= lineStartPosn) {
  1276C        style = actual_style(styler.StyleAt(pos));
  1277C        if (style == SCE_RB_DEFAULT) {
  1278C        if (iswhitespace(ch = styler[pos])) {
  1279C        //continue
  1280C        } else if (ch == '\r' || ch == '\n') {
  1281C        // Scintilla's LineStart() and GetLine() routines aren't
  1282C        // platform-independent, so if we have text prepared with
  1283C        // a different system we can't rely on it.
  1284C        return false;
296U1285U        }
  1286A        } else {
  1287A            break;
297U1288U        }
298C        chPrev2 = chPrev; 1289C    }
299C        chPrev = ch; 1290C    if (pos < lineStartPosn) {
300C    } 1291C        return false; //XXX not quite right if the prev line is a continuation
  1292C    }
  1293C    // First things where the action is unambiguous
  1294C    switch (style) {
  1295C        case SCE_RB_DEFAULT:
  1296C        case SCE_RB_COMMENTLINE:
  1297C        case SCE_RB_POD:
  1298C        case SCE_RB_CLASSNAME:
  1299C        case SCE_RB_DEFNAME:
  1300C        case SCE_RB_MODULE_NAME:
  1301C            return false;
  1302C        case SCE_RB_OPERATOR:
  1303C            break;
301C    if (state == SCE_P_WORD) { 1304C        case SCE_RB_WORD:
  1305C            // Watch out for uses of 'else if'
  1306C            //XXX: Make a list of other keywords where 'if' isn't a modifier
  1307C            //     and can appear legitimately
  1308C            // Formulate this to avoid warnings from most compilers
  1309C            if (strcmp(word, "if") == 0) {
  1310C                char prevWord[MAX_KEYWORD_LENGTH + 1];
  1311C                getPrevWord(pos, prevWord, styler, SCE_RB_WORD);
302C        ClassifyWordRb(styler.GetStartSegment(), lengthDoc-1, keywordsstyler, prevWord); 1312C                return strcmp(prevWord, "else") != 0;
  1313C            }
  1314C            return true;
  1315C        default:
  1316C            return true;
  1317C    }
  1318C    // Assume that if the keyword follows an operator,
  1319C    // usually it's a block assignment, like
303C    } else { 1320C    // a << if x then y else z
  1321C     
304C        styler.ColourTo(lengthDoc-1, state); 1322C    ch = styler[pos];
  1323C    switch (ch) {
  1324C        case ')':
  1325C        case ']':
  1326C        case '}':
  1327C            return true;
  1328C        default:
  1329C            return false;
305C    } 1330C    }
306U1331U}
307U1332U 
  1333C#define WHILE_BACKWARDS "elihw"
  1334C#define UNTIL_BACKWARDS "litnu"
  1335C 
  1336C// Nothing fancy -- look to see if we follow a while/until somewhere
  1337C// on the current line
  1338C 
308Cstatic void FoldRbDoc(unsigned int startPos, int length, int initStyle, 1339Cstatic bool keywordDoStartsLoop(int pos,
  1340C                                Accessor &styler)
  1341C{
  1342C    char ch;
  1343C    int style;
  1344C    int lineStart = styler.GetLine(pos);
  1345C    int lineStartPosn = styler.LineStart(lineStart);
  1346C    styler.Flush();
  1347C    while (--pos >= lineStartPosn) {
  1348C        style = actual_style(styler.StyleAt(pos));
  1349C        if (style == SCE_RB_DEFAULT) {
  1350C        if ((ch = styler[pos]) == '\r' || ch == '\n') {
  1351C        // Scintilla's LineStart() and GetLine() routines aren't
  1352C        // platform-independent, so if we have text prepared with
  1353C        // a different system we can't rely on it.
  1354C        return false;
  1355C        }
309C           WordList *[], Accessor &styler) { 1356C        } else if (style == SCE_RB_WORD) {
  1357C            // Check for while or until, but write the word in backwards
  1358C            char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
  1359C            char *dst = prevWord;
  1360C            int wordLen = 0;
310C    int lengthDoc = startPos + length; 1361C            int start_word;
  1362C            for (start_word = pos;
  1363C                 start_word >= lineStartPosn && actual_style(styler.StyleAt(start_word)) == SCE_RB_WORD;
  1364C                 start_word--) {
  1365C                if (++wordLen < MAX_KEYWORD_LENGTH) {
  1366C                    *dst++ = styler[start_word];
  1367C                }
  1368C            }
  1369C            *dst = 0;
  1370C            // Did we see our keyword?
  1371C            if (!strcmp(prevWord, WHILE_BACKWARDS)
48 skipped lines
  1420C *  true undef
  1421C 
  1422C *  Always increment:
  1423C *  begin  class def do for module when {
  1424C * 
  1425C *  Always decrement:
  1426C *  end }
  1427C * 
  1428C *  Increment if these start a statement
  1429C *  if unless until while -- do nothing if they're modifiers
311U1430U 
  1431C *  These end a block if there's no modifier, but don't bother
  1432C *  break next redo retry return yield
  1433C * 
  1434C *  These temporarily de-indent, but re-indent
  1435C *  case else elsif ensure rescue
  1436C * 
  1437C *  This means that the folder reflects indentation rather
  1438C *  than setting it.  The language-service updates indentation
  1439C *  when users type return and finishes entering de-denters.
  1440C * 
  1441C *  Later offer to fold POD, here-docs, strings, and blocks of comments
  1442C */
  1443C 
  1444Cstatic void FoldRbDoc(unsigned int startPos, int length, int initStyle,
  1445C                      WordList *[], Accessor &styler) {
  1446C    const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
312C    // Backtrack to previous line in case need to fix its fold status 1447C    bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
  1448C     
  1449C    synchronizeDocStart(startPos, length, initStyle, styler, // ref args
  1450C                        false);
  1451C    unsigned int endPos = startPos + length;
  1452C    int visibleChars = 0;
313U1453U    int lineCurrent = styler.GetLine(startPos);
314C    if (startPos > 0) {  
315C        if (lineCurrent > 0) {  
316C        lineCurrent--;  
317C        startPos = styler.LineStart(lineCurrent);  
318C        if (startPos == 0) 1454C    int levelPrev = startPos == 0 ? 0 : (styler.LevelAt(lineCurrent)
319C        initStyle = SCE_P_DEFAULT; 1455C                                         & SC_FOLDLEVELNUMBERMASK
320C        else  
321C        initStyle = styler.StyleAt(startPos-1);  
322C        }  
323C    }  
324C    int state = initStyle & 31;  
325C    int spaceFlags = 0;  
326C    int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsRbComment); 1456C                                         & ~SC_FOLDLEVELBASE);
327C    if ((state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE))  
328C        indentCurrent |= SC_FOLDLEVELWHITEFLAG; 1457C    int levelCurrent = levelPrev;
329U1458U    char chNext = styler[startPos];
  1459C    int styleNext = styler.StyleAt(startPos);
  1460C    int stylePrev = startPos <= 1 ? SCE_RB_DEFAULT : styler.StyleAt(startPos - 1);
  1461C    bool buffer_ends_with_eol = false;
330C    for (int i = startPos; i < lengthDoc; i++) { 1462C    for (unsigned int i = startPos; i < endPosi++) {
331U1463U        char ch = chNext;
332U1464U        chNext = styler.SafeGetCharAt(i + 1);
  1465C        int style = styleNext;
333C        int style = styler.StyleAt(i) & 31; 1466C        styleNext = styler.StyleAt(i + 1);
334C   
335C        if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) { 1467C        bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
336C        int lev = indentCurrent;  
337C        int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsRbComment);  
338C        if ((style == SCE_P_TRIPLE) || (style== SCE_P_TRIPLEDOUBLE)) 1468C        if (style == SCE_RB_COMMENTLINE) {
339C        indentNext |= SC_FOLDLEVELWHITEFLAG;  
340C        if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { 1469C            if (foldComment && stylePrev != SCE_RB_COMMENTLINE) {
341C        // Only non whitespace lines can be headers  
342C        if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { 1470C                if (chNext == '{') {
343C        lev |= SC_FOLDLEVELHEADERFLAG; 1471C        levelCurrent++;
344C        } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {  
345C        // Line after is blank so check the next - maybe should continue further?  
346C        int spaceFlags2 = 0;  
347C        int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsRbComment);  
348C        if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) { 1472C        } else if (chNext == '}') {
349C        lev |= SC_FOLDLEVELHEADERFLAG; 1473C        levelCurrent--;
350C        }  
351U1474U        }
  1475A            }
  1476A        } else if (style == SCE_RB_OPERATOR) {
  1477A        if (strchr("[{(", ch)) {
  1478A        levelCurrent++;
  1479A        } else if (strchr(")}]", ch)) {
  1480A                // Don't decrement below 0
  1481A                if (levelCurrent > 0)
  1482A                    levelCurrent--;
352U1483U        }
353C        indentCurrent = indentNext; 1484C        } else if (style == SCE_RB_WORD && styleNext != SCE_RB_WORD) {
  1485C            // Look at the keyword on the left and decide what to do
  1486C            char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
  1487C            prevWord[0] = 0;
  1488C            getPrevWord(i, prevWord, styler, SCE_RB_WORD);
  1489C            if (!strcmp(prevWord, "end")) {
  1490C                // Don't decrement below 0
  1491C                if (levelCurrent > 0)
  1492C                    levelCurrent--;
  1493C            } else if (   !strcmp(prevWord, "if")
  1494C                       || !strcmp(prevWord, "def")
9 skipped lines
  1504C                          ) {
  1505C        levelCurrent++;
  1506C            }
  1507C        }
  1508C        if (atEOL) {
  1509C        int lev = levelPrev;
  1510C        if (visibleChars == 0 && foldCompact)
  1511C        lev |= SC_FOLDLEVELWHITEFLAG;
  1512C        if ((levelCurrent > levelPrev) && (visibleChars > 0))
  1513C        lev |= SC_FOLDLEVELHEADERFLAG;
354C        styler.SetLevel(lineCurrent, lev); 1514C            styler.SetLevel(lineCurrent, lev|SC_FOLDLEVELBASE);
355U1515U        lineCurrent++;
356C        } 1516C        levelPrev = levelCurrent;
357C    } 1517C        visibleChars = 0;
  1518C            buffer_ends_with_eol = true;
  1519C        } else if (!isspacechar(ch)) {
  1520C        visibleChars++;
  1521C            buffer_ends_with_eol = false;
  1522C        }
  1523C    }
  1524C    // Fill in the real level of the next line, keeping the current flags as they will be filled in later
  1525C    if (!buffer_ends_with_eol) {
  1526C        lineCurrent++;
  1527C        int new_lev = levelCurrent;
  1528C        if (visibleChars == 0 && foldCompact)
  1529C            new_lev |= SC_FOLDLEVELWHITEFLAG;
  1530C        if ((levelCurrent > levelPrev) && (visibleChars > 0))
  1531C        new_lev |= SC_FOLDLEVELHEADERFLAG;
  1532C            levelCurrent = new_lev;
  1533C    }
  1534C    styler.SetLevel(lineCurrent, levelCurrent|SC_FOLDLEVELBASE);
358U1535U}
359U1536U 
360U1537Ustatic const char * const rubyWordListDesc[] = {
6 skipped lines

   Text comparison Options  

Match character case: yes.
Match line endings: no.
Match spaces

At start of lines: yes,
In middle of lines: yes,
At end of lines: yes.
Blank lines as empty lines: no.
Activate comparison algorithm
At word level: yes,
At character level: no.


   Legend  

UExample of unchanged line
CExample of modified line
AExample of added line
RExample of removed line
IExample of ignored line
Modified text
Added text
Removed text

This report has been generated by Ellié Computing Merge on 2006-09-07 16:23:42.001 +0200.
© 2005-2006 Ellié Computing http://www.elliecomputing.com. All rights reserved.