mirror of
				https://github.com/notepad-plus-plus/notepad-plus-plus.git
				synced 2025-10-31 11:34:05 +01:00 
			
		
		
		
	[BUG_FIXED] (Author: Dave Brotherstone) Fix scintilla crash bug while closing a document. git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1104 f5eea248-9336-0410-98b8-ebc06183d4e3
		
			
				
	
	
		
			189 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // 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"
 | |
| 
 | |
| #ifdef SCI_NAMESPACE
 | |
| using namespace Scintilla;
 | |
| #endif
 | |
| 
 | |
| // 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(unsigned int startPos, int 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(unsigned int, int, 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);
 |