~ubuntu-branches/ubuntu/natty/geany/natty

« back to all changes in this revision

Viewing changes to scintilla/LexR.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Gauvain Pocentek
  • Date: 2009-01-01 18:40:50 UTC
  • mfrom: (1.1.8 upstream) (3.1.2 experimental)
  • Revision ID: james.westby@ubuntu.com-20090101184050-u635kualu7amyt4a
Tags: 0.15-1ubuntu1
* Merge from debian experimental, remaining change:
  - patches/20_add_debdiff_as_diff_type.dpatch: Also recognize .dpatch files
    as diff's
  - debian/geany.xpm: Replace icon with a .xpm of the new one

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Scintilla source code edit control
 
2
/** @file Lexr.cxx
 
3
 ** Lexer for R, S, SPlus Statistics Program (Heavily derived from CPP Lexer).
 
4
 **
 
5
 **/
 
6
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 
7
// The License.txt file describes the conditions under which this software may be distributed.
 
8
 
 
9
#include <stdlib.h>
 
10
#include <string.h>
 
11
#include <ctype.h>
 
12
#include <stdio.h>
 
13
#include <stdarg.h>
 
14
 
 
15
#include "Platform.h"
 
16
 
 
17
#include "PropSet.h"
 
18
#include "Accessor.h"
 
19
#include "StyleContext.h"
 
20
#include "KeyWords.h"
 
21
#include "Scintilla.h"
 
22
#include "SciLexer.h"
 
23
 
 
24
#ifdef SCI_NAMESPACE
 
25
using namespace Scintilla;
 
26
#endif
 
27
 
 
28
static inline bool IsAWordChar(const int ch) {
 
29
        return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
 
30
}
 
31
 
 
32
static inline bool IsAWordStart(const int ch) {
 
33
        return (ch < 0x80) && (isalnum(ch) || ch == '_');
 
34
}
 
35
 
 
36
static inline bool IsAnOperator(const int ch) {
 
37
        if (isascii(ch) && isalnum(ch))
 
38
                return false;
 
39
        // '.' left out as it is used to make up numbers
 
40
        if (ch == '-' || ch == '+' || ch == '!' || ch == '~' ||
 
41
                ch == '?' || ch == ':' || ch == '*' || ch == '/' ||
 
42
                ch == '^' || ch == '<' || ch == '>' || ch == '=' ||
 
43
                ch == '&' || ch == '|' || ch == '$' || ch == '(' ||
 
44
                ch == ')' || ch == '}' || ch == '{' || ch == '[' ||
 
45
                ch == ']')
 
46
                return true;
 
47
        return false;
 
48
}
 
49
 
 
50
static void ColouriseRDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
 
51
                            Accessor &styler) {
 
52
 
 
53
        WordList &keywords   = *keywordlists[0];
 
54
        WordList &keywords2 = *keywordlists[1];
 
55
        WordList &keywords3 = *keywordlists[2];
 
56
 
 
57
 
 
58
        // Do not leak onto next line
 
59
        if (initStyle == SCE_R_INFIXEOL)
 
60
                initStyle = SCE_R_DEFAULT;
 
61
 
 
62
 
 
63
        StyleContext sc(startPos, length, initStyle, styler);
 
64
 
 
65
        for (; sc.More(); sc.Forward()) {
 
66
 
 
67
                if (sc.atLineStart && (sc.state == SCE_R_STRING)) {
 
68
                        // Prevent SCE_R_STRINGEOL from leaking back to previous line
 
69
                        sc.SetState(SCE_R_STRING);
 
70
                }
 
71
 
 
72
                // Determine if the current state should terminate.
 
73
                if (sc.state == SCE_R_OPERATOR) {
 
74
                        sc.SetState(SCE_R_DEFAULT);
 
75
                } else if (sc.state == SCE_R_NUMBER) {
 
76
                        if (!IsADigit(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {
 
77
                                sc.SetState(SCE_R_DEFAULT);
 
78
                        }
 
79
                } else if (sc.state == SCE_R_IDENTIFIER) {
 
80
                        if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
 
81
                                char s[100];
 
82
                                sc.GetCurrentLowered(s, sizeof(s));
 
83
                                if (keywords.InList(s)) {
 
84
                                        sc.ChangeState(SCE_R_KWORD);
 
85
                                } else if  (keywords2.InList(s)) {
 
86
                                        sc.ChangeState(SCE_R_BASEKWORD);
 
87
                                } else if  (keywords3.InList(s)) {
 
88
                                        sc.ChangeState(SCE_R_OTHERKWORD);
 
89
                                }
 
90
                                sc.SetState(SCE_R_DEFAULT);
 
91
                        }
 
92
                } else if (sc.state == SCE_R_COMMENT) {
 
93
                        if (sc.ch == '\r' || sc.ch == '\n') {
 
94
                                sc.SetState(SCE_R_DEFAULT);
 
95
                        }
 
96
                } else if (sc.state == SCE_R_STRING) {
 
97
                        if (sc.ch == '\\') {
 
98
                                if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 
99
                                        sc.Forward();
 
100
                                }
 
101
                        } else if (sc.ch == '\"') {
 
102
                                sc.ForwardSetState(SCE_R_DEFAULT);
 
103
                        }
 
104
                } else if (sc.state == SCE_R_INFIX) {
 
105
                        if (sc.ch == '%') {
 
106
                                sc.ForwardSetState(SCE_R_DEFAULT);
 
107
                        } else if (sc.atLineEnd) {
 
108
                                sc.ChangeState(SCE_R_INFIXEOL);
 
109
                                sc.ForwardSetState(SCE_R_DEFAULT);
 
110
                        }
 
111
                }else if (sc.state == SCE_R_STRING2) {
 
112
                        if (sc.ch == '\\') {
 
113
                                if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 
114
                                        sc.Forward();
 
115
                                }
 
116
                        } else if (sc.ch == '\'') {
 
117
                                sc.ForwardSetState(SCE_R_DEFAULT);
 
118
                        }
 
119
                }
 
120
 
 
121
                // Determine if a new state should be entered.
 
122
                if (sc.state == SCE_R_DEFAULT) {
 
123
                        if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 
124
                                sc.SetState(SCE_R_NUMBER);
 
125
                        } else if (IsAWordStart(sc.ch) ) {
 
126
                                sc.SetState(SCE_R_IDENTIFIER);
 
127
                        } else if (sc.Match('#')) {
 
128
                                        sc.SetState(SCE_R_COMMENT);
 
129
                        } else if (sc.ch == '\"') {
 
130
                                sc.SetState(SCE_R_STRING);
 
131
                        } else if (sc.ch == '%') {
 
132
                                sc.SetState(SCE_R_INFIX);
 
133
                        } else if (sc.ch == '\'') {
 
134
                                sc.SetState(SCE_R_STRING2);
 
135
                        } else if (IsAnOperator(sc.ch)) {
 
136
                                sc.SetState(SCE_R_OPERATOR);
 
137
                        }
 
138
                }
 
139
        }
 
140
        sc.Complete();
 
141
}
 
142
 
 
143
// Store both the current line's fold level and the next lines in the
 
144
// level store to make it easy to pick up with each increment
 
145
// and to make it possible to fiddle the current level for "} else {".
 
146
static void FoldRDoc(unsigned int startPos, int length, int, WordList *[],
 
147
                       Accessor &styler) {
 
148
        bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 
149
        bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
 
150
        unsigned int endPos = startPos + length;
 
151
        int visibleChars = 0;
 
152
        int lineCurrent = styler.GetLine(startPos);
 
153
        int levelCurrent = SC_FOLDLEVELBASE;
 
154
        if (lineCurrent > 0)
 
155
                levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 
156
        int levelMinCurrent = levelCurrent;
 
157
        int levelNext = levelCurrent;
 
158
        char chNext = styler[startPos];
 
159
        int styleNext = styler.StyleAt(startPos);
 
160
        for (unsigned int i = startPos; i < endPos; i++) {
 
161
                char ch = chNext;
 
162
                chNext = styler.SafeGetCharAt(i + 1);
 
163
                int style = styleNext;
 
164
                styleNext = styler.StyleAt(i + 1);
 
165
                bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 
166
                if (style == SCE_R_OPERATOR) {
 
167
                        if (ch == '{') {
 
168
                                // Measure the minimum before a '{' to allow
 
169
                                // folding on "} else {"
 
170
                                if (levelMinCurrent > levelNext) {
 
171
                                        levelMinCurrent = levelNext;
 
172
                                }
 
173
                                levelNext++;
 
174
                        } else if (ch == '}') {
 
175
                                levelNext--;
 
176
                        }
 
177
                }
 
178
                if (atEOL) {
 
179
                        int levelUse = levelCurrent;
 
180
                        if (foldAtElse) {
 
181
                                levelUse = levelMinCurrent;
 
182
                        }
 
183
                        int lev = levelUse | levelNext << 16;
 
184
                        if (visibleChars == 0 && foldCompact)
 
185
                                lev |= SC_FOLDLEVELWHITEFLAG;
 
186
                        if (levelUse < levelNext)
 
187
                                lev |= SC_FOLDLEVELHEADERFLAG;
 
188
                        if (lev != styler.LevelAt(lineCurrent)) {
 
189
                                styler.SetLevel(lineCurrent, lev);
 
190
                        }
 
191
                        lineCurrent++;
 
192
                        levelCurrent = levelNext;
 
193
                        levelMinCurrent = levelCurrent;
 
194
                        visibleChars = 0;
 
195
                }
 
196
                if (!isspacechar(ch))
 
197
                        visibleChars++;
 
198
        }
 
199
}
 
200
 
 
201
 
 
202
static const char * const RWordLists[] = {
 
203
            "Language Keywords",
 
204
            "Base / Default package function",
 
205
            "Other Package Functions",
 
206
            "Unused",
 
207
            "Unused",
 
208
            0,
 
209
        };
 
210
 
 
211
 
 
212
 
 
213
LexerModule lmR(SCLEX_R, ColouriseRDoc, "r", FoldRDoc, RWordLists);