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