File: LexAsn1.cxx

package info (click to toggle)
scite 4.4.5-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 12,928 kB
  • sloc: cpp: 145,539; ansic: 19,277; python: 6,120; makefile: 806; perl: 200; sh: 184; sql: 160; objc: 18; ruby: 6; tcl: 6; php: 4
file content (186 lines) | stat: -rw-r--r-- 5,275 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// Scintilla source code edit control
/** @file LexAsn1.cxx
 ** Lexer for ASN.1
 **/
// Copyright 2004 by Herr Pfarrer rpfarrer <at> yahoo <dot> de
// Last Updated: 20/07/2004
// 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 "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"

#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"

using namespace Scintilla;

// Some char test functions
static bool isAsn1Number(int ch)
{
	return (ch >= '0' && ch <= '9');
}

static bool isAsn1Letter(int ch)
{
	return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}

static bool isAsn1Char(int ch)
{
	return (ch == '-' ) || isAsn1Number(ch) || isAsn1Letter (ch);
}

//
//	Function determining the color of a given code portion
//	Based on a "state"
//
static void ColouriseAsn1Doc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordLists[], Accessor &styler)
{
	// The keywords
	WordList &Keywords = *keywordLists[0];
	WordList &Attributes = *keywordLists[1];
	WordList &Descriptors = *keywordLists[2];
	WordList &Types = *keywordLists[3];

	// Parse the whole buffer character by character using StyleContext
	StyleContext sc(startPos, length, initStyle, styler);
	for (; sc.More(); sc.Forward())
	{
		// The state engine
		switch (sc.state)
		{
		case SCE_ASN1_DEFAULT:		// Plain characters
asn1_default:
			if (sc.ch == '-' && sc.chNext == '-')
				// A comment begins here
				sc.SetState(SCE_ASN1_COMMENT);
			else if (sc.ch == '"')
				// A string begins here
				sc.SetState(SCE_ASN1_STRING);
			else if (isAsn1Number (sc.ch))
				// A number starts here (identifier should start with a letter in ASN.1)
				sc.SetState(SCE_ASN1_SCALAR);
			else if (isAsn1Char (sc.ch))
				// An identifier starts here (identifier always start with a letter)
				sc.SetState(SCE_ASN1_IDENTIFIER);
			else if (sc.ch == ':')
				// A ::= operator starts here
				sc.SetState(SCE_ASN1_OPERATOR);
			break;
		case SCE_ASN1_COMMENT:		// A comment
			if (sc.ch == '\r' || sc.ch == '\n')
				// A comment ends here
				sc.SetState(SCE_ASN1_DEFAULT);
			break;
		case SCE_ASN1_IDENTIFIER:	// An identifier (keyword, attribute, descriptor or type)
			if (!isAsn1Char (sc.ch))
			{
				// The end of identifier is here: we can look for it in lists by now and change its state
				char s[100];
				sc.GetCurrent(s, sizeof(s));
				if (Keywords.InList(s))
					// It's a keyword, change its state
					sc.ChangeState(SCE_ASN1_KEYWORD);
				else if (Attributes.InList(s))
					// It's an attribute, change its state
					sc.ChangeState(SCE_ASN1_ATTRIBUTE);
				else if (Descriptors.InList(s))
					// It's a descriptor, change its state
					sc.ChangeState(SCE_ASN1_DESCRIPTOR);
				else if (Types.InList(s))
					// It's a type, change its state
					sc.ChangeState(SCE_ASN1_TYPE);

				// Set to default now
				sc.SetState(SCE_ASN1_DEFAULT);
			}
			break;
		case SCE_ASN1_STRING:		// A string delimited by ""
			if (sc.ch == '"')
			{
				// A string ends here
				sc.ForwardSetState(SCE_ASN1_DEFAULT);

				// To correctly manage a char sticking to the string quote
				goto asn1_default;
			}
			break;
		case SCE_ASN1_SCALAR:		// A plain number
			if (!isAsn1Number (sc.ch))
				// A number ends here
				sc.SetState(SCE_ASN1_DEFAULT);
			break;
		case SCE_ASN1_OPERATOR:		// The affectation operator ::= and wath follows (eg: ::= { org 6 } OID or ::= 12 trap)
			if (sc.ch == '{')
			{
				// An OID definition starts here: enter the sub loop
				for (; sc.More(); sc.Forward())
				{
					if (isAsn1Number (sc.ch) && (!isAsn1Char (sc.chPrev) || isAsn1Number (sc.chPrev)))
						// The OID number is highlighted
						sc.SetState(SCE_ASN1_OID);
					else if (isAsn1Char (sc.ch))
						// The OID parent identifier is plain
						sc.SetState(SCE_ASN1_IDENTIFIER);
					else
						sc.SetState(SCE_ASN1_DEFAULT);

					if (sc.ch == '}')
						// Here ends the OID and the operator sub loop: go back to main loop
						break;
				}
			}
			else if (isAsn1Number (sc.ch))
			{
				// A trap number definition starts here: enter the sub loop
				for (; sc.More(); sc.Forward())
				{
					if (isAsn1Number (sc.ch))
						// The trap number is highlighted
						sc.SetState(SCE_ASN1_OID);
					else
					{
						// The number ends here: go back to main loop
						sc.SetState(SCE_ASN1_DEFAULT);
						break;
					}
				}
			}
			else if (sc.ch != ':' && sc.ch != '=' && sc.ch != ' ')
				// The operator doesn't imply an OID definition nor a trap, back to main loop
				goto asn1_default; // To be sure to handle actually the state change
			break;
		}
	}
	sc.Complete();
}

static void FoldAsn1Doc(Sci_PositionU, Sci_Position, int, WordList *[], Accessor &styler)
{
	// No folding enabled, no reason to continue...
	if( styler.GetPropertyInt("fold") == 0 )
		return;

	// No folding implemented: doesn't make sense for ASN.1
}

static const char * const asn1WordLists[] = {
	"Keywords",
	"Attributes",
	"Descriptors",
	"Types",
	0, };


LexerModule lmAsn1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists);