]>
Commit | Line | Data |
---|---|---|
a33203cb RD |
1 | // Scintilla source code edit control |
2 | /** @file LexAsn1.cxx | |
3 | ** Lexer for ASN.1 | |
4 | **/ | |
5 | // Copyright 2004 by Herr Pfarrer rpfarrer <at> yahoo <dot> de | |
6 | // Last Updated: 20/07/2004 | |
7 | // The License.txt file describes the conditions under which this software may be distributed. | |
8 | #include <stdlib.h> | |
9 | #include <string.h> | |
10 | #include <ctype.h> | |
11 | #include <stdio.h> | |
12 | #include <stdarg.h> | |
13 | ||
14 | #include "Platform.h" | |
15 | ||
16 | #include "PropSet.h" | |
17 | #include "Accessor.h" | |
18 | #include "StyleContext.h" | |
19 | #include "KeyWords.h" | |
20 | #include "Scintilla.h" | |
21 | #include "SciLexer.h" | |
22 | ||
7e0c58e9 RD |
23 | #ifdef SCI_NAMESPACE |
24 | using namespace Scintilla; | |
25 | #endif | |
26 | ||
a33203cb RD |
27 | // Some char test functions |
28 | static bool isAsn1Number(int ch) | |
29 | { | |
30 | return (ch >= '0' && ch <= '9'); | |
31 | } | |
32 | ||
33 | static bool isAsn1Letter(int ch) | |
34 | { | |
35 | return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); | |
36 | } | |
37 | ||
38 | static bool isAsn1Char(int ch) | |
39 | { | |
40 | return (ch == '-' ) || isAsn1Number(ch) || isAsn1Letter (ch); | |
41 | } | |
42 | ||
43 | // | |
44 | // Function determining the color of a given code portion | |
45 | // Based on a "state" | |
46 | // | |
47 | static void ColouriseAsn1Doc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[], Accessor &styler) | |
48 | { | |
49 | // The keywords | |
50 | WordList &Keywords = *keywordLists[0]; | |
51 | WordList &Attributes = *keywordLists[1]; | |
52 | WordList &Descriptors = *keywordLists[2]; | |
53 | WordList &Types = *keywordLists[3]; | |
54 | ||
55 | // Parse the whole buffer character by character using StyleContext | |
56 | StyleContext sc(startPos, length, initStyle, styler); | |
57 | for (; sc.More(); sc.Forward()) | |
58 | { | |
59 | // The state engine | |
60 | switch (sc.state) | |
61 | { | |
62 | case SCE_ASN1_DEFAULT: // Plain characters | |
63 | asn1_default: | |
64 | if (sc.ch == '-' && sc.chNext == '-') | |
65 | // A comment begins here | |
66 | sc.SetState(SCE_ASN1_COMMENT); | |
67 | else if (sc.ch == '"') | |
68 | // A string begins here | |
69 | sc.SetState(SCE_ASN1_STRING); | |
70 | else if (isAsn1Number (sc.ch)) | |
71 | // A number starts here (identifier should start with a letter in ASN.1) | |
72 | sc.SetState(SCE_ASN1_SCALAR); | |
73 | else if (isAsn1Char (sc.ch)) | |
74 | // An identifier starts here (identifier always start with a letter) | |
75 | sc.SetState(SCE_ASN1_IDENTIFIER); | |
76 | else if (sc.ch == ':') | |
77 | // A ::= operator starts here | |
78 | sc.SetState(SCE_ASN1_OPERATOR); | |
79 | break; | |
80 | case SCE_ASN1_COMMENT: // A comment | |
81 | if (sc.ch == '\r' || sc.ch == '\n') | |
82 | // A comment ends here | |
83 | sc.SetState(SCE_ASN1_DEFAULT); | |
84 | break; | |
85 | case SCE_ASN1_IDENTIFIER: // An identifier (keyword, attribute, descriptor or type) | |
86 | if (!isAsn1Char (sc.ch)) | |
87 | { | |
88 | // The end of identifier is here: we can look for it in lists by now and change its state | |
89 | char s[100]; | |
90 | sc.GetCurrent(s, sizeof(s)); | |
91 | if (Keywords.InList(s)) | |
92 | // It's a keyword, change its state | |
93 | sc.ChangeState(SCE_ASN1_KEYWORD); | |
94 | else if (Attributes.InList(s)) | |
95 | // It's an attribute, change its state | |
96 | sc.ChangeState(SCE_ASN1_ATTRIBUTE); | |
97 | else if (Descriptors.InList(s)) | |
98 | // It's a descriptor, change its state | |
99 | sc.ChangeState(SCE_ASN1_DESCRIPTOR); | |
100 | else if (Types.InList(s)) | |
101 | // It's a type, change its state | |
102 | sc.ChangeState(SCE_ASN1_TYPE); | |
103 | ||
104 | // Set to default now | |
105 | sc.SetState(SCE_ASN1_DEFAULT); | |
106 | } | |
107 | break; | |
108 | case SCE_ASN1_STRING: // A string delimited by "" | |
109 | if (sc.ch == '"') | |
110 | { | |
111 | // A string ends here | |
112 | sc.ForwardSetState(SCE_ASN1_DEFAULT); | |
113 | ||
114 | // To correctly manage a char sticking to the string quote | |
115 | goto asn1_default; | |
116 | } | |
117 | break; | |
118 | case SCE_ASN1_SCALAR: // A plain number | |
119 | if (!isAsn1Number (sc.ch)) | |
120 | // A number ends here | |
121 | sc.SetState(SCE_ASN1_DEFAULT); | |
122 | break; | |
123 | case SCE_ASN1_OPERATOR: // The affectation operator ::= and wath follows (eg: ::= { org 6 } OID or ::= 12 trap) | |
124 | if (sc.ch == '{') | |
125 | { | |
126 | // An OID definition starts here: enter the sub loop | |
127 | for (; sc.More(); sc.Forward()) | |
128 | { | |
129 | if (isAsn1Number (sc.ch) && (!isAsn1Char (sc.chPrev) || isAsn1Number (sc.chPrev))) | |
130 | // The OID number is highlighted | |
131 | sc.SetState(SCE_ASN1_OID); | |
132 | else if (isAsn1Char (sc.ch)) | |
133 | // The OID parent identifier is plain | |
134 | sc.SetState(SCE_ASN1_IDENTIFIER); | |
135 | else | |
136 | sc.SetState(SCE_ASN1_DEFAULT); | |
137 | ||
138 | if (sc.ch == '}') | |
139 | // Here ends the OID and the operator sub loop: go back to main loop | |
140 | break; | |
141 | } | |
142 | } | |
143 | else if (isAsn1Number (sc.ch)) | |
144 | { | |
145 | // A trap number definition starts here: enter the sub loop | |
146 | for (; sc.More(); sc.Forward()) | |
147 | { | |
148 | if (isAsn1Number (sc.ch)) | |
149 | // The trap number is highlighted | |
150 | sc.SetState(SCE_ASN1_OID); | |
151 | else | |
152 | { | |
153 | // The number ends here: go back to main loop | |
154 | sc.SetState(SCE_ASN1_DEFAULT); | |
155 | break; | |
156 | } | |
157 | } | |
158 | } | |
159 | else if (sc.ch != ':' && sc.ch != '=' && sc.ch != ' ') | |
160 | // The operator doesn't imply an OID definition nor a trap, back to main loop | |
161 | goto asn1_default; // To be sure to handle actually the state change | |
162 | break; | |
163 | } | |
164 | } | |
165 | sc.Complete(); | |
166 | } | |
167 | ||
168 | static void FoldAsn1Doc(unsigned int, int, int, WordList *[], Accessor &styler) | |
169 | { | |
170 | // No folding enabled, no reason to continue... | |
171 | if( styler.GetPropertyInt("fold") == 0 ) | |
172 | return; | |
173 | ||
174 | // No folding implemented: doesn't make sense for ASN.1 | |
175 | } | |
176 | ||
177 | static const char * const asn1WordLists[] = { | |
178 | "Keywords", | |
179 | "Attributes", | |
180 | "Descriptors", | |
181 | "Types", | |
182 | 0, }; | |
183 | ||
184 | ||
1e9bafca | 185 | LexerModule lmAns1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists); |