mirror of
https://github.com/notepad-plus-plus/notepad-plus-plus.git
synced 2025-04-08 17:15:37 +02:00
Release 5.5.2 ( https://www.scintilla.org/scintilla552.zip ) Released 21 August 2024. Add SCI_SETCOPYSEPARATOR for separator between parts of a multiple selection when copied to the clipboard. Feature #1530. Add SCI_GETUNDOSEQUENCE to determine whether an undo sequence is active and its nesting depth. Add SCI_STYLESETSTRETCH to support condensed and expanded text styles. Add SCI_LINEINDENT and SCI_LINEDEDENT. Feature #1524. Fix bug on Cocoa where double-click stopped working when system had been running for a long time. On Cocoa implement more values of font weight and stretch. Release 5.4.0 ( https://www.scintilla.org/lexilla540.zip ) Released 21 August 2024. Inside Lexilla, LexerModule instances are now const. This will require changes to applications that modify Lexilla.cxx, which may be done to add custom lexers. Lexer added for TOML "toml". Bash: Handle backslash in heredoc delimiter. Issue #257. Progress: Fix lexing of nested comments. Pull request #258. Force lower-casing of case-insensitive keyword lists so keywords match in some lexers. Issue #259. Close #15564
190 lines
5.2 KiB
C++
190 lines
5.2 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 <string>
|
|
#include <string_view>
|
|
|
|
#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 Lexilla;
|
|
|
|
// 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, };
|
|
|
|
|
|
extern const LexerModule lmAsn1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists);
|