fix build under newer KConfig by bump cmake min version
This commit is contained in:
		
							
								
								
									
										31
									
								
								3rdparty/lexilla540/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								3rdparty/lexilla540/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
# this file is actually the CMake version of Lexilla.pro
 | 
			
		||||
cmake_minimum_required(VERSION 3.10)
 | 
			
		||||
 | 
			
		||||
project(lexilla)
 | 
			
		||||
 | 
			
		||||
add_library(${PROJECT_NAME} SHARED)
 | 
			
		||||
 | 
			
		||||
set(CMAKE_CXX_STANDARD 17)
 | 
			
		||||
 | 
			
		||||
file(GLOB_RECURSE SRCS CONFIGURE_DEPENDS
 | 
			
		||||
    # main library binding
 | 
			
		||||
    "${CMAKE_CURRENT_SOURCE_DIR}/lexilla/include/Lexilla.h"
 | 
			
		||||
    "${CMAKE_CURRENT_SOURCE_DIR}/lexilla/src/Lexilla.cxx"
 | 
			
		||||
    # lexlib
 | 
			
		||||
    "${CMAKE_CURRENT_SOURCE_DIR}/lexilla/lexlib/*.h"
 | 
			
		||||
    "${CMAKE_CURRENT_SOURCE_DIR}/lexilla/lexlib/*.cxx"
 | 
			
		||||
    # lexers
 | 
			
		||||
    "${CMAKE_CURRENT_SOURCE_DIR}/lexilla/lexers/Lex*.cxx"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_sources(${PROJECT_NAME}
 | 
			
		||||
PRIVATE
 | 
			
		||||
    ${SRCS}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_include_directories(${PROJECT_NAME}
 | 
			
		||||
PUBLIC
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/lexilla/include
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/lexilla/lexlib
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/../scintilla552/scintilla/include
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										17
									
								
								3rdparty/lexilla540/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								3rdparty/lexilla540/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
# About Lexilla
 | 
			
		||||
 | 
			
		||||
## Source
 | 
			
		||||
 | 
			
		||||
The vendored Lexilla source code is fetched from their official website [^1]. Version is 5.4.0. All vendored code are inside the `scintilla` folder.
 | 
			
		||||
 | 
			
		||||
[^1]: https://www.scintilla.org/LexillaDownload.html
 | 
			
		||||
 | 
			
		||||
## How to update
 | 
			
		||||
 | 
			
		||||
To update the vendored code to the newer version, do the following steps.
 | 
			
		||||
 | 
			
		||||
1. Download the ZIP archive of the new version, unzip it and replace the `lexilla` folder.
 | 
			
		||||
2. Reconfigure project, start to build, and see if it fails. If so, review the change of `Lexilla.pro` and see if we need to update the `CMakeLists.txt` in this folder (along with this `README.md` file).
 | 
			
		||||
3. Done, we can commit the change now.
 | 
			
		||||
 | 
			
		||||
The folder name that this sub-project lives at currently indicates the Lexilla version that we uses. If updated, consider also update the folder name as well.
 | 
			
		||||
							
								
								
									
										88
									
								
								3rdparty/lexilla540/lexilla/.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								3rdparty/lexilla540/lexilla/.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
* -text
 | 
			
		||||
**.cxx text
 | 
			
		||||
**.cpp text
 | 
			
		||||
**.c text
 | 
			
		||||
**.h text
 | 
			
		||||
**.hpp text
 | 
			
		||||
**.m text
 | 
			
		||||
**.mm text
 | 
			
		||||
**.iface text
 | 
			
		||||
**.template text
 | 
			
		||||
**.mk text
 | 
			
		||||
**.mk text
 | 
			
		||||
**.py text
 | 
			
		||||
**.rc text
 | 
			
		||||
**.css text
 | 
			
		||||
**.html text
 | 
			
		||||
**.bat text
 | 
			
		||||
**.bsh text
 | 
			
		||||
**.zsh text
 | 
			
		||||
**.mak text
 | 
			
		||||
**.def text
 | 
			
		||||
**.manifest text
 | 
			
		||||
**.properties text
 | 
			
		||||
**.props text
 | 
			
		||||
**.session text
 | 
			
		||||
**.styled text
 | 
			
		||||
**.folded text
 | 
			
		||||
**.adoc text
 | 
			
		||||
**.asp text
 | 
			
		||||
**.aspx text
 | 
			
		||||
**.php text
 | 
			
		||||
**.vb text
 | 
			
		||||
**.vbs text
 | 
			
		||||
**.asm text
 | 
			
		||||
**.cob text
 | 
			
		||||
**.cmake text
 | 
			
		||||
**.d text
 | 
			
		||||
**.diff text
 | 
			
		||||
**.erl text
 | 
			
		||||
**.f text
 | 
			
		||||
**.gd text
 | 
			
		||||
**.gui text
 | 
			
		||||
**.iss text
 | 
			
		||||
**.jl text
 | 
			
		||||
**.json text
 | 
			
		||||
**.lua text
 | 
			
		||||
**.m3 text
 | 
			
		||||
**.matlab text
 | 
			
		||||
**.ml text
 | 
			
		||||
**.nim text
 | 
			
		||||
**.octave text
 | 
			
		||||
**.p text
 | 
			
		||||
**.pl text
 | 
			
		||||
**.p6 text
 | 
			
		||||
**.ps1 text
 | 
			
		||||
**.r text
 | 
			
		||||
**.rb text
 | 
			
		||||
**.rs text
 | 
			
		||||
**.sql text
 | 
			
		||||
**.tcl text
 | 
			
		||||
**.toml text
 | 
			
		||||
**.tsql text
 | 
			
		||||
**.err text
 | 
			
		||||
**.mms text
 | 
			
		||||
**.tex text
 | 
			
		||||
**.fs text
 | 
			
		||||
**.vh text
 | 
			
		||||
**.vhd text
 | 
			
		||||
**.x12 text
 | 
			
		||||
**.yaml text
 | 
			
		||||
**.md text
 | 
			
		||||
**.txt text
 | 
			
		||||
**.pch text
 | 
			
		||||
**.hg* text
 | 
			
		||||
**.dsp text
 | 
			
		||||
**.pbxproj text
 | 
			
		||||
**.plist text
 | 
			
		||||
**.xcworkspacedata text
 | 
			
		||||
**.pro text
 | 
			
		||||
**.gen text
 | 
			
		||||
**makefile text
 | 
			
		||||
**.bmp binary
 | 
			
		||||
**.cur binary
 | 
			
		||||
**.ico binary
 | 
			
		||||
**.jpg binary
 | 
			
		||||
**.png binary
 | 
			
		||||
**.sh text eol=lf
 | 
			
		||||
tgzsrc text eol=lf
 | 
			
		||||
							
								
								
									
										33
									
								
								3rdparty/lexilla540/lexilla/.github/workflows/build-check-macos.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								3rdparty/lexilla540/lexilla/.github/workflows/build-check-macos.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
name: "Build and check Lexilla on macOS"
 | 
			
		||||
 | 
			
		||||
on: [push]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
    build:
 | 
			
		||||
 | 
			
		||||
        runs-on: macos-latest
 | 
			
		||||
 | 
			
		||||
        strategy:
 | 
			
		||||
            matrix:
 | 
			
		||||
                cpp_compiler: [clang++]
 | 
			
		||||
 | 
			
		||||
        steps:
 | 
			
		||||
        - uses: actions/checkout@v4
 | 
			
		||||
        - name: Install Scintilla source
 | 
			
		||||
          run: |
 | 
			
		||||
              (cd .. && wget --no-verbose https://www.scintilla.org/scintilla500.zip)
 | 
			
		||||
              (cd .. && unzip scintilla500.zip)
 | 
			
		||||
        - name: Unit Test
 | 
			
		||||
          run: (cd test/unit && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) test)
 | 
			
		||||
        - name: Build Lexilla
 | 
			
		||||
          run: (cd src && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN))
 | 
			
		||||
        - uses: actions/upload-artifact@v4
 | 
			
		||||
          with:
 | 
			
		||||
              name: liblexilla.dylib
 | 
			
		||||
              path: bin/liblexilla.dylib
 | 
			
		||||
        - name: Test lexing and folding
 | 
			
		||||
          run: (cd test && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) test)
 | 
			
		||||
        - name: CheckLexilla C Example
 | 
			
		||||
          run: (cd examples/CheckLexilla && make DEBUG=1 --jobs=$(getconf _NPROCESSORS_ONLN) check)
 | 
			
		||||
        - name: SimpleLexer Example
 | 
			
		||||
          run: (cd examples/SimpleLexer && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) check)
 | 
			
		||||
							
								
								
									
										53
									
								
								3rdparty/lexilla540/lexilla/.github/workflows/build-check-win32.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								3rdparty/lexilla540/lexilla/.github/workflows/build-check-win32.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
			
		||||
name: "Build and check Lexilla on Win32 with Visual C++"
 | 
			
		||||
 | 
			
		||||
on: [push]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
    build:
 | 
			
		||||
 | 
			
		||||
        runs-on: windows-latest
 | 
			
		||||
 | 
			
		||||
        steps:
 | 
			
		||||
        - uses: actions/checkout@v4
 | 
			
		||||
        - name: Preparing nmake
 | 
			
		||||
          uses: ilammy/msvc-dev-cmd@v1
 | 
			
		||||
          with:
 | 
			
		||||
            arch: x64
 | 
			
		||||
        - name: Install Scintilla source
 | 
			
		||||
          run: |
 | 
			
		||||
              pwd
 | 
			
		||||
              cd ..
 | 
			
		||||
              curl -O https://www.scintilla.org/scintilla500.zip
 | 
			
		||||
              ls
 | 
			
		||||
              7z x scintilla500.zip
 | 
			
		||||
              cd lexilla
 | 
			
		||||
        - name: Unit Test
 | 
			
		||||
          run: |
 | 
			
		||||
              cd test/unit
 | 
			
		||||
              nmake -f test.mak DEBUG=1 test
 | 
			
		||||
              cd ../..
 | 
			
		||||
        - name: Build Lexilla
 | 
			
		||||
          run: |
 | 
			
		||||
              cd src
 | 
			
		||||
              nmake -f lexilla.mak DEBUG=1
 | 
			
		||||
              cd ..
 | 
			
		||||
        - uses: actions/upload-artifact@v4
 | 
			
		||||
          with:
 | 
			
		||||
              name: lexilla.dll
 | 
			
		||||
              path: bin/lexilla.dll
 | 
			
		||||
        - name: Test lexing and folding
 | 
			
		||||
          run: |
 | 
			
		||||
              cd test
 | 
			
		||||
              nmake -f testlexers.mak DEBUG=1 test
 | 
			
		||||
              cd ..
 | 
			
		||||
        - name: CheckLexilla C Example
 | 
			
		||||
          run: |
 | 
			
		||||
              cd examples/CheckLexilla
 | 
			
		||||
              cl -MP CheckLexilla.c -I ../../include -Fe: CheckLexilla
 | 
			
		||||
              .\CheckLexilla.exe
 | 
			
		||||
              cd ../..
 | 
			
		||||
        - name: SimpleLexer Example
 | 
			
		||||
          run: |
 | 
			
		||||
              cd examples/SimpleLexer
 | 
			
		||||
              cl -MP -std:c++17 -EHsc -LD -I ../../../scintilla/include -I ../../include -I ../../lexlib SimpleLexer.cxx ../../lexlib/*.cxx
 | 
			
		||||
              cd ../..
 | 
			
		||||
							
								
								
									
										34
									
								
								3rdparty/lexilla540/lexilla/.github/workflows/build-check.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								3rdparty/lexilla540/lexilla/.github/workflows/build-check.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
name: "Build and check Lexilla on Linux"
 | 
			
		||||
 | 
			
		||||
on: [push]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
    build:
 | 
			
		||||
 | 
			
		||||
        runs-on: ubuntu-latest
 | 
			
		||||
 | 
			
		||||
        strategy:
 | 
			
		||||
            matrix:
 | 
			
		||||
                cpp_compiler: [g++, clang++]
 | 
			
		||||
 | 
			
		||||
        steps:
 | 
			
		||||
        - uses: actions/checkout@v4
 | 
			
		||||
        - name: Install Scintilla source
 | 
			
		||||
          run: |
 | 
			
		||||
              (cd .. && wget --no-verbose https://www.scintilla.org/scintilla500.zip)
 | 
			
		||||
              (cd .. && unzip scintilla500.zip)
 | 
			
		||||
        - name: Unit Test
 | 
			
		||||
          run: (cd test/unit && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) test)
 | 
			
		||||
        - name: Build Lexilla
 | 
			
		||||
          run: (cd src && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN))
 | 
			
		||||
        - uses: actions/upload-artifact@v4
 | 
			
		||||
          with:
 | 
			
		||||
              name: liblexilla-${{matrix.cpp_compiler}}.so
 | 
			
		||||
              path: bin/liblexilla.so
 | 
			
		||||
              overwrite: true
 | 
			
		||||
        - name: Test lexing and folding
 | 
			
		||||
          run: (cd test && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) test)
 | 
			
		||||
        - name: CheckLexilla C Example
 | 
			
		||||
          run: (cd examples/CheckLexilla && make DEBUG=1 --jobs=$(getconf _NPROCESSORS_ONLN) check)
 | 
			
		||||
        - name: SimpleLexer Example
 | 
			
		||||
          run: (cd examples/SimpleLexer && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) check)
 | 
			
		||||
							
								
								
									
										71
									
								
								3rdparty/lexilla540/lexilla/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								3rdparty/lexilla540/lexilla/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,71 @@
 | 
			
		||||
*.o
 | 
			
		||||
*.a
 | 
			
		||||
*.lib
 | 
			
		||||
*.obj
 | 
			
		||||
*.iobj
 | 
			
		||||
__pycache__
 | 
			
		||||
*.pyc
 | 
			
		||||
*.dll
 | 
			
		||||
*.so
 | 
			
		||||
*.dylib
 | 
			
		||||
*.framework
 | 
			
		||||
*.pyd
 | 
			
		||||
*.exe
 | 
			
		||||
*.exp
 | 
			
		||||
*.lib
 | 
			
		||||
*.pdb
 | 
			
		||||
*.ipdb
 | 
			
		||||
*.res
 | 
			
		||||
*.bak
 | 
			
		||||
*.sbr
 | 
			
		||||
*.suo
 | 
			
		||||
*.aps
 | 
			
		||||
*.sln
 | 
			
		||||
*.vcxproj.*
 | 
			
		||||
*.idb
 | 
			
		||||
*.bsc
 | 
			
		||||
*.intermediate.manifest
 | 
			
		||||
*.lastbuildstate
 | 
			
		||||
*.nativecodeanalysis.xml
 | 
			
		||||
*.cache
 | 
			
		||||
*.ilk
 | 
			
		||||
*.ncb
 | 
			
		||||
*.tlog
 | 
			
		||||
*.sdf
 | 
			
		||||
gtk/*.plist
 | 
			
		||||
win32/*.plist
 | 
			
		||||
*.opt
 | 
			
		||||
*.plg
 | 
			
		||||
*.pbxbtree
 | 
			
		||||
*.mode1v3
 | 
			
		||||
*.pbxuser
 | 
			
		||||
*.pbproj
 | 
			
		||||
*.tgz
 | 
			
		||||
*.log
 | 
			
		||||
*.xcbkptlist
 | 
			
		||||
*.xcuserstate
 | 
			
		||||
xcuserdata/
 | 
			
		||||
*.xcsettings
 | 
			
		||||
xcschememanagement.plist
 | 
			
		||||
.DS_Store
 | 
			
		||||
test/TestLexers
 | 
			
		||||
Release
 | 
			
		||||
Debug
 | 
			
		||||
x64
 | 
			
		||||
ARM64
 | 
			
		||||
cocoa/build
 | 
			
		||||
cocoa/ScintillaFramework/build
 | 
			
		||||
cocoa/ScintillaTest/build
 | 
			
		||||
macosx/SciTest/build
 | 
			
		||||
*.cppcheck
 | 
			
		||||
*.pro.user
 | 
			
		||||
.qmake.stash
 | 
			
		||||
cov-int
 | 
			
		||||
.vs
 | 
			
		||||
meson-private
 | 
			
		||||
meson-logs
 | 
			
		||||
build.ninja
 | 
			
		||||
.ninja*
 | 
			
		||||
compile_commands.json
 | 
			
		||||
.vscode/
 | 
			
		||||
VTune Profiler Results/
 | 
			
		||||
							
								
								
									
										42
									
								
								3rdparty/lexilla540/lexilla/.travis.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								3rdparty/lexilla540/lexilla/.travis.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
# Build Lexilla with gcc and clang on Linux, macOS, and Windows
 | 
			
		||||
# Test Lexilla with gcc and clang on Linux and macOS 
 | 
			
		||||
# Windows has older versions of libraries so can't compile std::filesystem
 | 
			
		||||
# with gcc or std::string::starts_with with clang.
 | 
			
		||||
# On macOS, gcc is a synonym for clang so exclude gcc.
 | 
			
		||||
os:
 | 
			
		||||
 - linux
 | 
			
		||||
 - osx
 | 
			
		||||
 - windows
 | 
			
		||||
 | 
			
		||||
dist: focal
 | 
			
		||||
 | 
			
		||||
osx_image: xcode12.3
 | 
			
		||||
 | 
			
		||||
language: cpp
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  exclude:
 | 
			
		||||
  - os: osx
 | 
			
		||||
    compiler: gcc
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
 - cd ..
 | 
			
		||||
 - wget --no-verbose https://www.scintilla.org/scintilla500.zip
 | 
			
		||||
 - if [ "$TRAVIS_OS_NAME" = "windows" ]; then 7z x scintilla500.zip ; else unzip scintilla500.zip ; fi
 | 
			
		||||
 - cd lexilla
 | 
			
		||||
 | 
			
		||||
compiler:
 | 
			
		||||
 - gcc
 | 
			
		||||
 - clang
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
 - if [ "$TRAVIS_OS_NAME" = "windows" ]; then MAKER="mingw32-make windir=1" ; else MAKER="make" ; fi
 | 
			
		||||
 - (cd src && $MAKER DEBUG=1)
 | 
			
		||||
 - cd test
 | 
			
		||||
 - if [ "$TRAVIS_OS_NAME" != "windows" ]; then make DEBUG=1 test ; fi
 | 
			
		||||
 - (cd unit && $MAKER DEBUG=1 test)
 | 
			
		||||
 - cd ..
 | 
			
		||||
 - cd examples
 | 
			
		||||
 - (cd CheckLexilla && $MAKER DEBUG=1 check)
 | 
			
		||||
 - (cd SimpleLexer && $MAKER DEBUG=1 check)
 | 
			
		||||
 - cd ..
 | 
			
		||||
							
								
								
									
										42
									
								
								3rdparty/lexilla540/lexilla/CONTRIBUTING
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								3rdparty/lexilla540/lexilla/CONTRIBUTING
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
Lexilla is on GitHub at https://github.com/ScintillaOrg/lexilla
 | 
			
		||||
 | 
			
		||||
Bugs, fixes and features should be posted to the Issue Tracker
 | 
			
		||||
https://github.com/ScintillaOrg/lexilla/issues
 | 
			
		||||
 | 
			
		||||
Patches should include test cases. Add a test case file in 
 | 
			
		||||
lexilla/test/examples/<language> and run the test program in 
 | 
			
		||||
lexilla/test.
 | 
			
		||||
The result will be new files with ".styled.new" and ".folded.new"
 | 
			
		||||
appended containing lexing or folding results.
 | 
			
		||||
For lexing, there are brace surrounded style numbers for each style
 | 
			
		||||
start as markup:
 | 
			
		||||
{5}import{0} {11}contextlib{0}
 | 
			
		||||
 | 
			
		||||
For folding, there are 4 columns of folding results preceding the example text:
 | 
			
		||||
 2 400   0 + --[[ coding:UTF-8
 | 
			
		||||
 0 402   0 | comment ]]
 | 
			
		||||
See the test/README file for more explanation of the folding results.
 | 
			
		||||
 | 
			
		||||
To build lexilla and the tests with gcc there are Windows batch
 | 
			
		||||
and Unix shell files scripts/RunTest.bat scripts/RunTest.sh.
 | 
			
		||||
Check the result of the .new files and, if correct, rename replacing
 | 
			
		||||
".styled.new" with ".styled" and ".folded.new" with ".folded".
 | 
			
		||||
Run the tests again and success should be reported.
 | 
			
		||||
Include the .styled and .folded files in the patch.
 | 
			
		||||
Including test cases ensures that the change won't be undone by
 | 
			
		||||
other changes in the future and clarifies the intentions of the author.
 | 
			
		||||
 | 
			
		||||
Either send unified diffs (or patch files) or zip archives with whole files.
 | 
			
		||||
Mercurial/Git patch files are best as they include author information and commit
 | 
			
		||||
messages.
 | 
			
		||||
 | 
			
		||||
Questions should go to the scintilla-interest mailing list
 | 
			
		||||
https://groups.google.com/forum/#!forum/scintilla-interest
 | 
			
		||||
 | 
			
		||||
Code should follow the guidelines at
 | 
			
		||||
https://www.scintilla.org/SciCoding.html
 | 
			
		||||
 | 
			
		||||
Lexilla is on GitHub so use its facilities rather than SourceForge which is
 | 
			
		||||
the home of Scintilla.
 | 
			
		||||
The neilh @ scintilla.org account receives much spam and is only checked
 | 
			
		||||
occasionally. Almost all Scintilla mail should go to the mailing list.
 | 
			
		||||
							
								
								
									
										20
									
								
								3rdparty/lexilla540/lexilla/License.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								3rdparty/lexilla540/lexilla/License.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
License for Lexilla, Scintilla, and SciTE
 | 
			
		||||
 | 
			
		||||
Copyright 1998-2021 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
 | 
			
		||||
All Rights Reserved
 | 
			
		||||
 | 
			
		||||
Permission to use, copy, modify, and distribute this software and its
 | 
			
		||||
documentation for any purpose and without fee is hereby granted,
 | 
			
		||||
provided that the above copyright notice appear in all copies and that
 | 
			
		||||
both that copyright notice and this permission notice appear in
 | 
			
		||||
supporting documentation.
 | 
			
		||||
 | 
			
		||||
NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 | 
			
		||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 | 
			
		||||
AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY
 | 
			
		||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 | 
			
		||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | 
			
		||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
 | 
			
		||||
OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
							
								
								
									
										49
									
								
								3rdparty/lexilla540/lexilla/README
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								3rdparty/lexilla540/lexilla/README
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
			
		||||
README for Lexilla library.
 | 
			
		||||
 | 
			
		||||
The Lexilla library contains a set of lexers and folders that provides support for
 | 
			
		||||
programming, mark-up, and data languages for the Scintilla source code editing
 | 
			
		||||
component.
 | 
			
		||||
 | 
			
		||||
Lexilla is made available as both a shared library and static library.
 | 
			
		||||
The shared library is called liblexilla.so / liblexilla.dylib / lexilla.dll on Linux / macOS /
 | 
			
		||||
Windows.
 | 
			
		||||
The static library is called liblexilla.a when built with GCC or Clang and liblexilla.lib
 | 
			
		||||
when built with MSVC.
 | 
			
		||||
 | 
			
		||||
Lexilla is developed on Windows, Linux, and macOS and requires a C++17 compiler.
 | 
			
		||||
It may work on other Unix platforms like BSD but that is not a development focus.
 | 
			
		||||
MSVC 2019.4, GCC 9.0, Clang 9.0, and Apple Clang 11.0 are known to work.
 | 
			
		||||
 | 
			
		||||
MSVC is only available on Windows.
 | 
			
		||||
 | 
			
		||||
GCC and Clang work on Windows and Linux.
 | 
			
		||||
 | 
			
		||||
On macOS, only Apple Clang is available.
 | 
			
		||||
 | 
			
		||||
Lexilla requires some headers from Scintilla to build and expects a directory named
 | 
			
		||||
"scintilla" containing a copy of Scintilla 5+ to be a peer of the Lexilla top level
 | 
			
		||||
directory conventionally called "lexilla".
 | 
			
		||||
 | 
			
		||||
To use GCC, run lexilla/src/makefile:
 | 
			
		||||
	make
 | 
			
		||||
 | 
			
		||||
To use Clang, run lexilla/test/makefile:
 | 
			
		||||
	make CLANG=1
 | 
			
		||||
On macOS, CLANG is set automatically so this can just be
 | 
			
		||||
	make
 | 
			
		||||
 | 
			
		||||
To use MSVC, run lexilla/test/lexilla.mak:
 | 
			
		||||
	nmake -f lexilla.mak
 | 
			
		||||
 | 
			
		||||
To build a debugging version of the library, add DEBUG=1 to the command:
 | 
			
		||||
	make DEBUG=1
 | 
			
		||||
	
 | 
			
		||||
The built libraries are copied into lexilla/bin.
 | 
			
		||||
 | 
			
		||||
Lexilla relies on a list of lexers from the lexilla/lexers directory. If any changes are
 | 
			
		||||
made to the set of lexers then source and build files can be regenerated with the
 | 
			
		||||
lexilla/scripts/LexillaGen.py script which requires Python 3 and is tested with 3.7+.
 | 
			
		||||
Unix:
 | 
			
		||||
	python3 LexillaGen.py
 | 
			
		||||
Windows:
 | 
			
		||||
	pyw LexillaGen.py
 | 
			
		||||
							
								
								
									
										285
									
								
								3rdparty/lexilla540/lexilla/access/LexillaAccess.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										285
									
								
								3rdparty/lexilla540/lexilla/access/LexillaAccess.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,285 @@
 | 
			
		||||
// SciTE - Scintilla based Text Editor
 | 
			
		||||
/** @file LexillaAccess.cxx
 | 
			
		||||
 ** Interface to loadable lexers.
 | 
			
		||||
 ** Maintains a list of lexer library paths and CreateLexer functions.
 | 
			
		||||
 ** If list changes then load all the lexer libraries and find the functions.
 | 
			
		||||
 ** When asked to create a lexer, call each function until one succeeds.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2019 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <set>
 | 
			
		||||
 | 
			
		||||
#if !defined(_WIN32)
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
 | 
			
		||||
#include "Lexilla.h"
 | 
			
		||||
 | 
			
		||||
#include "LexillaAccess.h"
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
typedef FARPROC Function;
 | 
			
		||||
typedef HMODULE Module;
 | 
			
		||||
constexpr const char *pathSeparator = "\\";
 | 
			
		||||
#else
 | 
			
		||||
typedef void *Function;
 | 
			
		||||
typedef void *Module;
 | 
			
		||||
constexpr const char *pathSeparator = "/";
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Generic function to convert from a Function(void* or FARPROC) to a function pointer.
 | 
			
		||||
/// This avoids undefined and conditionally defined behaviour.
 | 
			
		||||
template<typename T>
 | 
			
		||||
T FunctionPointer(Function function) noexcept {
 | 
			
		||||
	static_assert(sizeof(T) == sizeof(function));
 | 
			
		||||
	T fp {};
 | 
			
		||||
	memcpy(&fp, &function, sizeof(T));
 | 
			
		||||
	return fp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
 | 
			
		||||
std::wstring WideStringFromUTF8(std::string_view sv) {
 | 
			
		||||
	const int sLength = static_cast<int>(sv.length());
 | 
			
		||||
	const int cchWide = ::MultiByteToWideChar(CP_UTF8, 0, sv.data(), sLength, nullptr, 0);
 | 
			
		||||
	std::wstring sWide(cchWide, 0);
 | 
			
		||||
	::MultiByteToWideChar(CP_UTF8, 0, sv.data(), sLength, sWide.data(), cchWide);
 | 
			
		||||
	return sWide;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Turn off deprecation checks as LexillaAccess deprecates its wrapper over
 | 
			
		||||
// the deprecated LexerNameFromID. Thus use within LexillaAccess is intentional.
 | 
			
		||||
#if defined(__GNUC__) || defined(__clang__)
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 | 
			
		||||
#else
 | 
			
		||||
#pragma warning(disable: 4996)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
std::string directoryLoadDefault;
 | 
			
		||||
std::string lastLoaded;
 | 
			
		||||
 | 
			
		||||
struct LexLibrary {
 | 
			
		||||
	Lexilla::CreateLexerFn fnCL;
 | 
			
		||||
	Lexilla::LexerNameFromIDFn fnLNFI;
 | 
			
		||||
	Lexilla::GetLibraryPropertyNamesFn fnGLPN;
 | 
			
		||||
	Lexilla::SetLibraryPropertyFn fnSLP;
 | 
			
		||||
	std::string nameSpace;
 | 
			
		||||
};
 | 
			
		||||
std::vector<LexLibrary> libraries;
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> lexers;
 | 
			
		||||
std::vector<std::string> libraryProperties;
 | 
			
		||||
 | 
			
		||||
Function FindSymbol(Module m, const char *symbol) noexcept {
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
	return ::GetProcAddress(m, symbol);
 | 
			
		||||
#else
 | 
			
		||||
	return dlsym(m, symbol);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Lexilla::CreateLexerFn pCreateLexerDefault = nullptr;
 | 
			
		||||
 | 
			
		||||
bool NameContainsDot(std::string_view path) noexcept {
 | 
			
		||||
	for (std::string_view::const_reverse_iterator it = path.crbegin();
 | 
			
		||||
	     it != path.crend(); ++it) {
 | 
			
		||||
		if (*it == '.')
 | 
			
		||||
			return true;
 | 
			
		||||
		if (*it == '/' || *it == '\\')
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr bool HasPrefix(std::string_view s, std::string_view prefix) noexcept {
 | 
			
		||||
	return (s.size() >= prefix.size()) && (prefix == s.substr(0, prefix.size()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Lexilla::SetDefault(CreateLexerFn pCreate) noexcept {
 | 
			
		||||
	pCreateLexerDefault = pCreate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Lexilla::SetDefaultDirectory(std::string_view directory) {
 | 
			
		||||
	directoryLoadDefault = directory;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Lexilla::Load(std::string_view sharedLibraryPaths) {
 | 
			
		||||
	if (sharedLibraryPaths == lastLoaded) {
 | 
			
		||||
		return !libraries.empty();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::string_view paths = sharedLibraryPaths;
 | 
			
		||||
	lexers.clear();
 | 
			
		||||
 | 
			
		||||
	libraries.clear();
 | 
			
		||||
	while (!paths.empty()) {
 | 
			
		||||
		const size_t separator = paths.find_first_of(';');
 | 
			
		||||
		std::string path(paths.substr(0, separator));
 | 
			
		||||
		if (separator == std::string::npos) {
 | 
			
		||||
			paths.remove_prefix(paths.size());
 | 
			
		||||
		} else {
 | 
			
		||||
			paths.remove_prefix(separator + 1);
 | 
			
		||||
		}
 | 
			
		||||
		if (path == ".") {
 | 
			
		||||
			if (directoryLoadDefault.empty()) {
 | 
			
		||||
				path = "";
 | 
			
		||||
			} else {
 | 
			
		||||
				path = directoryLoadDefault;
 | 
			
		||||
				path += pathSeparator;
 | 
			
		||||
			}
 | 
			
		||||
			path += LEXILLA_LIB;
 | 
			
		||||
		}
 | 
			
		||||
		if (!NameContainsDot(path)) {
 | 
			
		||||
			// No '.' in name so add extension
 | 
			
		||||
			path.append(LEXILLA_EXTENSION);
 | 
			
		||||
		}
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
		// Convert from UTF-8 to wide characters
 | 
			
		||||
		std::wstring wsPath = WideStringFromUTF8(path);
 | 
			
		||||
		Module lexillaDL = ::LoadLibraryW(wsPath.c_str());
 | 
			
		||||
#else
 | 
			
		||||
		Module lexillaDL = dlopen(path.c_str(), RTLD_LAZY);
 | 
			
		||||
#endif
 | 
			
		||||
		if (lexillaDL) {
 | 
			
		||||
			GetLexerCountFn fnLexerCount = FunctionPointer<GetLexerCountFn>(
 | 
			
		||||
				FindSymbol(lexillaDL, LEXILLA_GETLEXERCOUNT));
 | 
			
		||||
			GetLexerNameFn fnLexerName = FunctionPointer<GetLexerNameFn>(
 | 
			
		||||
				FindSymbol(lexillaDL, LEXILLA_GETLEXERNAME));
 | 
			
		||||
			if (fnLexerCount && fnLexerName) {
 | 
			
		||||
				const int nLexers = fnLexerCount();
 | 
			
		||||
				for (int i = 0; i < nLexers; i++) {
 | 
			
		||||
					char name[100] = "";
 | 
			
		||||
					fnLexerName(i, name, sizeof(name));
 | 
			
		||||
					lexers.push_back(name);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			CreateLexerFn fnCL = FunctionPointer<CreateLexerFn>(
 | 
			
		||||
				FindSymbol(lexillaDL, LEXILLA_CREATELEXER));
 | 
			
		||||
			LexerNameFromIDFn fnLNFI = FunctionPointer<LexerNameFromIDFn>(
 | 
			
		||||
				FindSymbol(lexillaDL, LEXILLA_LEXERNAMEFROMID));
 | 
			
		||||
			GetLibraryPropertyNamesFn fnGLPN = FunctionPointer<GetLibraryPropertyNamesFn>(
 | 
			
		||||
				FindSymbol(lexillaDL, LEXILLA_GETLIBRARYPROPERTYNAMES));
 | 
			
		||||
			SetLibraryPropertyFn fnSLP = FunctionPointer<SetLibraryPropertyFn>(
 | 
			
		||||
				FindSymbol(lexillaDL, LEXILLA_SETLIBRARYPROPERTY));
 | 
			
		||||
			GetNameSpaceFn fnGNS = FunctionPointer<GetNameSpaceFn>(
 | 
			
		||||
				FindSymbol(lexillaDL, LEXILLA_GETNAMESPACE));
 | 
			
		||||
			std::string nameSpace;
 | 
			
		||||
			if (fnGNS) {
 | 
			
		||||
				nameSpace = fnGNS();
 | 
			
		||||
				nameSpace += LEXILLA_NAMESPACE_SEPARATOR;
 | 
			
		||||
			}
 | 
			
		||||
			LexLibrary lexLib {
 | 
			
		||||
				fnCL,
 | 
			
		||||
				fnLNFI,
 | 
			
		||||
				fnGLPN,
 | 
			
		||||
				fnSLP,
 | 
			
		||||
				nameSpace
 | 
			
		||||
			};
 | 
			
		||||
			libraries.push_back(lexLib);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	lastLoaded = sharedLibraryPaths;
 | 
			
		||||
 | 
			
		||||
	std::set<std::string> nameSet;
 | 
			
		||||
	for (const LexLibrary &lexLib : libraries) {
 | 
			
		||||
		if (lexLib.fnGLPN) {
 | 
			
		||||
			const char *cpNames = lexLib.fnGLPN();
 | 
			
		||||
			if (cpNames) {
 | 
			
		||||
				std::string_view names = cpNames;
 | 
			
		||||
				while (!names.empty()) {
 | 
			
		||||
					const size_t separator = names.find_first_of('\n');
 | 
			
		||||
					std::string name(names.substr(0, separator));
 | 
			
		||||
					nameSet.insert(name);
 | 
			
		||||
					if (separator == std::string::npos) {
 | 
			
		||||
						names.remove_prefix(names.size());
 | 
			
		||||
					} else {
 | 
			
		||||
						names.remove_prefix(separator + 1);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Standard Lexilla does not have any properties so can't be added to set.
 | 
			
		||||
	libraryProperties = std::vector<std::string>(nameSet.begin(), nameSet.end());
 | 
			
		||||
 | 
			
		||||
	return !libraries.empty();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Scintilla::ILexer5 *Lexilla::MakeLexer(std::string_view languageName) {
 | 
			
		||||
	std::string sLanguageName(languageName);	// Ensure NUL-termination
 | 
			
		||||
	// First, try to match namespace then name suffix
 | 
			
		||||
	for (const LexLibrary &lexLib : libraries) {
 | 
			
		||||
		if (lexLib.fnCL && !lexLib.nameSpace.empty()) {
 | 
			
		||||
			if (HasPrefix(languageName, lexLib.nameSpace)) {
 | 
			
		||||
				Scintilla::ILexer5 *pLexer = lexLib.fnCL(sLanguageName.substr(lexLib.nameSpace.size()).c_str());
 | 
			
		||||
				if (pLexer) {
 | 
			
		||||
					return pLexer;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// If no match with namespace, try to just match name
 | 
			
		||||
	for (const LexLibrary &lexLib : libraries) {
 | 
			
		||||
		if (lexLib.fnCL) {
 | 
			
		||||
			Scintilla::ILexer5 *pLexer = lexLib.fnCL(sLanguageName.c_str());
 | 
			
		||||
			if (pLexer) {
 | 
			
		||||
				return pLexer;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (pCreateLexerDefault) {
 | 
			
		||||
		return pCreateLexerDefault(sLanguageName.c_str());
 | 
			
		||||
	}
 | 
			
		||||
#if defined(LEXILLA_STATIC)
 | 
			
		||||
	Scintilla::ILexer5 *pLexer = CreateLexer(sLanguageName.c_str());
 | 
			
		||||
	if (pLexer) {
 | 
			
		||||
		return pLexer;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> Lexilla::Lexers() {
 | 
			
		||||
	return lexers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Lexilla::NameFromID(int identifier) {
 | 
			
		||||
	for (const LexLibrary &lexLib : libraries) {
 | 
			
		||||
		if (lexLib.fnLNFI) {
 | 
			
		||||
			const char *name = lexLib.fnLNFI(identifier);
 | 
			
		||||
			if (name) {
 | 
			
		||||
				return name;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return std::string();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> Lexilla::LibraryProperties() {
 | 
			
		||||
	return libraryProperties;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Lexilla::SetProperty(const char *key, const char *value) {
 | 
			
		||||
	for (const LexLibrary &lexLib : libraries) {
 | 
			
		||||
		if (lexLib.fnSLP) {
 | 
			
		||||
			lexLib.fnSLP(key, value);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Standard Lexilla does not have any properties so don't set.
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								3rdparty/lexilla540/lexilla/access/LexillaAccess.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								3rdparty/lexilla540/lexilla/access/LexillaAccess.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
// SciTE - Scintilla based Text Editor
 | 
			
		||||
/** @file LexillaAccess.h
 | 
			
		||||
 ** Interface to loadable lexers.
 | 
			
		||||
 ** This does not depend on SciTE code so can be copied out into other projects.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2019 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
#ifndef LEXILLAACCESS_H
 | 
			
		||||
#define LEXILLAACCESS_H
 | 
			
		||||
 | 
			
		||||
namespace Lexilla {
 | 
			
		||||
 | 
			
		||||
// Directory to load default Lexilla from, commonly the directory of the application.
 | 
			
		||||
void SetDefaultDirectory(std::string_view directory);
 | 
			
		||||
 | 
			
		||||
// Specify CreateLexer when statically linked so no hard dependency in LexillaAccess
 | 
			
		||||
// so it doesn't have to be built in two forms - static and dynamic.
 | 
			
		||||
void SetDefault(CreateLexerFn pCreate) noexcept;
 | 
			
		||||
 | 
			
		||||
// sharedLibraryPaths is a ';' separated list of shared libraries to load.
 | 
			
		||||
// On Win32 it is treated as UTF-8 and on Unix it is passed to dlopen directly.
 | 
			
		||||
// Return true if any shared libraries are loaded.
 | 
			
		||||
bool Load(std::string_view sharedLibraryPaths);
 | 
			
		||||
 | 
			
		||||
Scintilla::ILexer5 *MakeLexer(std::string_view languageName);
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> Lexers();
 | 
			
		||||
[[deprecated]] std::string NameFromID(int identifier);
 | 
			
		||||
std::vector<std::string> LibraryProperties();
 | 
			
		||||
void SetProperty(const char *key, const char *value);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										9
									
								
								3rdparty/lexilla540/lexilla/access/README
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								3rdparty/lexilla540/lexilla/access/README
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
README for access directory.
 | 
			
		||||
 | 
			
		||||
LexillaAccess is a module that simplifies using multiple libraries that follow the Lexilla protocol.
 | 
			
		||||
 | 
			
		||||
It can be compiled into a Lexilla client application.
 | 
			
		||||
 | 
			
		||||
Applications with complex needs can copy the code and customise it to meet their requirements.
 | 
			
		||||
 | 
			
		||||
This module is not meant to be compiled into Lexilla.
 | 
			
		||||
							
								
								
									
										1
									
								
								3rdparty/lexilla540/lexilla/bin/empty.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								3rdparty/lexilla540/lexilla/bin/empty.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
This empty files ensures that the directory is created.
 | 
			
		||||
							
								
								
									
										215
									
								
								3rdparty/lexilla540/lexilla/cppcheck.suppress
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								3rdparty/lexilla540/lexilla/cppcheck.suppress
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,215 @@
 | 
			
		||||
// File to suppress cppcheck warnings for files that will not be fixed.
 | 
			
		||||
// Does not suppress warnings where an additional occurrence of the warning may be of interest.
 | 
			
		||||
// Configured for cppcheck 2.12
 | 
			
		||||
 | 
			
		||||
// Coding style is to use assignments in constructor when there are many
 | 
			
		||||
// members to initialize or the initialization is complex or has comments.
 | 
			
		||||
useInitializationList
 | 
			
		||||
 | 
			
		||||
// These may be interesting but its not clear without examining each instance closely
 | 
			
		||||
// Would have to ensure that any_of/all_of has same early/late exits as current code and
 | 
			
		||||
// produces same result on empty collections
 | 
			
		||||
useStlAlgorithm
 | 
			
		||||
 | 
			
		||||
// Common for lexer object destructors
 | 
			
		||||
missingOverride
 | 
			
		||||
 | 
			
		||||
// Some non-explicit constructors are used for conversions or are private to lexers
 | 
			
		||||
noExplicitConstructor
 | 
			
		||||
 | 
			
		||||
// The performance cost of by-value passing is often small and using a reference decreases
 | 
			
		||||
// code legibility.
 | 
			
		||||
passedByValue
 | 
			
		||||
 | 
			
		||||
// cppcheck 2.11 can't find system headers on Win32.
 | 
			
		||||
missingIncludeSystem
 | 
			
		||||
 | 
			
		||||
// Passing temporary string into hidden object creator functions: they do not hold the argument
 | 
			
		||||
danglingTemporaryLifetime:lexilla/access/LexillaAccess.cxx
 | 
			
		||||
returnDanglingLifetime:lexilla/access/LexillaAccess.cxx
 | 
			
		||||
 | 
			
		||||
// cppcheck seems to believe that unique_ptr<char *[]>::get returns void* instead of char**
 | 
			
		||||
arithOperationsOnVoidPointer:lexilla/lexlib/WordList.cxx
 | 
			
		||||
 | 
			
		||||
// cppcheck 2.11 limits checking of complex functions unless --check-level=exhaustive but that
 | 
			
		||||
// only finds one false issue in LexRuby
 | 
			
		||||
checkLevelNormal:lexilla/lexers/LexBash.cxx
 | 
			
		||||
checkLevelNormal:lexilla/lexers/LexCPP.cxx
 | 
			
		||||
checkLevelNormal:lexilla/lexers/LexHTML.cxx
 | 
			
		||||
checkLevelNormal:lexilla/lexers/LexPerl.cxx
 | 
			
		||||
checkLevelNormal:lexilla/lexers/LexRuby.cxx
 | 
			
		||||
 | 
			
		||||
// Physically but not logically const.
 | 
			
		||||
constVariablePointer:lexilla/examples/CheckLexilla/CheckLexilla.c
 | 
			
		||||
 | 
			
		||||
// Suppress most lexer warnings since the lexers are maintained by others
 | 
			
		||||
redundantCondition:lexilla/lexers/LexA68k.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexAbaqus.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexAda.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexAsciidoc.cxx
 | 
			
		||||
constParameterCallback:lexilla/lexers/LexAsn1.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexAU3.cxx
 | 
			
		||||
shadowVariable:lexilla/lexers/LexAU3.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexBaan.cxx
 | 
			
		||||
unreadVariable:lexilla/lexers/LexBaan.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexBaan.cxx
 | 
			
		||||
constParameterPointer:lexilla/lexers/LexBaan.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexBash.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexBash.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexBash.cxx
 | 
			
		||||
constVariable:lexilla/lexers/LexBasic.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexCLW.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexCLW.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexCmake.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexCmake.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexCmake.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexCOBOL.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexCoffeeScript.cxx
 | 
			
		||||
constParameterPointer:lexilla/lexers/LexCoffeeScript.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexCoffeeScript.cxx
 | 
			
		||||
constVariableReference:lexilla/lexers/LexConf.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexCPP.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexCSS.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexDataflex.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexDataflex.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexDataflex.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexECL.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexECL.cxx
 | 
			
		||||
constParameter:lexilla/lexers/LexEDIFACT.cxx
 | 
			
		||||
constParameterPointer:lexilla/lexers/LexEDIFACT.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexEiffel.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexErlang.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexEScript.cxx
 | 
			
		||||
constParameter:lexilla/lexers/LexFortran.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexFortran.cxx
 | 
			
		||||
redundantContinue:lexilla/lexers/LexFortran.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexFSharp.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexGAP.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexGDScript.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexGui4Cli.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexHaskell.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexHex.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexHex.cxx
 | 
			
		||||
constVariable:lexilla/lexers/LexHollywood.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexInno.cxx
 | 
			
		||||
constVariableReference:lexilla/lexers/LexInno.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexJSON.cxx
 | 
			
		||||
constParameterPointer:lexilla/lexers/LexJulia.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexJulia.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexJulia.cxx
 | 
			
		||||
unreadVariable:lexilla/lexers/LexJulia.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexJulia.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexLaTeX.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexLaTeX.cxx
 | 
			
		||||
constParameterPointer:lexilla/lexers/LexMagik.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexMagik.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexMarkdown.cxx
 | 
			
		||||
constParameterPointer:lexilla/lexers/LexMatlab.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexMatlab.cxx
 | 
			
		||||
unreadVariable:lexilla/lexers/LexMatlab.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexMatlab.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexMetapost.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexModula.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexModula.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexMPT.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexMSSQL.cxx
 | 
			
		||||
shadowArgument:lexilla/lexers/LexMySQL.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexNim.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexNimrod.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexNimrod.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexNimrod.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexNsis.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexNsis.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexNsis.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexOpal.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexOpal.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexOpal.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexOScript.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexPascal.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexPB.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexPerl.cxx
 | 
			
		||||
constVariableReference:lexilla/lexers/LexPerl.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexPerl.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexPLM.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexPO.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexPython.cxx
 | 
			
		||||
shadowVariable:lexilla/lexers/LexPowerPro.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexPowerPro.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexProgress.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexProgress.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexRaku.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexRaku.cxx
 | 
			
		||||
redundantInitialization:lexilla/lexers/LexRegistry.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexRuby.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexRust.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexScriptol.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexSpecman.cxx
 | 
			
		||||
unreadVariable:lexilla/lexers/LexSpice.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexSpice.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexSTTXT.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexTACL.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexTACL.cxx
 | 
			
		||||
clarifyCalculation:lexilla/lexers/LexTADS3.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexTADS3.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexTAL.cxx
 | 
			
		||||
constVariableReference:lexilla/lexers/LexTCL.cxx
 | 
			
		||||
invalidscanf:lexilla/lexers/LexTCMD.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexTeX.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexTeX.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexVB.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexVerilog.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexVerilog.cxx
 | 
			
		||||
badBitmaskCheck:lexilla/lexers/LexVerilog.cxx
 | 
			
		||||
uselessCallsSubstr:lexilla/lexers/LexVerilog.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexVHDL.cxx
 | 
			
		||||
constVariable:lexilla/lexers/LexVHDL.cxx
 | 
			
		||||
shadowVariable:lexilla/lexers/LexVHDL.cxx
 | 
			
		||||
unreadVariable:lexilla/lexers/LexVHDL.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexVHDL.cxx
 | 
			
		||||
unreadVariable:lexilla/lexers/LexVisualProlog.cxx
 | 
			
		||||
variableScope:lexilla/lexers/LexVisualProlog.cxx
 | 
			
		||||
shiftTooManyBitsSigned:lexilla/lexers/LexVisualProlog.cxx
 | 
			
		||||
iterateByValue:lexilla/lexers/LexVisualProlog.cxx
 | 
			
		||||
unreadVariable:lexilla/lexers/LexX12.cxx
 | 
			
		||||
constVariableReference:lexilla/lexers/LexX12.cxx
 | 
			
		||||
constParameterPointer:lexilla/lexers/LexX12.cxx
 | 
			
		||||
uselessCallsSubstr:lexilla/lexers/LexX12.cxx
 | 
			
		||||
constParameterReference:lexilla/lexers/LexYAML.cxx
 | 
			
		||||
constParameterPointer:lexilla/lexers/LexYAML.cxx
 | 
			
		||||
knownConditionTrueFalse:lexilla/lexers/LexYAML.cxx
 | 
			
		||||
 | 
			
		||||
// These are due to Accessor::IndentAmount not declaring the callback as taking a const.
 | 
			
		||||
// Changing this could cause problems for downstream projects.
 | 
			
		||||
constParameterCallback:lexilla/lexers/LexEiffel.cxx
 | 
			
		||||
constParameterCallback:lexilla/lexers/LexGDScript.cxx
 | 
			
		||||
constParameterCallback:lexilla/lexers/LexPython.cxx
 | 
			
		||||
constParameterCallback:lexilla/lexers/LexScriptol.cxx
 | 
			
		||||
constParameterCallback:lexilla/lexers/LexVB.cxx
 | 
			
		||||
 | 
			
		||||
constVariableReference:lexilla/lexers/LexBibTeX.cxx
 | 
			
		||||
constVariableReference:lexilla/lexers/LexCSS.cxx
 | 
			
		||||
constVariableReference:lexilla/lexers/LexCrontab.cxx
 | 
			
		||||
constVariableReference:lexilla/lexers/LexGui4Cli.cxx
 | 
			
		||||
constVariableReference:lexilla/lexers/LexMetapost.cxx
 | 
			
		||||
constVariableReference:lexilla/lexers/LexOpal.cxx
 | 
			
		||||
 | 
			
		||||
// Suppress everything in test example files
 | 
			
		||||
*:lexilla/test/examples/*
 | 
			
		||||
 | 
			
		||||
// Suppress everything in catch.hpp as won't be changing
 | 
			
		||||
*:lexilla/test/unit/catch.hpp
 | 
			
		||||
// cppcheck gives up inside catch.hpp
 | 
			
		||||
*:lexilla/test/unit/UnitTester.cxx
 | 
			
		||||
*:lexilla/test/unit/unitTest.cxx
 | 
			
		||||
 | 
			
		||||
// Tests often test things that are always true
 | 
			
		||||
knownConditionTrueFalse:lexilla/test/unit/testCharacterSet.cxx
 | 
			
		||||
 | 
			
		||||
// cppcheck fails REQUIRE from Catch
 | 
			
		||||
comparisonOfFuncReturningBoolError:lexilla/test/unit/*.cxx
 | 
			
		||||
 | 
			
		||||
// cppcheck fails SECTION from Catch
 | 
			
		||||
syntaxError:lexilla/test/unit/*.cxx
 | 
			
		||||
 | 
			
		||||
// argv has a standardised type
 | 
			
		||||
constParameter:lexilla/examples/CheckLexilla/CheckLexilla.c
 | 
			
		||||
							
								
								
									
										1
									
								
								3rdparty/lexilla540/lexilla/delbin.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								3rdparty/lexilla540/lexilla/delbin.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
@del /S /Q *.a *.aps *.bsc *.dll *.dsw *.exe *.idb *.ilc *.ild *.ilf *.ilk *.ils *.lib *.map *.ncb *.obj *.o *.opt *.ipdb *.pdb *.plg *.res *.sbr *.tds *.exp *.tlog *.lastbuildstate >NUL:
 | 
			
		||||
							
								
								
									
										161
									
								
								3rdparty/lexilla540/lexilla/doc/Lexilla.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								3rdparty/lexilla540/lexilla/doc/Lexilla.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,161 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 | 
			
		||||
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 | 
			
		||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta name="generator" content="HTML Tidy, see www.w3.org" />
 | 
			
		||||
    <meta name="generator" content="SciTE" />
 | 
			
		||||
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
 | 
			
		||||
    <meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
 | 
			
		||||
    <meta name="Description"
 | 
			
		||||
    content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
 | 
			
		||||
    <meta name="Date.Modified" content="20240821" />
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1" />
 | 
			
		||||
    <style type="text/css">
 | 
			
		||||
        .logo {
 | 
			
		||||
            background: url(https://www.scintilla.org/LexillaLogo.png) no-repeat;
 | 
			
		||||
            background-image: image-set(
 | 
			
		||||
                        url(https://www.scintilla.org/LexillaLogo.png) 1x,
 | 
			
		||||
                        url(https://www.scintilla.org/LexillaLogo2x.png) 2x  );
 | 
			
		||||
            height:150px;
 | 
			
		||||
        }
 | 
			
		||||
        #versionlist {
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: .5em;
 | 
			
		||||
            list-style-type: none;
 | 
			
		||||
            color: #FFCC99;
 | 
			
		||||
            background: #000000;
 | 
			
		||||
        }
 | 
			
		||||
        #versionlist li {
 | 
			
		||||
            margin-bottom: .5em;
 | 
			
		||||
        }
 | 
			
		||||
        #menu {
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: .5em 0;
 | 
			
		||||
            list-style-type: none;
 | 
			
		||||
            font-size: larger;
 | 
			
		||||
            background: #CCCCCC;
 | 
			
		||||
        }
 | 
			
		||||
        #menu li {
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: 0 .5em;
 | 
			
		||||
            display: inline;
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
    <script type="text/javascript">
 | 
			
		||||
   	function IsRemote() {
 | 
			
		||||
		var loc = '' + window.location;
 | 
			
		||||
		return (loc.indexOf('http:')) != -1 || (loc.indexOf('https:') != -1);
 | 
			
		||||
   	}
 | 
			
		||||
    </script>
 | 
			
		||||
     <title>
 | 
			
		||||
       Lexilla
 | 
			
		||||
     </title>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
    <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0">
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td width="256">
 | 
			
		||||
        </td>
 | 
			
		||||
        <td width="40%" align="left">
 | 
			
		||||
          <font color="#FFCC99" size="4"> A library of language lexers for use with Scintilla</font>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td width="40%" align="right">
 | 
			
		||||
          <font color="#FFCC99" size="3">Release version 5.4.0<br />
 | 
			
		||||
           Site last modified August 21 2024</font>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td width="20%">
 | 
			
		||||
           
 | 
			
		||||
        </td>
 | 
			
		||||
      </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
    <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0">
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td width="100%" class="logo">
 | 
			
		||||
           
 | 
			
		||||
        </td>
 | 
			
		||||
      </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
    <ul id="versionlist">
 | 
			
		||||
      <li>Version 5.4.0 adds a TOML lexer.</li>
 | 
			
		||||
      <li>Version 5.3.3 improves HTML, JavaScript, Lua, PHP, and XML.</li>
 | 
			
		||||
      <li>Version 5.3.2 improves COBOL, HTML, Lua, Ruby, and Rust.</li>
 | 
			
		||||
      <li>Version 5.3.1 improves Assembler, Bash, Batch, JavaScript, Python, and Ruby.</li>
 | 
			
		||||
      <li>Version 5.3.0 improves Bash, HTML, and Lua.</li>
 | 
			
		||||
    </ul>
 | 
			
		||||
    <ul id="menu">
 | 
			
		||||
      <li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>
 | 
			
		||||
      <li id="remote2"><a href="https://www.scintilla.org/LexillaDownload.html">Download</a></li>
 | 
			
		||||
      <li><a href="https://www.scintilla.org/LexillaDoc.html">Documentation</a></li>
 | 
			
		||||
      <li><a href="https://github.com/ScintillaOrg/lexilla/issues">Bugs</a></li>
 | 
			
		||||
      <li id="remote3"><a href="https://www.scintilla.org/SciTE.html">SciTE</a></li>
 | 
			
		||||
      <li><a href="https://www.scintilla.org/LexillaHistory.html">History</a></li>
 | 
			
		||||
      <li><a href="https://www.scintilla.org/ScintillaRelated.html">Related</a></li>
 | 
			
		||||
      <li id="remote4"><a href="https://www.scintilla.org/Privacy.html">Privacy</a></li>
 | 
			
		||||
    </ul>
 | 
			
		||||
<script type="text/javascript" language="JavaScript"><!--
 | 
			
		||||
if (!IsRemote()) { //if NOT remote...
 | 
			
		||||
    document.getElementById('remote1').style.display='none';
 | 
			
		||||
    document.getElementById('remote2').style.display='none';
 | 
			
		||||
    document.getElementById('remote3').style.display='none';
 | 
			
		||||
    document.getElementById('remote4').style.display='none';
 | 
			
		||||
}
 | 
			
		||||
//--></script>
 | 
			
		||||
    <p>
 | 
			
		||||
       <a href="https://www.scintilla.org/LexillaDoc.html">Lexilla</a> is a free library of language
 | 
			
		||||
       lexers that can be used with the <a href="https://www.scintilla.org/index.html">Scintilla</a>
 | 
			
		||||
       editing component.
 | 
			
		||||
       It comes with complete source code and a <a href="https://www.scintilla.org/License.txt">license</a> that
 | 
			
		||||
       permits use in any free project or commercial product.
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
       Originally, this functionality was incorporated inside Scintilla.
 | 
			
		||||
       It has been extracted as a separate project to make it easier for contributors to work on
 | 
			
		||||
       support for new languages and to fix bugs in existing lexers.
 | 
			
		||||
       It also defines a protocol where projects can implement their own lexers and distribute
 | 
			
		||||
       them as they wish.
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
       Current development requires a recent C++ compiler that supports C++17.
 | 
			
		||||
       The testing framework uses some C++20 features but the basic library only uses C++17.
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
       Lexilla is currently available for Intel Win32, macOS, and Linux compatible operating
 | 
			
		||||
      systems. It has been run on Windows 10, macOS 10.13+, and on Ubuntu 20.04 but is likely
 | 
			
		||||
      to run on earlier systems as it has no GUI functionality.
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
       You can <a href="https://www.scintilla.org/LexillaDownload.html">download Lexilla.</a>
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
       The source code can be downloaded via Git at GitHub
 | 
			
		||||
	<a href="https://github.com/ScintillaOrg/lexilla">Lexilla project page</a>.<br />
 | 
			
		||||
        git clone https://github.com/ScintillaOrg/lexilla
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>Current repository status:<br />
 | 
			
		||||
    <a href="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml"><img src="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml/badge.svg" /></a><br />
 | 
			
		||||
    <a href="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check-win32.yml"><img src="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check-win32.yml/badge.svg" /></a><br />
 | 
			
		||||
    <a href="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check-macos.yml"><img src="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check-macos.yml/badge.svg" /></a>
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
       <a href="https://www.scintilla.org/ScintillaRelated.html">Related sites.</a>
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
       <a href="https://github.com/ScintillaOrg/lexilla/issues">Bugs and other issues.</a>
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
       <a href="https://www.scintilla.org/LexillaHistory.html">History and contribution credits.</a>
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
      Questions and comments about Lexilla should be directed to the
 | 
			
		||||
      <a href="https://groups.google.com/forum/#!forum/scintilla-interest">scintilla-interest</a>
 | 
			
		||||
      mailing list,
 | 
			
		||||
      which is for discussion of Scintilla and related projects, their bugs and future features.
 | 
			
		||||
      This is a low traffic list, averaging less than 20 messages per week.
 | 
			
		||||
      To avoid spam, only list members can write to the list.
 | 
			
		||||
      New versions of Lexilla are announced on scintilla-interest.
 | 
			
		||||
      <br />
 | 
			
		||||
    </p>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										254
									
								
								3rdparty/lexilla540/lexilla/doc/LexillaDoc.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								3rdparty/lexilla540/lexilla/doc/LexillaDoc.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,254 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 | 
			
		||||
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 | 
			
		||||
 | 
			
		||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta name="generator"
 | 
			
		||||
    content="HTML Tidy for Windows (vers 1st August 2002), see www.w3.org" />
 | 
			
		||||
    <meta name="generator" content="SciTE" />
 | 
			
		||||
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
 | 
			
		||||
 | 
			
		||||
    <title>Lexilla Documentation</title>
 | 
			
		||||
 | 
			
		||||
    <style type="text/css">
 | 
			
		||||
<!--
 | 
			
		||||
/*<![CDATA[*/
 | 
			
		||||
	CODE { font-weight: bold; font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace; }
 | 
			
		||||
	A:visited { color: blue; }
 | 
			
		||||
	A:hover { text-decoration: underline ! important; }
 | 
			
		||||
	A.message { text-decoration: none; font-weight: bold; font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace; }
 | 
			
		||||
	A.seealso { text-decoration: none; font-weight: bold; font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace; }
 | 
			
		||||
	A.toc { text-decoration: none; }
 | 
			
		||||
	A.jump { text-decoration: none; }
 | 
			
		||||
	LI.message { text-decoration: none; font-weight: bold; font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace; }
 | 
			
		||||
	H2 { background: #E0EAFF; }
 | 
			
		||||
 | 
			
		||||
	table {
 | 
			
		||||
		border: 0px;
 | 
			
		||||
		border-collapse: collapse;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
        div.console {
 | 
			
		||||
            font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;
 | 
			
		||||
            color: #008000;
 | 
			
		||||
            font-weight: bold;
 | 
			
		||||
            background: #F7FCF7;
 | 
			
		||||
            border: 1px solid #C0D7C0;
 | 
			
		||||
            margin: 0.3em 3em;
 | 
			
		||||
            padding: 0.3em 0.6em;
 | 
			
		||||
        }
 | 
			
		||||
        span.console {
 | 
			
		||||
            font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;
 | 
			
		||||
            color: #008000;
 | 
			
		||||
            font-weight: bold;
 | 
			
		||||
            background: #F7FCF7;
 | 
			
		||||
            border: 1px solid #C0D7C0;
 | 
			
		||||
            margin: 0.1em 0em;
 | 
			
		||||
            padding: 0.1em 0.3em;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .name {
 | 
			
		||||
		color: #B08000;
 | 
			
		||||
        }
 | 
			
		||||
/*]]>*/
 | 
			
		||||
-->
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
 | 
			
		||||
  <body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
    <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"
 | 
			
		||||
    summary="Banner">
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><img src="SciTEIco.png" border="3" height="64" width="64" alt="Lexilla icon" /></td>
 | 
			
		||||
 | 
			
		||||
        <td><a href="index.html"
 | 
			
		||||
        style="color:white;text-decoration:none;font-size:200%">Lexilla</a></td>
 | 
			
		||||
      </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h1>Lexilla Documentation</h1>
 | 
			
		||||
 | 
			
		||||
    <p>Last edited 21 April 2021 NH</p>
 | 
			
		||||
 | 
			
		||||
    <h2>Introduction</h2>
 | 
			
		||||
 | 
			
		||||
    <p>Lexilla is a library containing lexers for use with Scintilla. It can be either a static library
 | 
			
		||||
    that is linked into an application or a shared library that is loaded at runtime.</p>
 | 
			
		||||
 | 
			
		||||
    <p>Lexilla does not interact with the display so there is no need to compile it for a
 | 
			
		||||
    particular GUI toolkit. Therefore there can be a common library shared by applications using
 | 
			
		||||
    different GUI toolkits. In some circumstances there may need to be both 32-bit and 64-bit versions
 | 
			
		||||
    on one system to match different applications.</p>
 | 
			
		||||
 | 
			
		||||
    <p>Different extensions are commonly used for shared libraries: .so on Linux, .dylib on macOS, and .DLL on Windows.
 | 
			
		||||
     </p>
 | 
			
		||||
 | 
			
		||||
    <h2>The Lexilla protocol</h2>
 | 
			
		||||
 | 
			
		||||
    <p>A set of functions is defined by Lexilla for use by applications. Libraries that provide these functions
 | 
			
		||||
    can be used as a replacement for Lexilla or to add new lexers beyond those provided by Lexilla.</p>
 | 
			
		||||
 | 
			
		||||
    <p>The Lexilla protocol is a superset of the external lexer protocol and defines these functions that may be exported from a shared library:<br />
 | 
			
		||||
    <code>int <span class="name">GetLexerCount</span>()</code><br />
 | 
			
		||||
    <code>void <span class="name">GetLexerName</span>(unsigned int index, char *name, int buflength)</code><br />
 | 
			
		||||
    <code>LexerFactoryFunction <span class="name">GetLexerFactory</span>(unsigned int index)</code><br />
 | 
			
		||||
    <code>ILexer5 *<span class="name">CreateLexer</span>(const char *name)</code><br />
 | 
			
		||||
    <code>const char *<span class="name">LexerNameFromID</span>(int identifier)</code><br />
 | 
			
		||||
    <code>const char *<span class="name">GetLibraryPropertyNames</span>()</code><br />
 | 
			
		||||
    <code>void <span class="name">SetLibraryProperty</span>(const char *key, const char *value)</code><br />
 | 
			
		||||
    <code>const char *<span class="name">GetNameSpace</span>()</code>
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p><span class="name">ILexer5</span> is defined by Scintilla in include/ILexer.h as the interface provided by lexers which is called by Scintilla.
 | 
			
		||||
    Many clients do not actually need to call methods on <span class="name">ILexer5</span> - they just take the return from CreateLexer and plug it
 | 
			
		||||
    straight into Scintilla so it can be treated as a machine pointer (void *).
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p><span class="name">LexerFactoryFunction</span> is defined as a function that takes no arguments and returns an <span class="name">ILexer5</span> *:
 | 
			
		||||
    <code>ILexer5 *(*LexerFactoryFunction)()</code> but this can be ignored by most client code.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p>The Lexilla protocol is a superset of the earlier external lexer protocol that defined the first 3 functions
 | 
			
		||||
    (<span class="name">GetLexerCount</span>, <span class="name">GetLexerName</span>, <span class="name">GetLexerFactory</span>)
 | 
			
		||||
    so Lexilla can be loaded by applications that support that protocol.
 | 
			
		||||
    <span class="name">GetLexerFactory</span> will rarely be used now as it is easier to call <span class="name">CreateLexer</span>.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p><span class="name">CreateLexer</span> is the main call that will create a lexer for a particular language. The returned lexer can then be
 | 
			
		||||
    set as the current lexer in Scintilla by calling
 | 
			
		||||
    <a class="seealso" href="ScintillaDoc.html#SCI_SETILEXER">SCI_SETILEXER</a>.</p>
 | 
			
		||||
 | 
			
		||||
    <p><span class="name">LexerNameFromID</span> is an optional function that returns the name for a lexer identifier.
 | 
			
		||||
    <code>LexerNameFromID(SCLEX_CPP) → "cpp"</code>.
 | 
			
		||||
    This is a temporary affordance to make it easier to convert applications to using Lexilla.
 | 
			
		||||
    Applications should move to using lexer names instead of IDs.
 | 
			
		||||
    This function is deprecated, showing warnings with some compilers, and will be removed in a future version of Lexilla.</p>
 | 
			
		||||
 | 
			
		||||
    <p><span class="name">SetLibraryProperty</span> and <span class="name">GetLibraryPropertyNames</span>
 | 
			
		||||
    are optional functions that can be
 | 
			
		||||
    defined if a library requires initialisation before calling other methods.
 | 
			
		||||
    For example, a lexer library that reads language definitions from XML files may require that the
 | 
			
		||||
    directory containing these files be set before a call to CreateLexer.
 | 
			
		||||
    <code>SetLibraryProperty("definitions.directory", "/usr/share/xeditor/language-definitions")</code>
 | 
			
		||||
    If a library implements SetLibraryProperty then it may also provide a set of valid property names with
 | 
			
		||||
    GetLibraryPropertyNames that can then be used by the application to define configuration file property
 | 
			
		||||
    names or user interface elements for options dialogs.</p>
 | 
			
		||||
 | 
			
		||||
    <p><span class="name">GetNameSpace</span> is an optional function that returns a namespace string
 | 
			
		||||
    that can be used to disambiguate lexers with the same name from different providers.
 | 
			
		||||
    If Lexilla and XMLLexers both provide a "cpp" lexer than a request for "cpp" may be satisfied by either but "xmllexers.cpp"
 | 
			
		||||
    unambiguously refers to the "cpp" lexer from XMLLexers.</p>
 | 
			
		||||
 | 
			
		||||
    <h2>Building Lexilla</h2>
 | 
			
		||||
 | 
			
		||||
    <p>Before using Lexilla it must be built or downloaded.</p>
 | 
			
		||||
    <p>Lexilla requires some headers from Scintilla to build and expects a directory named
 | 
			
		||||
    "scintilla" containing a copy of Scintilla 5+ to be a peer of the Lexilla top level
 | 
			
		||||
    directory conventionally called "lexilla".</p>
 | 
			
		||||
 | 
			
		||||
    <div>To build Lexilla, in the lexilla/src directory, run make (for gcc or clang)</div>
 | 
			
		||||
    <div class="console">make</div>
 | 
			
		||||
    <div>or nmake for MSVC</div>
 | 
			
		||||
    <div class="console">nmake -f lexilla.mak</div>
 | 
			
		||||
    <br />
 | 
			
		||||
 | 
			
		||||
    <div>After building Lexilla, its test suite can be run with make/nmake in the lexilla/test directory. For gcc or clang</div>
 | 
			
		||||
    <div class="console">make test</div>
 | 
			
		||||
    or for MSVC<br />
 | 
			
		||||
    <div class="console">nmake -f testlexers.mak test</div>
 | 
			
		||||
    <div>Each test case should show "<code>Lexing ...</code>" and errors will display a diagnostic, commonly showing
 | 
			
		||||
    a difference between the actual and expected result:<br>
 | 
			
		||||
    <code>C:\u\hg\lexilla\test\examples\python\x.py:1: is different</code>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <p>There are also RunTest.sh / RunTest.bat scripts in the scripts directory to build Lexilla and then build and run the tests.
 | 
			
		||||
    These both use gcc/clang, not MSVC.</p>
 | 
			
		||||
 | 
			
		||||
    <p>There are Microsoft Visual C++ and Xcode projects that can be used to build Lexilla.
 | 
			
		||||
    For Visual C++: src/Lexilla.vcxproj. For Xcode: src/Lexilla/Lexilla.xcodeproj.
 | 
			
		||||
    There is also test/TestLexers.vcxproj to build the tests with Visual C++.</p>
 | 
			
		||||
 | 
			
		||||
    <h2>Using Lexilla</h2>
 | 
			
		||||
 | 
			
		||||
    <p>Definitions for using Lexilla from C and C++ are included in lexilla/include/Lexilla.h.
 | 
			
		||||
    For C++, scintilla/include/ILexer.h should be included before Lexilla.h as the
 | 
			
		||||
    <code>ILexer5</code> type is used.
 | 
			
		||||
    For C, ILexer.h should not be included as C does not understand it and from C,
 | 
			
		||||
    <code>void*</code> is used instead of <code>ILexer5*</code>.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p>For many applications the main Lexilla operations are loading the Lexilla library, creating a
 | 
			
		||||
    lexer and using that lexer in Scintilla.
 | 
			
		||||
    Applications need to define the location (or locations) they expect
 | 
			
		||||
    to find Lexilla or libraries that support the Lexilla protocol.
 | 
			
		||||
    They also need to define how they request particular lexers, perhaps with a mapping from
 | 
			
		||||
    file extensions to lexer names.</p>
 | 
			
		||||
 | 
			
		||||
    <h3 id="CheckLexilla">From C - CheckLexilla</h3>
 | 
			
		||||
 | 
			
		||||
    <p>An example C program for accessing Lexilla is provided in lexilla/examples/CheckLexilla.
 | 
			
		||||
    Build with <span class="console">make</span> and run with <span class="console">make check</span>.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h3>From C++ - LexillaAccess</h3>
 | 
			
		||||
 | 
			
		||||
    <p>A C++ module, LexillaAccess.cxx / LexillaAccess.h is provided in lexilla/access.
 | 
			
		||||
    This can either be compiled into the application when it is sufficient
 | 
			
		||||
    or the source code can be copied into the application and customized when the application has additional requirements
 | 
			
		||||
    (such as checking code signatures).
 | 
			
		||||
    SciTE uses LexillaAccess.</p>
 | 
			
		||||
 | 
			
		||||
    <p>LexillaAccess supports loading multiple shared libraries implementing the Lexilla protocol at one time.</p>
 | 
			
		||||
 | 
			
		||||
    <h3>From Qt</h3>
 | 
			
		||||
 | 
			
		||||
    <p>For Qt, use either LexillaAccess from above or Qt's QLibrary class. With 'Call' defined to call Scintilla APIs.<br />
 | 
			
		||||
    <code>
 | 
			
		||||
#if _WIN32<br />
 | 
			
		||||
    typedef void *(__stdcall *CreateLexerFn)(const char *name);<br />
 | 
			
		||||
#else<br />
 | 
			
		||||
    typedef void *(*CreateLexerFn)(const char *name);<br />
 | 
			
		||||
#endif<br />
 | 
			
		||||
    QFunctionPointer fn = QLibrary::resolve("lexilla", "CreateLexer");<br />
 | 
			
		||||
    void *lexCpp = ((CreateLexerFn)fn)("cpp");<br />
 | 
			
		||||
    Call(SCI_SETILEXER, 0, (sptr_t)(void *)lexCpp);<br />
 | 
			
		||||
    </code></p>
 | 
			
		||||
 | 
			
		||||
    <p>Applications may discover the set of lexers provided by a library by first calling
 | 
			
		||||
    <span class="name">GetLexerCount</span> to find the number of lexers implemented in the library then looping over calling
 | 
			
		||||
    <span class="name">GetLexerName</span> with integers 0 to <code>GetLexerCount()-1</code>.</p>
 | 
			
		||||
 | 
			
		||||
    <p>Applications may set properties on a library by calling <span class="name">SetLibraryProperty</span> if provided.
 | 
			
		||||
    This may be needed for initialisation so should before calling <span class="name">GetLexerCount</span> or <span class="name">CreateLexer</span>.
 | 
			
		||||
    A set of property names may be available from <span class="name">GetLibraryPropertyNames</span> if provided.
 | 
			
		||||
    It returns a string pointer where the string contains a list of property names separated by '\n'.
 | 
			
		||||
    It is up to applications to define how properties are defined and persisted in its user interface
 | 
			
		||||
    and configuration files.</p>
 | 
			
		||||
 | 
			
		||||
    <h2>Modifying or adding lexers</h2>
 | 
			
		||||
 | 
			
		||||
    <p>Lexilla can be modified or a new library created that can be used to replace or augment Lexilla.</p>
 | 
			
		||||
 | 
			
		||||
    <p>Lexer libraries that provide the same functions as Lexilla may provide lexers for use by Scintilla,
 | 
			
		||||
    augmenting or replacing those provided by Lexilla.
 | 
			
		||||
    To allow initialisation of lexer libraries, a <code>SetLibraryProperty(const char *key, const char *value)</code>
 | 
			
		||||
    may optionally be implemented. For example, a lexer library that uses XML based lexer definitions may
 | 
			
		||||
    be provided with a directory to search for such definitions.
 | 
			
		||||
    Lexer libraries should ignore any properties that they do not understand.
 | 
			
		||||
    The set of properties supported by a lexer library is specified as a '\n' separated list of property names by
 | 
			
		||||
    an optional <code>const char *GetLibraryPropertyNames()</code> function.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p>Lexilla and its contained lexers can be tested with the TestLexers program in lexilla/test.
 | 
			
		||||
    Read lexilla/test/README for information on building and using TestLexers.</p>
 | 
			
		||||
 | 
			
		||||
    <p>An example of a simple lexer housed in a shared library that is compatible with the
 | 
			
		||||
    Lexilla protocol can be found in lexilla/examples/SimpleLexer. It is implemented in C++.
 | 
			
		||||
    Build with <span class="console">make</span> and check by running <a href="#CheckLexilla">CheckLexilla</a> against it with
 | 
			
		||||
    <span class="console">make check</span>.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										71
									
								
								3rdparty/lexilla540/lexilla/doc/LexillaDownload.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								3rdparty/lexilla540/lexilla/doc/LexillaDownload.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,71 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 | 
			
		||||
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 | 
			
		||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta name="generator" content="HTML Tidy, see www.w3.org" />
 | 
			
		||||
    <meta name="generator" content="SciTE" />
 | 
			
		||||
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1" />
 | 
			
		||||
    <title>
 | 
			
		||||
      Download Lexilla
 | 
			
		||||
    </title>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
    <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0">
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td>
 | 
			
		||||
          <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" />
 | 
			
		||||
        </td>
 | 
			
		||||
        <td>
 | 
			
		||||
          <a href="index.html" style="color:white;text-decoration:none"><font size="5">Download
 | 
			
		||||
          Lexilla</font></a>
 | 
			
		||||
        </td>
 | 
			
		||||
      </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
    <table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td>
 | 
			
		||||
          <font size="4"> <a href="https://www.scintilla.org/lexilla540.zip">
 | 
			
		||||
	Windows</a>  
 | 
			
		||||
	<a href="https://www.scintilla.org/lexilla540.tgz">
 | 
			
		||||
          GTK/Linux</a>  
 | 
			
		||||
	</font>
 | 
			
		||||
        </td>
 | 
			
		||||
      </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
    <h2>
 | 
			
		||||
       Download.
 | 
			
		||||
    </h2>
 | 
			
		||||
    <p>
 | 
			
		||||
       The <a href="License.txt">license</a> for using Lexilla is similar to that of Python
 | 
			
		||||
      containing very few restrictions.
 | 
			
		||||
    </p>
 | 
			
		||||
    <h3>
 | 
			
		||||
       Release 5.4.0
 | 
			
		||||
    </h3>
 | 
			
		||||
    <h4>
 | 
			
		||||
       Source Code
 | 
			
		||||
    </h4>
 | 
			
		||||
       The source code package contains all of the source code for Lexilla but no binary
 | 
			
		||||
	executable code and is available in
 | 
			
		||||
       <ul>
 | 
			
		||||
       <li><a href="https://www.scintilla.org/lexilla540.zip">zip format</a> (1.3M) commonly used on Windows</li>
 | 
			
		||||
       <li><a href="https://www.scintilla.org/lexilla540.tgz">tgz format</a> (0.9M) commonly used on Linux and compatible operating systems</li>
 | 
			
		||||
       </ul>
 | 
			
		||||
       Instructions for building on both Windows and Linux are included in the readme file.
 | 
			
		||||
    <h4>
 | 
			
		||||
       Windows Executable Code
 | 
			
		||||
    </h4>
 | 
			
		||||
       There is no download available containing only the Lexilla DLL.
 | 
			
		||||
       However, it is included in the <a href="SciTEDownload.html">SciTE
 | 
			
		||||
       executable full download</a> as Lexilla.DLL.
 | 
			
		||||
    <p>
 | 
			
		||||
       <a href="SciTEDownload.html">SciTE</a> is a good demonstration of Lexilla.
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
       Previous versions can be downloaded from the <a href="LexillaHistory.html">history
 | 
			
		||||
      page</a>.
 | 
			
		||||
    </p>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										14158
									
								
								3rdparty/lexilla540/lexilla/doc/LexillaHistory.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14158
									
								
								3rdparty/lexilla540/lexilla/doc/LexillaHistory.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								3rdparty/lexilla540/lexilla/doc/LexillaLogo.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								3rdparty/lexilla540/lexilla/doc/LexillaLogo.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 34 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								3rdparty/lexilla540/lexilla/doc/LexillaLogo2x.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								3rdparty/lexilla540/lexilla/doc/LexillaLogo2x.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 44 KiB  | 
							
								
								
									
										144
									
								
								3rdparty/lexilla540/lexilla/examples/CheckLexilla/CheckLexilla.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								3rdparty/lexilla540/lexilla/examples/CheckLexilla/CheckLexilla.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,144 @@
 | 
			
		||||
// Lexilla lexer library use example
 | 
			
		||||
/** @file CheckLexilla.c
 | 
			
		||||
 ** Check that Lexilla.h works.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2021 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// This file is in the public domain.
 | 
			
		||||
// If the public domain is not possible in your location then it can also be used under the same
 | 
			
		||||
// license as Scintilla. https://www.scintilla.org/License.txt
 | 
			
		||||
 | 
			
		||||
/* Build and run
 | 
			
		||||
 | 
			
		||||
    Win32
 | 
			
		||||
gcc CheckLexilla.c -I ../../include -o CheckLexilla
 | 
			
		||||
CheckLexilla
 | 
			
		||||
CheckLexilla ../SimpleLexer/SimpleLexer.dll
 | 
			
		||||
 | 
			
		||||
   Win32 Visual C++
 | 
			
		||||
cl CheckLexilla.c -I ../../include -Fe: CheckLexilla
 | 
			
		||||
CheckLexilla
 | 
			
		||||
CheckLexilla ../SimpleLexer/SimpleLexer.dll
 | 
			
		||||
 | 
			
		||||
    macOS
 | 
			
		||||
clang CheckLexilla.c -I ../../include -o CheckLexilla
 | 
			
		||||
./CheckLexilla
 | 
			
		||||
./CheckLexilla ../SimpleLexer/SimpleLexer.dylib
 | 
			
		||||
 | 
			
		||||
    Linux
 | 
			
		||||
gcc CheckLexilla.c -I ../../include -ldl -o CheckLexilla
 | 
			
		||||
./CheckLexilla
 | 
			
		||||
./CheckLexilla ../SimpleLexer/SimpleLexer.so
 | 
			
		||||
 | 
			
		||||
While principally meant for compilation as C to act as an example of using Lexilla
 | 
			
		||||
from C it can also be built as C++.
 | 
			
		||||
 | 
			
		||||
Warnings are intentionally shown for the deprecated typedef LexerNameFromIDFn when compiled with
 | 
			
		||||
GCC or Clang or as C++.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "Lexilla.h"
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
typedef FARPROC Function;
 | 
			
		||||
typedef HMODULE Module;
 | 
			
		||||
#else
 | 
			
		||||
typedef void *Function;
 | 
			
		||||
typedef void *Module;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static Function FindSymbol(Module m, const char *symbol) {
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
	return GetProcAddress(m, symbol);
 | 
			
		||||
#else
 | 
			
		||||
	return dlsym(m, symbol);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]) {
 | 
			
		||||
	char szLexillaPath[] = "../../bin/" LEXILLA_LIB LEXILLA_EXTENSION;
 | 
			
		||||
	const char *libPath = szLexillaPath;
 | 
			
		||||
	if (argc > 1) {
 | 
			
		||||
		libPath = argv[1];
 | 
			
		||||
	}
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
	Module lexillaLibrary = LoadLibraryA(libPath);
 | 
			
		||||
#else
 | 
			
		||||
	Module lexillaLibrary = dlopen(libPath, RTLD_LAZY);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	printf("Opened %s -> %p.\n", libPath, lexillaLibrary);
 | 
			
		||||
	if (lexillaLibrary) {
 | 
			
		||||
		GetLexerCountFn lexerCount = (GetLexerCountFn)FindSymbol(lexillaLibrary, LEXILLA_GETLEXERCOUNT);
 | 
			
		||||
		if (lexerCount) {
 | 
			
		||||
			int nLexers = lexerCount();
 | 
			
		||||
			printf("There are %d lexers.\n", nLexers);
 | 
			
		||||
			GetLexerNameFn lexerName = (GetLexerNameFn)FindSymbol(lexillaLibrary, LEXILLA_GETLEXERNAME);
 | 
			
		||||
			for (int i = 0; i < nLexers; i++) {
 | 
			
		||||
				char name[100] = "";
 | 
			
		||||
				lexerName(i, name, sizeof(name));
 | 
			
		||||
				printf("%s ", name);
 | 
			
		||||
			}
 | 
			
		||||
			printf("\n");
 | 
			
		||||
 | 
			
		||||
			GetLexerFactoryFn lexerFactory = (GetLexerFactoryFn)FindSymbol(lexillaLibrary, LEXILLA_GETLEXERFACTORY);
 | 
			
		||||
			LexerFactoryFunction lexerFactory4 = lexerFactory(4);	// 4th entry is "as" which is an object lexer so works
 | 
			
		||||
			printf("Lexer factory 4 -> %p.\n", lexerFactory4);
 | 
			
		||||
 | 
			
		||||
			CreateLexerFn lexerCreate = (CreateLexerFn)FindSymbol(lexillaLibrary, LEXILLA_CREATELEXER);
 | 
			
		||||
			ILexer5 *lexerCpp = lexerCreate("cpp");
 | 
			
		||||
			printf("Created cpp lexer -> %p.\n", lexerCpp);
 | 
			
		||||
 | 
			
		||||
			LexerNameFromIDFn lexerNameFromID = (LexerNameFromIDFn)FindSymbol(lexillaLibrary, LEXILLA_LEXERNAMEFROMID);
 | 
			
		||||
			if (lexerNameFromID) {
 | 
			
		||||
				const char *lexerNameCpp = lexerNameFromID(3);	// SCLEX_CPP=3
 | 
			
		||||
				if (lexerNameCpp) {
 | 
			
		||||
					printf("Lexer name 3 -> %s.\n", lexerNameCpp);
 | 
			
		||||
				} else {
 | 
			
		||||
					printf("Lexer name 3 not available.\n");
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				printf("Lexer name from ID not supported.\n");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			GetLibraryPropertyNamesFn libraryProperties = (GetLibraryPropertyNamesFn)FindSymbol(lexillaLibrary, LEXILLA_GETLIBRARYPROPERTYNAMES);
 | 
			
		||||
			if (libraryProperties) {
 | 
			
		||||
				const char *names = libraryProperties();
 | 
			
		||||
				printf("Property names '%s'.\n", names);
 | 
			
		||||
			} else {
 | 
			
		||||
				printf("Property names not supported.\n");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			SetLibraryPropertyFn librarySetProperty = (SetLibraryPropertyFn)FindSymbol(lexillaLibrary, LEXILLA_SETLIBRARYPROPERTY);
 | 
			
		||||
			if (librarySetProperty) {
 | 
			
		||||
				librarySetProperty("key", "value");
 | 
			
		||||
			} else {
 | 
			
		||||
				printf("Set property not supported.\n");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			GetNameSpaceFn libraryNameSpace = (GetLibraryPropertyNamesFn)FindSymbol(lexillaLibrary, LEXILLA_GETNAMESPACE);
 | 
			
		||||
			if (libraryNameSpace) {
 | 
			
		||||
				const char *nameSpace = libraryNameSpace();
 | 
			
		||||
				printf("Name space '%s'.\n", nameSpace);
 | 
			
		||||
			} else {
 | 
			
		||||
				printf("Name space not supported.\n");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								3rdparty/lexilla540/lexilla/examples/CheckLexilla/makefile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								3rdparty/lexilla540/lexilla/examples/CheckLexilla/makefile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
.PHONY: all check clean
 | 
			
		||||
 | 
			
		||||
INCLUDES = -I ../../include
 | 
			
		||||
EXE = $(if $(windir),CheckLexilla.exe,CheckLexilla)
 | 
			
		||||
 | 
			
		||||
ifdef windir
 | 
			
		||||
	RM = $(if $(wildcard $(dir $(SHELL))rm.exe), $(dir $(SHELL))rm.exe -f, del /q)
 | 
			
		||||
	CC = gcc
 | 
			
		||||
else
 | 
			
		||||
	LIBS += -ldl
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
all: $(EXE)
 | 
			
		||||
 | 
			
		||||
check: $(EXE)
 | 
			
		||||
	./$(EXE)
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	$(RM) $(EXE)
 | 
			
		||||
 | 
			
		||||
$(EXE): *.c
 | 
			
		||||
	$(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $^ $(LIBS) $(LDLIBS) -o $@
 | 
			
		||||
							
								
								
									
										123
									
								
								3rdparty/lexilla540/lexilla/examples/SimpleLexer/SimpleLexer.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								3rdparty/lexilla540/lexilla/examples/SimpleLexer/SimpleLexer.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,123 @@
 | 
			
		||||
//  A simple lexer
 | 
			
		||||
/** @file SimpleLexer.cxx
 | 
			
		||||
 ** A lexer that follows the Lexilla protocol to allow it to be used from Lexilla clients like SciTE.
 | 
			
		||||
 ** The lexer applies alternating styles (0,1) to bytes of the text.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2021 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// This file is in the public domain.
 | 
			
		||||
// If the public domain is not possible in your location then it can also be used under the same
 | 
			
		||||
// license as Scintilla. https://www.scintilla.org/License.txt
 | 
			
		||||
 | 
			
		||||
// Windows/MSVC
 | 
			
		||||
// cl -std:c++17 -EHsc -LD -I ../../../scintilla/include -I ../../include -I ../../lexlib SimpleLexer.cxx ../../lexlib/*.cxx
 | 
			
		||||
 | 
			
		||||
// macOS/clang
 | 
			
		||||
// clang++ -dynamiclib --std=c++17 -I ../../../scintilla/include -I ../../include -I ../../lexlib SimpleLexer.cxx ../../lexlib/*.cxx -o SimpleLexer.dylib
 | 
			
		||||
 | 
			
		||||
// Linux/g++
 | 
			
		||||
// g++ -fPIC -shared --std=c++17 -I ../../../scintilla/include -I ../../include -I ../../lexlib SimpleLexer.cxx ../../lexlib/*.cxx -o SimpleLexer.so
 | 
			
		||||
 | 
			
		||||
/* It can be demonstrated in SciTE like this, substituting the actual shared library location as lexilla.path:
 | 
			
		||||
lexilla.path=.;C:\u\hg\lexilla\examples\SimpleLexer\SimpleLexer.dll
 | 
			
		||||
lexer.*.xx=simple
 | 
			
		||||
style.simple.1=fore:#FF0000
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#include <string_view>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
// Lexilla.h should not be included here as it declares statically linked functions without the __declspec( dllexport )
 | 
			
		||||
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "PropSetSimple.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "Accessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "LexerBase.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
class LexerSimple : public LexerBase {
 | 
			
		||||
public:
 | 
			
		||||
        LexerSimple() {
 | 
			
		||||
        }
 | 
			
		||||
        void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override {
 | 
			
		||||
                try {
 | 
			
		||||
			Accessor astyler(pAccess, &props);
 | 
			
		||||
			if (length > 0) {
 | 
			
		||||
				astyler.StartAt(startPos);
 | 
			
		||||
				astyler.StartSegment(startPos);
 | 
			
		||||
				for (unsigned int k=0; k<length; k++) {
 | 
			
		||||
					astyler.ColourTo(startPos+k, (startPos+k)%2);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
                        astyler.Flush();
 | 
			
		||||
                } catch (...) {
 | 
			
		||||
                        // Should not throw into caller as may be compiled with different compiler or options
 | 
			
		||||
                        pAccess->SetErrorStatus(SC_STATUS_FAILURE);
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
        void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static ILexer5 *LexerFactorySimple() {
 | 
			
		||||
                try {
 | 
			
		||||
                        return new LexerSimple();
 | 
			
		||||
                } catch (...) {
 | 
			
		||||
                        // Should not throw into caller as may be compiled with different compiler or options
 | 
			
		||||
                        return nullptr;
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
#define EXPORT_FUNCTION __declspec(dllexport)
 | 
			
		||||
#define CALLING_CONVENTION __stdcall
 | 
			
		||||
#else
 | 
			
		||||
#define EXPORT_FUNCTION __attribute__((visibility("default")))
 | 
			
		||||
#define CALLING_CONVENTION
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static const char *lexerName = "simple";
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
 | 
			
		||||
EXPORT_FUNCTION int CALLING_CONVENTION GetLexerCount() {
 | 
			
		||||
        return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXPORT_FUNCTION void CALLING_CONVENTION GetLexerName(unsigned int index, char *name, int buflength) {
 | 
			
		||||
        *name = 0;
 | 
			
		||||
        if ((index == 0) && (buflength > static_cast<int>(strlen(lexerName)))) {
 | 
			
		||||
                strcpy(name, lexerName);
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXPORT_FUNCTION LexerFactoryFunction CALLING_CONVENTION GetLexerFactory(unsigned int index) {
 | 
			
		||||
        if (index == 0)
 | 
			
		||||
                return LexerSimple::LexerFactorySimple;
 | 
			
		||||
        else
 | 
			
		||||
                return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXPORT_FUNCTION Scintilla::ILexer5* CALLING_CONVENTION CreateLexer(const char *name) {
 | 
			
		||||
	if (0 == strcmp(name, lexerName)) {
 | 
			
		||||
		return LexerSimple::LexerFactorySimple();
 | 
			
		||||
	}
 | 
			
		||||
	return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXPORT_FUNCTION const char * CALLING_CONVENTION GetNameSpace() {
 | 
			
		||||
	return "example";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								3rdparty/lexilla540/lexilla/examples/SimpleLexer/makefile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								3rdparty/lexilla540/lexilla/examples/SimpleLexer/makefile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
			
		||||
.PHONY: all check clean
 | 
			
		||||
 | 
			
		||||
INCLUDES = -I ../../../scintilla/include -I ../../include -I ../../lexlib
 | 
			
		||||
 | 
			
		||||
BASE_FLAGS += --std=c++17
 | 
			
		||||
 | 
			
		||||
ifdef windir
 | 
			
		||||
    SHAREDEXTENSION = dll
 | 
			
		||||
else
 | 
			
		||||
    ifeq ($(shell uname),Darwin)
 | 
			
		||||
        SHAREDEXTENSION = dylib
 | 
			
		||||
        BASE_FLAGS += -arch arm64 -arch x86_64
 | 
			
		||||
        LINK_FLAGS += -dynamiclib
 | 
			
		||||
    else
 | 
			
		||||
        BASE_FLAGS += -fPIC
 | 
			
		||||
        SHAREDEXTENSION = so
 | 
			
		||||
    endif
 | 
			
		||||
    BASE_FLAGS += -fvisibility=hidden
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifdef windir
 | 
			
		||||
	RM = $(if $(wildcard $(dir $(SHELL))rm.exe), $(dir $(SHELL))rm.exe -f, del /q)
 | 
			
		||||
	CXX = g++
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
LIBRARY = SimpleLexer.$(SHAREDEXTENSION)
 | 
			
		||||
 | 
			
		||||
vpath %.cxx ../../lexlib
 | 
			
		||||
 
 | 
			
		||||
LEXLIB_SOURCES := $(sort $(notdir $(wildcard ../../lexlib/*.cxx)))
 | 
			
		||||
LEXLIB = $(LEXLIB_SOURCES:.cxx=.o)
 | 
			
		||||
 | 
			
		||||
%.o: %.cxx
 | 
			
		||||
	$(CXX) $(INCLUDES) $(BASE_FLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
 | 
			
		||||
 | 
			
		||||
all: $(LIBRARY)
 | 
			
		||||
 | 
			
		||||
# make check requires CheckLexilla to have already been built
 | 
			
		||||
check: $(LIBRARY)
 | 
			
		||||
	../CheckLexilla/CheckLexilla ./$(LIBRARY)
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	$(RM) *.o *obj *.lib *.exp $(LIBRARY)
 | 
			
		||||
 | 
			
		||||
$(LIBRARY): $(LEXLIB) *.cxx
 | 
			
		||||
	$(CXX) $(INCLUDES) $(LINK_FLAGS) $(BASE_FLAGS) -shared $(CPPFLAGS) $(CXXFLAGS) $^ $(LIBS) $(LDLIBS) -o $@
 | 
			
		||||
							
								
								
									
										2330
									
								
								3rdparty/lexilla540/lexilla/include/LexicalStyles.iface
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2330
									
								
								3rdparty/lexilla540/lexilla/include/LexicalStyles.iface
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										108
									
								
								3rdparty/lexilla540/lexilla/include/Lexilla.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								3rdparty/lexilla540/lexilla/include/Lexilla.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,108 @@
 | 
			
		||||
// Lexilla lexer library
 | 
			
		||||
/** @file Lexilla.h
 | 
			
		||||
 ** Lexilla definitions for dynamic and static linking.
 | 
			
		||||
 ** For C++, more features and type safety are available with the LexillaAccess module.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2020 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
#ifndef LEXILLA_H
 | 
			
		||||
#define LEXILLA_H
 | 
			
		||||
 | 
			
		||||
// Define the default Lexilla shared library name for each platform
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
#define LEXILLA_LIB "lexilla"
 | 
			
		||||
#define LEXILLA_EXTENSION ".dll"
 | 
			
		||||
#else
 | 
			
		||||
#define LEXILLA_LIB "liblexilla"
 | 
			
		||||
#if defined(__APPLE__)
 | 
			
		||||
#define LEXILLA_EXTENSION ".dylib"
 | 
			
		||||
#else
 | 
			
		||||
#define LEXILLA_EXTENSION ".so"
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// On Win32 use the stdcall calling convention otherwise use the standard calling convention
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
#define LEXILLA_CALL __stdcall
 | 
			
		||||
#else
 | 
			
		||||
#define LEXILLA_CALL
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__OBJC2__)
 | 
			
		||||
// Objective C(++) treats '[' as a message expression.
 | 
			
		||||
#define DEPRECATE_DEFINITION
 | 
			
		||||
#elif defined(__cplusplus)
 | 
			
		||||
#define DEPRECATE_DEFINITION [[deprecated]]
 | 
			
		||||
#elif defined(__GNUC__) || defined(__clang__)
 | 
			
		||||
#define DEPRECATE_DEFINITION __attribute__((deprecated))
 | 
			
		||||
#else
 | 
			
		||||
// MSVC __declspec(deprecated) has different positioning rules to GCC so define to nothing
 | 
			
		||||
#define DEPRECATE_DEFINITION
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
// Must have already included ILexer.h to have Scintilla::ILexer5 defined.
 | 
			
		||||
using Scintilla::ILexer5;
 | 
			
		||||
#else
 | 
			
		||||
typedef void ILexer5;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef ILexer5 *(*LexerFactoryFunction)(void);
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
namespace Lexilla {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef int (LEXILLA_CALL *GetLexerCountFn)(void);
 | 
			
		||||
typedef void (LEXILLA_CALL *GetLexerNameFn)(unsigned int Index, char *name, int buflength);
 | 
			
		||||
typedef LexerFactoryFunction(LEXILLA_CALL *GetLexerFactoryFn)(unsigned int Index);
 | 
			
		||||
typedef ILexer5*(LEXILLA_CALL *CreateLexerFn)(const char *name);
 | 
			
		||||
DEPRECATE_DEFINITION typedef const char *(LEXILLA_CALL *LexerNameFromIDFn)(int identifier);
 | 
			
		||||
typedef const char *(LEXILLA_CALL *GetLibraryPropertyNamesFn)(void);
 | 
			
		||||
typedef void(LEXILLA_CALL *SetLibraryPropertyFn)(const char *key, const char *value);
 | 
			
		||||
typedef const char *(LEXILLA_CALL *GetNameSpaceFn)(void);
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define LEXILLA_NAMESPACE_SEPARATOR '.'
 | 
			
		||||
 | 
			
		||||
#define LEXILLA_GETLEXERCOUNT "GetLexerCount"
 | 
			
		||||
#define LEXILLA_GETLEXERNAME "GetLexerName"
 | 
			
		||||
#define LEXILLA_GETLEXERFACTORY "GetLexerFactory"
 | 
			
		||||
#define LEXILLA_CREATELEXER "CreateLexer"
 | 
			
		||||
#define LEXILLA_LEXERNAMEFROMID "LexerNameFromID"
 | 
			
		||||
#define LEXILLA_GETLIBRARYPROPERTYNAMES "GetLibraryPropertyNames"
 | 
			
		||||
#define LEXILLA_SETLIBRARYPROPERTY "SetLibraryProperty"
 | 
			
		||||
#define LEXILLA_GETNAMESPACE "GetNameSpace"
 | 
			
		||||
 | 
			
		||||
// Static linking prototypes
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
ILexer5 * LEXILLA_CALL CreateLexer(const char *name);
 | 
			
		||||
int LEXILLA_CALL GetLexerCount(void);
 | 
			
		||||
void LEXILLA_CALL GetLexerName(unsigned int index, char *name, int buflength);
 | 
			
		||||
LexerFactoryFunction LEXILLA_CALL GetLexerFactory(unsigned int index);
 | 
			
		||||
DEPRECATE_DEFINITION const char *LEXILLA_CALL LexerNameFromID(int identifier);
 | 
			
		||||
const char * LEXILLA_CALL GetLibraryPropertyNames(void);
 | 
			
		||||
void LEXILLA_CALL SetLibraryProperty(const char *key, const char *value);
 | 
			
		||||
const char *LEXILLA_CALL GetNameSpace(void);
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
namespace Lexilla {
 | 
			
		||||
	class LexerModule;
 | 
			
		||||
}
 | 
			
		||||
// Add a static lexer (in the same binary) to Lexilla's list
 | 
			
		||||
void AddStaticLexerModule(const Lexilla::LexerModule *plm);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										2079
									
								
								3rdparty/lexilla540/lexilla/include/SciLexer.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2079
									
								
								3rdparty/lexilla540/lexilla/include/SciLexer.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										348
									
								
								3rdparty/lexilla540/lexilla/lexers/LexA68k.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										348
									
								
								3rdparty/lexilla540/lexilla/lexers/LexA68k.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,348 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexA68k.cxx
 | 
			
		||||
 ** Lexer for Assembler, just for the MASM syntax
 | 
			
		||||
 ** Written by Martial Demolins AKA Folco
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2010 Martial Demolins <mdemolins(a)gmail.com>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Return values for GetOperatorType
 | 
			
		||||
#define NO_OPERATOR     0
 | 
			
		||||
#define OPERATOR_1CHAR  1
 | 
			
		||||
#define OPERATOR_2CHAR  2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  IsIdentifierStart
 | 
			
		||||
 *
 | 
			
		||||
 *  Return true if the given char is a valid identifier first char
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static inline bool IsIdentifierStart (const int ch)
 | 
			
		||||
{
 | 
			
		||||
    return (isalpha(ch) || (ch == '_') || (ch == '\\'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  IsIdentifierChar
 | 
			
		||||
 *
 | 
			
		||||
 *  Return true if the given char is a valid identifier char
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static inline bool IsIdentifierChar (const int ch)
 | 
			
		||||
{
 | 
			
		||||
    return (isalnum(ch) || (ch == '_') || (ch == '@') || (ch == ':') || (ch == '.'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  GetOperatorType
 | 
			
		||||
 *
 | 
			
		||||
 *  Return:
 | 
			
		||||
 *  NO_OPERATOR     if char is not an operator
 | 
			
		||||
 *  OPERATOR_1CHAR  if the operator is one char long
 | 
			
		||||
 *  OPERATOR_2CHAR  if the operator is two chars long
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static inline int GetOperatorType (const int ch1, const int ch2)
 | 
			
		||||
{
 | 
			
		||||
    int OpType = NO_OPERATOR;
 | 
			
		||||
 | 
			
		||||
    if ((ch1 == '+') || (ch1 == '-') || (ch1 == '*') || (ch1 == '/') || (ch1 == '#') ||
 | 
			
		||||
        (ch1 == '(') || (ch1 == ')') || (ch1 == '~') || (ch1 == '&') || (ch1 == '|') || (ch1 == ','))
 | 
			
		||||
        OpType = OPERATOR_1CHAR;
 | 
			
		||||
 | 
			
		||||
    else if ((ch1 == ch2) && (ch1 == '<' || ch1 == '>'))
 | 
			
		||||
        OpType = OPERATOR_2CHAR;
 | 
			
		||||
 | 
			
		||||
    return OpType;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  IsBin
 | 
			
		||||
 *
 | 
			
		||||
 *  Return true if the given char is 0 or 1
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static inline bool IsBin (const int ch)
 | 
			
		||||
{
 | 
			
		||||
    return (ch == '0') || (ch == '1');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  IsDoxygenChar
 | 
			
		||||
 *
 | 
			
		||||
 *  Return true if the char may be part of a Doxygen keyword
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static inline bool IsDoxygenChar (const int ch)
 | 
			
		||||
{
 | 
			
		||||
    return isalpha(ch) || (ch == '$') || (ch == '[') || (ch == ']') || (ch == '{') || (ch == '}');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  ColouriseA68kDoc
 | 
			
		||||
 *
 | 
			
		||||
 *  Main function, which colourises a 68k source
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static void ColouriseA68kDoc (Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
    // Used to buffer a string, to be able to compare it using built-in functions
 | 
			
		||||
    char Buffer[100];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Used to know the length of an operator
 | 
			
		||||
    int OpType;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Get references to keywords lists
 | 
			
		||||
    WordList &cpuInstruction = *keywordlists[0];
 | 
			
		||||
    WordList ®isters = *keywordlists[1];
 | 
			
		||||
    WordList &directive = *keywordlists[2];
 | 
			
		||||
    WordList &extInstruction = *keywordlists[3];
 | 
			
		||||
    WordList &alert          = *keywordlists[4];
 | 
			
		||||
    WordList &doxygenKeyword = *keywordlists[5];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Instanciate a context for our source
 | 
			
		||||
    StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /************************************************************
 | 
			
		||||
    *
 | 
			
		||||
    *   Parse the source
 | 
			
		||||
    *
 | 
			
		||||
    ************************************************************/
 | 
			
		||||
 | 
			
		||||
    for ( ; sc.More(); sc.Forward())
 | 
			
		||||
    {
 | 
			
		||||
        /************************************************************
 | 
			
		||||
        *
 | 
			
		||||
        *   A style always terminates at the end of a line, even for
 | 
			
		||||
        *   comments (no multi-lines comments)
 | 
			
		||||
        *
 | 
			
		||||
        ************************************************************/
 | 
			
		||||
        if (sc.atLineStart) {
 | 
			
		||||
            sc.SetState(SCE_A68K_DEFAULT);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /************************************************************
 | 
			
		||||
        *
 | 
			
		||||
        *   If we are not in "default style", check if the style continues
 | 
			
		||||
        *   In this case, we just have to loop
 | 
			
		||||
        *
 | 
			
		||||
        ************************************************************/
 | 
			
		||||
 | 
			
		||||
        if (sc.state != SCE_A68K_DEFAULT)
 | 
			
		||||
        {
 | 
			
		||||
            if (   ((sc.state == SCE_A68K_NUMBER_DEC)        && isdigit(sc.ch))                      // Decimal number
 | 
			
		||||
                || ((sc.state == SCE_A68K_NUMBER_BIN) && IsBin(sc.ch))                                      // Binary number
 | 
			
		||||
                || ((sc.state == SCE_A68K_NUMBER_HEX) && isxdigit(sc.ch))                                   // Hexa number
 | 
			
		||||
                || ((sc.state == SCE_A68K_MACRO_ARG)         && isdigit(sc.ch))                      // Macro argument
 | 
			
		||||
                || ((sc.state == SCE_A68K_STRING1)    && (sc.ch != '\''))                                   // String single-quoted
 | 
			
		||||
                || ((sc.state == SCE_A68K_STRING2)    && (sc.ch != '\"'))                                   // String double-quoted
 | 
			
		||||
                || ((sc.state == SCE_A68K_MACRO_DECLARATION) && IsIdentifierChar(sc.ch))             // Macro declaration (or global label, we don't know at this point)
 | 
			
		||||
                || ((sc.state == SCE_A68K_IDENTIFIER)        && IsIdentifierChar(sc.ch))             // Identifier
 | 
			
		||||
                || ((sc.state == SCE_A68K_LABEL)             && IsIdentifierChar(sc.ch))             // Label (local)
 | 
			
		||||
                || ((sc.state == SCE_A68K_COMMENT_DOXYGEN)   && IsDoxygenChar(sc.ch))                // Doxygen keyword
 | 
			
		||||
                || ((sc.state == SCE_A68K_COMMENT_SPECIAL)   && isalpha(sc.ch))                      // Alert
 | 
			
		||||
                || ((sc.state == SCE_A68K_COMMENT)           && !isalpha(sc.ch) && (sc.ch != '\\'))) // Normal comment
 | 
			
		||||
            {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        /************************************************************
 | 
			
		||||
        *
 | 
			
		||||
        *   Check if current state terminates
 | 
			
		||||
        *
 | 
			
		||||
        ************************************************************/
 | 
			
		||||
 | 
			
		||||
            // Strings: include terminal ' or " in the current string by skipping it
 | 
			
		||||
            if ((sc.state == SCE_A68K_STRING1) || (sc.state == SCE_A68K_STRING2)) {
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // If a macro declaration was terminated with ':', it was a label
 | 
			
		||||
            else if ((sc.state == SCE_A68K_MACRO_DECLARATION) && (sc.chPrev == ':')) {
 | 
			
		||||
                sc.ChangeState(SCE_A68K_LABEL);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // If it wasn't a Doxygen keyword, change it to normal comment
 | 
			
		||||
            else if (sc.state == SCE_A68K_COMMENT_DOXYGEN) {
 | 
			
		||||
                sc.GetCurrent(Buffer, sizeof(Buffer));
 | 
			
		||||
                if (!doxygenKeyword.InList(Buffer)) {
 | 
			
		||||
                    sc.ChangeState(SCE_A68K_COMMENT);
 | 
			
		||||
                }
 | 
			
		||||
                sc.SetState(SCE_A68K_COMMENT);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // If it wasn't an Alert, change it to normal comment
 | 
			
		||||
            else if (sc.state == SCE_A68K_COMMENT_SPECIAL) {
 | 
			
		||||
                sc.GetCurrent(Buffer, sizeof(Buffer));
 | 
			
		||||
                if (!alert.InList(Buffer)) {
 | 
			
		||||
                    sc.ChangeState(SCE_A68K_COMMENT);
 | 
			
		||||
                }
 | 
			
		||||
                // Reset style to normal comment, or to Doxygen keyword if it begins with '\'
 | 
			
		||||
                if (sc.ch == '\\') {
 | 
			
		||||
                    sc.SetState(SCE_A68K_COMMENT_DOXYGEN);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                sc.SetState(SCE_A68K_COMMENT);
 | 
			
		||||
                }
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // If we are in a comment, it's a Doxygen keyword or an Alert
 | 
			
		||||
            else if (sc.state == SCE_A68K_COMMENT) {
 | 
			
		||||
                if (sc.ch == '\\') {
 | 
			
		||||
                    sc.SetState(SCE_A68K_COMMENT_DOXYGEN);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    sc.SetState(SCE_A68K_COMMENT_SPECIAL);
 | 
			
		||||
                }
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // Check if we are at the end of an identifier
 | 
			
		||||
            // In this case, colourise it if was a keyword.
 | 
			
		||||
            else if ((sc.state == SCE_A68K_IDENTIFIER) && !IsIdentifierChar(sc.ch)) {
 | 
			
		||||
                sc.GetCurrentLowered(Buffer, sizeof(Buffer));                           // Buffer the string of the current context
 | 
			
		||||
                if (cpuInstruction.InList(Buffer)) {                                    // And check if it belongs to a keyword list
 | 
			
		||||
                    sc.ChangeState(SCE_A68K_CPUINSTRUCTION);
 | 
			
		||||
                }
 | 
			
		||||
                else if (extInstruction.InList(Buffer)) {
 | 
			
		||||
                    sc.ChangeState(SCE_A68K_EXTINSTRUCTION);
 | 
			
		||||
                }
 | 
			
		||||
                else if (registers.InList(Buffer)) {
 | 
			
		||||
                    sc.ChangeState(SCE_A68K_REGISTER);
 | 
			
		||||
                }
 | 
			
		||||
                else if (directive.InList(Buffer)) {
 | 
			
		||||
                    sc.ChangeState(SCE_A68K_DIRECTIVE);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // All special contexts are now handled.Come back to default style
 | 
			
		||||
            sc.SetState(SCE_A68K_DEFAULT);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /************************************************************
 | 
			
		||||
        *
 | 
			
		||||
        *   Check if we must enter a new state
 | 
			
		||||
        *
 | 
			
		||||
        ************************************************************/
 | 
			
		||||
 | 
			
		||||
        // Something which begins at the beginning of a line, and with
 | 
			
		||||
        // - '\' + an identifier start char, or
 | 
			
		||||
        // - '\\@' + an identifier start char
 | 
			
		||||
        // is a local label (second case is used for macro local labels). We set it already as a label, it can't be a macro/equ declaration
 | 
			
		||||
        if (sc.atLineStart && (sc.ch < 0x80) && IsIdentifierStart(sc.chNext) && (sc.ch == '\\')) {
 | 
			
		||||
            sc.SetState(SCE_A68K_LABEL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (sc.atLineStart && (sc.ch < 0x80) && (sc.ch == '\\') && (sc.chNext == '\\')) {
 | 
			
		||||
            sc.Forward(2);
 | 
			
		||||
            if ((sc.ch == '@') && IsIdentifierStart(sc.chNext)) {
 | 
			
		||||
                sc.ChangeState(SCE_A68K_LABEL);
 | 
			
		||||
                sc.SetState(SCE_A68K_LABEL);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Label and macro identifiers start at the beginning of a line
 | 
			
		||||
        // We set both as a macro id, but if it wasn't one (':' at the end),
 | 
			
		||||
        // it will be changed as a label.
 | 
			
		||||
        if (sc.atLineStart && (sc.ch < 0x80) && IsIdentifierStart(sc.ch)) {
 | 
			
		||||
            sc.SetState(SCE_A68K_MACRO_DECLARATION);
 | 
			
		||||
        }
 | 
			
		||||
        else if ((sc.ch < 0x80) && (sc.ch == ';')) {                            // Default: alert in a comment. If it doesn't match
 | 
			
		||||
            sc.SetState(SCE_A68K_COMMENT);                                      // with an alert, it will be toggle to a normal comment
 | 
			
		||||
        }
 | 
			
		||||
        else if ((sc.ch < 0x80) && isdigit(sc.ch)) {                            // Decimal numbers haven't prefix
 | 
			
		||||
            sc.SetState(SCE_A68K_NUMBER_DEC);
 | 
			
		||||
        }
 | 
			
		||||
        else if ((sc.ch < 0x80) && (sc.ch == '%')) {                            // Binary numbers are prefixed with '%'
 | 
			
		||||
            sc.SetState(SCE_A68K_NUMBER_BIN);
 | 
			
		||||
        }
 | 
			
		||||
        else if ((sc.ch < 0x80) && (sc.ch == '$')) {                            // Hexadecimal numbers are prefixed with '$'
 | 
			
		||||
            sc.SetState(SCE_A68K_NUMBER_HEX);
 | 
			
		||||
        }
 | 
			
		||||
        else if ((sc.ch < 0x80) && (sc.ch == '\'')) {                           // String (single-quoted)
 | 
			
		||||
            sc.SetState(SCE_A68K_STRING1);
 | 
			
		||||
        }
 | 
			
		||||
        else if ((sc.ch < 0x80) && (sc.ch == '\"')) {                           // String (double-quoted)
 | 
			
		||||
            sc.SetState(SCE_A68K_STRING2);
 | 
			
		||||
        }
 | 
			
		||||
        else if ((sc.ch < 0x80) && (sc.ch == '\\') && (isdigit(sc.chNext))) {   // Replacement symbols in macro are prefixed with '\'
 | 
			
		||||
            sc.SetState(SCE_A68K_MACRO_ARG);
 | 
			
		||||
        }
 | 
			
		||||
        else if ((sc.ch < 0x80) && IsIdentifierStart(sc.ch)) {                  // An identifier: constant, label, etc...
 | 
			
		||||
            sc.SetState(SCE_A68K_IDENTIFIER);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            if (sc.ch < 0x80) {
 | 
			
		||||
                OpType = GetOperatorType(sc.ch, sc.chNext);                     // Check if current char is an operator
 | 
			
		||||
                if (OpType != NO_OPERATOR) {
 | 
			
		||||
                    sc.SetState(SCE_A68K_OPERATOR);
 | 
			
		||||
                    if (OpType == OPERATOR_2CHAR) {                             // Check if the operator is 2 bytes long
 | 
			
		||||
                        sc.ForwardSetState(SCE_A68K_OPERATOR);                  // (>> or <<)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }                                                                           // End of for()
 | 
			
		||||
    sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Names of the keyword lists
 | 
			
		||||
 | 
			
		||||
static const char * const a68kWordListDesc[] =
 | 
			
		||||
{
 | 
			
		||||
    "CPU instructions",
 | 
			
		||||
    "Registers",
 | 
			
		||||
    "Directives",
 | 
			
		||||
    "Extended instructions",
 | 
			
		||||
    "Comment special words",
 | 
			
		||||
    "Doxygen keywords",
 | 
			
		||||
    0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmA68k(SCLEX_A68K, ColouriseA68kDoc, "a68k", 0, a68kWordListDesc);
 | 
			
		||||
							
								
								
									
										260
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAPDL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAPDL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,260 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexAPDL.cxx
 | 
			
		||||
 ** Lexer for APDL. Based on the lexer for Assembler by The Black Horus.
 | 
			
		||||
 ** By Hadar Raz.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80 && (isalnum(ch) || ch == '_'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsAnOperator(char ch) {
 | 
			
		||||
	// '.' left out as it is used to make up numbers
 | 
			
		||||
	if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
 | 
			
		||||
		ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
 | 
			
		||||
		ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
 | 
			
		||||
		ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
 | 
			
		||||
		ch == '$' || ch == ':' || ch == '%')
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseAPDLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	int stringStart = ' ';
 | 
			
		||||
 | 
			
		||||
	WordList &processors = *keywordlists[0];
 | 
			
		||||
	WordList &commands = *keywordlists[1];
 | 
			
		||||
	WordList &slashcommands = *keywordlists[2];
 | 
			
		||||
	WordList &starcommands = *keywordlists[3];
 | 
			
		||||
	WordList &arguments = *keywordlists[4];
 | 
			
		||||
	WordList &functions = *keywordlists[5];
 | 
			
		||||
 | 
			
		||||
	// Do not leak onto next line
 | 
			
		||||
	initStyle = SCE_APDL_DEFAULT;
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		if (sc.state == SCE_APDL_NUMBER) {
 | 
			
		||||
			if (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
 | 
			
		||||
				((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
 | 
			
		||||
				sc.SetState(SCE_APDL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_APDL_COMMENT) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_APDL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_APDL_COMMENTBLOCK) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				if (sc.ch == '\r') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				sc.ForwardSetState(SCE_APDL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_APDL_STRING) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_APDL_DEFAULT);
 | 
			
		||||
			} else if ((sc.ch == '\'' && stringStart == '\'') || (sc.ch == '\"' && stringStart == '\"')) {
 | 
			
		||||
				sc.ForwardSetState(SCE_APDL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_APDL_WORD) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
				if (processors.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_APDL_PROCESSOR);
 | 
			
		||||
				} else if (slashcommands.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_APDL_SLASHCOMMAND);
 | 
			
		||||
				} else if (starcommands.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_APDL_STARCOMMAND);
 | 
			
		||||
				} else if (commands.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_APDL_COMMAND);
 | 
			
		||||
				} else if (arguments.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_APDL_ARGUMENT);
 | 
			
		||||
				} else if (functions.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_APDL_FUNCTION);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_APDL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_APDL_OPERATOR) {
 | 
			
		||||
			if (!IsAnOperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
			    sc.SetState(SCE_APDL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_APDL_DEFAULT) {
 | 
			
		||||
			if (sc.ch == '!' && sc.chNext == '!') {
 | 
			
		||||
				sc.SetState(SCE_APDL_COMMENTBLOCK);
 | 
			
		||||
			} else if (sc.ch == '!') {
 | 
			
		||||
				sc.SetState(SCE_APDL_COMMENT);
 | 
			
		||||
			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_APDL_NUMBER);
 | 
			
		||||
			} else if (sc.ch == '\'' || sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_APDL_STRING);
 | 
			
		||||
				stringStart = sc.ch;
 | 
			
		||||
			} else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) {
 | 
			
		||||
				sc.SetState(SCE_APDL_WORD);
 | 
			
		||||
			} else if (IsAnOperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_APDL_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// 06-27-07 Sergio Lucato
 | 
			
		||||
// - Included code folding for Ansys APDL lexer
 | 
			
		||||
// - Copyied from LexBasic.cxx and modified for APDL
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/* Bits:
 | 
			
		||||
 * 1  - whitespace
 | 
			
		||||
 * 2  - operator
 | 
			
		||||
 * 4  - identifier
 | 
			
		||||
 * 8  - decimal digit
 | 
			
		||||
 * 16 - hex digit
 | 
			
		||||
 * 32 - bin digit
 | 
			
		||||
 */
 | 
			
		||||
static int character_classification[128] =
 | 
			
		||||
{
 | 
			
		||||
    0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  1,  0,  0,
 | 
			
		||||
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
    1,  2,  0,  2,  2,  2,  2,  2,  2,  2,  6,  2,  2,  2,  10, 6,
 | 
			
		||||
    60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2,  2,  2,  2,  2,  2,
 | 
			
		||||
    2,  20, 20, 20, 20, 20, 20, 4,  4,  4,  4,  4,  4,  4,  4,  4,
 | 
			
		||||
    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2,  2,  2,  4,
 | 
			
		||||
    2,  20, 20, 20, 20, 20, 20, 4,  4,  4,  4,  4,  4,  4,  4,  4,
 | 
			
		||||
    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2,  2,  2,  0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool IsSpace(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsIdentifier(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int LowerCase(int c)
 | 
			
		||||
{
 | 
			
		||||
	if (c >= 'A' && c <= 'Z')
 | 
			
		||||
		return 'a' + c - 'A';
 | 
			
		||||
	return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CheckAPDLFoldPoint(char const *token, int &level) {
 | 
			
		||||
	if (!strcmp(token, "*if") ||
 | 
			
		||||
		!strcmp(token, "*do") ||
 | 
			
		||||
		!strcmp(token, "*dowhile") ) {
 | 
			
		||||
		level |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	if (!strcmp(token, "*endif") ||
 | 
			
		||||
		!strcmp(token, "*enddo") ) {
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldAPDLDoc(Sci_PositionU startPos, Sci_Position length, int,
 | 
			
		||||
	WordList *[], Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	Sci_Position line = styler.GetLine(startPos);
 | 
			
		||||
	int level = styler.LevelAt(line);
 | 
			
		||||
	int go = 0, done = 0;
 | 
			
		||||
	Sci_Position endPos = startPos + length;
 | 
			
		||||
	char word[256];
 | 
			
		||||
	int wordlen = 0;
 | 
			
		||||
	Sci_Position i;
 | 
			
		||||
    bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
	// Scan for tokens at the start of the line (they may include
 | 
			
		||||
	// whitespace, for tokens like "End Function"
 | 
			
		||||
	for (i = startPos; i < endPos; i++) {
 | 
			
		||||
		int c = styler.SafeGetCharAt(i);
 | 
			
		||||
		if (!done && !go) {
 | 
			
		||||
			if (wordlen) { // are we scanning a token already?
 | 
			
		||||
				word[wordlen] = static_cast<char>(LowerCase(c));
 | 
			
		||||
				if (!IsIdentifier(c)) { // done with token
 | 
			
		||||
					word[wordlen] = '\0';
 | 
			
		||||
					go = CheckAPDLFoldPoint(word, level);
 | 
			
		||||
					if (!go) {
 | 
			
		||||
						// Treat any whitespace as single blank, for
 | 
			
		||||
						// things like "End   Function".
 | 
			
		||||
						if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
 | 
			
		||||
							word[wordlen] = ' ';
 | 
			
		||||
							if (wordlen < 255)
 | 
			
		||||
								wordlen++;
 | 
			
		||||
						}
 | 
			
		||||
						else // done with this line
 | 
			
		||||
							done = 1;
 | 
			
		||||
					}
 | 
			
		||||
				} else if (wordlen < 255) {
 | 
			
		||||
					wordlen++;
 | 
			
		||||
				}
 | 
			
		||||
			} else { // start scanning at first non-whitespace character
 | 
			
		||||
				if (!IsSpace(c)) {
 | 
			
		||||
					if (IsIdentifier(c)) {
 | 
			
		||||
						word[0] = static_cast<char>(LowerCase(c));
 | 
			
		||||
						wordlen = 1;
 | 
			
		||||
					} else // done with this line
 | 
			
		||||
						done = 1;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (c == '\n') { // line end
 | 
			
		||||
			if (!done && wordlen == 0 && foldCompact) // line was only space
 | 
			
		||||
				level |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if (level != styler.LevelAt(line))
 | 
			
		||||
				styler.SetLevel(line, level);
 | 
			
		||||
			level += go;
 | 
			
		||||
			line++;
 | 
			
		||||
			// reset state
 | 
			
		||||
			wordlen = 0;
 | 
			
		||||
			level &= ~SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			level &= ~SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			go = 0;
 | 
			
		||||
			done = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const apdlWordListDesc[] = {
 | 
			
		||||
    "processors",
 | 
			
		||||
    "commands",
 | 
			
		||||
    "slashommands",
 | 
			
		||||
    "starcommands",
 | 
			
		||||
    "arguments",
 | 
			
		||||
    "functions",
 | 
			
		||||
    0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmAPDL(SCLEX_APDL, ColouriseAPDLDoc, "apdl", FoldAPDLDoc, apdlWordListDesc);
 | 
			
		||||
							
								
								
									
										275
									
								
								3rdparty/lexilla540/lexilla/lexers/LexASY.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								3rdparty/lexilla540/lexilla/lexers/LexASY.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,275 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
// @file LexASY.cxx
 | 
			
		||||
//Author: instanton (email: soft_share<at>126<dot>com)
 | 
			
		||||
// This lexer is for the Asymptote vector graphics language
 | 
			
		||||
// https://en.wikipedia.org/wiki/Asymptote_(vector_graphics_language)
 | 
			
		||||
// 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;
 | 
			
		||||
 | 
			
		||||
static void ColouriseAsyDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
		WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
	WordList &keywords2 = *keywordlists[1];
 | 
			
		||||
 | 
			
		||||
	CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
 | 
			
		||||
	CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
 | 
			
		||||
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
		if (sc.atLineStart) {
 | 
			
		||||
			if (sc.state == SCE_ASY_STRING) {
 | 
			
		||||
				sc.SetState(SCE_ASY_STRING);
 | 
			
		||||
			}
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.ch == '\\') {
 | 
			
		||||
			if (sc.chNext == '\n' || sc.chNext == '\r') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				if (sc.ch == '\r' && sc.chNext == '\n') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
//				continuationLine = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		switch (sc.state) {
 | 
			
		||||
			case SCE_ASY_OPERATOR:
 | 
			
		||||
				sc.SetState(SCE_ASY_DEFAULT);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ASY_NUMBER:
 | 
			
		||||
				if (!setWord.Contains(sc.ch)) {
 | 
			
		||||
					sc.SetState(SCE_ASY_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ASY_IDENTIFIER:
 | 
			
		||||
				if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
 | 
			
		||||
					char s[1000];
 | 
			
		||||
					sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
					if (keywords.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_ASY_WORD);
 | 
			
		||||
					} else if (keywords2.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_ASY_WORD2);
 | 
			
		||||
					}
 | 
			
		||||
					sc.SetState(SCE_ASY_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ASY_COMMENT:
 | 
			
		||||
				if (sc.Match('*', '/')) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_ASY_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ASY_COMMENTLINE:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_ASY_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ASY_STRING:
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.ChangeState(SCE_ASY_STRINGEOL);
 | 
			
		||||
				} else if (sc.ch == '\\') {
 | 
			
		||||
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.ch == '\"') {
 | 
			
		||||
					sc.ForwardSetState(SCE_ASY_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ASY_CHARACTER:
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.ChangeState(SCE_ASY_STRINGEOL);
 | 
			
		||||
				} else 	if (sc.ch == '\\') {
 | 
			
		||||
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.ch == '\'') {
 | 
			
		||||
					sc.ForwardSetState(SCE_ASY_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_ASY_DEFAULT) {
 | 
			
		||||
			if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
 | 
			
		||||
				sc.SetState(SCE_ASY_IDENTIFIER);
 | 
			
		||||
			} else if (sc.Match('/', '*')) {
 | 
			
		||||
				sc.SetState(SCE_ASY_COMMENT);
 | 
			
		||||
				sc.Forward();	//
 | 
			
		||||
			} else if (sc.Match('/', '/')) {
 | 
			
		||||
				sc.SetState(SCE_ASY_COMMENTLINE);
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_ASY_STRING);
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(SCE_ASY_CHARACTER);
 | 
			
		||||
			} else if (sc.ch == '#' && visibleChars == 0) {
 | 
			
		||||
				do {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.SetState(SCE_ASY_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (isoperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_ASY_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsAsyCommentStyle(int style) {
 | 
			
		||||
	return style == SCE_ASY_COMMENT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline bool isASYidentifier(int ch) {
 | 
			
		||||
	return
 | 
			
		||||
      ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int ParseASYWord(Sci_PositionU pos, Accessor &styler, char *word)
 | 
			
		||||
{
 | 
			
		||||
  int length=0;
 | 
			
		||||
  char ch=styler.SafeGetCharAt(pos);
 | 
			
		||||
  *word=0;
 | 
			
		||||
 | 
			
		||||
  while(isASYidentifier(ch) && length<100){
 | 
			
		||||
          word[length]=ch;
 | 
			
		||||
          length++;
 | 
			
		||||
          ch=styler.SafeGetCharAt(pos+length);
 | 
			
		||||
  }
 | 
			
		||||
  word[length]=0;
 | 
			
		||||
  return length;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsASYDrawingLine(Sci_Position line, Accessor &styler) {
 | 
			
		||||
	Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
	Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
 | 
			
		||||
	Sci_Position startpos = pos;
 | 
			
		||||
	char buffer[100]="";
 | 
			
		||||
 | 
			
		||||
	while (startpos<eol_pos){
 | 
			
		||||
		char ch = styler[startpos];
 | 
			
		||||
		ParseASYWord(startpos,styler,buffer);
 | 
			
		||||
		bool drawcommands = strncmp(buffer,"draw",4)==0||
 | 
			
		||||
			strncmp(buffer,"pair",4)==0||strncmp(buffer,"label",5)==0;
 | 
			
		||||
		if (!drawcommands && ch!=' ') return false;
 | 
			
		||||
		else if (drawcommands) return true;
 | 
			
		||||
		startpos++;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldAsyDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
					   WordList *[], Accessor &styler) {
 | 
			
		||||
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
	bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
	if (lineCurrent > 0)
 | 
			
		||||
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 | 
			
		||||
	int levelMinCurrent = levelCurrent;
 | 
			
		||||
	int levelNext = levelCurrent;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int stylePrev = style;
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if (foldComment && IsAsyCommentStyle(style)) {
 | 
			
		||||
			if (!IsAsyCommentStyle(stylePrev) && (stylePrev != SCE_ASY_COMMENTLINEDOC)) {
 | 
			
		||||
				levelNext++;
 | 
			
		||||
			} else if (!IsAsyCommentStyle(styleNext) && (styleNext != SCE_ASY_COMMENTLINEDOC) && !atEOL) {
 | 
			
		||||
				levelNext--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (style == SCE_ASY_OPERATOR) {
 | 
			
		||||
			if (ch == '{') {
 | 
			
		||||
				if (levelMinCurrent > levelNext) {
 | 
			
		||||
					levelMinCurrent = levelNext;
 | 
			
		||||
				}
 | 
			
		||||
				levelNext++;
 | 
			
		||||
			} else if (ch == '}') {
 | 
			
		||||
				levelNext--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atEOL && IsASYDrawingLine(lineCurrent, styler)){
 | 
			
		||||
			if (lineCurrent==0 && IsASYDrawingLine(lineCurrent + 1, styler))
 | 
			
		||||
				levelNext++;
 | 
			
		||||
			else if (lineCurrent!=0 && !IsASYDrawingLine(lineCurrent - 1, styler)
 | 
			
		||||
				&& IsASYDrawingLine(lineCurrent + 1, styler)
 | 
			
		||||
				)
 | 
			
		||||
				levelNext++;
 | 
			
		||||
			else if (lineCurrent!=0 && IsASYDrawingLine(lineCurrent - 1, styler) &&
 | 
			
		||||
				!IsASYDrawingLine(lineCurrent+1, styler))
 | 
			
		||||
				levelNext--;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int levelUse = levelCurrent;
 | 
			
		||||
			if (foldAtElse) {
 | 
			
		||||
				levelUse = levelMinCurrent;
 | 
			
		||||
			}
 | 
			
		||||
			int lev = levelUse | levelNext << 16;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if (levelUse < levelNext)
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelCurrent = levelNext;
 | 
			
		||||
			levelMinCurrent = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!IsASpace(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const asyWordLists[] = {
 | 
			
		||||
            "Primary keywords and identifiers",
 | 
			
		||||
            "Secondary keywords and identifiers",
 | 
			
		||||
            0,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmASY(SCLEX_ASYMPTOTE, ColouriseAsyDoc, "asy", FoldAsyDoc, asyWordLists);
 | 
			
		||||
							
								
								
									
										911
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAU3.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										911
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAU3.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,911 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
// @file LexAU3.cxx
 | 
			
		||||
// Lexer for AutoIt3 https://www.autoitscript.com/site/
 | 
			
		||||
// by Jos van der Zande, jvdzande@yahoo.com
 | 
			
		||||
//
 | 
			
		||||
// Changes:
 | 
			
		||||
// March 28, 2004 - Added the standard Folding code
 | 
			
		||||
// April 21, 2004 - Added Preprosessor Table + Syntax Highlighting
 | 
			
		||||
//                  Fixed Number highlighting
 | 
			
		||||
//                  Changed default isoperator to IsAOperator to have a better match to AutoIt3
 | 
			
		||||
//                  Fixed "#comments_start" -> "#comments-start"
 | 
			
		||||
//                  Fixed "#comments_end" -> "#comments-end"
 | 
			
		||||
//                  Fixed Sendkeys in Strings when not terminated with }
 | 
			
		||||
//                  Added support for Sendkey strings that have second parameter e.g. {UP 5} or {a down}
 | 
			
		||||
// April 26, 2004 - Fixed # pre-processor statement inside of comment block would invalidly change the color.
 | 
			
		||||
//                  Added logic for #include <xyz.au3> to treat the <> as string
 | 
			
		||||
//                  Added underscore to IsAOperator.
 | 
			
		||||
// May 17, 2004   - Changed the folding logic from indent to keyword folding.
 | 
			
		||||
//                  Added Folding logic for blocks of single-commentlines or commentblock.
 | 
			
		||||
//                        triggered by: fold.comment=1
 | 
			
		||||
//                  Added Folding logic for preprocessor blocks triggered by fold.preprocessor=1
 | 
			
		||||
//                  Added Special for #region - #endregion syntax highlight and folding.
 | 
			
		||||
// May 30, 2004   - Fixed issue with continuation lines on If statements.
 | 
			
		||||
// June 5, 2004   - Added comma to Operators for better readability.
 | 
			
		||||
//                  Added fold.compact support set with fold.compact=1
 | 
			
		||||
//                  Changed folding inside of #cs-#ce. Default is no keyword folding inside comment blocks when fold.comment=1
 | 
			
		||||
//                        it will now only happen when fold.comment=2.
 | 
			
		||||
// Sep 5, 2004    - Added logic to handle colourizing words on the last line.
 | 
			
		||||
//                        Typed Characters now show as "default" till they match any table.
 | 
			
		||||
// Oct 10, 2004   - Added logic to show Comments in "Special" directives.
 | 
			
		||||
// Nov  1, 2004   - Added better testing for Numbers supporting x and e notation.
 | 
			
		||||
// Nov 28, 2004   - Added logic to handle continuation lines for syntax highlighting.
 | 
			
		||||
// Jan 10, 2005   - Added Abbreviations Keyword used for expansion
 | 
			
		||||
// Mar 24, 2005   - Updated Abbreviations Keywords to fix when followed by Operator.
 | 
			
		||||
// Apr 18, 2005   - Updated #CE/#Comment-End logic to take a linecomment ";" into account
 | 
			
		||||
//                - Added folding support for With...EndWith
 | 
			
		||||
//                - Added support for a DOT in variable names
 | 
			
		||||
//                - Fixed Underscore in CommentBlock
 | 
			
		||||
// May 23, 2005   - Fixed the SentKey lexing in case of a missing }
 | 
			
		||||
// Aug 11, 2005   - Fixed possible bug with s_save length > 100.
 | 
			
		||||
// Aug 23, 2005   - Added Switch/endswitch support to the folding logic.
 | 
			
		||||
// Sep 27, 2005   - Fixed the SentKey lexing logic in case of multiple sentkeys.
 | 
			
		||||
// Mar 12, 2006   - Fixed issue with <> coloring as String in stead of Operator in rare occasions.
 | 
			
		||||
// Apr  8, 2006   - Added support for AutoIt3 Standard UDF library (SCE_AU3_UDF)
 | 
			
		||||
// Mar  9, 2007   - Fixed bug with + following a String getting the wrong Color.
 | 
			
		||||
// Jun 20, 2007   - Fixed Commentblock issue when LF's are used as EOL.
 | 
			
		||||
// Jul 26, 2007   - Fixed #endregion undetected bug.
 | 
			
		||||
//
 | 
			
		||||
// Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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;
 | 
			
		||||
 | 
			
		||||
static inline bool IsTypeCharacter(const int ch)
 | 
			
		||||
{
 | 
			
		||||
    return ch == '$';
 | 
			
		||||
}
 | 
			
		||||
static inline bool IsAWordChar(const int ch)
 | 
			
		||||
{
 | 
			
		||||
    return (ch < 0x80) && (isalnum(ch) || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordStart(const int ch)
 | 
			
		||||
{
 | 
			
		||||
    return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$' || ch == '.');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsAOperator(char ch) {
 | 
			
		||||
	if (IsASCII(ch) && isalnum(ch))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
 | 
			
		||||
	    ch == '&' || ch == '^' || ch == '=' || ch == '<' || ch == '>' ||
 | 
			
		||||
	    ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == ',' )
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// GetSendKey() filters the portion before and after a/multiple space(s)
 | 
			
		||||
// and return the first portion to be looked-up in the table
 | 
			
		||||
// also check if the second portion is valid... (up,down.on.off,toggle or a number)
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
static int GetSendKey(const char *szLine, char *szKey)
 | 
			
		||||
{
 | 
			
		||||
	int		nFlag	= 0;
 | 
			
		||||
	int		nStartFound	= 0;
 | 
			
		||||
	int		nKeyPos	= 0;
 | 
			
		||||
	int		nSpecPos= 0;
 | 
			
		||||
	int		nSpecNum= 1;
 | 
			
		||||
	int		nPos	= 0;
 | 
			
		||||
	char	cTemp;
 | 
			
		||||
	char	szSpecial[100];
 | 
			
		||||
 | 
			
		||||
	// split the portion of the sendkey in the part before and after the spaces
 | 
			
		||||
	while ( ( (cTemp = szLine[nPos]) != '\0'))
 | 
			
		||||
	{
 | 
			
		||||
		// skip leading Ctrl/Shift/Alt state
 | 
			
		||||
		if (cTemp == '{') {
 | 
			
		||||
			nStartFound = 1;
 | 
			
		||||
		}
 | 
			
		||||
		//
 | 
			
		||||
		if (nStartFound == 1) {
 | 
			
		||||
			if ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space
 | 
			
		||||
			{
 | 
			
		||||
				nFlag = 1;
 | 
			
		||||
				// Add } to the end of the first bit for table lookup later.
 | 
			
		||||
				szKey[nKeyPos++] = '}';
 | 
			
		||||
			}
 | 
			
		||||
			else if (cTemp == ' ')
 | 
			
		||||
			{
 | 
			
		||||
				// skip other spaces
 | 
			
		||||
			}
 | 
			
		||||
			else if (nFlag == 0)
 | 
			
		||||
			{
 | 
			
		||||
				// save first portion into var till space or } is hit
 | 
			
		||||
				szKey[nKeyPos++] = cTemp;
 | 
			
		||||
			}
 | 
			
		||||
			else if ((nFlag == 1) && (cTemp != '}'))
 | 
			
		||||
			{
 | 
			
		||||
				// Save second portion into var...
 | 
			
		||||
				szSpecial[nSpecPos++] = cTemp;
 | 
			
		||||
				// check if Second portion is all numbers for repeat fuction
 | 
			
		||||
				if (isdigit(cTemp) == false) {nSpecNum = 0;}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		nPos++;									// skip to next char
 | 
			
		||||
 | 
			
		||||
	} // End While
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// Check if the second portion is either a number or one of these keywords
 | 
			
		||||
	szKey[nKeyPos] = '\0';
 | 
			
		||||
	szSpecial[nSpecPos] = '\0';
 | 
			
		||||
	if (strcmp(szSpecial,"down")== 0    || strcmp(szSpecial,"up")== 0  ||
 | 
			
		||||
		strcmp(szSpecial,"on")== 0      || strcmp(szSpecial,"off")== 0 ||
 | 
			
		||||
		strcmp(szSpecial,"toggle")== 0  || nSpecNum == 1 )
 | 
			
		||||
	{
 | 
			
		||||
		nFlag = 0;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		nFlag = 1;
 | 
			
		||||
	}
 | 
			
		||||
	return nFlag;  // 1 is bad, 0 is good
 | 
			
		||||
 | 
			
		||||
} // GetSendKey()
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Routine to check the last "none comment" character on a line to see if its a continuation
 | 
			
		||||
//
 | 
			
		||||
static bool IsContinuationLine(Sci_PositionU szLine, Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
	Sci_Position nsPos = styler.LineStart(szLine);
 | 
			
		||||
	Sci_Position nePos = styler.LineStart(szLine+1) - 2;
 | 
			
		||||
	//int stylech = styler.StyleAt(nsPos);
 | 
			
		||||
	while (nsPos < nePos)
 | 
			
		||||
	{
 | 
			
		||||
		//stylech = styler.StyleAt(nePos);
 | 
			
		||||
		int stylech = styler.StyleAt(nsPos);
 | 
			
		||||
		if (!(stylech == SCE_AU3_COMMENT)) {
 | 
			
		||||
			char ch = styler.SafeGetCharAt(nePos);
 | 
			
		||||
			if (!isspacechar(ch)) {
 | 
			
		||||
				if (ch == '_')
 | 
			
		||||
					return true;
 | 
			
		||||
				else
 | 
			
		||||
					return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		nePos--; // skip to next char
 | 
			
		||||
	} // End While
 | 
			
		||||
	return false;
 | 
			
		||||
} // IsContinuationLine()
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// syntax highlighting logic
 | 
			
		||||
static void ColouriseAU3Doc(Sci_PositionU startPos,
 | 
			
		||||
							Sci_Position length, int initStyle,
 | 
			
		||||
							WordList *keywordlists[],
 | 
			
		||||
							Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
    WordList &keywords = *keywordlists[0];
 | 
			
		||||
    WordList &keywords2 = *keywordlists[1];
 | 
			
		||||
    WordList &keywords3 = *keywordlists[2];
 | 
			
		||||
    WordList &keywords4 = *keywordlists[3];
 | 
			
		||||
    WordList &keywords5 = *keywordlists[4];
 | 
			
		||||
    WordList &keywords6 = *keywordlists[5];
 | 
			
		||||
    WordList &keywords7 = *keywordlists[6];
 | 
			
		||||
    WordList &keywords8 = *keywordlists[7];
 | 
			
		||||
	// find the first previous line without continuation character at the end
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	Sci_Position s_startPos = startPos;
 | 
			
		||||
	// When not inside a Block comment: find First line without _
 | 
			
		||||
	if (!(initStyle==SCE_AU3_COMMENTBLOCK)) {
 | 
			
		||||
		while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
 | 
			
		||||
			   (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
 | 
			
		||||
			lineCurrent--;
 | 
			
		||||
			startPos = styler.LineStart(lineCurrent); // get start position
 | 
			
		||||
			initStyle =  0;                           // reset the start style to 0
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Set the new length to include it from the start and set the start position
 | 
			
		||||
	length = length + s_startPos - startPos;      // correct the total length to process
 | 
			
		||||
    styler.StartAt(startPos);
 | 
			
		||||
 | 
			
		||||
    StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
	char si;     // string indicator "=1 '=2
 | 
			
		||||
	char ni;     // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3
 | 
			
		||||
	char ci;     // comment indicator 0=not linecomment(;)
 | 
			
		||||
	char s_save[100] = "";
 | 
			
		||||
	si=0;
 | 
			
		||||
	ni=0;
 | 
			
		||||
	ci=0;
 | 
			
		||||
	//$$$
 | 
			
		||||
    for (; sc.More(); sc.Forward()) {
 | 
			
		||||
		char s[100];
 | 
			
		||||
		sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
		// **********************************************
 | 
			
		||||
		// save the total current word for eof processing
 | 
			
		||||
		if (IsAWordChar(sc.ch) || sc.ch == '}')
 | 
			
		||||
		{
 | 
			
		||||
			strcpy(s_save,s);
 | 
			
		||||
			int tp = static_cast<int>(strlen(s_save));
 | 
			
		||||
			if (tp < 99) {
 | 
			
		||||
				s_save[tp] = static_cast<char>(tolower(sc.ch));
 | 
			
		||||
				s_save[tp+1] = '\0';
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// **********************************************
 | 
			
		||||
		//
 | 
			
		||||
		switch (sc.state)
 | 
			
		||||
        {
 | 
			
		||||
            case SCE_AU3_COMMENTBLOCK:
 | 
			
		||||
            {
 | 
			
		||||
				//Reset at line end
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					ci=0;
 | 
			
		||||
					if (strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0) {
 | 
			
		||||
						if (sc.atLineEnd)
 | 
			
		||||
							sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
						else
 | 
			
		||||
							sc.SetState(SCE_AU3_COMMENTBLOCK);
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				//skip rest of line when a ; is encountered
 | 
			
		||||
				if (sc.chPrev == ';') {
 | 
			
		||||
					ci=2;
 | 
			
		||||
					sc.SetState(SCE_AU3_COMMENTBLOCK);
 | 
			
		||||
				}
 | 
			
		||||
				// skip rest of the line
 | 
			
		||||
				if (ci==2)
 | 
			
		||||
					break;
 | 
			
		||||
				// check when first character is detected on the line
 | 
			
		||||
				if (ci==0) {
 | 
			
		||||
					if (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
						ci=1;
 | 
			
		||||
						sc.SetState(SCE_AU3_COMMENTBLOCK);
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0))) {
 | 
			
		||||
					if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0))
 | 
			
		||||
							sc.SetState(SCE_AU3_COMMENT);  // set to comment line for the rest of the line
 | 
			
		||||
					else
 | 
			
		||||
						ci=2;  // line doesn't begin with #CE so skip the rest of the line
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
            case SCE_AU3_COMMENT:
 | 
			
		||||
            {
 | 
			
		||||
                if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case SCE_AU3_OPERATOR:
 | 
			
		||||
            {
 | 
			
		||||
                // check if its a COMobject
 | 
			
		||||
				if (sc.chPrev == '.' && IsAWordChar(sc.ch)) {
 | 
			
		||||
					sc.SetState(SCE_AU3_COMOBJ);
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case SCE_AU3_SPECIAL:
 | 
			
		||||
            {
 | 
			
		||||
                if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
 | 
			
		||||
				if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case SCE_AU3_KEYWORD:
 | 
			
		||||
            {
 | 
			
		||||
                if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && (strcmp(s, "#comments") == 0 || strcmp(s, "#include") == 0))))
 | 
			
		||||
                {
 | 
			
		||||
                    if (!IsTypeCharacter(sc.ch))
 | 
			
		||||
                    {
 | 
			
		||||
						if (strcmp(s, "#cs")== 0 || strcmp(s, "#comments-start")== 0 )
 | 
			
		||||
						{
 | 
			
		||||
							sc.ChangeState(SCE_AU3_COMMENTBLOCK);
 | 
			
		||||
							sc.SetState(SCE_AU3_COMMENTBLOCK);
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
						else if (keywords.InList(s)) {
 | 
			
		||||
							sc.ChangeState(SCE_AU3_KEYWORD);
 | 
			
		||||
							sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
						}
 | 
			
		||||
						else if (keywords2.InList(s)) {
 | 
			
		||||
							sc.ChangeState(SCE_AU3_FUNCTION);
 | 
			
		||||
							sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
						}
 | 
			
		||||
						else if (keywords3.InList(s)) {
 | 
			
		||||
							sc.ChangeState(SCE_AU3_MACRO);
 | 
			
		||||
							sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
						}
 | 
			
		||||
						else if (keywords5.InList(s)) {
 | 
			
		||||
							sc.ChangeState(SCE_AU3_PREPROCESSOR);
 | 
			
		||||
							sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
							if (strcmp(s, "#include")== 0)
 | 
			
		||||
							{
 | 
			
		||||
								si = 3;   // use to determine string start for #inlude <>
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						else if (keywords6.InList(s)) {
 | 
			
		||||
							sc.ChangeState(SCE_AU3_SPECIAL);
 | 
			
		||||
							sc.SetState(SCE_AU3_SPECIAL);
 | 
			
		||||
						}
 | 
			
		||||
						else if ((keywords7.InList(s)) && (!IsAOperator(static_cast<char>(sc.ch)))) {
 | 
			
		||||
							sc.ChangeState(SCE_AU3_EXPAND);
 | 
			
		||||
							sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
						}
 | 
			
		||||
						else if (keywords8.InList(s)) {
 | 
			
		||||
							sc.ChangeState(SCE_AU3_UDF);
 | 
			
		||||
							sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
						}
 | 
			
		||||
						else if (strcmp(s, "_") == 0) {
 | 
			
		||||
							sc.ChangeState(SCE_AU3_OPERATOR);
 | 
			
		||||
							sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
						}
 | 
			
		||||
						else if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
							sc.ChangeState(SCE_AU3_DEFAULT);
 | 
			
		||||
							sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
                if (sc.atLineEnd) {
 | 
			
		||||
					sc.SetState(SCE_AU3_DEFAULT);}
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
			case SCE_AU3_NUMBER:
 | 
			
		||||
            {
 | 
			
		||||
				// Numeric indicator error=9 normal=0 normal+dec=1 hex=2 E-not=3
 | 
			
		||||
				//
 | 
			
		||||
				// test for Hex notation
 | 
			
		||||
				if (strcmp(s, "0") == 0 && (sc.ch == 'x' || sc.ch == 'X') && ni == 0)
 | 
			
		||||
				{
 | 
			
		||||
					ni = 2;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				// test for E notation
 | 
			
		||||
				if (IsADigit(sc.chPrev) && (sc.ch == 'e' || sc.ch == 'E') && ni <= 1)
 | 
			
		||||
				{
 | 
			
		||||
					ni = 3;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				//  Allow Hex characters inside hex numeric strings
 | 
			
		||||
				if ((ni == 2) &&
 | 
			
		||||
					(sc.ch == 'a' || sc.ch == 'b' || sc.ch == 'c' || sc.ch == 'd' || sc.ch == 'e' || sc.ch == 'f' ||
 | 
			
		||||
					 sc.ch == 'A' || sc.ch == 'B' || sc.ch == 'C' || sc.ch == 'D' || sc.ch == 'E' || sc.ch == 'F' ))
 | 
			
		||||
				{
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				// test for 1 dec point only
 | 
			
		||||
				if (sc.ch == '.')
 | 
			
		||||
				{
 | 
			
		||||
					if (ni==0)
 | 
			
		||||
					{
 | 
			
		||||
						ni=1;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						ni=9;
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				// end of numeric string ?
 | 
			
		||||
				if (!(IsADigit(sc.ch)))
 | 
			
		||||
				{
 | 
			
		||||
					if (ni==9)
 | 
			
		||||
					{
 | 
			
		||||
						sc.ChangeState(SCE_AU3_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
					sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case SCE_AU3_VARIABLE:
 | 
			
		||||
			{
 | 
			
		||||
				// Check if its a COMObject
 | 
			
		||||
				if (sc.ch == '.' && !IsADigit(sc.chNext)) {
 | 
			
		||||
					sc.SetState(SCE_AU3_OPERATOR);
 | 
			
		||||
				}
 | 
			
		||||
				else if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
					sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
            }
 | 
			
		||||
			case SCE_AU3_COMOBJ:
 | 
			
		||||
			{
 | 
			
		||||
				if (!(IsAWordChar(sc.ch))) {
 | 
			
		||||
					sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
            }
 | 
			
		||||
            case SCE_AU3_STRING:
 | 
			
		||||
            {
 | 
			
		||||
				// check for " to end a double qouted string or
 | 
			
		||||
				// check for ' to end a single qouted string
 | 
			
		||||
	            if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\'') || (si == 3 && sc.ch == '>'))
 | 
			
		||||
				{
 | 
			
		||||
					sc.ForwardSetState(SCE_AU3_DEFAULT);
 | 
			
		||||
					si=0;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
                if (sc.atLineEnd)
 | 
			
		||||
				{
 | 
			
		||||
					si=0;
 | 
			
		||||
					// at line end and not found a continuation char then reset to default
 | 
			
		||||
					Sci_Position lineCurrent = styler.GetLine(sc.currentPos);
 | 
			
		||||
					if (!IsContinuationLine(lineCurrent,styler))
 | 
			
		||||
					{
 | 
			
		||||
						sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				// find Sendkeys in a STRING
 | 
			
		||||
				if (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ) {
 | 
			
		||||
					sc.SetState(SCE_AU3_SENT);}
 | 
			
		||||
				break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case SCE_AU3_SENT:
 | 
			
		||||
            {
 | 
			
		||||
				// Send key string ended
 | 
			
		||||
				if (sc.chPrev == '}' && sc.ch != '}')
 | 
			
		||||
				{
 | 
			
		||||
					// set color to SENDKEY when valid sendkey .. else set back to regular string
 | 
			
		||||
					char sk[100];
 | 
			
		||||
					// split {111 222} and return {111} and check if 222 is valid.
 | 
			
		||||
					// if return code = 1 then invalid 222 so must be string
 | 
			
		||||
					if (GetSendKey(s,sk))
 | 
			
		||||
					{
 | 
			
		||||
						sc.ChangeState(SCE_AU3_STRING);
 | 
			
		||||
					}
 | 
			
		||||
					// if single char between {?} then its ok as sendkey for a single character
 | 
			
		||||
					else if (strlen(sk) == 3)
 | 
			
		||||
					{
 | 
			
		||||
						sc.ChangeState(SCE_AU3_SENT);
 | 
			
		||||
					}
 | 
			
		||||
					// if sendkey {111} is in table then ok as sendkey
 | 
			
		||||
					else if (keywords4.InList(sk))
 | 
			
		||||
					{
 | 
			
		||||
						sc.ChangeState(SCE_AU3_SENT);
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						sc.ChangeState(SCE_AU3_STRING);
 | 
			
		||||
					}
 | 
			
		||||
					sc.SetState(SCE_AU3_STRING);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					// check if the start is a valid SendKey start
 | 
			
		||||
					Sci_Position		nPos	= 0;
 | 
			
		||||
					int		nState	= 1;
 | 
			
		||||
					char	cTemp;
 | 
			
		||||
					while (!(nState == 2) && ((cTemp = s[nPos]) != '\0'))
 | 
			
		||||
					{
 | 
			
		||||
						if (cTemp == '{' && nState == 1)
 | 
			
		||||
						{
 | 
			
		||||
							nState = 2;
 | 
			
		||||
						}
 | 
			
		||||
						if (nState == 1 && !(cTemp == '+' || cTemp == '!' || cTemp == '^' || cTemp == '#' ))
 | 
			
		||||
						{
 | 
			
		||||
							nState = 0;
 | 
			
		||||
						}
 | 
			
		||||
						nPos++;
 | 
			
		||||
					}
 | 
			
		||||
					//Verify characters infront of { ... if not assume  regular string
 | 
			
		||||
					if (nState == 1 && (!(sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ))) {
 | 
			
		||||
						sc.ChangeState(SCE_AU3_STRING);
 | 
			
		||||
						sc.SetState(SCE_AU3_STRING);
 | 
			
		||||
					}
 | 
			
		||||
					// If invalid character found then assume its a regular string
 | 
			
		||||
					if (nState == 0) {
 | 
			
		||||
						sc.ChangeState(SCE_AU3_STRING);
 | 
			
		||||
						sc.SetState(SCE_AU3_STRING);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				// check if next portion is again a sendkey
 | 
			
		||||
				if (sc.atLineEnd)
 | 
			
		||||
				{
 | 
			
		||||
					sc.ChangeState(SCE_AU3_STRING);
 | 
			
		||||
					sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
					si = 0;  // reset string indicator
 | 
			
		||||
				}
 | 
			
		||||
				//* check in next characters following a sentkey are again a sent key
 | 
			
		||||
				// Need this test incase of 2 sentkeys like {F1}{ENTER} but not detect {{}
 | 
			
		||||
				if (sc.state == SCE_AU3_STRING && (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' )) {
 | 
			
		||||
					sc.SetState(SCE_AU3_SENT);}
 | 
			
		||||
				// check to see if the string ended...
 | 
			
		||||
				// Sendkey string isn't complete but the string ended....
 | 
			
		||||
				if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\''))
 | 
			
		||||
				{
 | 
			
		||||
					sc.ChangeState(SCE_AU3_STRING);
 | 
			
		||||
					sc.ForwardSetState(SCE_AU3_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
            }
 | 
			
		||||
        }  //switch (sc.state)
 | 
			
		||||
 | 
			
		||||
        // Determine if a new state should be entered:
 | 
			
		||||
 | 
			
		||||
		if (sc.state == SCE_AU3_DEFAULT)
 | 
			
		||||
        {
 | 
			
		||||
            if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
 | 
			
		||||
            else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);}
 | 
			
		||||
            else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);}
 | 
			
		||||
            else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);}
 | 
			
		||||
            else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
 | 
			
		||||
            //else if (sc.ch == '_') {sc.SetState(SCE_AU3_KEYWORD);}
 | 
			
		||||
            else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);}  // string after #include
 | 
			
		||||
            else if (sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_AU3_STRING);
 | 
			
		||||
				si = 1;	}
 | 
			
		||||
            else if (sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(SCE_AU3_STRING);
 | 
			
		||||
				si = 2;	}
 | 
			
		||||
            else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
 | 
			
		||||
			{
 | 
			
		||||
				sc.SetState(SCE_AU3_NUMBER);
 | 
			
		||||
				ni = 0;
 | 
			
		||||
			}
 | 
			
		||||
            else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
 | 
			
		||||
            else if (IsAOperator(static_cast<char>(sc.ch))) {sc.SetState(SCE_AU3_OPERATOR);}
 | 
			
		||||
			else if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
 | 
			
		||||
        }
 | 
			
		||||
    }      //for (; sc.More(); sc.Forward())
 | 
			
		||||
 | 
			
		||||
	//*************************************
 | 
			
		||||
	// Colourize the last word correctly
 | 
			
		||||
	//*************************************
 | 
			
		||||
	if (sc.state == SCE_AU3_KEYWORD)
 | 
			
		||||
		{
 | 
			
		||||
		if (strcmp(s_save, "#cs")== 0 || strcmp(s_save, "#comments-start")== 0 )
 | 
			
		||||
		{
 | 
			
		||||
			sc.ChangeState(SCE_AU3_COMMENTBLOCK);
 | 
			
		||||
			sc.SetState(SCE_AU3_COMMENTBLOCK);
 | 
			
		||||
		}
 | 
			
		||||
		else if (keywords.InList(s_save)) {
 | 
			
		||||
			sc.ChangeState(SCE_AU3_KEYWORD);
 | 
			
		||||
			sc.SetState(SCE_AU3_KEYWORD);
 | 
			
		||||
		}
 | 
			
		||||
		else if (keywords2.InList(s_save)) {
 | 
			
		||||
			sc.ChangeState(SCE_AU3_FUNCTION);
 | 
			
		||||
			sc.SetState(SCE_AU3_FUNCTION);
 | 
			
		||||
		}
 | 
			
		||||
		else if (keywords3.InList(s_save)) {
 | 
			
		||||
			sc.ChangeState(SCE_AU3_MACRO);
 | 
			
		||||
			sc.SetState(SCE_AU3_MACRO);
 | 
			
		||||
		}
 | 
			
		||||
		else if (keywords5.InList(s_save)) {
 | 
			
		||||
			sc.ChangeState(SCE_AU3_PREPROCESSOR);
 | 
			
		||||
			sc.SetState(SCE_AU3_PREPROCESSOR);
 | 
			
		||||
		}
 | 
			
		||||
		else if (keywords6.InList(s_save)) {
 | 
			
		||||
			sc.ChangeState(SCE_AU3_SPECIAL);
 | 
			
		||||
			sc.SetState(SCE_AU3_SPECIAL);
 | 
			
		||||
		}
 | 
			
		||||
		else if (keywords7.InList(s_save) && sc.atLineEnd) {
 | 
			
		||||
			sc.ChangeState(SCE_AU3_EXPAND);
 | 
			
		||||
			sc.SetState(SCE_AU3_EXPAND);
 | 
			
		||||
		}
 | 
			
		||||
		else if (keywords8.InList(s_save)) {
 | 
			
		||||
			sc.ChangeState(SCE_AU3_UDF);
 | 
			
		||||
			sc.SetState(SCE_AU3_UDF);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			sc.ChangeState(SCE_AU3_DEFAULT);
 | 
			
		||||
			sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (sc.state == SCE_AU3_SENT)
 | 
			
		||||
    {
 | 
			
		||||
		// Send key string ended
 | 
			
		||||
		if (sc.chPrev == '}' && sc.ch != '}')
 | 
			
		||||
		{
 | 
			
		||||
			// set color to SENDKEY when valid sendkey .. else set back to regular string
 | 
			
		||||
			char sk[100];
 | 
			
		||||
			// split {111 222} and return {111} and check if 222 is valid.
 | 
			
		||||
			// if return code = 1 then invalid 222 so must be string
 | 
			
		||||
			if (GetSendKey(s_save,sk))
 | 
			
		||||
			{
 | 
			
		||||
				sc.ChangeState(SCE_AU3_STRING);
 | 
			
		||||
			}
 | 
			
		||||
			// if single char between {?} then its ok as sendkey for a single character
 | 
			
		||||
			else if (strlen(sk) == 3)
 | 
			
		||||
			{
 | 
			
		||||
				sc.ChangeState(SCE_AU3_SENT);
 | 
			
		||||
			}
 | 
			
		||||
			// if sendkey {111} is in table then ok as sendkey
 | 
			
		||||
			else if (keywords4.InList(sk))
 | 
			
		||||
			{
 | 
			
		||||
				sc.ChangeState(SCE_AU3_SENT);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				sc.ChangeState(SCE_AU3_STRING);
 | 
			
		||||
			}
 | 
			
		||||
			sc.SetState(SCE_AU3_STRING);
 | 
			
		||||
		}
 | 
			
		||||
		// check if next portion is again a sendkey
 | 
			
		||||
		if (sc.atLineEnd)
 | 
			
		||||
		{
 | 
			
		||||
			sc.ChangeState(SCE_AU3_STRING);
 | 
			
		||||
			sc.SetState(SCE_AU3_DEFAULT);
 | 
			
		||||
		}
 | 
			
		||||
    }
 | 
			
		||||
	//*************************************
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
static bool IsStreamCommentStyle(int style) {
 | 
			
		||||
	return style == SCE_AU3_COMMENT || style == SCE_AU3_COMMENTBLOCK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Routine to find first none space on the current line and return its Style
 | 
			
		||||
// needed for comment lines not starting on pos 1
 | 
			
		||||
static int GetStyleFirstWord(Sci_PositionU szLine, Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
	Sci_Position nsPos = styler.LineStart(szLine);
 | 
			
		||||
	Sci_Position nePos = styler.LineStart(szLine+1) - 1;
 | 
			
		||||
	while (isspacechar(styler.SafeGetCharAt(nsPos)) && nsPos < nePos)
 | 
			
		||||
	{
 | 
			
		||||
		nsPos++; // skip to next char
 | 
			
		||||
 | 
			
		||||
	} // End While
 | 
			
		||||
	return styler.StyleAt(nsPos);
 | 
			
		||||
 | 
			
		||||
} // GetStyleFirstWord()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
static void FoldAU3Doc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
	Sci_Position endPos = startPos + length;
 | 
			
		||||
	// get settings from the config files for folding comments and preprocessor lines
 | 
			
		||||
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 | 
			
		||||
	bool foldInComment = styler.GetPropertyInt("fold.comment") == 2;
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
	bool foldpreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
 | 
			
		||||
	// Backtrack to previous line in case need to fix its fold status
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	if (startPos > 0) {
 | 
			
		||||
		if (lineCurrent > 0) {
 | 
			
		||||
			lineCurrent--;
 | 
			
		||||
			startPos = styler.LineStart(lineCurrent);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// vars for style of previous/current/next lines
 | 
			
		||||
	int style = GetStyleFirstWord(lineCurrent,styler);
 | 
			
		||||
	int stylePrev = 0;
 | 
			
		||||
	// find the first previous line without continuation character at the end
 | 
			
		||||
	while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
 | 
			
		||||
	       (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
 | 
			
		||||
		lineCurrent--;
 | 
			
		||||
		startPos = styler.LineStart(lineCurrent);
 | 
			
		||||
	}
 | 
			
		||||
	if (lineCurrent > 0) {
 | 
			
		||||
		stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
 | 
			
		||||
	}
 | 
			
		||||
	// vars for getting first word to check for keywords
 | 
			
		||||
	bool FirstWordStart = false;
 | 
			
		||||
	bool FirstWordEnd = false;
 | 
			
		||||
	char szKeyword[11]="";
 | 
			
		||||
	int	 szKeywordlen = 0;
 | 
			
		||||
	char szThen[5]="";
 | 
			
		||||
	int	 szThenlen = 0;
 | 
			
		||||
	bool ThenFoundLast = false;
 | 
			
		||||
	// var for indentlevel
 | 
			
		||||
	int levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
	if (lineCurrent > 0)
 | 
			
		||||
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 | 
			
		||||
	int levelNext = levelCurrent;
 | 
			
		||||
	//
 | 
			
		||||
	int	visibleChars = 0;
 | 
			
		||||
	char chNext = styler.SafeGetCharAt(startPos);
 | 
			
		||||
	char chPrev = ' ';
 | 
			
		||||
	//
 | 
			
		||||
	for (Sci_Position i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		if (IsAWordChar(ch)) {
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
		// get the syle for the current character neede to check in comment
 | 
			
		||||
		int stylech = styler.StyleAt(i);
 | 
			
		||||
		// get first word for the line for indent check max 9 characters
 | 
			
		||||
		if (FirstWordStart && (!(FirstWordEnd))) {
 | 
			
		||||
			if (!IsAWordChar(ch)) {
 | 
			
		||||
				FirstWordEnd = true;
 | 
			
		||||
				szKeyword[szKeywordlen] = '\0';
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				if (szKeywordlen < 10) {
 | 
			
		||||
				szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// start the capture of the first word
 | 
			
		||||
		if (!(FirstWordStart)) {
 | 
			
		||||
			if (IsAWordChar(ch) || IsAWordStart(ch) || ch == ';') {
 | 
			
		||||
				FirstWordStart = true;
 | 
			
		||||
				szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// only process this logic when not in comment section
 | 
			
		||||
		if (!(stylech == SCE_AU3_COMMENT)) {
 | 
			
		||||
			if (ThenFoundLast) {
 | 
			
		||||
				if (IsAWordChar(ch)) {
 | 
			
		||||
					ThenFoundLast = false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// find out if the word "then" is the last on a "if" line
 | 
			
		||||
			if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
 | 
			
		||||
				if (szThenlen == 4) {
 | 
			
		||||
					szThen[0] = szThen[1];
 | 
			
		||||
					szThen[1] = szThen[2];
 | 
			
		||||
					szThen[2] = szThen[3];
 | 
			
		||||
					szThen[3] = static_cast<char>(tolower(ch));
 | 
			
		||||
					if (strcmp(szThen,"then") == 0 ) {
 | 
			
		||||
						ThenFoundLast = true;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					szThen[szThenlen++] = static_cast<char>(tolower(ch));
 | 
			
		||||
					if (szThenlen == 5) {
 | 
			
		||||
						szThen[4] = '\0';
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// End of Line found so process the information
 | 
			
		||||
		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
 | 
			
		||||
			// **************************
 | 
			
		||||
			// Folding logic for Keywords
 | 
			
		||||
			// **************************
 | 
			
		||||
			// if a keyword is found on the current line and the line doesn't end with _ (continuation)
 | 
			
		||||
			//    and we are not inside a commentblock.
 | 
			
		||||
			if (szKeywordlen > 0 && (!(chPrev == '_')) &&
 | 
			
		||||
				((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
 | 
			
		||||
				szKeyword[szKeywordlen] = '\0';
 | 
			
		||||
				// only fold "if" last keyword is "then"  (else its a one line if)
 | 
			
		||||
				if (strcmp(szKeyword,"if") == 0  && ThenFoundLast) {
 | 
			
		||||
						levelNext++;
 | 
			
		||||
				}
 | 
			
		||||
				// create new fold for these words
 | 
			
		||||
				if (strcmp(szKeyword,"do") == 0   || strcmp(szKeyword,"for") == 0 ||
 | 
			
		||||
					strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0||
 | 
			
		||||
					strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"#region") == 0 ) {
 | 
			
		||||
						levelNext++;
 | 
			
		||||
				}
 | 
			
		||||
				// create double Fold for select&switch because Case will subtract one of the current level
 | 
			
		||||
				if (strcmp(szKeyword,"select") == 0 || strcmp(szKeyword,"switch") == 0) {
 | 
			
		||||
						levelNext++;
 | 
			
		||||
						levelNext++;
 | 
			
		||||
				}
 | 
			
		||||
				// end the fold for these words before the current line
 | 
			
		||||
				if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 ||
 | 
			
		||||
					strcmp(szKeyword,"next") == 0    || strcmp(szKeyword,"until") == 0 ||
 | 
			
		||||
					strcmp(szKeyword,"endwith") == 0 ||strcmp(szKeyword,"wend") == 0){
 | 
			
		||||
						levelNext--;
 | 
			
		||||
						levelCurrent--;
 | 
			
		||||
				}
 | 
			
		||||
				// end the fold for these words before the current line and Start new fold
 | 
			
		||||
				if (strcmp(szKeyword,"case") == 0      || strcmp(szKeyword,"else") == 0 ||
 | 
			
		||||
					strcmp(szKeyword,"elseif") == 0 ) {
 | 
			
		||||
						levelCurrent--;
 | 
			
		||||
				}
 | 
			
		||||
				// end the double fold for this word before the current line
 | 
			
		||||
				if (strcmp(szKeyword,"endselect") == 0 || strcmp(szKeyword,"endswitch") == 0 ) {
 | 
			
		||||
						levelNext--;
 | 
			
		||||
						levelNext--;
 | 
			
		||||
						levelCurrent--;
 | 
			
		||||
						levelCurrent--;
 | 
			
		||||
				}
 | 
			
		||||
				// end the fold for these words on the current line
 | 
			
		||||
				if (strcmp(szKeyword,"#endregion") == 0 ) {
 | 
			
		||||
						levelNext--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// Preprocessor and Comment folding
 | 
			
		||||
			int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
 | 
			
		||||
			// *************************************
 | 
			
		||||
			// Folding logic for preprocessor blocks
 | 
			
		||||
			// *************************************
 | 
			
		||||
			// process preprosessor line
 | 
			
		||||
			if (foldpreprocessor && style == SCE_AU3_PREPROCESSOR) {
 | 
			
		||||
				if (!(stylePrev == SCE_AU3_PREPROCESSOR) && (styleNext == SCE_AU3_PREPROCESSOR)) {
 | 
			
		||||
				    levelNext++;
 | 
			
		||||
				}
 | 
			
		||||
				// fold till the last line for normal comment lines
 | 
			
		||||
				else if (stylePrev == SCE_AU3_PREPROCESSOR && !(styleNext == SCE_AU3_PREPROCESSOR)) {
 | 
			
		||||
					levelNext--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// *********************************
 | 
			
		||||
			// Folding logic for Comment blocks
 | 
			
		||||
			// *********************************
 | 
			
		||||
			if (foldComment && IsStreamCommentStyle(style)) {
 | 
			
		||||
				// Start of a comment block
 | 
			
		||||
				if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
 | 
			
		||||
				    levelNext++;
 | 
			
		||||
				}
 | 
			
		||||
				// fold till the last line for normal comment lines
 | 
			
		||||
				else if (IsStreamCommentStyle(stylePrev)
 | 
			
		||||
						&& !(styleNext == SCE_AU3_COMMENT)
 | 
			
		||||
						&& stylePrev == SCE_AU3_COMMENT
 | 
			
		||||
						&& style == SCE_AU3_COMMENT) {
 | 
			
		||||
					levelNext--;
 | 
			
		||||
				}
 | 
			
		||||
				// fold till the one but last line for Blockcomment lines
 | 
			
		||||
				else if (IsStreamCommentStyle(stylePrev)
 | 
			
		||||
						&& !(styleNext == SCE_AU3_COMMENTBLOCK)
 | 
			
		||||
						&& style == SCE_AU3_COMMENTBLOCK) {
 | 
			
		||||
					levelNext--;
 | 
			
		||||
					levelCurrent--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			int levelUse = levelCurrent;
 | 
			
		||||
			int lev = levelUse | levelNext << 16;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if (levelUse < levelNext) {
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			// reset values for the next line
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			stylePrev = style;
 | 
			
		||||
			style = styleNext;
 | 
			
		||||
			levelCurrent = levelNext;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
			// if the last character is an Underscore then don't reset since the line continues on the next line.
 | 
			
		||||
			if (!(chPrev == '_')) {
 | 
			
		||||
				szKeywordlen = 0;
 | 
			
		||||
				szThenlen = 0;
 | 
			
		||||
				FirstWordStart = false;
 | 
			
		||||
				FirstWordEnd = false;
 | 
			
		||||
				ThenFoundLast = false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// save the last processed character
 | 
			
		||||
		if (!isspacechar(ch)) {
 | 
			
		||||
			chPrev = ch;
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
static const char * const AU3WordLists[] = {
 | 
			
		||||
    "#autoit keywords",
 | 
			
		||||
    "#autoit functions",
 | 
			
		||||
    "#autoit macros",
 | 
			
		||||
    "#autoit Sent keys",
 | 
			
		||||
    "#autoit Pre-processors",
 | 
			
		||||
    "#autoit Special",
 | 
			
		||||
    "#autoit Expand",
 | 
			
		||||
    "#autoit UDF",
 | 
			
		||||
    0
 | 
			
		||||
};
 | 
			
		||||
extern const LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", FoldAU3Doc , AU3WordLists);
 | 
			
		||||
							
								
								
									
										232
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAVE.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAVE.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,232 @@
 | 
			
		||||
// SciTE - Scintilla based Text Editor
 | 
			
		||||
/** @file LexAVE.cxx
 | 
			
		||||
 ** Lexer for Avenue.
 | 
			
		||||
 **
 | 
			
		||||
  ** Written by Alexey Yutkin <yutkin@geol.msu.ru>.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
static inline bool IsEnumChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch)|| ch == '_');
 | 
			
		||||
}
 | 
			
		||||
static inline bool IsANumberChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '.' );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool IsAWordStart(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool isAveOperator(char ch) {
 | 
			
		||||
	if (IsASCII(ch) && isalnum(ch))
 | 
			
		||||
		return false;
 | 
			
		||||
	// '.' left out as it is used to make up numbers
 | 
			
		||||
	if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
 | 
			
		||||
		ch == '(' || ch == ')' || ch == '=' ||
 | 
			
		||||
		ch == '{' || ch == '}' ||
 | 
			
		||||
		ch == '[' || ch == ']' || ch == ';' ||
 | 
			
		||||
		ch == '<' || ch == '>' || ch == ',' ||
 | 
			
		||||
		ch == '.'  )
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseAveDoc(
 | 
			
		||||
	Sci_PositionU startPos,
 | 
			
		||||
	Sci_Position length,
 | 
			
		||||
	int initStyle,
 | 
			
		||||
	WordList *keywordlists[],
 | 
			
		||||
	Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
	WordList &keywords2 = *keywordlists[1];
 | 
			
		||||
	WordList &keywords3 = *keywordlists[2];
 | 
			
		||||
	WordList &keywords4 = *keywordlists[3];
 | 
			
		||||
	WordList &keywords5 = *keywordlists[4];
 | 
			
		||||
	WordList &keywords6 = *keywordlists[5];
 | 
			
		||||
 | 
			
		||||
	// Do not leak onto next line
 | 
			
		||||
	if (initStyle == SCE_AVE_STRINGEOL) {
 | 
			
		||||
		initStyle = SCE_AVE_DEFAULT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
		if (sc.atLineEnd) {
 | 
			
		||||
			// Update the line state, so it can be seen by next line
 | 
			
		||||
			Sci_Position currentLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
			styler.SetLineState(currentLine, 0);
 | 
			
		||||
		}
 | 
			
		||||
		if (sc.atLineStart && (sc.state == SCE_AVE_STRING)) {
 | 
			
		||||
			// Prevent SCE_AVE_STRINGEOL from leaking back to previous line
 | 
			
		||||
			sc.SetState(SCE_AVE_STRING);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		if (sc.state == SCE_AVE_OPERATOR) {
 | 
			
		||||
			sc.SetState(SCE_AVE_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_AVE_NUMBER) {
 | 
			
		||||
			if (!IsANumberChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_AVE_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_AVE_ENUM) {
 | 
			
		||||
			if (!IsEnumChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_AVE_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_AVE_IDENTIFIER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				//sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
				if (keywords.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVE_WORD);
 | 
			
		||||
				} else if (keywords2.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVE_WORD2);
 | 
			
		||||
				} else if (keywords3.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVE_WORD3);
 | 
			
		||||
				} else if (keywords4.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVE_WORD4);
 | 
			
		||||
				} else if (keywords5.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVE_WORD5);
 | 
			
		||||
				} else if (keywords6.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVE_WORD6);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_AVE_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_AVE_COMMENT) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_AVE_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_AVE_STRING) {
 | 
			
		||||
			 if (sc.ch == '\"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_AVE_DEFAULT);
 | 
			
		||||
			} else if (sc.atLineEnd) {
 | 
			
		||||
				sc.ChangeState(SCE_AVE_STRINGEOL);
 | 
			
		||||
				sc.ForwardSetState(SCE_AVE_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_AVE_DEFAULT) {
 | 
			
		||||
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_AVE_NUMBER);
 | 
			
		||||
			} else if (IsAWordStart(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_AVE_IDENTIFIER);
 | 
			
		||||
			} else if (sc.Match('\"')) {
 | 
			
		||||
				sc.SetState(SCE_AVE_STRING);
 | 
			
		||||
			} else if (sc.Match('\'')) {
 | 
			
		||||
				sc.SetState(SCE_AVE_COMMENT);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (isAveOperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_AVE_OPERATOR);
 | 
			
		||||
			} else if (sc.Match('#')) {
 | 
			
		||||
				sc.SetState(SCE_AVE_ENUM);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldAveDoc(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[],
 | 
			
		||||
                       Accessor &styler) {
 | 
			
		||||
	Sci_PositionU lengthDoc = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = static_cast<char>(tolower(styler[startPos]));
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	char s[10] = "";
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		char ch = static_cast<char>(tolower(chNext));
 | 
			
		||||
		chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));
 | 
			
		||||
		int style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if (style == SCE_AVE_WORD) {
 | 
			
		||||
			if (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') {
 | 
			
		||||
				for (unsigned int j = 0; j < 6; j++) {
 | 
			
		||||
					if (!iswordchar(styler[i + j])) {
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					s[j] = static_cast<char>(tolower(styler[i + j]));
 | 
			
		||||
					s[j + 1] = '\0';
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) {
 | 
			
		||||
					levelCurrent++;
 | 
			
		||||
				}
 | 
			
		||||
				if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) {
 | 
			
		||||
					// Normally "elseif" and "then" will be on the same line and will cancel
 | 
			
		||||
					// each other out.  // As implemented, this does not support fold.at.else.
 | 
			
		||||
					levelCurrent--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (style == SCE_AVE_OPERATOR) {
 | 
			
		||||
			if (ch == '{' || ch == '(') {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			} else if (ch == '}' || ch == ')') {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact) {
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!isspacechar(ch)) {
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave", FoldAveDoc);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										294
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAVS.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										294
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAVS.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,294 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexAVS.cxx
 | 
			
		||||
 ** Lexer for AviSynth.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2012 by Bruno Barbieri <brunorex@gmail.com>
 | 
			
		||||
// Heavily based on LexPOV by Neil Hodgson
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordStart(int ch) {
 | 
			
		||||
	return isalpha(ch) || (ch != ' ' && ch != '\n' && ch != '(' && ch != '.' && ch != ',');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsANumberChar(int ch) {
 | 
			
		||||
	// Not exactly following number definition (several dots are seen as OK, etc.)
 | 
			
		||||
	// but probably enough in most cases.
 | 
			
		||||
	return (ch < 0x80) &&
 | 
			
		||||
			(isdigit(ch) || ch == '.' || ch == '-' || ch == '+');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseAvsDoc(
 | 
			
		||||
	Sci_PositionU startPos,
 | 
			
		||||
	Sci_Position length,
 | 
			
		||||
	int initStyle,
 | 
			
		||||
	WordList *keywordlists[],
 | 
			
		||||
	Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
	WordList &filters = *keywordlists[1];
 | 
			
		||||
	WordList &plugins = *keywordlists[2];
 | 
			
		||||
	WordList &functions = *keywordlists[3];
 | 
			
		||||
	WordList &clipProperties = *keywordlists[4];
 | 
			
		||||
	WordList &userDefined = *keywordlists[5];
 | 
			
		||||
 | 
			
		||||
	Sci_Position currentLine = styler.GetLine(startPos);
 | 
			
		||||
	// Initialize the block comment nesting level, if we are inside such a comment.
 | 
			
		||||
	int blockCommentLevel = 0;
 | 
			
		||||
	if (initStyle == SCE_AVS_COMMENTBLOCK || initStyle == SCE_AVS_COMMENTBLOCKN) {
 | 
			
		||||
		blockCommentLevel = styler.GetLineState(currentLine - 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Do not leak onto next line
 | 
			
		||||
	if (initStyle == SCE_AVS_COMMENTLINE) {
 | 
			
		||||
		initStyle = SCE_AVS_DEFAULT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
		if (sc.atLineEnd) {
 | 
			
		||||
			// Update the line state, so it can be seen by next line
 | 
			
		||||
			currentLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
			if (sc.state == SCE_AVS_COMMENTBLOCK || sc.state == SCE_AVS_COMMENTBLOCKN) {
 | 
			
		||||
				// Inside a block comment, we set the line state
 | 
			
		||||
				styler.SetLineState(currentLine, blockCommentLevel);
 | 
			
		||||
			} else {
 | 
			
		||||
				// Reset the line state
 | 
			
		||||
				styler.SetLineState(currentLine, 0);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		if (sc.state == SCE_AVS_OPERATOR) {
 | 
			
		||||
			sc.SetState(SCE_AVS_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_AVS_NUMBER) {
 | 
			
		||||
			// We stop the number definition on non-numerical non-dot non-sign char
 | 
			
		||||
			if (!IsANumberChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_AVS_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_AVS_IDENTIFIER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
 | 
			
		||||
				if (keywords.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVS_KEYWORD);
 | 
			
		||||
				} else if (filters.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVS_FILTER);
 | 
			
		||||
				} else if (plugins.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVS_PLUGIN);
 | 
			
		||||
				} else if (functions.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVS_FUNCTION);
 | 
			
		||||
				} else if (clipProperties.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVS_CLIPPROP);
 | 
			
		||||
				} else if (userDefined.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_AVS_USERDFN);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_AVS_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_AVS_COMMENTBLOCK) {
 | 
			
		||||
			if (sc.Match('/', '*')) {
 | 
			
		||||
				blockCommentLevel++;
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.Match('*', '/') && blockCommentLevel > 0) {
 | 
			
		||||
				blockCommentLevel--;
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				if (blockCommentLevel == 0) {
 | 
			
		||||
					sc.ForwardSetState(SCE_AVS_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_AVS_COMMENTBLOCKN) {
 | 
			
		||||
			if (sc.Match('[', '*')) {
 | 
			
		||||
				blockCommentLevel++;
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.Match('*', ']') && blockCommentLevel > 0) {
 | 
			
		||||
				blockCommentLevel--;
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				if (blockCommentLevel == 0) {
 | 
			
		||||
					sc.ForwardSetState(SCE_AVS_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_AVS_COMMENTLINE) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.ForwardSetState(SCE_AVS_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_AVS_STRING) {
 | 
			
		||||
			if (sc.ch == '\"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_AVS_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_AVS_TRIPLESTRING) {
 | 
			
		||||
			if (sc.Match("\"\"\"")) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.ForwardSetState(SCE_AVS_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_AVS_DEFAULT) {
 | 
			
		||||
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_AVS_NUMBER);
 | 
			
		||||
			} else 	if (IsADigit(sc.ch) || (sc.ch == ',' && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.SetState(SCE_AVS_NUMBER);
 | 
			
		||||
			} else if (sc.Match('/', '*')) {
 | 
			
		||||
				blockCommentLevel = 1;
 | 
			
		||||
				sc.SetState(SCE_AVS_COMMENTBLOCK);
 | 
			
		||||
				sc.Forward();	// Eat the * so it isn't used for the end of the comment
 | 
			
		||||
			} else if (sc.Match('[', '*')) {
 | 
			
		||||
				blockCommentLevel = 1;
 | 
			
		||||
				sc.SetState(SCE_AVS_COMMENTBLOCKN);
 | 
			
		||||
				sc.Forward();	// Eat the * so it isn't used for the end of the comment
 | 
			
		||||
			} else if (sc.ch == '#') {
 | 
			
		||||
				sc.SetState(SCE_AVS_COMMENTLINE);
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				if (sc.Match("\"\"\"")) {
 | 
			
		||||
					sc.SetState(SCE_AVS_TRIPLESTRING);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_AVS_STRING);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (isoperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_AVS_OPERATOR);
 | 
			
		||||
			} else if (IsAWordStart(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_AVS_IDENTIFIER);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// End of file: complete any pending changeState
 | 
			
		||||
	if (sc.state == SCE_AVS_IDENTIFIER) {
 | 
			
		||||
		if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
			char s[100];
 | 
			
		||||
			sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
 | 
			
		||||
			if (keywords.InList(s)) {
 | 
			
		||||
				sc.ChangeState(SCE_AVS_KEYWORD);
 | 
			
		||||
			} else if (filters.InList(s)) {
 | 
			
		||||
				sc.ChangeState(SCE_AVS_FILTER);
 | 
			
		||||
			} else if (plugins.InList(s)) {
 | 
			
		||||
				sc.ChangeState(SCE_AVS_PLUGIN);
 | 
			
		||||
			} else if (functions.InList(s)) {
 | 
			
		||||
				sc.ChangeState(SCE_AVS_FUNCTION);
 | 
			
		||||
			} else if (clipProperties.InList(s)) {
 | 
			
		||||
				sc.ChangeState(SCE_AVS_CLIPPROP);
 | 
			
		||||
			} else if (userDefined.InList(s)) {
 | 
			
		||||
				sc.ChangeState(SCE_AVS_USERDFN);
 | 
			
		||||
			}
 | 
			
		||||
			sc.SetState(SCE_AVS_DEFAULT);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldAvsDoc(
 | 
			
		||||
	Sci_PositionU startPos,
 | 
			
		||||
	Sci_Position length,
 | 
			
		||||
	int initStyle,
 | 
			
		||||
	WordList *[],
 | 
			
		||||
	Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int stylePrev = style;
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if (foldComment && style == SCE_AVS_COMMENTBLOCK) {
 | 
			
		||||
			if (stylePrev != SCE_AVS_COMMENTBLOCK) {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			} else if ((styleNext != SCE_AVS_COMMENTBLOCK) && !atEOL) {
 | 
			
		||||
				// Comments don't end at end of line and the next character may be unstyled.
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (foldComment && style == SCE_AVS_COMMENTBLOCKN) {
 | 
			
		||||
			if (stylePrev != SCE_AVS_COMMENTBLOCKN) {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			} else if ((styleNext != SCE_AVS_COMMENTBLOCKN) && !atEOL) {
 | 
			
		||||
				// Comments don't end at end of line and the next character may be unstyled.
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (style == SCE_AVS_OPERATOR) {
 | 
			
		||||
			if (ch == '{') {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			} else if (ch == '}') {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const avsWordLists[] = {
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	"Filters",
 | 
			
		||||
	"Plugins",
 | 
			
		||||
	"Functions",
 | 
			
		||||
	"Clip properties",
 | 
			
		||||
	"User defined functions",
 | 
			
		||||
	0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmAVS(SCLEX_AVS, ColouriseAvsDoc, "avs", FoldAvsDoc, avsWordLists);
 | 
			
		||||
							
								
								
									
										606
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAbaqus.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										606
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAbaqus.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,606 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexAbaqus.cxx
 | 
			
		||||
 ** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz.
 | 
			
		||||
 ** By Sergio Lucato.
 | 
			
		||||
 ** Sort of completely rewritten by Gertjan Kloosterman
 | 
			
		||||
 **/
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
// Code folding copyied and modified from LexBasic.cxx
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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;
 | 
			
		||||
 | 
			
		||||
static inline bool IsAKeywordChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' ')));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsASetChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-')));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseABAQUSDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList*[] /* *keywordlists[] */,
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
	enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \
 | 
			
		||||
					  DAT_LINE_VAL, DAT_LINE_COMMA,\
 | 
			
		||||
					  COMMENT_LINE,\
 | 
			
		||||
					  ST_ERROR, LINE_END } state ;
 | 
			
		||||
 | 
			
		||||
	// Do not leak onto next line
 | 
			
		||||
	state = LINE_END ;
 | 
			
		||||
	initStyle = SCE_ABAQUS_DEFAULT;
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	// Things are actually quite simple
 | 
			
		||||
	// we have commentlines
 | 
			
		||||
	// keywordlines and datalines
 | 
			
		||||
	// On a data line there will only be colouring of numbers
 | 
			
		||||
	// a keyword line is constructed as
 | 
			
		||||
	// *word,[ paramname[=paramvalue]]*
 | 
			
		||||
	// if the line ends with a , the keyword line continues onto the new line
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
		switch ( state ) {
 | 
			
		||||
        case KW_LINE_KW :
 | 
			
		||||
            if ( sc.atLineEnd ) {
 | 
			
		||||
                // finished the line in keyword state, switch to LINE_END
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                state = LINE_END ;
 | 
			
		||||
            } else if ( IsAKeywordChar(sc.ch) ) {
 | 
			
		||||
                // nothing changes
 | 
			
		||||
                state = KW_LINE_KW ;
 | 
			
		||||
            } else if ( sc.ch == ',' ) {
 | 
			
		||||
                // Well well we say a comma, arguments *MUST* follow
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_OPERATOR) ;
 | 
			
		||||
                state = KW_LINE_COMMA ;
 | 
			
		||||
            } else {
 | 
			
		||||
                // Flag an error
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
 | 
			
		||||
                state = ST_ERROR ;
 | 
			
		||||
            }
 | 
			
		||||
            // Done with processing
 | 
			
		||||
            break ;
 | 
			
		||||
        case KW_LINE_COMMA :
 | 
			
		||||
            // acomma on a keywordline was seen
 | 
			
		||||
            if ( IsAKeywordChar(sc.ch)) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_ARGUMENT) ;
 | 
			
		||||
                state = KW_LINE_PAR ;
 | 
			
		||||
            } else if ( sc.atLineEnd || (sc.ch == ',') ) {
 | 
			
		||||
                // we remain in keyword mode
 | 
			
		||||
                state = KW_LINE_COMMA ;
 | 
			
		||||
            } else if ( sc.ch == ' ' ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                state = KW_LINE_COMMA ;
 | 
			
		||||
            } else {
 | 
			
		||||
                // Anything else constitutes an error
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
 | 
			
		||||
                state = ST_ERROR ;
 | 
			
		||||
            }
 | 
			
		||||
            break ;
 | 
			
		||||
        case KW_LINE_PAR :
 | 
			
		||||
            if ( sc.atLineEnd ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                state = LINE_END ;
 | 
			
		||||
            } else if ( IsAKeywordChar(sc.ch) || (sc.ch == '-') ) {
 | 
			
		||||
                // remain in this state
 | 
			
		||||
                state = KW_LINE_PAR ;
 | 
			
		||||
            } else if ( sc.ch == ',' ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_OPERATOR) ;
 | 
			
		||||
                state = KW_LINE_COMMA ;
 | 
			
		||||
            } else if ( sc.ch == '=' ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_OPERATOR) ;
 | 
			
		||||
                state = KW_LINE_EQ ;
 | 
			
		||||
            } else {
 | 
			
		||||
                // Anything else constitutes an error
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
 | 
			
		||||
                state = ST_ERROR ;
 | 
			
		||||
            }
 | 
			
		||||
            break ;
 | 
			
		||||
        case KW_LINE_EQ :
 | 
			
		||||
            if ( sc.ch == ' ' ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                // remain in this state
 | 
			
		||||
                state = KW_LINE_EQ ;
 | 
			
		||||
            } else if ( IsADigit(sc.ch) || (sc.ch == '-') || (sc.ch == '.' && IsADigit(sc.chNext)) ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_NUMBER) ;
 | 
			
		||||
                state = KW_LINE_VAL ;
 | 
			
		||||
            } else if ( IsAKeywordChar(sc.ch) ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                state = KW_LINE_VAL ;
 | 
			
		||||
            } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_STRING) ;
 | 
			
		||||
                state = KW_LINE_VAL ;
 | 
			
		||||
            } else {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
 | 
			
		||||
                state = ST_ERROR ;
 | 
			
		||||
            }
 | 
			
		||||
            break ;
 | 
			
		||||
        case KW_LINE_VAL :
 | 
			
		||||
            if ( sc.atLineEnd ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                state = LINE_END ;
 | 
			
		||||
            } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
 | 
			
		||||
                // nothing changes
 | 
			
		||||
                state = KW_LINE_VAL ;
 | 
			
		||||
            } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
 | 
			
		||||
                    ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
 | 
			
		||||
                    (sc.state == SCE_ABAQUS_NUMBER)) {
 | 
			
		||||
                // remain in number mode
 | 
			
		||||
                state = KW_LINE_VAL ;
 | 
			
		||||
            } else if (sc.state == SCE_ABAQUS_STRING) {
 | 
			
		||||
                // accept everything until a closing quote
 | 
			
		||||
                if ( sc.ch == '\'' || sc.ch == '\"' ) {
 | 
			
		||||
                    sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                    state = KW_LINE_VAL ;
 | 
			
		||||
                }
 | 
			
		||||
            } else if ( sc.ch == ',' ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_OPERATOR) ;
 | 
			
		||||
                state = KW_LINE_COMMA ;
 | 
			
		||||
            } else {
 | 
			
		||||
                // anything else is an error
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
 | 
			
		||||
                state = ST_ERROR ;
 | 
			
		||||
            }
 | 
			
		||||
            break ;
 | 
			
		||||
        case DAT_LINE_VAL :
 | 
			
		||||
            if ( sc.atLineEnd ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                state = LINE_END ;
 | 
			
		||||
            } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
 | 
			
		||||
                // nothing changes
 | 
			
		||||
                state = DAT_LINE_VAL ;
 | 
			
		||||
            } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
 | 
			
		||||
                    ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
 | 
			
		||||
                    (sc.state == SCE_ABAQUS_NUMBER)) {
 | 
			
		||||
                // remain in number mode
 | 
			
		||||
                state = DAT_LINE_VAL ;
 | 
			
		||||
            } else if (sc.state == SCE_ABAQUS_STRING) {
 | 
			
		||||
                // accept everything until a closing quote
 | 
			
		||||
                if ( sc.ch == '\'' || sc.ch == '\"' ) {
 | 
			
		||||
                    sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                    state = DAT_LINE_VAL ;
 | 
			
		||||
                }
 | 
			
		||||
            } else if ( sc.ch == ',' ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_OPERATOR) ;
 | 
			
		||||
                state = DAT_LINE_COMMA ;
 | 
			
		||||
            } else {
 | 
			
		||||
                // anything else is an error
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
 | 
			
		||||
                state = ST_ERROR ;
 | 
			
		||||
            }
 | 
			
		||||
            break ;
 | 
			
		||||
        case DAT_LINE_COMMA :
 | 
			
		||||
            // a comma on a data line was seen
 | 
			
		||||
            if ( sc.atLineEnd ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                state = LINE_END ;
 | 
			
		||||
            } else if ( sc.ch == ' ' ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                state = DAT_LINE_COMMA ;
 | 
			
		||||
            } else if (sc.ch == ',')  {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_OPERATOR) ;
 | 
			
		||||
                state = DAT_LINE_COMMA ;
 | 
			
		||||
            } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_NUMBER) ;
 | 
			
		||||
                state = DAT_LINE_VAL ;
 | 
			
		||||
            } else if ( IsAKeywordChar(sc.ch) ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                state = DAT_LINE_VAL ;
 | 
			
		||||
            } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_STRING) ;
 | 
			
		||||
                state = DAT_LINE_VAL ;
 | 
			
		||||
            } else {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
 | 
			
		||||
                state = ST_ERROR ;
 | 
			
		||||
            }
 | 
			
		||||
            break ;
 | 
			
		||||
        case COMMENT_LINE :
 | 
			
		||||
            if ( sc.atLineEnd ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                state = LINE_END ;
 | 
			
		||||
            }
 | 
			
		||||
            break ;
 | 
			
		||||
        case ST_ERROR :
 | 
			
		||||
            if ( sc.atLineEnd ) {
 | 
			
		||||
                sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                state = LINE_END ;
 | 
			
		||||
            }
 | 
			
		||||
            break ;
 | 
			
		||||
        case LINE_END :
 | 
			
		||||
            if ( sc.atLineEnd || sc.ch == ' ' ) {
 | 
			
		||||
                // nothing changes
 | 
			
		||||
                state = LINE_END ;
 | 
			
		||||
            } else if ( sc.ch == '*' ) {
 | 
			
		||||
                if ( sc.chNext == '*' ) {
 | 
			
		||||
                    state = COMMENT_LINE ;
 | 
			
		||||
                    sc.SetState(SCE_ABAQUS_COMMENT) ;
 | 
			
		||||
                } else {
 | 
			
		||||
                    state = KW_LINE_KW ;
 | 
			
		||||
                    sc.SetState(SCE_ABAQUS_STARCOMMAND) ;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // it must be a data line, things are as if we are in DAT_LINE_COMMA
 | 
			
		||||
                if ( sc.ch == ',' ) {
 | 
			
		||||
                    sc.SetState(SCE_ABAQUS_OPERATOR) ;
 | 
			
		||||
                    state = DAT_LINE_COMMA ;
 | 
			
		||||
                } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
 | 
			
		||||
                    sc.SetState(SCE_ABAQUS_NUMBER) ;
 | 
			
		||||
                    state = DAT_LINE_VAL ;
 | 
			
		||||
                } else if ( IsAKeywordChar(sc.ch) ) {
 | 
			
		||||
                    sc.SetState(SCE_ABAQUS_DEFAULT) ;
 | 
			
		||||
                    state = DAT_LINE_VAL ;
 | 
			
		||||
                } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
 | 
			
		||||
                    sc.SetState(SCE_ABAQUS_STRING) ;
 | 
			
		||||
                    state = DAT_LINE_VAL ;
 | 
			
		||||
                } else {
 | 
			
		||||
                    sc.SetState(SCE_ABAQUS_PROCESSOR) ;
 | 
			
		||||
                    state = ST_ERROR ;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break ;
 | 
			
		||||
		  }
 | 
			
		||||
   }
 | 
			
		||||
   sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// This copyied and modified from LexBasic.cxx
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/* Bits:
 | 
			
		||||
 * 1  - whitespace
 | 
			
		||||
 * 2  - operator
 | 
			
		||||
 * 4  - identifier
 | 
			
		||||
 * 8  - decimal digit
 | 
			
		||||
 * 16 - hex digit
 | 
			
		||||
 * 32 - bin digit
 | 
			
		||||
 */
 | 
			
		||||
static int character_classification[128] =
 | 
			
		||||
{
 | 
			
		||||
    0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  1,  0,  0,
 | 
			
		||||
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
    1,  2,  0,  2,  2,  2,  2,  2,  2,  2,  6,  2,  2,  2,  10, 6,
 | 
			
		||||
    60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2,  2,  2,  2,  2,  2,
 | 
			
		||||
    2,  20, 20, 20, 20, 20, 20, 4,  4,  4,  4,  4,  4,  4,  4,  4,
 | 
			
		||||
    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2,  2,  2,  4,
 | 
			
		||||
    2,  20, 20, 20, 20, 20, 20, 4,  4,  4,  4,  4,  4,  4,  4,  4,
 | 
			
		||||
    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2,  2,  2,  0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool IsSpace(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsIdentifier(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int LowerCase(int c)
 | 
			
		||||
{
 | 
			
		||||
	if (c >= 'A' && c <= 'Z')
 | 
			
		||||
		return 'a' + c - 'A';
 | 
			
		||||
	return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Sci_Position LineEnd(Sci_Position line, Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
    const Sci_Position docLines = styler.GetLine(styler.Length() - 1);  // Available last line
 | 
			
		||||
    Sci_Position eol_pos ;
 | 
			
		||||
    // if the line is the last line, the eol_pos is styler.Length()
 | 
			
		||||
    // eol will contain a new line, or a virtual new line
 | 
			
		||||
    if ( docLines == line )
 | 
			
		||||
        eol_pos = styler.Length() ;
 | 
			
		||||
    else
 | 
			
		||||
        eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
    return eol_pos ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Sci_Position LineStart(Sci_Position line, Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
    return styler.LineStart(line) ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LineType
 | 
			
		||||
//
 | 
			
		||||
// bits determines the line type
 | 
			
		||||
// 1  : data line
 | 
			
		||||
// 2  : only whitespace
 | 
			
		||||
// 3  : data line with only whitespace
 | 
			
		||||
// 4  : keyword line
 | 
			
		||||
// 5  : block open keyword line
 | 
			
		||||
// 6  : block close keyword line
 | 
			
		||||
// 7  : keyword line in error
 | 
			
		||||
// 8  : comment line
 | 
			
		||||
static int LineType(Sci_Position line, Accessor &styler) {
 | 
			
		||||
    Sci_Position pos = LineStart(line, styler) ;
 | 
			
		||||
    Sci_Position eol_pos = LineEnd(line, styler) ;
 | 
			
		||||
 | 
			
		||||
    int c ;
 | 
			
		||||
    char ch = ' ';
 | 
			
		||||
 | 
			
		||||
    Sci_Position i = pos ;
 | 
			
		||||
    while ( i < eol_pos ) {
 | 
			
		||||
        c = styler.SafeGetCharAt(i);
 | 
			
		||||
        ch = static_cast<char>(LowerCase(c));
 | 
			
		||||
        // We can say something as soon as no whitespace
 | 
			
		||||
        // was encountered
 | 
			
		||||
        if ( !IsSpace(c) )
 | 
			
		||||
            break ;
 | 
			
		||||
        i++ ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( i >= eol_pos ) {
 | 
			
		||||
        // This is a whitespace line, currently
 | 
			
		||||
        // classifies as data line
 | 
			
		||||
        return 3 ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( ch != '*' ) {
 | 
			
		||||
        // This is a data line
 | 
			
		||||
        return 1 ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( i == eol_pos - 1 ) {
 | 
			
		||||
        // Only a single *, error but make keyword line
 | 
			
		||||
        return 4+3 ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This means we can have a second character
 | 
			
		||||
    // if that is also a * this means a comment
 | 
			
		||||
    // otherwise it is a keyword.
 | 
			
		||||
    c = styler.SafeGetCharAt(i+1);
 | 
			
		||||
    ch = static_cast<char>(LowerCase(c));
 | 
			
		||||
    if ( ch == '*' ) {
 | 
			
		||||
        return 8 ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // At this point we know this is a keyword line
 | 
			
		||||
    // the character at position i is a *
 | 
			
		||||
    // it is not a comment line
 | 
			
		||||
    char word[256] ;
 | 
			
		||||
    int  wlen = 0;
 | 
			
		||||
 | 
			
		||||
    word[wlen] = '*' ;
 | 
			
		||||
	wlen++ ;
 | 
			
		||||
 | 
			
		||||
    i++ ;
 | 
			
		||||
    while ( (i < eol_pos) && (wlen < 255) ) {
 | 
			
		||||
        c = styler.SafeGetCharAt(i);
 | 
			
		||||
        ch = static_cast<char>(LowerCase(c));
 | 
			
		||||
 | 
			
		||||
        if ( (!IsSpace(c)) && (!IsIdentifier(c)) )
 | 
			
		||||
            break ;
 | 
			
		||||
 | 
			
		||||
        if ( IsIdentifier(c) ) {
 | 
			
		||||
            word[wlen] = ch ;
 | 
			
		||||
			wlen++ ;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        i++ ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    word[wlen] = 0 ;
 | 
			
		||||
 | 
			
		||||
    // Make a comparison
 | 
			
		||||
	if ( !strcmp(word, "*step") ||
 | 
			
		||||
         !strcmp(word, "*part") ||
 | 
			
		||||
         !strcmp(word, "*instance") ||
 | 
			
		||||
         !strcmp(word, "*assembly")) {
 | 
			
		||||
       return 4+1 ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	if ( !strcmp(word, "*endstep") ||
 | 
			
		||||
         !strcmp(word, "*endpart") ||
 | 
			
		||||
         !strcmp(word, "*endinstance") ||
 | 
			
		||||
         !strcmp(word, "*endassembly")) {
 | 
			
		||||
       return 4+2 ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 4 ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void SafeSetLevel(Sci_Position line, int level, Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
    if ( line < 0 )
 | 
			
		||||
        return ;
 | 
			
		||||
 | 
			
		||||
    int mask = ((~SC_FOLDLEVELHEADERFLAG) | (~SC_FOLDLEVELWHITEFLAG));
 | 
			
		||||
 | 
			
		||||
    if ( (level & mask) < 0 )
 | 
			
		||||
        return ;
 | 
			
		||||
 | 
			
		||||
    if ( styler.LevelAt(line) != level )
 | 
			
		||||
        styler.SetLevel(line, level) ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldABAQUSDoc(Sci_PositionU startPos, Sci_Position length, int,
 | 
			
		||||
WordList *[], Accessor &styler) {
 | 
			
		||||
    Sci_Position startLine = styler.GetLine(startPos) ;
 | 
			
		||||
    Sci_Position endLine   = styler.GetLine(startPos+length-1) ;
 | 
			
		||||
 | 
			
		||||
    // bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
    // We want to deal with all the cases
 | 
			
		||||
    // To know the correct indentlevel, we need to look back to the
 | 
			
		||||
    // previous command line indentation level
 | 
			
		||||
	// order of formatting keyline datalines commentlines
 | 
			
		||||
    Sci_Position beginData    = -1 ;
 | 
			
		||||
    Sci_Position beginComment = -1 ;
 | 
			
		||||
    Sci_Position prvKeyLine   = startLine ;
 | 
			
		||||
    Sci_Position prvKeyLineTp =  0 ;
 | 
			
		||||
 | 
			
		||||
    // Scan until we find the previous keyword line
 | 
			
		||||
    // this will give us the level reference that we need
 | 
			
		||||
    while ( prvKeyLine > 0 ) {
 | 
			
		||||
        prvKeyLine-- ;
 | 
			
		||||
        prvKeyLineTp = LineType(prvKeyLine, styler) ;
 | 
			
		||||
        if ( prvKeyLineTp & 4 )
 | 
			
		||||
            break ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Determine the base line level of all lines following
 | 
			
		||||
    // the previous keyword
 | 
			
		||||
    // new keyword lines are placed on this level
 | 
			
		||||
    //if ( prvKeyLineTp & 4 ) {
 | 
			
		||||
    int level = styler.LevelAt(prvKeyLine) & ~SC_FOLDLEVELHEADERFLAG ;
 | 
			
		||||
    //}
 | 
			
		||||
 | 
			
		||||
    // uncomment line below if weird behaviour continues
 | 
			
		||||
    prvKeyLine = -1 ;
 | 
			
		||||
 | 
			
		||||
    // Now start scanning over the lines.
 | 
			
		||||
    for ( Sci_Position line = startLine; line <= endLine; line++ ) {
 | 
			
		||||
        int lineType = LineType(line, styler) ;
 | 
			
		||||
 | 
			
		||||
        // Check for comment line
 | 
			
		||||
        if ( lineType == 8 ) {
 | 
			
		||||
            if ( beginComment < 0 ) {
 | 
			
		||||
                beginComment = line ;
 | 
			
		||||
			}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check for data line
 | 
			
		||||
        if ( (lineType == 1) || (lineType == 3) ) {
 | 
			
		||||
            if ( beginData < 0 ) {
 | 
			
		||||
                if ( beginComment >= 0 ) {
 | 
			
		||||
                    beginData = beginComment ;
 | 
			
		||||
                } else {
 | 
			
		||||
                    beginData = line ;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
			beginComment = -1 ;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        // Check for keywordline.
 | 
			
		||||
        // As soon as a keyword line is encountered, we can set the
 | 
			
		||||
        // levels of everything from the previous keyword line to this one
 | 
			
		||||
        if ( lineType & 4 ) {
 | 
			
		||||
            // this is a keyword, we can now place the previous keyword
 | 
			
		||||
            // all its data lines and the remainder
 | 
			
		||||
 | 
			
		||||
            // Write comments and data line
 | 
			
		||||
            if ( beginComment < 0 ) {
 | 
			
		||||
                beginComment = line ;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            if ( beginData < 0 ) {
 | 
			
		||||
                beginData = beginComment ;
 | 
			
		||||
				if ( prvKeyLineTp != 5 )
 | 
			
		||||
					SafeSetLevel(prvKeyLine, level, styler) ;
 | 
			
		||||
				else
 | 
			
		||||
					SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
 | 
			
		||||
            } else {
 | 
			
		||||
                SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int datLevel = level + 1 ;
 | 
			
		||||
			if ( !(prvKeyLineTp & 4) ) {
 | 
			
		||||
				datLevel = level ;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            for ( Sci_Position ll = beginData; ll < beginComment; ll++ )
 | 
			
		||||
                SafeSetLevel(ll, datLevel, styler) ;
 | 
			
		||||
 | 
			
		||||
            // The keyword we just found is going to be written at another level
 | 
			
		||||
            // if we have a type 5 and type 6
 | 
			
		||||
            if ( prvKeyLineTp == 5 ) {
 | 
			
		||||
                level += 1 ;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            if ( prvKeyLineTp == 6 ) {
 | 
			
		||||
                level -= 1 ;
 | 
			
		||||
				if ( level < 0 ) {
 | 
			
		||||
					level = 0 ;
 | 
			
		||||
				}
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for ( Sci_Position lll = beginComment; lll < line; lll++ )
 | 
			
		||||
                SafeSetLevel(lll, level, styler) ;
 | 
			
		||||
 | 
			
		||||
            // wrap and reset
 | 
			
		||||
            beginComment = -1 ;
 | 
			
		||||
            beginData    = -1 ;
 | 
			
		||||
            prvKeyLine   = line ;
 | 
			
		||||
            prvKeyLineTp = lineType ;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( beginComment < 0 ) {
 | 
			
		||||
        beginComment = endLine + 1 ;
 | 
			
		||||
    } else {
 | 
			
		||||
        // We need to find out whether this comment block is followed by
 | 
			
		||||
        // a data line or a keyword line
 | 
			
		||||
        const Sci_Position docLines = styler.GetLine(styler.Length() - 1);
 | 
			
		||||
 | 
			
		||||
        for ( Sci_Position line = endLine + 1; line <= docLines; line++ ) {
 | 
			
		||||
            Sci_Position lineType = LineType(line, styler) ;
 | 
			
		||||
 | 
			
		||||
            if ( lineType != 8 ) {
 | 
			
		||||
				if ( !(lineType & 4) )  {
 | 
			
		||||
					beginComment = endLine + 1 ;
 | 
			
		||||
				}
 | 
			
		||||
                break ;
 | 
			
		||||
			}
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( beginData < 0 ) {
 | 
			
		||||
        beginData = beginComment ;
 | 
			
		||||
		if ( prvKeyLineTp != 5 )
 | 
			
		||||
			SafeSetLevel(prvKeyLine, level, styler) ;
 | 
			
		||||
		else
 | 
			
		||||
			SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
 | 
			
		||||
    } else {
 | 
			
		||||
        SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int datLevel = level + 1 ;
 | 
			
		||||
	if ( !(prvKeyLineTp & 4) ) {
 | 
			
		||||
		datLevel = level ;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    for ( Sci_Position ll = beginData; ll < beginComment; ll++ )
 | 
			
		||||
        SafeSetLevel(ll, datLevel, styler) ;
 | 
			
		||||
 | 
			
		||||
    if ( prvKeyLineTp == 5 ) {
 | 
			
		||||
        level += 1 ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( prvKeyLineTp == 6 ) {
 | 
			
		||||
        level -= 1 ;
 | 
			
		||||
    }
 | 
			
		||||
    for ( Sci_Position m = beginComment; m <= endLine; m++ )
 | 
			
		||||
        SafeSetLevel(m, level, styler) ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const abaqusWordListDesc[] = {
 | 
			
		||||
    "processors",
 | 
			
		||||
    "commands",
 | 
			
		||||
    "slashommands",
 | 
			
		||||
    "starcommands",
 | 
			
		||||
    "arguments",
 | 
			
		||||
    "functions",
 | 
			
		||||
    0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, "abaqus", FoldABAQUSDoc, abaqusWordListDesc);
 | 
			
		||||
							
								
								
									
										514
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAda.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										514
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAda.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,514 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexAda.cxx
 | 
			
		||||
 ** Lexer for Ada 95
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Interface
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static void ColouriseDocument(
 | 
			
		||||
    Sci_PositionU startPos,
 | 
			
		||||
    Sci_Position length,
 | 
			
		||||
    int initStyle,
 | 
			
		||||
    WordList *keywordlists[],
 | 
			
		||||
    Accessor &styler);
 | 
			
		||||
 | 
			
		||||
static const char * const adaWordListDesc[] = {
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Implementation
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// Functions that have apostropheStartsAttribute as a parameter set it according to whether
 | 
			
		||||
// an apostrophe encountered after processing the current token will start an attribute or
 | 
			
		||||
// a character literal.
 | 
			
		||||
static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute);
 | 
			
		||||
static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
 | 
			
		||||
static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL);
 | 
			
		||||
static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
 | 
			
		||||
static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
 | 
			
		||||
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
 | 
			
		||||
static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute);
 | 
			
		||||
static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
 | 
			
		||||
static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
 | 
			
		||||
 | 
			
		||||
static inline bool IsDelimiterCharacter(int ch);
 | 
			
		||||
static inline bool IsSeparatorOrDelimiterCharacter(int ch);
 | 
			
		||||
static bool IsValidIdentifier(const std::string& identifier);
 | 
			
		||||
static bool IsValidNumber(const std::string& number);
 | 
			
		||||
static inline bool IsWordStartCharacter(int ch);
 | 
			
		||||
static inline bool IsWordCharacter(int ch);
 | 
			
		||||
 | 
			
		||||
static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) {
 | 
			
		||||
	apostropheStartsAttribute = true;
 | 
			
		||||
 | 
			
		||||
	sc.SetState(SCE_ADA_CHARACTER);
 | 
			
		||||
 | 
			
		||||
	// Skip the apostrophe and one more character (so that '' is shown as non-terminated and '''
 | 
			
		||||
	// is handled correctly)
 | 
			
		||||
	sc.Forward();
 | 
			
		||||
	sc.Forward();
 | 
			
		||||
 | 
			
		||||
	ColouriseContext(sc, '\'', SCE_ADA_CHARACTEREOL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) {
 | 
			
		||||
	while (!sc.atLineEnd && !sc.Match(chEnd)) {
 | 
			
		||||
		sc.Forward();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!sc.atLineEnd) {
 | 
			
		||||
		sc.ForwardSetState(SCE_ADA_DEFAULT);
 | 
			
		||||
	} else {
 | 
			
		||||
		sc.ChangeState(stateEOL);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
 | 
			
		||||
	// Apostrophe meaning is not changed, but the parameter is present for uniformity
 | 
			
		||||
 | 
			
		||||
	sc.SetState(SCE_ADA_COMMENTLINE);
 | 
			
		||||
 | 
			
		||||
	while (!sc.atLineEnd) {
 | 
			
		||||
		sc.Forward();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
 | 
			
		||||
	apostropheStartsAttribute = sc.Match (')');
 | 
			
		||||
	sc.SetState(SCE_ADA_DELIMITER);
 | 
			
		||||
	sc.ForwardSetState(SCE_ADA_DEFAULT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
 | 
			
		||||
	apostropheStartsAttribute = false;
 | 
			
		||||
 | 
			
		||||
	sc.SetState(SCE_ADA_LABEL);
 | 
			
		||||
 | 
			
		||||
	// Skip "<<"
 | 
			
		||||
	sc.Forward();
 | 
			
		||||
	sc.Forward();
 | 
			
		||||
 | 
			
		||||
	std::string identifier;
 | 
			
		||||
 | 
			
		||||
	while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
 | 
			
		||||
		identifier += static_cast<char>(tolower(sc.ch));
 | 
			
		||||
		sc.Forward();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Skip ">>"
 | 
			
		||||
	if (sc.Match('>', '>')) {
 | 
			
		||||
		sc.Forward();
 | 
			
		||||
		sc.Forward();
 | 
			
		||||
	} else {
 | 
			
		||||
		sc.ChangeState(SCE_ADA_ILLEGAL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If the name is an invalid identifier or a keyword, then make it invalid label
 | 
			
		||||
	if (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) {
 | 
			
		||||
		sc.ChangeState(SCE_ADA_ILLEGAL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc.SetState(SCE_ADA_DEFAULT);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
 | 
			
		||||
	apostropheStartsAttribute = true;
 | 
			
		||||
 | 
			
		||||
	std::string number;
 | 
			
		||||
	sc.SetState(SCE_ADA_NUMBER);
 | 
			
		||||
 | 
			
		||||
	// Get all characters up to a delimiter or a separator, including points, but excluding
 | 
			
		||||
	// double points (ranges).
 | 
			
		||||
	while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
 | 
			
		||||
		number += static_cast<char>(sc.ch);
 | 
			
		||||
		sc.Forward();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Special case: exponent with sign
 | 
			
		||||
	if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
 | 
			
		||||
	        (sc.ch == '+' || sc.ch == '-')) {
 | 
			
		||||
		number += static_cast<char>(sc.ch);
 | 
			
		||||
		sc.Forward ();
 | 
			
		||||
 | 
			
		||||
		while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
 | 
			
		||||
			number += static_cast<char>(sc.ch);
 | 
			
		||||
			sc.Forward();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!IsValidNumber(number)) {
 | 
			
		||||
		sc.ChangeState(SCE_ADA_ILLEGAL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc.SetState(SCE_ADA_DEFAULT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) {
 | 
			
		||||
	apostropheStartsAttribute = true;
 | 
			
		||||
 | 
			
		||||
	sc.SetState(SCE_ADA_STRING);
 | 
			
		||||
	sc.Forward();
 | 
			
		||||
 | 
			
		||||
	ColouriseContext(sc, '"', SCE_ADA_STRINGEOL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseWhiteSpace(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
 | 
			
		||||
	// Apostrophe meaning is not changed, but the parameter is present for uniformity
 | 
			
		||||
	sc.SetState(SCE_ADA_DEFAULT);
 | 
			
		||||
	sc.ForwardSetState(SCE_ADA_DEFAULT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
 | 
			
		||||
	apostropheStartsAttribute = true;
 | 
			
		||||
	sc.SetState(SCE_ADA_IDENTIFIER);
 | 
			
		||||
 | 
			
		||||
	std::string word;
 | 
			
		||||
 | 
			
		||||
	while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
 | 
			
		||||
		word += static_cast<char>(tolower(sc.ch));
 | 
			
		||||
		sc.Forward();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!IsValidIdentifier(word)) {
 | 
			
		||||
		sc.ChangeState(SCE_ADA_ILLEGAL);
 | 
			
		||||
 | 
			
		||||
	} else if (keywords.InList(word.c_str())) {
 | 
			
		||||
		sc.ChangeState(SCE_ADA_WORD);
 | 
			
		||||
 | 
			
		||||
		if (word != "all") {
 | 
			
		||||
			apostropheStartsAttribute = false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc.SetState(SCE_ADA_DEFAULT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// ColouriseDocument
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
static void ColouriseDocument(
 | 
			
		||||
    Sci_PositionU startPos,
 | 
			
		||||
    Sci_Position length,
 | 
			
		||||
    int initStyle,
 | 
			
		||||
    WordList *keywordlists[],
 | 
			
		||||
    Accessor &styler) {
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
 | 
			
		||||
 | 
			
		||||
	while (sc.More()) {
 | 
			
		||||
		if (sc.atLineEnd) {
 | 
			
		||||
			// Go to the next line
 | 
			
		||||
			sc.Forward();
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
 | 
			
		||||
			// Remember the line state for future incremental lexing
 | 
			
		||||
			styler.SetLineState(lineCurrent, apostropheStartsAttribute);
 | 
			
		||||
 | 
			
		||||
			// Don't continue any styles on the next line
 | 
			
		||||
			sc.SetState(SCE_ADA_DEFAULT);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Comments
 | 
			
		||||
		if (sc.Match('-', '-')) {
 | 
			
		||||
			ColouriseComment(sc, apostropheStartsAttribute);
 | 
			
		||||
 | 
			
		||||
		// Strings
 | 
			
		||||
		} else if (sc.Match('"')) {
 | 
			
		||||
			ColouriseString(sc, apostropheStartsAttribute);
 | 
			
		||||
 | 
			
		||||
		// Characters
 | 
			
		||||
		} else if (sc.Match('\'') && !apostropheStartsAttribute) {
 | 
			
		||||
			ColouriseCharacter(sc, apostropheStartsAttribute);
 | 
			
		||||
 | 
			
		||||
		// Labels
 | 
			
		||||
		} else if (sc.Match('<', '<')) {
 | 
			
		||||
			ColouriseLabel(sc, keywords, apostropheStartsAttribute);
 | 
			
		||||
 | 
			
		||||
		// Whitespace
 | 
			
		||||
		} else if (IsASpace(sc.ch)) {
 | 
			
		||||
			ColouriseWhiteSpace(sc, apostropheStartsAttribute);
 | 
			
		||||
 | 
			
		||||
		// Delimiters
 | 
			
		||||
		} else if (IsDelimiterCharacter(sc.ch)) {
 | 
			
		||||
			ColouriseDelimiter(sc, apostropheStartsAttribute);
 | 
			
		||||
 | 
			
		||||
		// Numbers
 | 
			
		||||
		} else if (IsADigit(sc.ch) || sc.ch == '#') {
 | 
			
		||||
			ColouriseNumber(sc, apostropheStartsAttribute);
 | 
			
		||||
 | 
			
		||||
		// Keywords or identifiers
 | 
			
		||||
		} else {
 | 
			
		||||
			ColouriseWord(sc, keywords, apostropheStartsAttribute);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsDelimiterCharacter(int ch) {
 | 
			
		||||
	switch (ch) {
 | 
			
		||||
	case '&':
 | 
			
		||||
	case '\'':
 | 
			
		||||
	case '(':
 | 
			
		||||
	case ')':
 | 
			
		||||
	case '*':
 | 
			
		||||
	case '+':
 | 
			
		||||
	case ',':
 | 
			
		||||
	case '-':
 | 
			
		||||
	case '.':
 | 
			
		||||
	case '/':
 | 
			
		||||
	case ':':
 | 
			
		||||
	case ';':
 | 
			
		||||
	case '<':
 | 
			
		||||
	case '=':
 | 
			
		||||
	case '>':
 | 
			
		||||
	case '|':
 | 
			
		||||
		return true;
 | 
			
		||||
	default:
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
 | 
			
		||||
	return IsASpace(ch) || IsDelimiterCharacter(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsValidIdentifier(const std::string& identifier) {
 | 
			
		||||
	// First character can't be '_', so initialize the flag to true
 | 
			
		||||
	bool lastWasUnderscore = true;
 | 
			
		||||
 | 
			
		||||
	size_t length = identifier.length();
 | 
			
		||||
 | 
			
		||||
	// Zero-length identifiers are not valid (these can occur inside labels)
 | 
			
		||||
	if (length == 0) {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check for valid character at the start
 | 
			
		||||
	if (!IsWordStartCharacter(identifier[0])) {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check for only valid characters and no double underscores
 | 
			
		||||
	for (size_t i = 0; i < length; i++) {
 | 
			
		||||
		if (!IsWordCharacter(identifier[i]) ||
 | 
			
		||||
		        (identifier[i] == '_' && lastWasUnderscore)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		lastWasUnderscore = identifier[i] == '_';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check for underscore at the end
 | 
			
		||||
	if (lastWasUnderscore == true) {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// All checks passed
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsValidNumber(const std::string& number) {
 | 
			
		||||
	size_t hashPos = number.find("#");
 | 
			
		||||
	bool seenDot = false;
 | 
			
		||||
 | 
			
		||||
	size_t i = 0;
 | 
			
		||||
	size_t length = number.length();
 | 
			
		||||
 | 
			
		||||
	if (length == 0)
 | 
			
		||||
		return false; // Just in case
 | 
			
		||||
 | 
			
		||||
	// Decimal number
 | 
			
		||||
	if (hashPos == std::string::npos) {
 | 
			
		||||
		bool canBeSpecial = false;
 | 
			
		||||
 | 
			
		||||
		for (; i < length; i++) {
 | 
			
		||||
			if (number[i] == '_') {
 | 
			
		||||
				if (!canBeSpecial) {
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				canBeSpecial = false;
 | 
			
		||||
			} else if (number[i] == '.') {
 | 
			
		||||
				if (!canBeSpecial || seenDot) {
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				canBeSpecial = false;
 | 
			
		||||
				seenDot = true;
 | 
			
		||||
			} else if (IsADigit(number[i])) {
 | 
			
		||||
				canBeSpecial = true;
 | 
			
		||||
			} else {
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!canBeSpecial)
 | 
			
		||||
			return false;
 | 
			
		||||
	} else {
 | 
			
		||||
		// Based number
 | 
			
		||||
		bool canBeSpecial = false;
 | 
			
		||||
		int base = 0;
 | 
			
		||||
 | 
			
		||||
		// Parse base
 | 
			
		||||
		for (; i < length; i++) {
 | 
			
		||||
			int ch = number[i];
 | 
			
		||||
			if (ch == '_') {
 | 
			
		||||
				if (!canBeSpecial)
 | 
			
		||||
					return false;
 | 
			
		||||
				canBeSpecial = false;
 | 
			
		||||
			} else if (IsADigit(ch)) {
 | 
			
		||||
				base = base * 10 + (ch - '0');
 | 
			
		||||
				if (base > 16)
 | 
			
		||||
					return false;
 | 
			
		||||
				canBeSpecial = true;
 | 
			
		||||
			} else if (ch == '#' && canBeSpecial) {
 | 
			
		||||
				break;
 | 
			
		||||
			} else {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (base < 2)
 | 
			
		||||
			return false;
 | 
			
		||||
		if (i == length)
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		i++; // Skip over '#'
 | 
			
		||||
 | 
			
		||||
		// Parse number
 | 
			
		||||
		canBeSpecial = false;
 | 
			
		||||
 | 
			
		||||
		for (; i < length; i++) {
 | 
			
		||||
			int ch = tolower(number[i]);
 | 
			
		||||
 | 
			
		||||
			if (ch == '_') {
 | 
			
		||||
				if (!canBeSpecial) {
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				canBeSpecial = false;
 | 
			
		||||
 | 
			
		||||
			} else if (ch == '.') {
 | 
			
		||||
				if (!canBeSpecial || seenDot) {
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				canBeSpecial = false;
 | 
			
		||||
				seenDot = true;
 | 
			
		||||
 | 
			
		||||
			} else if (IsADigit(ch)) {
 | 
			
		||||
				if (ch - '0' >= base) {
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				canBeSpecial = true;
 | 
			
		||||
 | 
			
		||||
			} else if (ch >= 'a' && ch <= 'f') {
 | 
			
		||||
				if (ch - 'a' + 10 >= base) {
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				canBeSpecial = true;
 | 
			
		||||
 | 
			
		||||
			} else if (ch == '#' && canBeSpecial) {
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (i == length) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Exponent (optional)
 | 
			
		||||
	if (i < length) {
 | 
			
		||||
		if (number[i] != 'e' && number[i] != 'E')
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		i++; // Move past 'E'
 | 
			
		||||
 | 
			
		||||
		if (i == length) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (number[i] == '+')
 | 
			
		||||
			i++;
 | 
			
		||||
		else if (number[i] == '-') {
 | 
			
		||||
			if (seenDot) {
 | 
			
		||||
				i++;
 | 
			
		||||
			} else {
 | 
			
		||||
				return false; // Integer literals should not have negative exponents
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (i == length) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool canBeSpecial = false;
 | 
			
		||||
 | 
			
		||||
		for (; i < length; i++) {
 | 
			
		||||
			if (number[i] == '_') {
 | 
			
		||||
				if (!canBeSpecial) {
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				canBeSpecial = false;
 | 
			
		||||
			} else if (IsADigit(number[i])) {
 | 
			
		||||
				canBeSpecial = true;
 | 
			
		||||
			} else {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!canBeSpecial)
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// if i == length, number was parsed successfully.
 | 
			
		||||
	return i == length;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsWordCharacter(int ch) {
 | 
			
		||||
	return IsWordStartCharacter(ch) || IsADigit(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsWordStartCharacter(int ch) {
 | 
			
		||||
	return (IsASCII(ch) && isalpha(ch)) || ch == '_';
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										393
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAsciidoc.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAsciidoc.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,393 @@
 | 
			
		||||
/******************************************************************
 | 
			
		||||
 *  LexAsciidoc.cxx
 | 
			
		||||
 *
 | 
			
		||||
 *  A simple Asciidoc lexer for scintilla.
 | 
			
		||||
 *
 | 
			
		||||
 *  Based on the LexMarkdown.cxx by Jon Strait - jstrait@moonloop.net
 | 
			
		||||
 *
 | 
			
		||||
 *  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;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    bool start;
 | 
			
		||||
    int len1;
 | 
			
		||||
    int len2;
 | 
			
		||||
    const char *name;
 | 
			
		||||
} MacroItem;
 | 
			
		||||
 | 
			
		||||
static const MacroItem MacroList[] = {
 | 
			
		||||
    // Directives
 | 
			
		||||
    {true,  5, 2, "ifdef::"},
 | 
			
		||||
    {true,  6, 2, "ifeval::"},
 | 
			
		||||
    {true,  6, 2, "ifndef::"},
 | 
			
		||||
    {true,  5, 2, "endif::"},
 | 
			
		||||
    // Macros
 | 
			
		||||
    {true,  5, 2, "audio::"},
 | 
			
		||||
    {true,  7, 2, "include::"},
 | 
			
		||||
    {true,  5, 2, "image::"},
 | 
			
		||||
    {true,  5, 2, "video::"},
 | 
			
		||||
    {false, 8, 1, "asciimath:"},
 | 
			
		||||
    {false, 3, 1, "btn:"},
 | 
			
		||||
    {false, 5, 1, "image:"},
 | 
			
		||||
    {false, 3, 1, "kbd:"},
 | 
			
		||||
    {false, 9, 1, "latexmath:"},
 | 
			
		||||
    {false, 4, 1, "link:"},
 | 
			
		||||
    {false, 6, 1, "mailto:"},
 | 
			
		||||
    {false, 4, 1, "menu:"},
 | 
			
		||||
    {false, 4, 1, "pass:"},
 | 
			
		||||
    {false, 4, 1, "stem:"},
 | 
			
		||||
    {false, 4, 1, "xref:"},
 | 
			
		||||
    // Admonitions
 | 
			
		||||
    {true,  7, 1, "CAUTION:"},
 | 
			
		||||
    {true,  9, 1, "IMPORTANT:"},
 | 
			
		||||
    {true,  4, 1, "NOTE:"},
 | 
			
		||||
    {true,  3, 1, "TIP:"},
 | 
			
		||||
    {true,  7, 1, "WARNING:"},
 | 
			
		||||
    {false, 0, 0, NULL}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
constexpr bool IsNewline(const int ch) {
 | 
			
		||||
    // sc.GetRelative(i) returns '\0' if out of range
 | 
			
		||||
    return (ch == '\n' || ch == '\r' || ch == '\0');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool AtTermStart(StyleContext &sc) {
 | 
			
		||||
    return sc.currentPos == 0 || sc.chPrev == 0 || isspacechar(sc.chPrev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColorizeAsciidocDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                                WordList **, Accessor &styler) {
 | 
			
		||||
    bool freezeCursor = false;
 | 
			
		||||
 | 
			
		||||
    StyleContext sc(startPos, static_cast<Sci_PositionU>(length), initStyle, styler);
 | 
			
		||||
 | 
			
		||||
    while (sc.More()) {
 | 
			
		||||
        // Skip past escaped characters
 | 
			
		||||
        if (sc.ch == '\\') {
 | 
			
		||||
            sc.Forward();
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Skip newline.
 | 
			
		||||
        if (IsNewline(sc.ch)) {
 | 
			
		||||
            // Newline doesn't end blocks
 | 
			
		||||
            if (sc.state != SCE_ASCIIDOC_CODEBK && \
 | 
			
		||||
                sc.state != SCE_ASCIIDOC_PASSBK && \
 | 
			
		||||
                sc.state != SCE_ASCIIDOC_COMMENTBK && \
 | 
			
		||||
                sc.state != SCE_ASCIIDOC_LITERALBK) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            sc.Forward();
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Conditional state-based actions
 | 
			
		||||
        switch (sc.state) {
 | 
			
		||||
 | 
			
		||||
        // Strong
 | 
			
		||||
        case SCE_ASCIIDOC_STRONG1:
 | 
			
		||||
            if (sc.ch == '*' && sc.chPrev != ' ') {
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
                freezeCursor = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case SCE_ASCIIDOC_STRONG2:
 | 
			
		||||
            if (sc.Match("**") && sc.chPrev != ' ') {
 | 
			
		||||
                sc.Forward(2);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
                freezeCursor = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        // Emphasis
 | 
			
		||||
        case SCE_ASCIIDOC_EM1:
 | 
			
		||||
            if (sc.ch == '_' && sc.chPrev != ' ') {
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
                freezeCursor = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case SCE_ASCIIDOC_EM2:
 | 
			
		||||
            if (sc.Match("__") && sc.chPrev != ' ') {
 | 
			
		||||
                sc.Forward(2);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
                freezeCursor = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        // Link
 | 
			
		||||
        case SCE_ASCIIDOC_LINK:
 | 
			
		||||
            if (sc.ch == ']' && sc.chPrev != '\\') {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        // Code block
 | 
			
		||||
        case SCE_ASCIIDOC_CODEBK:
 | 
			
		||||
            if (sc.atLineStart && sc.Match("----") && IsNewline(sc.GetRelative(4))) {
 | 
			
		||||
                sc.Forward(4);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        // Passthrough block
 | 
			
		||||
        case SCE_ASCIIDOC_PASSBK:
 | 
			
		||||
            if (sc.atLineStart && sc.Match("++++") && IsNewline(sc.GetRelative(4))) {
 | 
			
		||||
                sc.Forward(4);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        // Comment block
 | 
			
		||||
        case SCE_ASCIIDOC_COMMENTBK:
 | 
			
		||||
            if (sc.atLineStart && sc.Match("////") && IsNewline(sc.GetRelative(4))) {
 | 
			
		||||
                sc.Forward(4);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        // Literal
 | 
			
		||||
        case SCE_ASCIIDOC_LITERAL:
 | 
			
		||||
            if (sc.ch == '+' && sc.chPrev != '\\') {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        // Literal block
 | 
			
		||||
        case SCE_ASCIIDOC_LITERALBK:
 | 
			
		||||
            if (sc.atLineStart && sc.Match("....") && IsNewline(sc.GetRelative(4))) {
 | 
			
		||||
                sc.Forward(4);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        // Attribute
 | 
			
		||||
        case SCE_ASCIIDOC_ATTRIB:
 | 
			
		||||
            if (sc.ch == ':' && sc.chPrev != ' ' && sc.chNext == ' ') {
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_ATTRIBVAL);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        // Macro
 | 
			
		||||
        case SCE_ASCIIDOC_MACRO:
 | 
			
		||||
            if (sc.ch == ']' && sc.chPrev != '\\') {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        // Default
 | 
			
		||||
        case SCE_ASCIIDOC_DEFAULT:
 | 
			
		||||
            // Headers
 | 
			
		||||
            if (sc.atLineStart && sc.Match("====== ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_HEADER6);
 | 
			
		||||
                sc.Forward(6);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("===== ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_HEADER5);
 | 
			
		||||
                sc.Forward(5);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("==== ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_HEADER4);
 | 
			
		||||
                sc.Forward(4);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("=== ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_HEADER3);
 | 
			
		||||
                sc.Forward(3);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("== ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_HEADER2);
 | 
			
		||||
                sc.Forward(2);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("= ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_HEADER1);
 | 
			
		||||
                sc.Forward(1);
 | 
			
		||||
            }
 | 
			
		||||
            // Unordered list item
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("****** ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | 
			
		||||
                sc.Forward(6);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("***** ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | 
			
		||||
                sc.Forward(5);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("**** ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | 
			
		||||
                sc.Forward(4);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("*** ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | 
			
		||||
                sc.Forward(3);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("** ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | 
			
		||||
                sc.Forward(2);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("* ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | 
			
		||||
                sc.Forward(1);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            // Ordered list item
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("...... ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | 
			
		||||
                sc.Forward(6);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("..... ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | 
			
		||||
                sc.Forward(5);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match(".... ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | 
			
		||||
                sc.Forward(4);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("... ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | 
			
		||||
                sc.Forward(3);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match(".. ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | 
			
		||||
                sc.Forward(2);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart && sc.Match(". ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | 
			
		||||
                sc.Forward(1);
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            // Blockquote
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("> ")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_BLOCKQUOTE);
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
            }
 | 
			
		||||
            // Link
 | 
			
		||||
            else if (!sc.atLineStart && sc.ch == '[' && sc.chPrev != '\\' && sc.chNext != ' ') {
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_LINK);
 | 
			
		||||
                freezeCursor = true;
 | 
			
		||||
            }
 | 
			
		||||
            // Code block
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("----") && IsNewline(sc.GetRelative(4))) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_CODEBK);
 | 
			
		||||
                sc.Forward(4);
 | 
			
		||||
            }
 | 
			
		||||
            // Passthrough block
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("++++") && IsNewline(sc.GetRelative(4))) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_PASSBK);
 | 
			
		||||
                sc.Forward(4);
 | 
			
		||||
            }
 | 
			
		||||
            // Comment block
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("////") && IsNewline(sc.GetRelative(4))) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_COMMENTBK);
 | 
			
		||||
                sc.Forward(4);
 | 
			
		||||
            }
 | 
			
		||||
            // Comment
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("//")) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_COMMENT);
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
            }
 | 
			
		||||
            // Literal
 | 
			
		||||
            else if (sc.ch == '+' && sc.chPrev != '\\' && sc.chNext != ' ' && AtTermStart(sc)) {
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_LITERAL);
 | 
			
		||||
                freezeCursor = true;
 | 
			
		||||
            }
 | 
			
		||||
            // Literal block
 | 
			
		||||
            else if (sc.atLineStart && sc.Match("....") && IsNewline(sc.GetRelative(4))) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_LITERALBK);
 | 
			
		||||
                sc.Forward(4);
 | 
			
		||||
            }
 | 
			
		||||
            // Attribute
 | 
			
		||||
            else if (sc.atLineStart && sc.ch == ':' && sc.chNext != ' ') {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_ATTRIB);
 | 
			
		||||
            }
 | 
			
		||||
            // Strong
 | 
			
		||||
            else if (sc.Match("**") && sc.GetRelative(2) != ' ') {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_STRONG2);
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.ch == '*' && sc.chNext != ' ' && AtTermStart(sc)) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_STRONG1);
 | 
			
		||||
            }
 | 
			
		||||
            // Emphasis
 | 
			
		||||
            else if (sc.Match("__") && sc.GetRelative(2) != ' ') {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_EM2);
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.ch == '_' && sc.chNext != ' ' && AtTermStart(sc)) {
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_EM1);
 | 
			
		||||
            }
 | 
			
		||||
            // Macro
 | 
			
		||||
            else if (sc.atLineStart && sc.ch == '[' && sc.chNext != ' ') {
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
                sc.SetState(SCE_ASCIIDOC_MACRO);
 | 
			
		||||
                freezeCursor = true;
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                int i = 0;
 | 
			
		||||
                bool found = false;
 | 
			
		||||
                while (!found && MacroList[i].name != NULL) {
 | 
			
		||||
                    if (MacroList[i].start)
 | 
			
		||||
                        found = sc.atLineStart && sc.Match(MacroList[i].name);
 | 
			
		||||
                    else
 | 
			
		||||
                        found = sc.Match(MacroList[i].name);
 | 
			
		||||
                    if (found) {
 | 
			
		||||
                        sc.SetState(SCE_ASCIIDOC_MACRO);
 | 
			
		||||
                        sc.Forward(MacroList[i].len1);
 | 
			
		||||
                        sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | 
			
		||||
                        if (MacroList[i].len2 > 1)
 | 
			
		||||
                            sc.Forward(MacroList[i].len2 - 1);
 | 
			
		||||
                    }
 | 
			
		||||
                    i++;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        // Advance if not holding back the cursor for this iteration.
 | 
			
		||||
        if (!freezeCursor)
 | 
			
		||||
            sc.Forward();
 | 
			
		||||
        freezeCursor = false;
 | 
			
		||||
    }
 | 
			
		||||
    sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmAsciidoc(SCLEX_ASCIIDOC, ColorizeAsciidocDoc, "asciidoc");
 | 
			
		||||
							
								
								
									
										479
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAsm.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										479
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAsm.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,479 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexAsm.cxx
 | 
			
		||||
 ** Lexer for Assembler, just for the MASM syntax
 | 
			
		||||
 ** Written by The Black Horus
 | 
			
		||||
 ** Enhancements and NASM stuff by Kein-Hong Man, 2003-10
 | 
			
		||||
 ** SCE_ASM_COMMENTBLOCK and SCE_ASM_CHARACTER are for future GNU as colouring
 | 
			
		||||
 ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cctype>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cstdarg>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "OptionSet.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
bool IsAWordChar(const int ch) noexcept {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
 | 
			
		||||
		ch == '_' || ch == '?');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool IsAWordStart(const int ch) noexcept {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
 | 
			
		||||
		ch == '%' || ch == '@' || ch == '$' || ch == '?');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool IsAsmOperator(const int ch) noexcept {
 | 
			
		||||
	if ((ch < 0x80) && (isalnum(ch)))
 | 
			
		||||
		return false;
 | 
			
		||||
	// '.' left out as it is used to make up numbers
 | 
			
		||||
	if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
 | 
			
		||||
		ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
 | 
			
		||||
		ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
 | 
			
		||||
		ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
 | 
			
		||||
		ch == '%' || ch == ':')
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr bool IsStreamCommentStyle(int style) noexcept {
 | 
			
		||||
	return style == SCE_ASM_COMMENTDIRECTIVE || style == SCE_ASM_COMMENTBLOCK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// An individual named option for use in an OptionSet
 | 
			
		||||
 | 
			
		||||
// Options used for LexerAsm
 | 
			
		||||
struct OptionsAsm {
 | 
			
		||||
	std::string delimiter;
 | 
			
		||||
	bool fold;
 | 
			
		||||
	bool foldSyntaxBased;
 | 
			
		||||
	bool foldCommentMultiline;
 | 
			
		||||
	bool foldCommentExplicit;
 | 
			
		||||
	std::string foldExplicitStart;
 | 
			
		||||
	std::string foldExplicitEnd;
 | 
			
		||||
	bool foldExplicitAnywhere;
 | 
			
		||||
	bool foldCompact;
 | 
			
		||||
	std::string commentChar;
 | 
			
		||||
	OptionsAsm() {
 | 
			
		||||
		delimiter = "";
 | 
			
		||||
		fold = false;
 | 
			
		||||
		foldSyntaxBased = true;
 | 
			
		||||
		foldCommentMultiline = false;
 | 
			
		||||
		foldCommentExplicit = false;
 | 
			
		||||
		foldExplicitStart = "";
 | 
			
		||||
		foldExplicitEnd   = "";
 | 
			
		||||
		foldExplicitAnywhere = false;
 | 
			
		||||
		foldCompact = true;
 | 
			
		||||
		commentChar = "";
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char *const asmWordListDesc[] = {
 | 
			
		||||
	"CPU instructions",
 | 
			
		||||
	"FPU instructions",
 | 
			
		||||
	"Registers",
 | 
			
		||||
	"Directives",
 | 
			
		||||
	"Directive operands",
 | 
			
		||||
	"Extended instructions",
 | 
			
		||||
	"Directives4Foldstart",
 | 
			
		||||
	"Directives4Foldend",
 | 
			
		||||
	nullptr
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct OptionSetAsm : public OptionSet<OptionsAsm> {
 | 
			
		||||
	OptionSetAsm() {
 | 
			
		||||
		DefineProperty("lexer.asm.comment.delimiter", &OptionsAsm::delimiter,
 | 
			
		||||
			"Character used for COMMENT directive's delimiter, replacing the standard \"~\".");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold", &OptionsAsm::fold);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.asm.syntax.based", &OptionsAsm::foldSyntaxBased,
 | 
			
		||||
			"Set this property to 0 to disable syntax based folding.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.asm.comment.multiline", &OptionsAsm::foldCommentMultiline,
 | 
			
		||||
			"Set this property to 1 to enable folding multi-line comments.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.asm.comment.explicit", &OptionsAsm::foldCommentExplicit,
 | 
			
		||||
			"This option enables folding explicit fold points when using the Asm lexer. "
 | 
			
		||||
			"Explicit fold points allows adding extra folding by placing a ;{ comment at the start and a ;} "
 | 
			
		||||
			"at the end of a section that should fold.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.asm.explicit.start", &OptionsAsm::foldExplicitStart,
 | 
			
		||||
			"The string to use for explicit fold start points, replacing the standard ;{.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.asm.explicit.end", &OptionsAsm::foldExplicitEnd,
 | 
			
		||||
			"The string to use for explicit fold end points, replacing the standard ;}.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.asm.explicit.anywhere", &OptionsAsm::foldExplicitAnywhere,
 | 
			
		||||
			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.compact", &OptionsAsm::foldCompact);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("lexer.as.comment.character", &OptionsAsm::commentChar,
 | 
			
		||||
			"Overrides the default comment character (which is ';' for asm and '#' for as).");
 | 
			
		||||
 | 
			
		||||
		DefineWordListSets(asmWordListDesc);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LexerAsm : public DefaultLexer {
 | 
			
		||||
	WordList cpuInstruction;
 | 
			
		||||
	WordList mathInstruction;
 | 
			
		||||
	WordList registers;
 | 
			
		||||
	WordList directive;
 | 
			
		||||
	WordList directiveOperand;
 | 
			
		||||
	WordList extInstruction;
 | 
			
		||||
	WordList directives4foldstart;
 | 
			
		||||
	WordList directives4foldend;
 | 
			
		||||
	OptionsAsm options;
 | 
			
		||||
	OptionSetAsm osAsm;
 | 
			
		||||
	int commentChar;
 | 
			
		||||
public:
 | 
			
		||||
	LexerAsm(const char *languageName_, int language_, int commentChar_) : DefaultLexer(languageName_, language_) {
 | 
			
		||||
		commentChar = commentChar_;
 | 
			
		||||
	}
 | 
			
		||||
	virtual ~LexerAsm() {
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD Release() override {
 | 
			
		||||
		delete this;
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD Version() const override {
 | 
			
		||||
		return lvRelease5;
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD PropertyNames() override {
 | 
			
		||||
		return osAsm.PropertyNames();
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD PropertyType(const char *name) override {
 | 
			
		||||
		return osAsm.PropertyType(name);
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD DescribeProperty(const char *name) override {
 | 
			
		||||
		return osAsm.DescribeProperty(name);
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
 | 
			
		||||
	const char * SCI_METHOD PropertyGet(const char *key) override {
 | 
			
		||||
		return osAsm.PropertyGet(key);
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD DescribeWordListSets() override {
 | 
			
		||||
		return osAsm.DescribeWordListSets();
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
 | 
			
		||||
	void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
	void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
 | 
			
		||||
	void * SCI_METHOD PrivateCall(int, void *) override {
 | 
			
		||||
		return nullptr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static ILexer5 *LexerFactoryAsm() {
 | 
			
		||||
		return new LexerAsm("asm", SCLEX_ASM, ';');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static ILexer5 *LexerFactoryAs() {
 | 
			
		||||
		return new LexerAsm("as", SCLEX_AS, '#');
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerAsm::PropertySet(const char *key, const char *val) {
 | 
			
		||||
	if (osAsm.PropertySet(&options, key, val)) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) {
 | 
			
		||||
	WordList *wordListN = nullptr;
 | 
			
		||||
	switch (n) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		wordListN = &cpuInstruction;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		wordListN = &mathInstruction;
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		wordListN = ®isters;
 | 
			
		||||
		break;
 | 
			
		||||
	case 3:
 | 
			
		||||
		wordListN = &directive;
 | 
			
		||||
		break;
 | 
			
		||||
	case 4:
 | 
			
		||||
		wordListN = &directiveOperand;
 | 
			
		||||
		break;
 | 
			
		||||
	case 5:
 | 
			
		||||
		wordListN = &extInstruction;
 | 
			
		||||
		break;
 | 
			
		||||
	case 6:
 | 
			
		||||
		wordListN = &directives4foldstart;
 | 
			
		||||
		break;
 | 
			
		||||
	case 7:
 | 
			
		||||
		wordListN = &directives4foldend;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position firstModification = -1;
 | 
			
		||||
	if (wordListN) {
 | 
			
		||||
		if (wordListN->Set(wl, true)) {
 | 
			
		||||
			firstModification = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return firstModification;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
 | 
			
		||||
	const char commentCharacter = options.commentChar.empty() ?
 | 
			
		||||
		commentChar : options.commentChar.front();
 | 
			
		||||
 | 
			
		||||
	// Do not leak onto next line
 | 
			
		||||
	if (initStyle == SCE_ASM_STRINGEOL)
 | 
			
		||||
		initStyle = SCE_ASM_DEFAULT;
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward())
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		if (sc.atLineStart) {
 | 
			
		||||
			switch (sc.state) {
 | 
			
		||||
			case SCE_ASM_STRING:
 | 
			
		||||
			case SCE_ASM_CHARACTER:
 | 
			
		||||
				// Prevent SCE_ASM_STRINGEOL from leaking back to previous line
 | 
			
		||||
				sc.SetState(sc.state);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ASM_COMMENT:
 | 
			
		||||
				sc.SetState(SCE_ASM_DEFAULT);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Handle line continuation generically.
 | 
			
		||||
		if (sc.ch == '\\') {
 | 
			
		||||
			if (sc.chNext == '\n' || sc.chNext == '\r') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				if (sc.ch == '\r' && sc.chNext == '\n') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		if (sc.state == SCE_ASM_OPERATOR) {
 | 
			
		||||
			if (!IsAsmOperator(sc.ch)) {
 | 
			
		||||
			    sc.SetState(SCE_ASM_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_ASM_NUMBER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_ASM_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_ASM_IDENTIFIER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch) ) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
				bool IsDirective = false;
 | 
			
		||||
 | 
			
		||||
				if (cpuInstruction.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_ASM_CPUINSTRUCTION);
 | 
			
		||||
				} else if (mathInstruction.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_ASM_MATHINSTRUCTION);
 | 
			
		||||
				} else if (registers.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_ASM_REGISTER);
 | 
			
		||||
				}  else if (directive.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_ASM_DIRECTIVE);
 | 
			
		||||
					IsDirective = true;
 | 
			
		||||
				} else if (directiveOperand.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);
 | 
			
		||||
				} else if (extInstruction.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_ASM_EXTINSTRUCTION);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_ASM_DEFAULT);
 | 
			
		||||
				if (IsDirective && !strcmp(s, "comment")) {
 | 
			
		||||
					const char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
 | 
			
		||||
					while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) {
 | 
			
		||||
						sc.ForwardSetState(SCE_ASM_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
					if (sc.ch == delimiter) {
 | 
			
		||||
						sc.SetState(SCE_ASM_COMMENTDIRECTIVE);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_ASM_COMMENTDIRECTIVE) {
 | 
			
		||||
			const char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
 | 
			
		||||
			if (sc.ch == delimiter) {
 | 
			
		||||
				while (!sc.MatchLineEnd()) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_ASM_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_ASM_STRING) {
 | 
			
		||||
			if (sc.ch == '\\') {
 | 
			
		||||
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_ASM_DEFAULT);
 | 
			
		||||
			} else if (sc.atLineEnd) {
 | 
			
		||||
				sc.ChangeState(SCE_ASM_STRINGEOL);
 | 
			
		||||
				sc.ForwardSetState(SCE_ASM_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_ASM_CHARACTER) {
 | 
			
		||||
			if (sc.ch == '\\') {
 | 
			
		||||
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.ForwardSetState(SCE_ASM_DEFAULT);
 | 
			
		||||
			} else if (sc.atLineEnd) {
 | 
			
		||||
				sc.ChangeState(SCE_ASM_STRINGEOL);
 | 
			
		||||
				sc.ForwardSetState(SCE_ASM_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_ASM_DEFAULT) {
 | 
			
		||||
			if (sc.ch == commentCharacter) {
 | 
			
		||||
				sc.SetState(SCE_ASM_COMMENT);
 | 
			
		||||
			} else if (IsASCII(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && IsASCII(sc.chNext) && isdigit(sc.chNext)))) {
 | 
			
		||||
				sc.SetState(SCE_ASM_NUMBER);
 | 
			
		||||
			} else if (IsAWordStart(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_ASM_IDENTIFIER);
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_ASM_STRING);
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(SCE_ASM_CHARACTER);
 | 
			
		||||
			} else if (IsAsmOperator(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_ASM_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Store both the current line's fold level and the next lines in the
 | 
			
		||||
// level store to make it easy to pick up with each increment
 | 
			
		||||
// and to make it possible to fiddle the current level for "else".
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
 | 
			
		||||
	if (!options.fold)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
 | 
			
		||||
	const Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
	if (lineCurrent > 0)
 | 
			
		||||
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 | 
			
		||||
	int levelNext = levelCurrent;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
	char word[100]{};
 | 
			
		||||
	int wordlen = 0;
 | 
			
		||||
	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		const char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		const int stylePrev = style;
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if (options.foldCommentMultiline && IsStreamCommentStyle(style)) {
 | 
			
		||||
			if (!IsStreamCommentStyle(stylePrev)) {
 | 
			
		||||
				levelNext++;
 | 
			
		||||
			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
 | 
			
		||||
				// Comments don't end at end of line and the next character may be unstyled.
 | 
			
		||||
				levelNext--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (options.foldCommentExplicit && ((style == SCE_ASM_COMMENT) || options.foldExplicitAnywhere)) {
 | 
			
		||||
			if (userDefinedFoldMarkers) {
 | 
			
		||||
				if (styler.Match(i, options.foldExplicitStart.c_str())) {
 | 
			
		||||
 					levelNext++;
 | 
			
		||||
				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
 | 
			
		||||
 					levelNext--;
 | 
			
		||||
 				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if (ch == ';') {
 | 
			
		||||
					if (chNext == '{') {
 | 
			
		||||
						levelNext++;
 | 
			
		||||
					} else if (chNext == '}') {
 | 
			
		||||
						levelNext--;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 			}
 | 
			
		||||
 		}
 | 
			
		||||
		if (options.foldSyntaxBased && (style == SCE_ASM_DIRECTIVE)) {
 | 
			
		||||
			word[wordlen++] = MakeLowerCase(ch);
 | 
			
		||||
			if (wordlen == 100) {                   // prevent overflow
 | 
			
		||||
				word[0] = '\0';
 | 
			
		||||
				wordlen = 1;
 | 
			
		||||
			}
 | 
			
		||||
			if (styleNext != SCE_ASM_DIRECTIVE) {   // reading directive ready
 | 
			
		||||
				word[wordlen] = '\0';
 | 
			
		||||
				wordlen = 0;
 | 
			
		||||
				if (directives4foldstart.InList(word)) {
 | 
			
		||||
					levelNext++;
 | 
			
		||||
				} else if (directives4foldend.InList(word)){
 | 
			
		||||
					levelNext--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!IsASpace(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		if (atEOL || (i == endPos-1)) {
 | 
			
		||||
			const int levelUse = levelCurrent;
 | 
			
		||||
			int lev = levelUse | levelNext << 16;
 | 
			
		||||
			if (visibleChars == 0 && options.foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if (levelUse < levelNext)
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelCurrent = levelNext;
 | 
			
		||||
			if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length() - 1))) {
 | 
			
		||||
				// There is an empty line at end of file so give it same level and empty
 | 
			
		||||
				styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
 | 
			
		||||
			}
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmAsm(SCLEX_ASM, LexerAsm::LexerFactoryAsm, "asm", asmWordListDesc);
 | 
			
		||||
extern const LexerModule lmAs(SCLEX_AS, LexerAsm::LexerFactoryAs, "as", asmWordListDesc);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										189
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAsn1.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								3rdparty/lexilla540/lexilla/lexers/LexAsn1.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,189 @@
 | 
			
		||||
// 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);
 | 
			
		||||
							
								
								
									
										995
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBaan.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										995
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBaan.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,995 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexBaan.cxx
 | 
			
		||||
** Lexer for Baan.
 | 
			
		||||
** Based heavily on LexCPP.cxx
 | 
			
		||||
**/
 | 
			
		||||
// Copyright 2001- by Vamsi Potluru <vamsi@who.net> & Praveen Ambekar <ambekarpraveen@yahoo.com>
 | 
			
		||||
// Maintainer Email: oirfeodent@yahoo.co.in
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
// C standard library
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
// C++ wrappers of C standard library
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
// C++ standard library
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
// Scintilla headers
 | 
			
		||||
 | 
			
		||||
// Non-platform-specific headers
 | 
			
		||||
 | 
			
		||||
// include
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
// lexlib
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "OptionSet.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
// Use an unnamed namespace to protect the functions and classes from name conflicts
 | 
			
		||||
 | 
			
		||||
// Options used for LexerBaan
 | 
			
		||||
struct OptionsBaan {
 | 
			
		||||
	bool fold;
 | 
			
		||||
	bool foldComment;
 | 
			
		||||
	bool foldPreprocessor;
 | 
			
		||||
	bool foldCompact;
 | 
			
		||||
	bool baanFoldSyntaxBased;
 | 
			
		||||
	bool baanFoldKeywordsBased;
 | 
			
		||||
	bool baanFoldSections;
 | 
			
		||||
	bool baanFoldInnerLevel;
 | 
			
		||||
	bool baanStylingWithinPreprocessor;
 | 
			
		||||
	OptionsBaan() {
 | 
			
		||||
		fold = false;
 | 
			
		||||
		foldComment = false;
 | 
			
		||||
		foldPreprocessor = false;
 | 
			
		||||
		foldCompact = false;
 | 
			
		||||
		baanFoldSyntaxBased = false;
 | 
			
		||||
		baanFoldKeywordsBased = false;
 | 
			
		||||
		baanFoldSections = false;
 | 
			
		||||
		baanFoldInnerLevel = false;
 | 
			
		||||
		baanStylingWithinPreprocessor = false;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char *const baanWordLists[] = {
 | 
			
		||||
	"Baan & BaanSQL Reserved Keywords ",
 | 
			
		||||
	"Baan Standard functions",
 | 
			
		||||
	"Baan Functions Abridged",
 | 
			
		||||
	"Baan Main Sections ",
 | 
			
		||||
	"Baan Sub Sections",
 | 
			
		||||
	"PreDefined Variables",
 | 
			
		||||
	"PreDefined Attributes",
 | 
			
		||||
	"Enumerates",
 | 
			
		||||
	0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct OptionSetBaan : public OptionSet<OptionsBaan> {
 | 
			
		||||
	OptionSetBaan() {
 | 
			
		||||
		DefineProperty("fold", &OptionsBaan::fold);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.comment", &OptionsBaan::foldComment);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.preprocessor", &OptionsBaan::foldPreprocessor);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.compact", &OptionsBaan::foldCompact);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.baan.syntax.based", &OptionsBaan::baanFoldSyntaxBased,
 | 
			
		||||
			"Set this property to 0 to disable syntax based folding, which is folding based on '{' & '('.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.baan.keywords.based", &OptionsBaan::baanFoldKeywordsBased,
 | 
			
		||||
			"Set this property to 0 to disable keywords based folding, which is folding based on "
 | 
			
		||||
			" for, if, on (case), repeat, select, while and fold ends based on endfor, endif, endcase, until, endselect, endwhile respectively."
 | 
			
		||||
			"Also folds declarations which are grouped together.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.baan.sections", &OptionsBaan::baanFoldSections,
 | 
			
		||||
			"Set this property to 0 to disable folding of Main Sections as well as Sub Sections.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.baan.inner.level", &OptionsBaan::baanFoldInnerLevel,
 | 
			
		||||
			"Set this property to 1 to enable folding of inner levels of select statements."
 | 
			
		||||
			"Disabled by default. case and if statements are also eligible" );
 | 
			
		||||
 | 
			
		||||
		DefineProperty("lexer.baan.styling.within.preprocessor", &OptionsBaan::baanStylingWithinPreprocessor,
 | 
			
		||||
			"For Baan code, determines whether all preprocessor code is styled in the "
 | 
			
		||||
			"preprocessor style (0, the default) or only from the initial # to the end "
 | 
			
		||||
			"of the command word(1).");
 | 
			
		||||
 | 
			
		||||
		DefineWordListSets(baanWordLists);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(const int  ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '$');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsAnOperator(int ch) {
 | 
			
		||||
	if (IsAlphaNumeric(ch))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (ch == '#' || ch == '^' || ch == '&' || ch == '*' ||
 | 
			
		||||
		ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
 | 
			
		||||
		ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
 | 
			
		||||
		ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
 | 
			
		||||
		ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
 | 
			
		||||
		ch == '?' || ch == '!' || ch == '"' || ch == '~' ||
 | 
			
		||||
		ch == '\\')
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int IsAnyOtherIdentifier(char *s, Sci_Position sLength) {
 | 
			
		||||
 | 
			
		||||
	/*	IsAnyOtherIdentifier uses standard templates used in baan.
 | 
			
		||||
	The matching template is shown as comments just above the return condition.
 | 
			
		||||
	^ - refers to any character [a-z].
 | 
			
		||||
	# - refers to any number [0-9].
 | 
			
		||||
	Other characters shown are compared as is.
 | 
			
		||||
	Tried implementing with Regex... it was too complicated for me.
 | 
			
		||||
	Any other implementation suggestion welcome.
 | 
			
		||||
	*/
 | 
			
		||||
	switch (sLength) {
 | 
			
		||||
	case 8:
 | 
			
		||||
		if (isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
 | 
			
		||||
			//^^^^^###
 | 
			
		||||
			return(SCE_BAAN_TABLEDEF);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 9:
 | 
			
		||||
		if (s[0] == 't' && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && isalpha(s[5]) && IsADigit(s[6]) && IsADigit(s[7]) && IsADigit(s[8])) {
 | 
			
		||||
			//t^^^^^###
 | 
			
		||||
			return(SCE_BAAN_TABLEDEF);
 | 
			
		||||
		}
 | 
			
		||||
		else if (s[8] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
 | 
			
		||||
			//^^^^^###.
 | 
			
		||||
			return(SCE_BAAN_TABLESQL);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 13:
 | 
			
		||||
		if (s[8] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
 | 
			
		||||
			//^^^^^###.****
 | 
			
		||||
			return(SCE_BAAN_TABLESQL);
 | 
			
		||||
		}
 | 
			
		||||
		else if (s[0] == 'r' && s[1] == 'c' && s[2] == 'd' && s[3] == '.' && s[4] == 't' && isalpha(s[5]) && isalpha(s[6]) && isalpha(s[7]) && isalpha(s[8]) && isalpha(s[9]) && IsADigit(s[10]) && IsADigit(s[11]) && IsADigit(s[12])) {
 | 
			
		||||
			//rcd.t^^^^^###
 | 
			
		||||
			return(SCE_BAAN_TABLEDEF);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 14:
 | 
			
		||||
	case 15:
 | 
			
		||||
		if (s[8] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
 | 
			
		||||
			if (s[13] != ':') {
 | 
			
		||||
				//^^^^^###.******
 | 
			
		||||
				return(SCE_BAAN_TABLESQL);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 16:
 | 
			
		||||
	case 17:
 | 
			
		||||
		if (s[8] == '.' && s[9] == '_' && s[10] == 'i' && s[11] == 'n' && s[12] == 'd' && s[13] == 'e' && s[14] == 'x' && IsADigit(s[15]) && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
 | 
			
		||||
			//^^^^^###._index##
 | 
			
		||||
			return(SCE_BAAN_TABLEDEF);
 | 
			
		||||
		}
 | 
			
		||||
		else if (s[8] == '.' && s[9] == '_' && s[10] == 'c' && s[11] == 'o' && s[12] == 'm' && s[13] == 'p' && s[14] == 'n' && s[15] == 'r' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
 | 
			
		||||
			//^^^^^###._compnr
 | 
			
		||||
			return(SCE_BAAN_TABLEDEF);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	if (sLength > 14 && s[5] == '.' && s[6] == 'd' && s[7] == 'l' && s[8] == 'l' && s[13] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[9]) && IsADigit(s[10]) && IsADigit(s[11]) && IsADigit(s[12])) {
 | 
			
		||||
		//^^^^^.dll####.
 | 
			
		||||
		return(SCE_BAAN_FUNCTION);
 | 
			
		||||
	}
 | 
			
		||||
	else if (sLength > 15 && s[2] == 'i' && s[3] == 'n' && s[4] == 't' && s[5] == '.' && s[6] == 'd' && s[7] == 'l' && s[8] == 'l' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[9]) && isalpha(s[10]) && isalpha(s[11]) && isalpha(s[12]) && isalpha(s[13])) {
 | 
			
		||||
		//^^int.dll^^^^^.
 | 
			
		||||
		return(SCE_BAAN_FUNCTION);
 | 
			
		||||
	}
 | 
			
		||||
	else if (sLength > 11 && s[0] == 'i' && s[10] == '.' && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && isalpha(s[5]) && IsADigit(s[6]) && IsADigit(s[7]) && IsADigit(s[8]) && IsADigit(s[9])) {
 | 
			
		||||
		//i^^^^^####.
 | 
			
		||||
		return(SCE_BAAN_FUNCTION);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return(SCE_BAAN_DEFAULT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsCommentLine(Sci_Position line, LexAccessor &styler) {
 | 
			
		||||
	Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
	Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
	for (Sci_Position i = pos; i < eol_pos; i++) {
 | 
			
		||||
		char ch = styler[i];
 | 
			
		||||
		int style = styler.StyleAt(i);
 | 
			
		||||
		if (ch == '|' && style == SCE_BAAN_COMMENT)
 | 
			
		||||
			return true;
 | 
			
		||||
		else if (!IsASpaceOrTab(ch))
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsPreProcLine(Sci_Position line, LexAccessor &styler) {
 | 
			
		||||
	Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
	Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
	for (Sci_Position i = pos; i < eol_pos; i++) {
 | 
			
		||||
		char ch = styler[i];
 | 
			
		||||
		int style = styler.StyleAt(i);
 | 
			
		||||
		if (ch == '#' && style == SCE_BAAN_PREPROCESSOR) {
 | 
			
		||||
			if (styler.Match(i, "#elif") || styler.Match(i, "#else") || styler.Match(i, "#endif")
 | 
			
		||||
				|| styler.Match(i, "#if") || styler.Match(i, "#ifdef") || styler.Match(i, "#ifndef"))
 | 
			
		||||
				// Above PreProcessors has a seperate fold mechanism.
 | 
			
		||||
				return false;
 | 
			
		||||
			else
 | 
			
		||||
				return true;
 | 
			
		||||
		}
 | 
			
		||||
		else if (ch == '^')
 | 
			
		||||
			return true;
 | 
			
		||||
		else if (!IsASpaceOrTab(ch))
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int mainOrSubSectionLine(Sci_Position line, LexAccessor &styler) {
 | 
			
		||||
	Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
	Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
	for (Sci_Position i = pos; i < eol_pos; i++) {
 | 
			
		||||
		char ch = styler[i];
 | 
			
		||||
		int style = styler.StyleAt(i);
 | 
			
		||||
		if (style == SCE_BAAN_WORD5 || style == SCE_BAAN_WORD4)
 | 
			
		||||
			return style;
 | 
			
		||||
		else if (IsASpaceOrTab(ch))
 | 
			
		||||
			continue;
 | 
			
		||||
		else
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool priorSectionIsSubSection(Sci_Position line, LexAccessor &styler){
 | 
			
		||||
	while (line > 0) {
 | 
			
		||||
		Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
		Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
		for (Sci_Position i = pos; i < eol_pos; i++) {
 | 
			
		||||
			char ch = styler[i];
 | 
			
		||||
			int style = styler.StyleAt(i);
 | 
			
		||||
			if (style == SCE_BAAN_WORD4)
 | 
			
		||||
				return true;
 | 
			
		||||
			else if (style == SCE_BAAN_WORD5)
 | 
			
		||||
				return false;
 | 
			
		||||
			else if (IsASpaceOrTab(ch))
 | 
			
		||||
				continue;
 | 
			
		||||
			else
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		line--;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool nextSectionIsSubSection(Sci_Position line, LexAccessor &styler) {
 | 
			
		||||
	while (line > 0) {
 | 
			
		||||
		Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
		Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
		for (Sci_Position i = pos; i < eol_pos; i++) {
 | 
			
		||||
			char ch = styler[i];
 | 
			
		||||
			int style = styler.StyleAt(i);
 | 
			
		||||
			if (style == SCE_BAAN_WORD4)
 | 
			
		||||
				return true;
 | 
			
		||||
			else if (style == SCE_BAAN_WORD5)
 | 
			
		||||
				return false;
 | 
			
		||||
			else if (IsASpaceOrTab(ch))
 | 
			
		||||
				continue;
 | 
			
		||||
			else
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		line++;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsDeclarationLine(Sci_Position line, LexAccessor &styler) {
 | 
			
		||||
	Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
	Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
	for (Sci_Position i = pos; i < eol_pos; i++) {
 | 
			
		||||
		char ch = styler[i];
 | 
			
		||||
		int style = styler.StyleAt(i);
 | 
			
		||||
		if (style == SCE_BAAN_WORD) {
 | 
			
		||||
			if (styler.Match(i, "table") || styler.Match(i, "extern") || styler.Match(i, "long")
 | 
			
		||||
				|| styler.Match(i, "double") || styler.Match(i, "boolean") || styler.Match(i, "string")
 | 
			
		||||
				|| styler.Match(i, "domain")) {
 | 
			
		||||
				for (Sci_Position j = eol_pos; j > pos; j--) {
 | 
			
		||||
					int styleFromEnd = styler.StyleAt(j);
 | 
			
		||||
					if (styleFromEnd == SCE_BAAN_COMMENT)
 | 
			
		||||
						continue;
 | 
			
		||||
					else if (IsASpace(styler[j]))
 | 
			
		||||
						continue;
 | 
			
		||||
					else if (styler[j] != ',')
 | 
			
		||||
						//Above conditions ensures, Declaration is not part of any function parameters.
 | 
			
		||||
						return true;
 | 
			
		||||
					else
 | 
			
		||||
						return false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				return false;
 | 
			
		||||
		}
 | 
			
		||||
		else if (!IsASpaceOrTab(ch))
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsInnerLevelFold(Sci_Position line, LexAccessor &styler) {
 | 
			
		||||
	Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
	Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
	for (Sci_Position i = pos; i < eol_pos; i++) {
 | 
			
		||||
		char ch = styler[i];
 | 
			
		||||
		int style = styler.StyleAt(i);
 | 
			
		||||
		if (style == SCE_BAAN_WORD && (styler.Match(i, "else" ) || styler.Match(i, "case")
 | 
			
		||||
			|| styler.Match(i, "default") || styler.Match(i, "selectdo") || styler.Match(i, "selecteos")
 | 
			
		||||
			|| styler.Match(i, "selectempty") || styler.Match(i, "selecterror")))
 | 
			
		||||
			return true;
 | 
			
		||||
		else if (IsASpaceOrTab(ch))
 | 
			
		||||
			continue;
 | 
			
		||||
		else
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool wordInArray(const std::string& value, std::string *array, int length)
 | 
			
		||||
{
 | 
			
		||||
	for (int i = 0; i < length; i++)
 | 
			
		||||
	{
 | 
			
		||||
		if (value == array[i])
 | 
			
		||||
		{
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class WordListAbridged : public WordList {
 | 
			
		||||
public:
 | 
			
		||||
	WordListAbridged() {
 | 
			
		||||
		kwAbridged = false;
 | 
			
		||||
		kwHasSection = false;
 | 
			
		||||
	};
 | 
			
		||||
	~WordListAbridged() {
 | 
			
		||||
		Clear();
 | 
			
		||||
	};
 | 
			
		||||
	bool kwAbridged;
 | 
			
		||||
	bool kwHasSection;
 | 
			
		||||
	bool Contains(const char *s) {
 | 
			
		||||
		return kwAbridged ? InListAbridged(s, '~') : InList(s);
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class LexerBaan : public DefaultLexer {
 | 
			
		||||
	WordListAbridged keywords;
 | 
			
		||||
	WordListAbridged keywords2;
 | 
			
		||||
	WordListAbridged keywords3;
 | 
			
		||||
	WordListAbridged keywords4;
 | 
			
		||||
	WordListAbridged keywords5;
 | 
			
		||||
	WordListAbridged keywords6;
 | 
			
		||||
	WordListAbridged keywords7;
 | 
			
		||||
	WordListAbridged keywords8;
 | 
			
		||||
	WordListAbridged keywords9;
 | 
			
		||||
	OptionsBaan options;
 | 
			
		||||
	OptionSetBaan osBaan;
 | 
			
		||||
public:
 | 
			
		||||
	LexerBaan() : DefaultLexer("baan", SCLEX_BAAN) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	virtual ~LexerBaan() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int SCI_METHOD Version() const override {
 | 
			
		||||
		return lvRelease5;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void SCI_METHOD Release() override {
 | 
			
		||||
		delete this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char * SCI_METHOD PropertyNames() override {
 | 
			
		||||
		return osBaan.PropertyNames();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int SCI_METHOD PropertyType(const char * name) override {
 | 
			
		||||
		return osBaan.PropertyType(name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char * SCI_METHOD DescribeProperty(const char * name) override {
 | 
			
		||||
		return osBaan.DescribeProperty(name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
 | 
			
		||||
 | 
			
		||||
	const char * SCI_METHOD PropertyGet(const char *key) override {
 | 
			
		||||
		return osBaan.PropertyGet(key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char * SCI_METHOD DescribeWordListSets() override {
 | 
			
		||||
		return osBaan.DescribeWordListSets();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
 | 
			
		||||
 | 
			
		||||
	void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
 | 
			
		||||
	void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
 | 
			
		||||
	void * SCI_METHOD PrivateCall(int, void *) override {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static ILexer5 * LexerFactoryBaan() {
 | 
			
		||||
		return new LexerBaan();
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerBaan::PropertySet(const char *key, const char *val) {
 | 
			
		||||
	if (osBaan.PropertySet(&options, key, val)) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerBaan::WordListSet(int n, const char *wl) {
 | 
			
		||||
	WordListAbridged *WordListAbridgedN = 0;
 | 
			
		||||
	switch (n) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		WordListAbridgedN = &keywords;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		WordListAbridgedN = &keywords2;
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		WordListAbridgedN = &keywords3;
 | 
			
		||||
		break;
 | 
			
		||||
	case 3:
 | 
			
		||||
		WordListAbridgedN = &keywords4;
 | 
			
		||||
		break;
 | 
			
		||||
	case 4:
 | 
			
		||||
		WordListAbridgedN = &keywords5;
 | 
			
		||||
		break;
 | 
			
		||||
	case 5:
 | 
			
		||||
		WordListAbridgedN = &keywords6;
 | 
			
		||||
		break;
 | 
			
		||||
	case 6:
 | 
			
		||||
		WordListAbridgedN = &keywords7;
 | 
			
		||||
		break;
 | 
			
		||||
	case 7:
 | 
			
		||||
		WordListAbridgedN = &keywords8;
 | 
			
		||||
		break;
 | 
			
		||||
	case 8:
 | 
			
		||||
		WordListAbridgedN = &keywords9;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position firstModification = -1;
 | 
			
		||||
	if (WordListAbridgedN) {
 | 
			
		||||
		WordListAbridged wlNew;
 | 
			
		||||
		wlNew.Set(wl);
 | 
			
		||||
		if (*WordListAbridgedN != wlNew) {
 | 
			
		||||
			WordListAbridgedN->Set(wl);
 | 
			
		||||
			WordListAbridgedN->kwAbridged = strchr(wl, '~') != NULL;
 | 
			
		||||
			WordListAbridgedN->kwHasSection = strchr(wl, ':') != NULL;
 | 
			
		||||
 | 
			
		||||
			firstModification = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return firstModification;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
 | 
			
		||||
	if (initStyle == SCE_BAAN_STRINGEOL)	// Does not leak onto next line
 | 
			
		||||
		initStyle = SCE_BAAN_DEFAULT;
 | 
			
		||||
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	bool lineHasDomain = false;
 | 
			
		||||
	bool lineHasFunction = false;
 | 
			
		||||
	bool lineHasPreProc = false;
 | 
			
		||||
	bool lineIgnoreString = false;
 | 
			
		||||
	bool lineHasDefines = false;
 | 
			
		||||
	bool numberIsHex = false;
 | 
			
		||||
	char word[1000];
 | 
			
		||||
	int wordlen = 0;
 | 
			
		||||
 | 
			
		||||
	std::string preProcessorTags[13] = { "#context_off", "#context_on",
 | 
			
		||||
		"#define", "#elif", "#else", "#endif",
 | 
			
		||||
		"#ident", "#if", "#ifdef", "#ifndef",
 | 
			
		||||
		"#include", "#pragma", "#undef" };
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		switch (sc.state) {
 | 
			
		||||
		case SCE_BAAN_OPERATOR:
 | 
			
		||||
			sc.SetState(SCE_BAAN_DEFAULT);
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_BAAN_NUMBER:
 | 
			
		||||
			if (IsASpaceOrTab(sc.ch) || sc.ch == '\r' || sc.ch == '\n' || IsAnOperator(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_BAAN_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			else if ((numberIsHex && !(MakeLowerCase(sc.ch) == 'x' || MakeLowerCase(sc.ch) == 'e' ||
 | 
			
		||||
				IsADigit(sc.ch, 16) || sc.ch == '.' || sc.ch == '-' || sc.ch == '+')) ||
 | 
			
		||||
				(!numberIsHex && !(MakeLowerCase(sc.ch) == 'e' || IsADigit(sc.ch)
 | 
			
		||||
				|| sc.ch == '.' || sc.ch == '-' || sc.ch == '+'))) {
 | 
			
		||||
					// check '-' for possible -10e-5. Add '+' as well.
 | 
			
		||||
					numberIsHex = false;
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_IDENTIFIER);
 | 
			
		||||
					sc.SetState(SCE_BAAN_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_BAAN_IDENTIFIER:
 | 
			
		||||
			if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
				char s[1000];
 | 
			
		||||
				char s1[1000];
 | 
			
		||||
				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
				if (sc.ch == ':') {
 | 
			
		||||
					memcpy(s1, s, sizeof(s));
 | 
			
		||||
					s1[sc.LengthCurrent()] = sc.ch;
 | 
			
		||||
					s1[sc.LengthCurrent() + 1] = '\0';
 | 
			
		||||
				}
 | 
			
		||||
				if ((keywords.kwHasSection && (sc.ch == ':')) ? keywords.Contains(s1) : keywords.Contains(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_WORD);
 | 
			
		||||
					if (0 == strcmp(s, "domain")) {
 | 
			
		||||
						lineHasDomain = true;
 | 
			
		||||
					}
 | 
			
		||||
					else if (0 == strcmp(s, "function")) {
 | 
			
		||||
						lineHasFunction = true;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else if (lineHasDomain) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_DOMDEF);
 | 
			
		||||
					lineHasDomain = false;
 | 
			
		||||
				}
 | 
			
		||||
				else if (lineHasFunction) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_FUNCDEF);
 | 
			
		||||
					lineHasFunction = false;
 | 
			
		||||
				}
 | 
			
		||||
				else if ((keywords2.kwHasSection && (sc.ch == ':')) ? keywords2.Contains(s1) : keywords2.Contains(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_WORD2);
 | 
			
		||||
				}
 | 
			
		||||
				else if ((keywords3.kwHasSection && (sc.ch == ':')) ? keywords3.Contains(s1) : keywords3.Contains(s)) {
 | 
			
		||||
					if (sc.ch == '(')
 | 
			
		||||
						sc.ChangeState(SCE_BAAN_WORD3);
 | 
			
		||||
					else
 | 
			
		||||
						sc.ChangeState(SCE_BAAN_IDENTIFIER);
 | 
			
		||||
				}
 | 
			
		||||
				else if ((keywords4.kwHasSection && (sc.ch == ':')) ? keywords4.Contains(s1) : keywords4.Contains(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_WORD4);
 | 
			
		||||
				}
 | 
			
		||||
				else if ((keywords5.kwHasSection && (sc.ch == ':')) ? keywords5.Contains(s1) : keywords5.Contains(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_WORD5);
 | 
			
		||||
				}
 | 
			
		||||
				else if ((keywords6.kwHasSection && (sc.ch == ':')) ? keywords6.Contains(s1) : keywords6.Contains(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_WORD6);
 | 
			
		||||
				}
 | 
			
		||||
				else if ((keywords7.kwHasSection && (sc.ch == ':')) ? keywords7.Contains(s1) : keywords7.Contains(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_WORD7);
 | 
			
		||||
				}
 | 
			
		||||
				else if ((keywords8.kwHasSection && (sc.ch == ':')) ? keywords8.Contains(s1) : keywords8.Contains(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_WORD8);
 | 
			
		||||
				}
 | 
			
		||||
				else if ((keywords9.kwHasSection && (sc.ch == ':')) ? keywords9.Contains(s1) : keywords9.Contains(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_WORD9);
 | 
			
		||||
				}
 | 
			
		||||
				else if (lineHasPreProc) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_OBJECTDEF);
 | 
			
		||||
					lineHasPreProc = false;
 | 
			
		||||
				}
 | 
			
		||||
				else if (lineHasDefines) {
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_DEFINEDEF);
 | 
			
		||||
					lineHasDefines = false;
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					int state = IsAnyOtherIdentifier(s, sc.LengthCurrent());
 | 
			
		||||
					if (state > 0) {
 | 
			
		||||
						sc.ChangeState(state);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_BAAN_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_BAAN_PREPROCESSOR:
 | 
			
		||||
			if (options.baanStylingWithinPreprocessor) {
 | 
			
		||||
				if (IsASpace(sc.ch) || IsAnOperator(sc.ch)) {
 | 
			
		||||
					sc.SetState(SCE_BAAN_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				if (sc.atLineEnd && (sc.chNext != '^')) {
 | 
			
		||||
					sc.SetState(SCE_BAAN_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_BAAN_COMMENT:
 | 
			
		||||
			if (sc.ch == '\r' || sc.ch == '\n') {
 | 
			
		||||
				sc.SetState(SCE_BAAN_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_BAAN_COMMENTDOC:
 | 
			
		||||
			if (sc.MatchIgnoreCase("enddllusage")) {
 | 
			
		||||
				for (unsigned int i = 0; i < 10; i++) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				sc.ForwardSetState(SCE_BAAN_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			else if (sc.MatchIgnoreCase("endfunctionusage")) {
 | 
			
		||||
				for (unsigned int i = 0; i < 15; i++) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				sc.ForwardSetState(SCE_BAAN_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_BAAN_STRING:
 | 
			
		||||
			if (sc.ch == '\"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_BAAN_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			else if ((sc.atLineEnd) && (sc.chNext != '^')) {
 | 
			
		||||
				sc.ChangeState(SCE_BAAN_STRINGEOL);
 | 
			
		||||
				sc.ForwardSetState(SCE_BAAN_DEFAULT);
 | 
			
		||||
				visibleChars = 0;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_BAAN_DEFAULT) {
 | 
			
		||||
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))
 | 
			
		||||
				|| ((sc.ch == '-' || sc.ch == '+') && (IsADigit(sc.chNext) || sc.chNext == '.'))
 | 
			
		||||
				|| (MakeLowerCase(sc.ch) == 'e' && (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-'))) {
 | 
			
		||||
				if ((sc.ch == '0' && MakeLowerCase(sc.chNext) == 'x') ||
 | 
			
		||||
					((sc.ch == '-' || sc.ch == '+') && sc.chNext == '0' && MakeLowerCase(sc.GetRelativeCharacter(2)) == 'x')){
 | 
			
		||||
					numberIsHex = true;
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_BAAN_NUMBER);
 | 
			
		||||
			}
 | 
			
		||||
			else if (sc.MatchIgnoreCase("dllusage") || sc.MatchIgnoreCase("functionusage")) {
 | 
			
		||||
				sc.SetState(SCE_BAAN_COMMENTDOC);
 | 
			
		||||
				do {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} while ((!sc.atLineEnd) && sc.More());
 | 
			
		||||
			}
 | 
			
		||||
			else if (iswordstart(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_BAAN_IDENTIFIER);
 | 
			
		||||
			}
 | 
			
		||||
			else if (sc.Match('|')) {
 | 
			
		||||
				sc.SetState(SCE_BAAN_COMMENT);
 | 
			
		||||
			}
 | 
			
		||||
			else if (sc.ch == '\"' && !(lineIgnoreString)) {
 | 
			
		||||
				sc.SetState(SCE_BAAN_STRING);
 | 
			
		||||
			}
 | 
			
		||||
			else if (sc.ch == '#' && visibleChars == 0) {
 | 
			
		||||
				// Preprocessor commands are alone on their line
 | 
			
		||||
				sc.SetState(SCE_BAAN_PREPROCESSOR);
 | 
			
		||||
				word[0] = '\0';
 | 
			
		||||
				wordlen = 0;
 | 
			
		||||
				while (sc.More() && !(IsASpace(sc.chNext) || IsAnOperator(sc.chNext))) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					wordlen++;
 | 
			
		||||
				}
 | 
			
		||||
				sc.GetCurrentLowered(word, sizeof(word));
 | 
			
		||||
				if (!sc.atLineEnd) {
 | 
			
		||||
					word[wordlen++] = sc.ch;
 | 
			
		||||
					word[wordlen++] = '\0';
 | 
			
		||||
				}
 | 
			
		||||
				if (!wordInArray(word, preProcessorTags, 13))
 | 
			
		||||
					// Colorise only preprocessor built in Baan.
 | 
			
		||||
					sc.ChangeState(SCE_BAAN_IDENTIFIER);
 | 
			
		||||
				if (strcmp(word, "#pragma") == 0 || strcmp(word, "#include") == 0) {
 | 
			
		||||
					lineHasPreProc = true;
 | 
			
		||||
					lineIgnoreString = true;
 | 
			
		||||
				}
 | 
			
		||||
				else if (strcmp(word, "#define") == 0 || strcmp(word, "#undef") == 0 ||
 | 
			
		||||
					strcmp(word, "#ifdef") == 0 || strcmp(word, "#if") == 0 || strcmp(word, "#ifndef") == 0) {
 | 
			
		||||
					lineHasDefines = true;
 | 
			
		||||
					lineIgnoreString = false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (IsAnOperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_BAAN_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.atLineEnd) {
 | 
			
		||||
			// Reset states to begining of colourise so no surprises
 | 
			
		||||
			// if different sets of lines lexed.
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
			lineHasDomain = false;
 | 
			
		||||
			lineHasFunction = false;
 | 
			
		||||
			lineHasPreProc = false;
 | 
			
		||||
			lineIgnoreString = false;
 | 
			
		||||
			lineHasDefines = false;
 | 
			
		||||
			numberIsHex = false;
 | 
			
		||||
		}
 | 
			
		||||
		if (!IsASpace(sc.ch)) {
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
	if (!options.fold)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	char word[100];
 | 
			
		||||
	int wordlen = 0;
 | 
			
		||||
	bool foldStart = true;
 | 
			
		||||
	bool foldNextSelect = true;
 | 
			
		||||
	bool afterFunctionSection = false;
 | 
			
		||||
	bool beforeDeclarationSection = false;
 | 
			
		||||
	int currLineStyle = 0;
 | 
			
		||||
	int nextLineStyle = 0;
 | 
			
		||||
 | 
			
		||||
	std::string startTags[6] = { "for", "if", "on", "repeat", "select", "while" };
 | 
			
		||||
	std::string endTags[6] = { "endcase", "endfor", "endif", "endselect", "endwhile", "until" };
 | 
			
		||||
	std::string selectCloseTags[5] = { "selectdo", "selecteos", "selectempty", "selecterror", "endselect" };
 | 
			
		||||
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
 | 
			
		||||
	// Backtrack to previous line in case need to fix its fold status
 | 
			
		||||
	if (startPos > 0) {
 | 
			
		||||
		if (lineCurrent > 0) {
 | 
			
		||||
			lineCurrent--;
 | 
			
		||||
			startPos = styler.LineStart(lineCurrent);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int levelPrev = SC_FOLDLEVELBASE;
 | 
			
		||||
	if (lineCurrent > 0)
 | 
			
		||||
		levelPrev = styler.LevelAt(lineCurrent - 1) >> 16;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		int stylePrev = (i) ? styler.StyleAt(i - 1) : SCE_BAAN_DEFAULT;
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
 | 
			
		||||
		// Comment folding
 | 
			
		||||
		if (options.foldComment && style == SCE_BAAN_COMMENTDOC) {
 | 
			
		||||
			if (style != stylePrev) {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			}
 | 
			
		||||
			else if (style != styleNext) {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {
 | 
			
		||||
			if (!IsCommentLine(lineCurrent - 1, styler)
 | 
			
		||||
				&& IsCommentLine(lineCurrent + 1, styler))
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			else if (IsCommentLine(lineCurrent - 1, styler)
 | 
			
		||||
				&& !IsCommentLine(lineCurrent + 1, styler))
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
		}
 | 
			
		||||
		// PreProcessor Folding
 | 
			
		||||
		if (options.foldPreprocessor) {
 | 
			
		||||
			if (atEOL && IsPreProcLine(lineCurrent, styler)) {
 | 
			
		||||
				if (!IsPreProcLine(lineCurrent - 1, styler)
 | 
			
		||||
					&& IsPreProcLine(lineCurrent + 1, styler))
 | 
			
		||||
					levelCurrent++;
 | 
			
		||||
				else if (IsPreProcLine(lineCurrent - 1, styler)
 | 
			
		||||
					&& !IsPreProcLine(lineCurrent + 1, styler))
 | 
			
		||||
					levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
			else if (style == SCE_BAAN_PREPROCESSOR) {
 | 
			
		||||
				// folds #ifdef/#if/#ifndef - they are not part of the IsPreProcLine folding.
 | 
			
		||||
				if (ch == '#') {
 | 
			
		||||
					if (styler.Match(i, "#ifdef") || styler.Match(i, "#if") || styler.Match(i, "#ifndef")
 | 
			
		||||
						|| styler.Match(i, "#context_on"))
 | 
			
		||||
						levelCurrent++;
 | 
			
		||||
					else if (styler.Match(i, "#endif") || styler.Match(i, "#context_off"))
 | 
			
		||||
						levelCurrent--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		//Syntax Folding
 | 
			
		||||
		if (options.baanFoldSyntaxBased && (style == SCE_BAAN_OPERATOR)) {
 | 
			
		||||
			if (ch == '{' || ch == '(') {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			}
 | 
			
		||||
			else if (ch == '}' || ch == ')') {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		//Keywords Folding
 | 
			
		||||
		if (options.baanFoldKeywordsBased) {
 | 
			
		||||
			if (atEOL && IsDeclarationLine(lineCurrent, styler)) {
 | 
			
		||||
				if (!IsDeclarationLine(lineCurrent - 1, styler)
 | 
			
		||||
					&& IsDeclarationLine(lineCurrent + 1, styler))
 | 
			
		||||
					levelCurrent++;
 | 
			
		||||
				else if (IsDeclarationLine(lineCurrent - 1, styler)
 | 
			
		||||
					&& !IsDeclarationLine(lineCurrent + 1, styler))
 | 
			
		||||
					levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
			else if (style == SCE_BAAN_WORD) {
 | 
			
		||||
				word[wordlen++] = static_cast<char>(MakeLowerCase(ch));
 | 
			
		||||
				if (wordlen == 100) {                   // prevent overflow
 | 
			
		||||
					word[0] = '\0';
 | 
			
		||||
					wordlen = 1;
 | 
			
		||||
				}
 | 
			
		||||
				if (styleNext != SCE_BAAN_WORD) {
 | 
			
		||||
					word[wordlen] = '\0';
 | 
			
		||||
					wordlen = 0;
 | 
			
		||||
					if (strcmp(word, "for") == 0) {
 | 
			
		||||
						Sci_PositionU j = i + 1;
 | 
			
		||||
						while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
 | 
			
		||||
							j++;
 | 
			
		||||
						}
 | 
			
		||||
						if (styler.Match(j, "update")) {
 | 
			
		||||
							// Means this is a "for update" used by Select which is already folded.
 | 
			
		||||
							foldStart = false;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else if (strcmp(word, "on") == 0) {
 | 
			
		||||
						Sci_PositionU j = i + 1;
 | 
			
		||||
						while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
 | 
			
		||||
							j++;
 | 
			
		||||
						}
 | 
			
		||||
						if (!styler.Match(j, "case")) {
 | 
			
		||||
							// Means this is not a "on Case" statement... could be "on" used by index.
 | 
			
		||||
							foldStart = false;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else if (strcmp(word, "select") == 0) {
 | 
			
		||||
						if (foldNextSelect) {
 | 
			
		||||
							// Next Selects are sub-clause till reach of selectCloseTags[] array.
 | 
			
		||||
							foldNextSelect = false;
 | 
			
		||||
							foldStart = true;
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
							foldNextSelect = false;
 | 
			
		||||
							foldStart = false;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else if (wordInArray(word, selectCloseTags, 5)) {
 | 
			
		||||
						// select clause ends, next select clause can be folded.
 | 
			
		||||
						foldNextSelect = true;
 | 
			
		||||
						foldStart = true;
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						foldStart = true;
 | 
			
		||||
					}
 | 
			
		||||
					if (foldStart) {
 | 
			
		||||
						if (wordInArray(word, startTags, 6)) {
 | 
			
		||||
							levelCurrent++;
 | 
			
		||||
						}
 | 
			
		||||
						else if (wordInArray(word, endTags, 6)) {
 | 
			
		||||
							levelCurrent--;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// Fold inner level of if/select/case statements
 | 
			
		||||
		if (options.baanFoldInnerLevel && atEOL) {
 | 
			
		||||
			bool currLineInnerLevel = IsInnerLevelFold(lineCurrent, styler);
 | 
			
		||||
			bool nextLineInnerLevel = IsInnerLevelFold(lineCurrent + 1, styler);
 | 
			
		||||
			if (currLineInnerLevel && currLineInnerLevel != nextLineInnerLevel) {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			}
 | 
			
		||||
			else if (nextLineInnerLevel && nextLineInnerLevel != currLineInnerLevel) {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// Section Foldings.
 | 
			
		||||
		// One way of implementing Section Foldings, as there is no END markings of sections.
 | 
			
		||||
		// first section ends on the previous line of next section.
 | 
			
		||||
		// Re-written whole folding to accomodate this.
 | 
			
		||||
		if (options.baanFoldSections && atEOL) {
 | 
			
		||||
			currLineStyle = mainOrSubSectionLine(lineCurrent, styler);
 | 
			
		||||
			nextLineStyle = mainOrSubSectionLine(lineCurrent + 1, styler);
 | 
			
		||||
			if (currLineStyle != 0 && currLineStyle != nextLineStyle) {
 | 
			
		||||
				if (levelCurrent < levelPrev)
 | 
			
		||||
					--levelPrev;
 | 
			
		||||
				for (Sci_Position j = styler.LineStart(lineCurrent); j < styler.LineStart(lineCurrent + 1) - 1; j++) {
 | 
			
		||||
					if (IsASpaceOrTab(styler[j]))
 | 
			
		||||
						continue;
 | 
			
		||||
					else if (styler.StyleAt(j) == SCE_BAAN_WORD5) {
 | 
			
		||||
						if (styler.Match(j, "functions:")) {
 | 
			
		||||
							// Means functions: is the end of MainSections.
 | 
			
		||||
							// Nothing to fold after this.
 | 
			
		||||
							afterFunctionSection = true;
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
							afterFunctionSection = false;
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						afterFunctionSection = false;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (!afterFunctionSection)
 | 
			
		||||
					levelCurrent++;
 | 
			
		||||
			}
 | 
			
		||||
			else if (nextLineStyle != 0 && currLineStyle != nextLineStyle
 | 
			
		||||
				&& (priorSectionIsSubSection(lineCurrent -1 ,styler)
 | 
			
		||||
					|| !nextSectionIsSubSection(lineCurrent + 1, styler))) {
 | 
			
		||||
				for (Sci_Position j = styler.LineStart(lineCurrent + 1); j < styler.LineStart(lineCurrent + 1 + 1) - 1; j++) {
 | 
			
		||||
					if (IsASpaceOrTab(styler[j]))
 | 
			
		||||
						continue;
 | 
			
		||||
					else if (styler.StyleAt(j) == SCE_BAAN_WORD5) {
 | 
			
		||||
						if (styler.Match(j, "declaration:")) {
 | 
			
		||||
							// Means declaration: is the start of MainSections.
 | 
			
		||||
							// Nothing to fold before this.
 | 
			
		||||
							beforeDeclarationSection = true;
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
							beforeDeclarationSection = false;
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						beforeDeclarationSection = false;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (!beforeDeclarationSection) {
 | 
			
		||||
					levelCurrent--;
 | 
			
		||||
					if (nextLineStyle == SCE_BAAN_WORD5 && priorSectionIsSubSection(lineCurrent-1, styler))
 | 
			
		||||
						// next levelCurrent--; is to unfold previous subsection fold.
 | 
			
		||||
						// On reaching the next main section, the previous main as well sub section ends.
 | 
			
		||||
						levelCurrent--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			lev |= levelCurrent << 16;
 | 
			
		||||
			if (visibleChars == 0 && options.foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmBaan(SCLEX_BAAN, LexerBaan::LexerFactoryBaan, "baan", baanWordLists);
 | 
			
		||||
							
								
								
									
										1291
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBash.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1291
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBash.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										573
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBasic.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										573
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBasic.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,573 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexBasic.cxx
 | 
			
		||||
 ** Lexer for BlitzBasic and PureBasic.
 | 
			
		||||
 ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
// This tries to be a unified Lexer/Folder for all the BlitzBasic/BlitzMax/PurBasic basics
 | 
			
		||||
// and derivatives. Once they diverge enough, might want to split it into multiple
 | 
			
		||||
// lexers for more code clearity.
 | 
			
		||||
//
 | 
			
		||||
// Mail me (elias <at> users <dot> sf <dot> net) for any bugs.
 | 
			
		||||
 | 
			
		||||
// Folding only works for simple things like functions or types.
 | 
			
		||||
 | 
			
		||||
// You may want to have a look at my ctags lexer as well, if you additionally to coloring
 | 
			
		||||
// and folding need to extract things like label tags in your editor.
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "OptionSet.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
/* Bits:
 | 
			
		||||
 * 1  - whitespace
 | 
			
		||||
 * 2  - operator
 | 
			
		||||
 * 4  - identifier
 | 
			
		||||
 * 8  - decimal digit
 | 
			
		||||
 * 16 - hex digit
 | 
			
		||||
 * 32 - bin digit
 | 
			
		||||
 * 64 - letter
 | 
			
		||||
 */
 | 
			
		||||
static int character_classification[128] =
 | 
			
		||||
{
 | 
			
		||||
		0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  1,  0,  0,
 | 
			
		||||
		0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
		1,  2,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  10, 2,
 | 
			
		||||
	 60, 60, 28, 28, 28, 28, 28, 28, 28, 28,  2,  2,  2,  2,  2,  2,
 | 
			
		||||
		2, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68,
 | 
			
		||||
	 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,  2,  2,  2,  2, 68,
 | 
			
		||||
		2, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68,
 | 
			
		||||
	 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,  2,  2,  2,  2,  0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool IsSpace(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsOperator(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsIdentifier(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsDigit(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsHexDigit(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 16);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsBinDigit(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 32);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsLetter(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 64);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int LowerCase(int c)
 | 
			
		||||
{
 | 
			
		||||
	if (c >= 'A' && c <= 'Z')
 | 
			
		||||
		return 'a' + c - 'A';
 | 
			
		||||
	return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CheckBlitzFoldPoint(char const *token, int &level) {
 | 
			
		||||
	if (!strcmp(token, "function") ||
 | 
			
		||||
		!strcmp(token, "type")) {
 | 
			
		||||
		level |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	if (!strcmp(token, "end function") ||
 | 
			
		||||
		!strcmp(token, "end type")) {
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CheckPureFoldPoint(char const *token, int &level) {
 | 
			
		||||
	if (!strcmp(token, "procedure") ||
 | 
			
		||||
		!strcmp(token, "enumeration") ||
 | 
			
		||||
		!strcmp(token, "interface") ||
 | 
			
		||||
		!strcmp(token, "structure")) {
 | 
			
		||||
		level |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	if (!strcmp(token, "endprocedure") ||
 | 
			
		||||
		!strcmp(token, "endenumeration") ||
 | 
			
		||||
		!strcmp(token, "endinterface") ||
 | 
			
		||||
		!strcmp(token, "endstructure")) {
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CheckFreeFoldPoint(char const *token, int &level) {
 | 
			
		||||
	if (!strcmp(token, "function") ||
 | 
			
		||||
		!strcmp(token, "sub") ||
 | 
			
		||||
		!strcmp(token, "enum") ||
 | 
			
		||||
		!strcmp(token, "type") ||
 | 
			
		||||
		!strcmp(token, "union") ||
 | 
			
		||||
		!strcmp(token, "property") ||
 | 
			
		||||
		!strcmp(token, "destructor") ||
 | 
			
		||||
		!strcmp(token, "constructor")) {
 | 
			
		||||
		level |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	if (!strcmp(token, "end function") ||
 | 
			
		||||
		!strcmp(token, "end sub") ||
 | 
			
		||||
		!strcmp(token, "end enum") ||
 | 
			
		||||
		!strcmp(token, "end type") ||
 | 
			
		||||
		!strcmp(token, "end union") ||
 | 
			
		||||
		!strcmp(token, "end property") ||
 | 
			
		||||
		!strcmp(token, "end destructor") ||
 | 
			
		||||
		!strcmp(token, "end constructor")) {
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// An individual named option for use in an OptionSet
 | 
			
		||||
 | 
			
		||||
// Options used for LexerBasic
 | 
			
		||||
struct OptionsBasic {
 | 
			
		||||
	bool fold;
 | 
			
		||||
	bool foldSyntaxBased;
 | 
			
		||||
	bool foldCommentExplicit;
 | 
			
		||||
	std::string foldExplicitStart;
 | 
			
		||||
	std::string foldExplicitEnd;
 | 
			
		||||
	bool foldExplicitAnywhere;
 | 
			
		||||
	bool foldCompact;
 | 
			
		||||
	OptionsBasic() {
 | 
			
		||||
		fold = false;
 | 
			
		||||
		foldSyntaxBased = true;
 | 
			
		||||
		foldCommentExplicit = false;
 | 
			
		||||
		foldExplicitStart = "";
 | 
			
		||||
		foldExplicitEnd   = "";
 | 
			
		||||
		foldExplicitAnywhere = false;
 | 
			
		||||
		foldCompact = true;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char * const blitzbasicWordListDesc[] = {
 | 
			
		||||
	"BlitzBasic Keywords",
 | 
			
		||||
	"user1",
 | 
			
		||||
	"user2",
 | 
			
		||||
	"user3",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char * const purebasicWordListDesc[] = {
 | 
			
		||||
	"PureBasic Keywords",
 | 
			
		||||
	"PureBasic PreProcessor Keywords",
 | 
			
		||||
	"user defined 1",
 | 
			
		||||
	"user defined 2",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char * const freebasicWordListDesc[] = {
 | 
			
		||||
	"FreeBasic Keywords",
 | 
			
		||||
	"FreeBasic PreProcessor Keywords",
 | 
			
		||||
	"user defined 1",
 | 
			
		||||
	"user defined 2",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct OptionSetBasic : public OptionSet<OptionsBasic> {
 | 
			
		||||
	OptionSetBasic(const char * const wordListDescriptions[]) {
 | 
			
		||||
		DefineProperty("fold", &OptionsBasic::fold);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.basic.syntax.based", &OptionsBasic::foldSyntaxBased,
 | 
			
		||||
			"Set this property to 0 to disable syntax based folding.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.basic.comment.explicit", &OptionsBasic::foldCommentExplicit,
 | 
			
		||||
			"This option enables folding explicit fold points when using the Basic lexer. "
 | 
			
		||||
			"Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start "
 | 
			
		||||
			"and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.basic.explicit.start", &OptionsBasic::foldExplicitStart,
 | 
			
		||||
			"The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.basic.explicit.end", &OptionsBasic::foldExplicitEnd,
 | 
			
		||||
			"The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.basic.explicit.anywhere", &OptionsBasic::foldExplicitAnywhere,
 | 
			
		||||
			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.compact", &OptionsBasic::foldCompact);
 | 
			
		||||
 | 
			
		||||
		DefineWordListSets(wordListDescriptions);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LexerBasic : public DefaultLexer {
 | 
			
		||||
	char comment_char;
 | 
			
		||||
	int (*CheckFoldPoint)(char const *, int &);
 | 
			
		||||
	WordList keywordlists[4];
 | 
			
		||||
	OptionsBasic options;
 | 
			
		||||
	OptionSetBasic osBasic;
 | 
			
		||||
public:
 | 
			
		||||
	LexerBasic(const char *languageName_, int language_, char comment_char_,
 | 
			
		||||
		int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) :
 | 
			
		||||
						 DefaultLexer(languageName_, language_),
 | 
			
		||||
						 comment_char(comment_char_),
 | 
			
		||||
						 CheckFoldPoint(CheckFoldPoint_),
 | 
			
		||||
						 osBasic(wordListDescriptions) {
 | 
			
		||||
	}
 | 
			
		||||
	virtual ~LexerBasic() {
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD Release() override {
 | 
			
		||||
		delete this;
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD Version() const override {
 | 
			
		||||
		return lvRelease5;
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD PropertyNames() override {
 | 
			
		||||
		return osBasic.PropertyNames();
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD PropertyType(const char *name) override {
 | 
			
		||||
		return osBasic.PropertyType(name);
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD DescribeProperty(const char *name) override {
 | 
			
		||||
		return osBasic.DescribeProperty(name);
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
 | 
			
		||||
	const char * SCI_METHOD PropertyGet(const char *key) override {
 | 
			
		||||
		return osBasic.PropertyGet(key);
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD DescribeWordListSets() override {
 | 
			
		||||
		return osBasic.DescribeWordListSets();
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
 | 
			
		||||
	void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
	void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
 | 
			
		||||
	void * SCI_METHOD PrivateCall(int, void *) override {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	static ILexer5 *LexerFactoryBlitzBasic() {
 | 
			
		||||
		return new LexerBasic("blitzbasic", SCLEX_BLITZBASIC, ';', CheckBlitzFoldPoint, blitzbasicWordListDesc);
 | 
			
		||||
	}
 | 
			
		||||
	static ILexer5 *LexerFactoryPureBasic() {
 | 
			
		||||
		return new LexerBasic("purebasic", SCLEX_PUREBASIC, ';', CheckPureFoldPoint, purebasicWordListDesc);
 | 
			
		||||
	}
 | 
			
		||||
	static ILexer5 *LexerFactoryFreeBasic() {
 | 
			
		||||
		return new LexerBasic("freebasic", SCLEX_FREEBASIC, '\'', CheckFreeFoldPoint, freebasicWordListDesc );
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerBasic::PropertySet(const char *key, const char *val) {
 | 
			
		||||
	if (osBasic.PropertySet(&options, key, val)) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerBasic::WordListSet(int n, const char *wl) {
 | 
			
		||||
	WordList *wordListN = 0;
 | 
			
		||||
	switch (n) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		wordListN = &keywordlists[0];
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		wordListN = &keywordlists[1];
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		wordListN = &keywordlists[2];
 | 
			
		||||
		break;
 | 
			
		||||
	case 3:
 | 
			
		||||
		wordListN = &keywordlists[3];
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position firstModification = -1;
 | 
			
		||||
	if (wordListN) {
 | 
			
		||||
		WordList wlNew;
 | 
			
		||||
		wlNew.Set(wl);
 | 
			
		||||
		if (*wordListN != wlNew) {
 | 
			
		||||
			wordListN->Set(wl);
 | 
			
		||||
			firstModification = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return firstModification;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerBasic::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
 | 
			
		||||
	bool wasfirst = true, isfirst = true; // true if first token in a line
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
	int styleBeforeKeyword = SCE_B_DEFAULT;
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	// Can't use sc.More() here else we miss the last character
 | 
			
		||||
	for (; ; sc.Forward()) {
 | 
			
		||||
		if (sc.state == SCE_B_IDENTIFIER) {
 | 
			
		||||
			if (!IsIdentifier(sc.ch)) {
 | 
			
		||||
				// Labels
 | 
			
		||||
				if (wasfirst && sc.Match(':')) {
 | 
			
		||||
					sc.ChangeState(SCE_B_LABEL);
 | 
			
		||||
					sc.ForwardSetState(SCE_B_DEFAULT);
 | 
			
		||||
				} else {
 | 
			
		||||
					char s[100];
 | 
			
		||||
					int kstates[4] = {
 | 
			
		||||
						SCE_B_KEYWORD,
 | 
			
		||||
						SCE_B_KEYWORD2,
 | 
			
		||||
						SCE_B_KEYWORD3,
 | 
			
		||||
						SCE_B_KEYWORD4,
 | 
			
		||||
					};
 | 
			
		||||
					sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
					for (int i = 0; i < 4; i++) {
 | 
			
		||||
						if (keywordlists[i].InList(s)) {
 | 
			
		||||
							sc.ChangeState(kstates[i]);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					// Types, must set them as operator else they will be
 | 
			
		||||
					// matched as number/constant
 | 
			
		||||
					if (sc.Match('.') || sc.Match('$') || sc.Match('%') ||
 | 
			
		||||
						sc.Match('#')) {
 | 
			
		||||
						sc.SetState(SCE_B_OPERATOR);
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.SetState(SCE_B_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_B_OPERATOR) {
 | 
			
		||||
			if (!IsOperator(sc.ch) || sc.Match('#'))
 | 
			
		||||
				sc.SetState(SCE_B_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_B_LABEL) {
 | 
			
		||||
			if (!IsIdentifier(sc.ch))
 | 
			
		||||
				sc.SetState(SCE_B_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_B_CONSTANT) {
 | 
			
		||||
			if (!IsIdentifier(sc.ch))
 | 
			
		||||
				sc.SetState(SCE_B_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_B_NUMBER) {
 | 
			
		||||
			if (!IsDigit(sc.ch))
 | 
			
		||||
				sc.SetState(SCE_B_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_B_HEXNUMBER) {
 | 
			
		||||
			if (!IsHexDigit(sc.ch))
 | 
			
		||||
				sc.SetState(SCE_B_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_B_BINNUMBER) {
 | 
			
		||||
			if (!IsBinDigit(sc.ch))
 | 
			
		||||
				sc.SetState(SCE_B_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_B_STRING) {
 | 
			
		||||
			if (sc.ch == '"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_B_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.ChangeState(SCE_B_ERROR);
 | 
			
		||||
				sc.SetState(SCE_B_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_B_COMMENT || sc.state == SCE_B_PREPROCESSOR) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_B_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_B_DOCLINE) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_B_DEFAULT);
 | 
			
		||||
			} else if (sc.ch == '\\' || sc.ch == '@') {
 | 
			
		||||
				if (IsLetter(sc.chNext) && sc.chPrev != '\\') {
 | 
			
		||||
					styleBeforeKeyword = sc.state;
 | 
			
		||||
					sc.SetState(SCE_B_DOCKEYWORD);
 | 
			
		||||
				};
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_B_DOCKEYWORD) {
 | 
			
		||||
			if (IsSpace(sc.ch)) {
 | 
			
		||||
				sc.SetState(styleBeforeKeyword);
 | 
			
		||||
			}	else if (sc.atLineEnd && styleBeforeKeyword == SCE_B_DOCLINE) {
 | 
			
		||||
				sc.SetState(SCE_B_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_B_COMMENTBLOCK) {
 | 
			
		||||
			if (sc.Match("\'/")) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.ForwardSetState(SCE_B_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_B_DOCBLOCK) {
 | 
			
		||||
			if (sc.Match("\'/")) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.ForwardSetState(SCE_B_DEFAULT);
 | 
			
		||||
			} else if (sc.ch == '\\' || sc.ch == '@') {
 | 
			
		||||
				if (IsLetter(sc.chNext) && sc.chPrev != '\\') {
 | 
			
		||||
					styleBeforeKeyword = sc.state;
 | 
			
		||||
					sc.SetState(SCE_B_DOCKEYWORD);
 | 
			
		||||
				};
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.atLineStart)
 | 
			
		||||
			isfirst = true;
 | 
			
		||||
 | 
			
		||||
		if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) {
 | 
			
		||||
			if (isfirst && sc.Match('.') && comment_char != '\'') {
 | 
			
		||||
					sc.SetState(SCE_B_LABEL);
 | 
			
		||||
			} else if (isfirst && sc.Match('#')) {
 | 
			
		||||
				wasfirst = isfirst;
 | 
			
		||||
				sc.SetState(SCE_B_IDENTIFIER);
 | 
			
		||||
			} else if (sc.Match(comment_char)) {
 | 
			
		||||
				// Hack to make deprecated QBASIC '$Include show
 | 
			
		||||
				// up in freebasic with SCE_B_PREPROCESSOR.
 | 
			
		||||
				if (comment_char == '\'' && sc.Match(comment_char, '$'))
 | 
			
		||||
					sc.SetState(SCE_B_PREPROCESSOR);
 | 
			
		||||
				else if (sc.Match("\'*") || sc.Match("\'!")) {
 | 
			
		||||
					sc.SetState(SCE_B_DOCLINE);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_B_COMMENT);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.Match("/\'")) {
 | 
			
		||||
				if (sc.Match("/\'*") || sc.Match("/\'!")) {	// Support of gtk-doc/Doxygen doc. style
 | 
			
		||||
					sc.SetState(SCE_B_DOCBLOCK);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_B_COMMENTBLOCK);
 | 
			
		||||
				}
 | 
			
		||||
				sc.Forward();	// Eat the ' so it isn't used for the end of the comment
 | 
			
		||||
			} else if (sc.Match('"')) {
 | 
			
		||||
				sc.SetState(SCE_B_STRING);
 | 
			
		||||
			} else if (IsDigit(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_B_NUMBER);
 | 
			
		||||
			} else if (sc.Match('$') || sc.Match("&h") || sc.Match("&H") || sc.Match("&o") || sc.Match("&O")) {
 | 
			
		||||
				sc.SetState(SCE_B_HEXNUMBER);
 | 
			
		||||
			} else if (sc.Match('%') || sc.Match("&b") || sc.Match("&B")) {
 | 
			
		||||
				sc.SetState(SCE_B_BINNUMBER);
 | 
			
		||||
			} else if (sc.Match('#')) {
 | 
			
		||||
				sc.SetState(SCE_B_CONSTANT);
 | 
			
		||||
			} else if (IsOperator(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_B_OPERATOR);
 | 
			
		||||
			} else if (IsIdentifier(sc.ch)) {
 | 
			
		||||
				wasfirst = isfirst;
 | 
			
		||||
				sc.SetState(SCE_B_IDENTIFIER);
 | 
			
		||||
			} else if (!IsSpace(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_B_ERROR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!IsSpace(sc.ch))
 | 
			
		||||
			isfirst = false;
 | 
			
		||||
 | 
			
		||||
		if (!sc.More())
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerBasic::Fold(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, IDocument *pAccess) {
 | 
			
		||||
 | 
			
		||||
	if (!options.fold)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
 | 
			
		||||
	Sci_Position line = styler.GetLine(startPos);
 | 
			
		||||
	int level = styler.LevelAt(line);
 | 
			
		||||
	int go = 0, done = 0;
 | 
			
		||||
	Sci_Position endPos = startPos + length;
 | 
			
		||||
	char word[256];
 | 
			
		||||
	int wordlen = 0;
 | 
			
		||||
	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
 | 
			
		||||
	int cNext = styler[startPos];
 | 
			
		||||
 | 
			
		||||
	// Scan for tokens at the start of the line (they may include
 | 
			
		||||
	// whitespace, for tokens like "End Function"
 | 
			
		||||
	for (Sci_Position i = startPos; i < endPos; i++) {
 | 
			
		||||
		int c = cNext;
 | 
			
		||||
		cNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		bool atEOL = (c == '\r' && cNext != '\n') || (c == '\n');
 | 
			
		||||
		if (options.foldSyntaxBased && !done && !go) {
 | 
			
		||||
			if (wordlen) { // are we scanning a token already?
 | 
			
		||||
				word[wordlen] = static_cast<char>(LowerCase(c));
 | 
			
		||||
				if (!IsIdentifier(c)) { // done with token
 | 
			
		||||
					word[wordlen] = '\0';
 | 
			
		||||
					go = CheckFoldPoint(word, level);
 | 
			
		||||
					if (!go) {
 | 
			
		||||
						// Treat any whitespace as single blank, for
 | 
			
		||||
						// things like "End   Function".
 | 
			
		||||
						if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
 | 
			
		||||
							word[wordlen] = ' ';
 | 
			
		||||
							if (wordlen < 255)
 | 
			
		||||
								wordlen++;
 | 
			
		||||
						}
 | 
			
		||||
						else // done with this line
 | 
			
		||||
							done = 1;
 | 
			
		||||
					}
 | 
			
		||||
				} else if (wordlen < 255) {
 | 
			
		||||
					wordlen++;
 | 
			
		||||
				}
 | 
			
		||||
			} else { // start scanning at first non-whitespace character
 | 
			
		||||
				if (!IsSpace(c)) {
 | 
			
		||||
					if (IsIdentifier(c)) {
 | 
			
		||||
						word[0] = static_cast<char>(LowerCase(c));
 | 
			
		||||
						wordlen = 1;
 | 
			
		||||
					} else // done with this line
 | 
			
		||||
						done = 1;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (options.foldCommentExplicit && ((styler.StyleAt(i) == SCE_B_COMMENT) || options.foldExplicitAnywhere)) {
 | 
			
		||||
			if (userDefinedFoldMarkers) {
 | 
			
		||||
				if (styler.Match(i, options.foldExplicitStart.c_str())) {
 | 
			
		||||
 					level |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
					go = 1;
 | 
			
		||||
				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
 | 
			
		||||
 					go = -1;
 | 
			
		||||
 				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if (c == comment_char) {
 | 
			
		||||
					if (cNext == '{') {
 | 
			
		||||
						level |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
						go = 1;
 | 
			
		||||
					} else if (cNext == '}') {
 | 
			
		||||
						go = -1;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 			}
 | 
			
		||||
 		}
 | 
			
		||||
		if (atEOL) { // line end
 | 
			
		||||
			if (!done && wordlen == 0 && options.foldCompact) // line was only space
 | 
			
		||||
				level |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if (level != styler.LevelAt(line))
 | 
			
		||||
				styler.SetLevel(line, level);
 | 
			
		||||
			level += go;
 | 
			
		||||
			line++;
 | 
			
		||||
			// reset state
 | 
			
		||||
			wordlen = 0;
 | 
			
		||||
			level &= ~SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			level &= ~SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			go = 0;
 | 
			
		||||
			done = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, "blitzbasic", blitzbasicWordListDesc);
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, "purebasic", purebasicWordListDesc);
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, "freebasic", freebasicWordListDesc);
 | 
			
		||||
							
								
								
									
										646
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBatch.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										646
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBatch.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,646 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexBatch.cxx
 | 
			
		||||
 ** Lexer for batch files.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cctype>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cstdarg>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <initializer_list>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "InList.h"
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "Accessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
constexpr bool Is0To9(char ch) noexcept {
 | 
			
		||||
	return (ch >= '0') && (ch <= '9');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool IsAlphabetic(int ch) noexcept {
 | 
			
		||||
	return IsASCII(ch) && isalpha(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
 | 
			
		||||
	return (styler[i] == '\n') ||
 | 
			
		||||
	       ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests for BATCH Operators
 | 
			
		||||
constexpr bool IsBOperator(char ch) noexcept {
 | 
			
		||||
	return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') ||
 | 
			
		||||
		(ch == '|') || (ch == '?') || (ch == '*')||
 | 
			
		||||
		(ch == '&') || (ch == '(') || (ch == ')');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests for BATCH Separators
 | 
			
		||||
constexpr bool IsBSeparator(char ch) noexcept {
 | 
			
		||||
	return (ch == '\\') || (ch == '.') || (ch == ';') ||
 | 
			
		||||
		(ch == '\"') || (ch == '\'') || (ch == '/');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests for escape character
 | 
			
		||||
constexpr bool IsEscaped(const char* wordStr, Sci_PositionU pos) noexcept {
 | 
			
		||||
	bool isQoted=false;
 | 
			
		||||
	while (pos>0){
 | 
			
		||||
		pos--;
 | 
			
		||||
		if (wordStr[pos]=='^')
 | 
			
		||||
			isQoted=!isQoted;
 | 
			
		||||
		else
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	return isQoted;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr bool IsQuotedBy(std::string_view svBuffer, char quote) noexcept {
 | 
			
		||||
	bool CurrentStatus = false;
 | 
			
		||||
	size_t pQuote = svBuffer.find(quote);
 | 
			
		||||
	while (pQuote != std::string_view::npos) {
 | 
			
		||||
		if (!IsEscaped(svBuffer.data(), pQuote)) {
 | 
			
		||||
			CurrentStatus = !CurrentStatus;
 | 
			
		||||
		}
 | 
			
		||||
		pQuote = svBuffer.find(quote, pQuote + 1);
 | 
			
		||||
	}
 | 
			
		||||
	return CurrentStatus;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests for quote character
 | 
			
		||||
constexpr bool textQuoted(const char *lineBuffer, Sci_PositionU endPos) noexcept {
 | 
			
		||||
	const std::string_view svBuffer(lineBuffer, endPos);
 | 
			
		||||
	return IsQuotedBy(svBuffer, '\"') || IsQuotedBy(svBuffer, '\'');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ColouriseBatchDoc(
 | 
			
		||||
    Sci_PositionU startPos,
 | 
			
		||||
    Sci_Position length,
 | 
			
		||||
    int /*initStyle*/,
 | 
			
		||||
    WordList *keywordlists[],
 | 
			
		||||
    Accessor &styler) {
 | 
			
		||||
	// Always backtracks to the start of a line that is not a continuation
 | 
			
		||||
	// of the previous line
 | 
			
		||||
	if (startPos > 0) {
 | 
			
		||||
		Sci_Position ln = styler.GetLine(startPos); // Current line number
 | 
			
		||||
		while (startPos > 0) {
 | 
			
		||||
			ln--;
 | 
			
		||||
			if ((styler.SafeGetCharAt(startPos-3) == '^' && styler.SafeGetCharAt(startPos-2) == '\r' && styler.SafeGetCharAt(startPos-1) == '\n')
 | 
			
		||||
			|| styler.SafeGetCharAt(startPos-2) == '^') {	// handle '^' line continuation
 | 
			
		||||
				// When the line continuation is found,
 | 
			
		||||
				// set the Start Position to the Start of the previous line
 | 
			
		||||
				length+=startPos-styler.LineStart(ln);
 | 
			
		||||
				startPos=styler.LineStart(ln);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char lineBuffer[1024] {};
 | 
			
		||||
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
	Sci_PositionU linePos = 0;
 | 
			
		||||
	Sci_PositionU startLine = startPos;
 | 
			
		||||
	bool continueProcessing = true;	// Used to toggle Regular Keyword Checking
 | 
			
		||||
	bool isNotAssigned=false; // Used to flag Assignment in Set operation
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < startPos + length; i++) {
 | 
			
		||||
		lineBuffer[linePos++] = styler[i];
 | 
			
		||||
		if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1) || (i==startPos + length-1)) {
 | 
			
		||||
			// End of line (or of line buffer) (or End of Last Line) met, colourise it
 | 
			
		||||
			lineBuffer[linePos] = '\0';
 | 
			
		||||
			const Sci_PositionU lengthLine=linePos;
 | 
			
		||||
			const Sci_PositionU endPos=i;
 | 
			
		||||
			const WordList &keywords = *keywordlists[0];      // Internal Commands
 | 
			
		||||
			const WordList &keywords2 = *keywordlists[1];     // External Commands (optional)
 | 
			
		||||
 | 
			
		||||
			// CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords
 | 
			
		||||
			//   Toggling Regular Keyword Checking off improves readability
 | 
			
		||||
			// Other Regular Keywords and External Commands / Programs might also benefit from toggling
 | 
			
		||||
			//   Need a more robust algorithm to properly toggle Regular Keyword Checking
 | 
			
		||||
			bool stopLineProcessing=false;  // Used to stop line processing if Comment or Drive Change found
 | 
			
		||||
 | 
			
		||||
			Sci_PositionU offset = 0;	// Line Buffer Offset
 | 
			
		||||
			// Skip initial spaces
 | 
			
		||||
			while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
 | 
			
		||||
				offset++;
 | 
			
		||||
			}
 | 
			
		||||
			// Colorize Default Text
 | 
			
		||||
			styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
 | 
			
		||||
			// Set External Command / Program Location
 | 
			
		||||
			Sci_PositionU cmdLoc = offset;
 | 
			
		||||
 | 
			
		||||
			// Check for Fake Label (Comment) or Real Label - return if found
 | 
			
		||||
			if (lineBuffer[offset] == ':') {
 | 
			
		||||
				if (lineBuffer[offset + 1] == ':') {
 | 
			
		||||
					// Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
 | 
			
		||||
					styler.ColourTo(endPos, SCE_BAT_COMMENT);
 | 
			
		||||
				} else {
 | 
			
		||||
					// Colorize Real Label
 | 
			
		||||
					// :[\t ]*[^\t &+:<>|]+
 | 
			
		||||
					const char *startLabelName = lineBuffer + offset + 1;
 | 
			
		||||
					const size_t whitespaceLength = strspn(startLabelName, "\t ");
 | 
			
		||||
					// Set of label-terminating characters determined experimentally
 | 
			
		||||
					const char *endLabel = strpbrk(startLabelName + whitespaceLength, "\t &+:<>|");
 | 
			
		||||
					if (endLabel) {
 | 
			
		||||
						styler.ColourTo(startLine + offset + endLabel - startLabelName, SCE_BAT_LABEL);
 | 
			
		||||
						styler.ColourTo(endPos, SCE_BAT_AFTER_LABEL);	// New style
 | 
			
		||||
					} else {
 | 
			
		||||
						styler.ColourTo(endPos, SCE_BAT_LABEL);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				stopLineProcessing=true;
 | 
			
		||||
			// Check for Drive Change (Drive Change is internal command) - return if found
 | 
			
		||||
			} else if ((IsAlphabetic(lineBuffer[offset])) &&
 | 
			
		||||
				(lineBuffer[offset + 1] == ':') &&
 | 
			
		||||
				((isspacechar(lineBuffer[offset + 2])) ||
 | 
			
		||||
				(((lineBuffer[offset + 2] == '\\')) &&
 | 
			
		||||
				(isspacechar(lineBuffer[offset + 3]))))) {
 | 
			
		||||
				// Colorize Regular Keyword
 | 
			
		||||
				styler.ColourTo(endPos, SCE_BAT_WORD);
 | 
			
		||||
				stopLineProcessing=true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Check for Hide Command (@ECHO OFF/ON)
 | 
			
		||||
			if (lineBuffer[offset] == '@') {
 | 
			
		||||
				styler.ColourTo(startLine + offset, SCE_BAT_HIDE);
 | 
			
		||||
				offset++;
 | 
			
		||||
			}
 | 
			
		||||
			// Skip next spaces
 | 
			
		||||
			while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
 | 
			
		||||
				offset++;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Read remainder of line word-at-a-time or remainder-of-word-at-a-time
 | 
			
		||||
			while (offset < lengthLine  && !stopLineProcessing) {
 | 
			
		||||
				if (offset > startLine) {
 | 
			
		||||
					// Colorize Default Text
 | 
			
		||||
					styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				char wordBuffer[81]{};		// Word Buffer - large to catch long paths
 | 
			
		||||
				// Copy word from Line Buffer into Word Buffer and convert to lower case
 | 
			
		||||
				Sci_PositionU wbl = 0;		// Word Buffer Length
 | 
			
		||||
				for (; offset < lengthLine && wbl < 80 &&
 | 
			
		||||
						!isspacechar(lineBuffer[offset]); wbl++, offset++) {
 | 
			
		||||
					wordBuffer[wbl] = MakeLowerCase(lineBuffer[offset]);
 | 
			
		||||
				}
 | 
			
		||||
				wordBuffer[wbl] = '\0';
 | 
			
		||||
				const std::string_view wordView(wordBuffer);
 | 
			
		||||
				Sci_PositionU wbo = 0;		// Word Buffer Offset - also Special Keyword Buffer Length
 | 
			
		||||
 | 
			
		||||
				// Check for Comment - return if found
 | 
			
		||||
				if (continueProcessing) {
 | 
			
		||||
					if ((wordView == "rem") || (wordBuffer[0] == ':' && wordBuffer[1] == ':')) {
 | 
			
		||||
						if ((offset == wbl) || !textQuoted(lineBuffer, offset - wbl)) {
 | 
			
		||||
							styler.ColourTo(startLine + offset - wbl - 1, SCE_BAT_DEFAULT);
 | 
			
		||||
							styler.ColourTo(endPos, SCE_BAT_COMMENT);
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				// Check for Separator
 | 
			
		||||
				if (IsBSeparator(wordBuffer[0])) {
 | 
			
		||||
					// Check for External Command / Program
 | 
			
		||||
					if ((cmdLoc == offset - wbl) &&
 | 
			
		||||
						((wordBuffer[0] == ':') ||
 | 
			
		||||
						(wordBuffer[0] == '\\') ||
 | 
			
		||||
						(wordBuffer[0] == '.'))) {
 | 
			
		||||
						// Reset Offset to re-process remainder of word
 | 
			
		||||
						offset -= (wbl - 1);
 | 
			
		||||
						// Colorize External Command / Program
 | 
			
		||||
						if (!keywords2) {
 | 
			
		||||
							styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
 | 
			
		||||
						} else if (keywords2.InList(wordBuffer)) {
 | 
			
		||||
							styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
 | 
			
		||||
						} else {
 | 
			
		||||
							styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
 | 
			
		||||
						}
 | 
			
		||||
						// Reset External Command / Program Location
 | 
			
		||||
						cmdLoc = offset;
 | 
			
		||||
					} else {
 | 
			
		||||
						// Reset Offset to re-process remainder of word
 | 
			
		||||
						offset -= (wbl - 1);
 | 
			
		||||
						// Colorize Default Text
 | 
			
		||||
						styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				// Check for Regular Keyword in list
 | 
			
		||||
				} else if ((keywords.InList(wordBuffer)) &&
 | 
			
		||||
					(continueProcessing)) {
 | 
			
		||||
					// ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking
 | 
			
		||||
					if (InList(wordView, {"echo", "goto", "prompt"})) {
 | 
			
		||||
						continueProcessing = false;
 | 
			
		||||
					}
 | 
			
		||||
					// SET requires additional processing for the assignment operator
 | 
			
		||||
					if (wordView == "set") {
 | 
			
		||||
						continueProcessing = false;
 | 
			
		||||
						isNotAssigned=true;
 | 
			
		||||
					}
 | 
			
		||||
					// Identify External Command / Program Location for ERRORLEVEL, and EXIST
 | 
			
		||||
					if (InList(wordView, {"errorlevel", "exist"})) {
 | 
			
		||||
						// Reset External Command / Program Location
 | 
			
		||||
						cmdLoc = offset;
 | 
			
		||||
						// Skip next spaces
 | 
			
		||||
						while ((cmdLoc < lengthLine) &&
 | 
			
		||||
							(isspacechar(lineBuffer[cmdLoc]))) {
 | 
			
		||||
							cmdLoc++;
 | 
			
		||||
						}
 | 
			
		||||
						// Skip comparison
 | 
			
		||||
						while ((cmdLoc < lengthLine) &&
 | 
			
		||||
							(!isspacechar(lineBuffer[cmdLoc]))) {
 | 
			
		||||
							cmdLoc++;
 | 
			
		||||
						}
 | 
			
		||||
						// Skip next spaces
 | 
			
		||||
						while ((cmdLoc < lengthLine) &&
 | 
			
		||||
							(isspacechar(lineBuffer[cmdLoc]))) {
 | 
			
		||||
							cmdLoc++;
 | 
			
		||||
						}
 | 
			
		||||
					// Identify External Command / Program Location for CALL, DO, LOADHIGH and LH
 | 
			
		||||
					} else if (InList(wordView, {"call", "do", "loadhigh", "lh"})) {
 | 
			
		||||
						// Reset External Command / Program Location
 | 
			
		||||
						cmdLoc = offset;
 | 
			
		||||
						// Skip next spaces
 | 
			
		||||
						while ((cmdLoc < lengthLine) &&
 | 
			
		||||
							(isspacechar(lineBuffer[cmdLoc]))) {
 | 
			
		||||
							cmdLoc++;
 | 
			
		||||
						}
 | 
			
		||||
						// Check if call is followed by a label
 | 
			
		||||
						if ((lineBuffer[cmdLoc] == ':') &&
 | 
			
		||||
							(wordView == "call")) {
 | 
			
		||||
							continueProcessing = false;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					// Colorize Regular keyword
 | 
			
		||||
					styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD);
 | 
			
		||||
					// No need to Reset Offset
 | 
			
		||||
				// Check for Special Keyword in list, External Command / Program, or Default Text
 | 
			
		||||
				} else if ((wordBuffer[0] != '%') &&
 | 
			
		||||
						   (wordBuffer[0] != '!') &&
 | 
			
		||||
					(!IsBOperator(wordBuffer[0])) &&
 | 
			
		||||
					(continueProcessing)) {
 | 
			
		||||
					// Check for Special Keyword
 | 
			
		||||
					//     Affected Commands are in Length range 2-6
 | 
			
		||||
					//     Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected
 | 
			
		||||
					bool sKeywordFound = false;		// Exit Special Keyword for-loop if found
 | 
			
		||||
					for (Sci_PositionU keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) {
 | 
			
		||||
						// Special Keywords are those that allow certain characters without whitespace after the command
 | 
			
		||||
						// Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path=
 | 
			
		||||
						// Special Keyword Buffer used to determine if the first n characters is a Keyword
 | 
			
		||||
						char sKeywordBuffer[10]{};	// Special Keyword Buffer
 | 
			
		||||
						wbo = 0;
 | 
			
		||||
						// Copy Keyword Length from Word Buffer into Special Keyword Buffer
 | 
			
		||||
						for (; wbo < keywordLength; wbo++) {
 | 
			
		||||
							sKeywordBuffer[wbo] = wordBuffer[wbo];
 | 
			
		||||
						}
 | 
			
		||||
						sKeywordBuffer[wbo] = '\0';
 | 
			
		||||
						// Check for Special Keyword in list
 | 
			
		||||
						if ((keywords.InList(sKeywordBuffer)) &&
 | 
			
		||||
							((IsBOperator(wordBuffer[wbo])) ||
 | 
			
		||||
							(IsBSeparator(wordBuffer[wbo])) ||
 | 
			
		||||
							(wordBuffer[wbo] == ':' &&
 | 
			
		||||
							(InList(sKeywordBuffer, {"call", "echo", "goto"}) )))) {
 | 
			
		||||
							sKeywordFound = true;
 | 
			
		||||
							// ECHO requires no further Regular Keyword Checking
 | 
			
		||||
							if (std::string_view(sKeywordBuffer) == "echo") {
 | 
			
		||||
								continueProcessing = false;
 | 
			
		||||
							}
 | 
			
		||||
							// Colorize Special Keyword as Regular Keyword
 | 
			
		||||
							styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD);
 | 
			
		||||
							// Reset Offset to re-process remainder of word
 | 
			
		||||
							offset -= (wbl - wbo);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					// Check for External Command / Program or Default Text
 | 
			
		||||
					if (!sKeywordFound) {
 | 
			
		||||
						wbo = 0;
 | 
			
		||||
						// Check for External Command / Program
 | 
			
		||||
						if (cmdLoc == offset - wbl) {
 | 
			
		||||
							// Read up to %, Operator or Separator
 | 
			
		||||
							while ((wbo < wbl) &&
 | 
			
		||||
								(((wordBuffer[wbo] != '%') &&
 | 
			
		||||
								(wordBuffer[wbo] != '!') &&
 | 
			
		||||
								(!IsBOperator(wordBuffer[wbo])) &&
 | 
			
		||||
								(!IsBSeparator(wordBuffer[wbo]))))) {
 | 
			
		||||
								wbo++;
 | 
			
		||||
							}
 | 
			
		||||
							// Reset External Command / Program Location
 | 
			
		||||
							cmdLoc = offset - (wbl - wbo);
 | 
			
		||||
							// Reset Offset to re-process remainder of word
 | 
			
		||||
							offset -= (wbl - wbo);
 | 
			
		||||
							// CHOICE requires no further Regular Keyword Checking
 | 
			
		||||
							if (wordView == "choice") {
 | 
			
		||||
								continueProcessing = false;
 | 
			
		||||
							}
 | 
			
		||||
							// Check for START (and its switches) - What follows is External Command \ Program
 | 
			
		||||
							if (wordView == "start") {
 | 
			
		||||
								// Reset External Command / Program Location
 | 
			
		||||
								cmdLoc = offset;
 | 
			
		||||
								// Skip next spaces
 | 
			
		||||
								while ((cmdLoc < lengthLine) &&
 | 
			
		||||
									(isspacechar(lineBuffer[cmdLoc]))) {
 | 
			
		||||
									cmdLoc++;
 | 
			
		||||
								}
 | 
			
		||||
								// Reset External Command / Program Location if command switch detected
 | 
			
		||||
								if (lineBuffer[cmdLoc] == '/') {
 | 
			
		||||
									// Skip command switch
 | 
			
		||||
									while ((cmdLoc < lengthLine) &&
 | 
			
		||||
										(!isspacechar(lineBuffer[cmdLoc]))) {
 | 
			
		||||
										cmdLoc++;
 | 
			
		||||
									}
 | 
			
		||||
									// Skip next spaces
 | 
			
		||||
									while ((cmdLoc < lengthLine) &&
 | 
			
		||||
										(isspacechar(lineBuffer[cmdLoc]))) {
 | 
			
		||||
										cmdLoc++;
 | 
			
		||||
									}
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
							// Colorize External Command / Program
 | 
			
		||||
							if (!keywords2) {
 | 
			
		||||
								styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
 | 
			
		||||
							} else if (keywords2.InList(wordBuffer)) {
 | 
			
		||||
								styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
 | 
			
		||||
							} else {
 | 
			
		||||
								styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
 | 
			
		||||
							}
 | 
			
		||||
							// No need to Reset Offset
 | 
			
		||||
						// Check for Default Text
 | 
			
		||||
						} else {
 | 
			
		||||
							// Read up to %, Operator or Separator
 | 
			
		||||
							while ((wbo < wbl) &&
 | 
			
		||||
								(((wordBuffer[wbo] != '%') &&
 | 
			
		||||
								(wordBuffer[wbo] != '!') &&
 | 
			
		||||
								(!IsBOperator(wordBuffer[wbo])) &&
 | 
			
		||||
								(!IsBSeparator(wordBuffer[wbo]))))) {
 | 
			
		||||
								wbo++;
 | 
			
		||||
							}
 | 
			
		||||
							// Colorize Default Text
 | 
			
		||||
							styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
 | 
			
		||||
							// Reset Offset to re-process remainder of word
 | 
			
		||||
							offset -= (wbl - wbo);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				// Check for Argument  (%n), Environment Variable (%x...%) or Local Variable (%%a)
 | 
			
		||||
				} else if (wordBuffer[0] == '%') {
 | 
			
		||||
					// Colorize Default Text
 | 
			
		||||
					styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
 | 
			
		||||
					wbo++;
 | 
			
		||||
					// Search to end of word for second % (can be a long path)
 | 
			
		||||
					while ((wbo < wbl) &&
 | 
			
		||||
						(wordBuffer[wbo] != '%')) {
 | 
			
		||||
						wbo++;
 | 
			
		||||
					}
 | 
			
		||||
					// Check for Argument (%n) or (%*)
 | 
			
		||||
					if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) &&
 | 
			
		||||
						(wordBuffer[wbo] != '%')) {
 | 
			
		||||
						// Check for External Command / Program
 | 
			
		||||
						if (cmdLoc == offset - wbl) {
 | 
			
		||||
							cmdLoc = offset - (wbl - 2);
 | 
			
		||||
						}
 | 
			
		||||
						// Colorize Argument
 | 
			
		||||
						styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER);
 | 
			
		||||
						// Reset Offset to re-process remainder of word
 | 
			
		||||
						offset -= (wbl - 2);
 | 
			
		||||
					// Check for Expanded Argument (%~...) / Variable (%%~...)
 | 
			
		||||
					// Expanded Argument: %~[<path-operators>]<single digit>
 | 
			
		||||
					// Expanded Variable: %%~[<path-operators>]<single identifier character>
 | 
			
		||||
					// Path operators are exclusively alphabetic.
 | 
			
		||||
					// Expanded arguments have a single digit at the end.
 | 
			
		||||
					// Expanded variables have a single identifier character as variable name.
 | 
			
		||||
					} else if (((wbl > 1) && (wordBuffer[1] == '~')) ||
 | 
			
		||||
						((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) {
 | 
			
		||||
						// Check for External Command / Program
 | 
			
		||||
						if (cmdLoc == offset - wbl) {
 | 
			
		||||
							cmdLoc = offset - (wbl - wbo);
 | 
			
		||||
						}
 | 
			
		||||
						const bool isArgument = (wordBuffer[1] == '~');
 | 
			
		||||
						if (isArgument) {
 | 
			
		||||
							Sci_PositionU expansionStopOffset = 2;
 | 
			
		||||
							bool isValid = false;
 | 
			
		||||
							for (; expansionStopOffset < wbl; expansionStopOffset++) {
 | 
			
		||||
								if (Is0To9(wordBuffer[expansionStopOffset])) {
 | 
			
		||||
									expansionStopOffset++;
 | 
			
		||||
									isValid = true;
 | 
			
		||||
									wbo = expansionStopOffset;
 | 
			
		||||
									// Colorize Expanded Argument
 | 
			
		||||
									styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
 | 
			
		||||
									break;
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
							if (!isValid) {
 | 
			
		||||
								// not a valid expanded argument or variable
 | 
			
		||||
								styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
 | 
			
		||||
							}
 | 
			
		||||
						// Expanded Variable
 | 
			
		||||
						} else {
 | 
			
		||||
							// start after ~
 | 
			
		||||
							wbo = 3;
 | 
			
		||||
							// Search to end of word for another % (can be a long path)
 | 
			
		||||
							while ((wbo < wbl) &&
 | 
			
		||||
								(wordBuffer[wbo] != '%') &&
 | 
			
		||||
								(!IsBOperator(wordBuffer[wbo])) &&
 | 
			
		||||
								(!IsBSeparator(wordBuffer[wbo]))) {
 | 
			
		||||
								wbo++;
 | 
			
		||||
							}
 | 
			
		||||
							if (wbo > 3) {
 | 
			
		||||
								// Colorize Expanded Variable
 | 
			
		||||
								styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
 | 
			
		||||
							} else {
 | 
			
		||||
								// not a valid expanded argument or variable
 | 
			
		||||
								styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						// Reset Offset to re-process remainder of word
 | 
			
		||||
						offset -= (wbl - wbo);
 | 
			
		||||
					// Check for Environment Variable (%x...%)
 | 
			
		||||
					} else if ((wordBuffer[1] != '%') &&
 | 
			
		||||
						(wordBuffer[wbo] == '%')) {
 | 
			
		||||
						wbo++;
 | 
			
		||||
						// Check for External Command / Program
 | 
			
		||||
						if (cmdLoc == offset - wbl) {
 | 
			
		||||
							cmdLoc = offset - (wbl - wbo);
 | 
			
		||||
						}
 | 
			
		||||
						// Colorize Environment Variable
 | 
			
		||||
						styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
 | 
			
		||||
						// Reset Offset to re-process remainder of word
 | 
			
		||||
						offset -= (wbl - wbo);
 | 
			
		||||
					// Check for Local Variable (%%a)
 | 
			
		||||
					} else if (
 | 
			
		||||
						(wbl > 2) &&
 | 
			
		||||
						(wordBuffer[1] == '%') &&
 | 
			
		||||
						(wordBuffer[2] != '%') &&
 | 
			
		||||
						(!IsBOperator(wordBuffer[2])) &&
 | 
			
		||||
						(!IsBSeparator(wordBuffer[2]))) {
 | 
			
		||||
						// Check for External Command / Program
 | 
			
		||||
						if (cmdLoc == offset - wbl) {
 | 
			
		||||
							cmdLoc = offset - (wbl - 3);
 | 
			
		||||
						}
 | 
			
		||||
						// Colorize Local Variable
 | 
			
		||||
						styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER);
 | 
			
		||||
						// Reset Offset to re-process remainder of word
 | 
			
		||||
						offset -= (wbl - 3);
 | 
			
		||||
					// escaped %
 | 
			
		||||
					} else if (
 | 
			
		||||
						(wbl > 1) &&
 | 
			
		||||
						(wordBuffer[1] == '%')) {
 | 
			
		||||
 | 
			
		||||
						// Reset Offset to re-process remainder of word
 | 
			
		||||
						styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_DEFAULT);
 | 
			
		||||
						offset -= (wbl - 2);
 | 
			
		||||
					}
 | 
			
		||||
				// Check for Environment Variable (!x...!)
 | 
			
		||||
				} else if (wordBuffer[0] == '!') {
 | 
			
		||||
					// Colorize Default Text
 | 
			
		||||
					styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
 | 
			
		||||
					wbo++;
 | 
			
		||||
					// Search to end of word for second ! (can be a long path)
 | 
			
		||||
					while ((wbo < wbl) &&
 | 
			
		||||
						(wordBuffer[wbo] != '!')) {
 | 
			
		||||
						wbo++;
 | 
			
		||||
					}
 | 
			
		||||
					if (wordBuffer[wbo] == '!') {
 | 
			
		||||
						wbo++;
 | 
			
		||||
						// Check for External Command / Program
 | 
			
		||||
						if (cmdLoc == offset - wbl) {
 | 
			
		||||
							cmdLoc = offset - (wbl - wbo);
 | 
			
		||||
						}
 | 
			
		||||
						// Colorize Environment Variable
 | 
			
		||||
						styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
 | 
			
		||||
						// Reset Offset to re-process remainder of word
 | 
			
		||||
						offset -= (wbl - wbo);
 | 
			
		||||
					}
 | 
			
		||||
				// Check for Operator
 | 
			
		||||
				} else if (IsBOperator(wordBuffer[0])) {
 | 
			
		||||
					// Colorize Default Text
 | 
			
		||||
					styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
 | 
			
		||||
					// Check for Comparison Operator
 | 
			
		||||
					if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) {
 | 
			
		||||
						// Identify External Command / Program Location for IF
 | 
			
		||||
						cmdLoc = offset;
 | 
			
		||||
						// Skip next spaces
 | 
			
		||||
						while ((cmdLoc < lengthLine) &&
 | 
			
		||||
							(isspacechar(lineBuffer[cmdLoc]))) {
 | 
			
		||||
							cmdLoc++;
 | 
			
		||||
						}
 | 
			
		||||
						// Colorize Comparison Operator
 | 
			
		||||
						if (continueProcessing)
 | 
			
		||||
							styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR);
 | 
			
		||||
						else
 | 
			
		||||
							styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_DEFAULT);
 | 
			
		||||
						// Reset Offset to re-process remainder of word
 | 
			
		||||
						offset -= (wbl - 2);
 | 
			
		||||
					// Check for Pipe Operator
 | 
			
		||||
					} else if ((wordBuffer[0] == '|') &&
 | 
			
		||||
								!(IsEscaped(lineBuffer,offset - wbl + wbo) || textQuoted(lineBuffer, offset - wbl) )) {
 | 
			
		||||
						// Reset External Command / Program Location
 | 
			
		||||
						cmdLoc = offset - wbl + 1;
 | 
			
		||||
						// Skip next spaces
 | 
			
		||||
						while ((cmdLoc < lengthLine) &&
 | 
			
		||||
							(isspacechar(lineBuffer[cmdLoc]))) {
 | 
			
		||||
							cmdLoc++;
 | 
			
		||||
						}
 | 
			
		||||
						// Colorize Pipe Operator
 | 
			
		||||
						styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
 | 
			
		||||
						// Reset Offset to re-process remainder of word
 | 
			
		||||
						offset -= (wbl - 1);
 | 
			
		||||
						continueProcessing = true;
 | 
			
		||||
					// Check for Other Operator
 | 
			
		||||
					} else {
 | 
			
		||||
						// Check for Operators: >, |, &
 | 
			
		||||
						if (((wordBuffer[0] == '>')||
 | 
			
		||||
						   (wordBuffer[0] == ')')||
 | 
			
		||||
						   (wordBuffer[0] == '(')||
 | 
			
		||||
						   (wordBuffer[0] == '&' )) &&
 | 
			
		||||
						   !(!continueProcessing && (IsEscaped(lineBuffer,offset - wbl + wbo)
 | 
			
		||||
						   || textQuoted(lineBuffer, offset - wbl) ))){
 | 
			
		||||
							// Turn Keyword and External Command / Program checking back on
 | 
			
		||||
							continueProcessing = true;
 | 
			
		||||
							isNotAssigned=false;
 | 
			
		||||
						}
 | 
			
		||||
						// Colorize Other Operators
 | 
			
		||||
						// Do not Colorize Parenthesis, quoted text and escaped operators
 | 
			
		||||
						if (((wordBuffer[0] != ')') && (wordBuffer[0] != '(')
 | 
			
		||||
						&& !textQuoted(lineBuffer, offset - wbl)  && !IsEscaped(lineBuffer,offset - wbl + wbo))
 | 
			
		||||
						&& !((wordBuffer[0] == '=') && !isNotAssigned ))
 | 
			
		||||
							styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
 | 
			
		||||
						else
 | 
			
		||||
							styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_DEFAULT);
 | 
			
		||||
						// Reset Offset to re-process remainder of word
 | 
			
		||||
						offset -= (wbl - 1);
 | 
			
		||||
 | 
			
		||||
						if ((wordBuffer[0] == '=') && isNotAssigned ){
 | 
			
		||||
							isNotAssigned=false;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				// Check for Default Text
 | 
			
		||||
				} else {
 | 
			
		||||
					// Read up to %, Operator or Separator
 | 
			
		||||
					while ((wbo < wbl) &&
 | 
			
		||||
						((wordBuffer[wbo] != '%') &&
 | 
			
		||||
						(wordBuffer[wbo] != '!') &&
 | 
			
		||||
						(!IsBOperator(wordBuffer[wbo])) &&
 | 
			
		||||
						(!IsBSeparator(wordBuffer[wbo])))) {
 | 
			
		||||
						wbo++;
 | 
			
		||||
					}
 | 
			
		||||
					// Colorize Default Text
 | 
			
		||||
					styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
 | 
			
		||||
					// Reset Offset to re-process remainder of word
 | 
			
		||||
					offset -= (wbl - wbo);
 | 
			
		||||
				}
 | 
			
		||||
				// Skip next spaces - nothing happens if Offset was Reset
 | 
			
		||||
				while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
 | 
			
		||||
					offset++;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// Colorize Default Text for remainder of line - currently not lexed
 | 
			
		||||
			styler.ColourTo(endPos, SCE_BAT_DEFAULT);
 | 
			
		||||
 | 
			
		||||
			// handle line continuation for SET and ECHO commands except the last line
 | 
			
		||||
			if (!continueProcessing && (i<startPos + length-1)) {
 | 
			
		||||
				if (linePos==1 || (linePos==2 && lineBuffer[1]=='\r')) // empty line on Unix and Mac or on Windows
 | 
			
		||||
					continueProcessing=true;
 | 
			
		||||
				else {
 | 
			
		||||
					Sci_PositionU lineContinuationPos;
 | 
			
		||||
					if ((linePos>2) && lineBuffer[linePos-2]=='\r') // Windows EOL
 | 
			
		||||
						lineContinuationPos=linePos-3;
 | 
			
		||||
					else
 | 
			
		||||
						lineContinuationPos=linePos-2; // Unix or Mac EOL
 | 
			
		||||
					// Reset continueProcessing	if line continuation was not found
 | 
			
		||||
					if ((lineBuffer[lineContinuationPos]!='^')
 | 
			
		||||
							|| IsEscaped(lineBuffer, lineContinuationPos)
 | 
			
		||||
							|| textQuoted(lineBuffer, lineContinuationPos))
 | 
			
		||||
						continueProcessing=true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			linePos = 0;
 | 
			
		||||
			startLine = i + 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *const batchWordListDesc[] = {
 | 
			
		||||
	"Internal Commands",
 | 
			
		||||
	"External Commands",
 | 
			
		||||
	nullptr
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", nullptr, batchWordListDesc);
 | 
			
		||||
							
								
								
									
										309
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBibTeX.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										309
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBibTeX.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,309 @@
 | 
			
		||||
// Copyright 2008-2010 Sergiu Dotenco. The License.txt file describes the
 | 
			
		||||
// conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file LexBibTeX.cxx
 | 
			
		||||
 * @brief General BibTeX coloring scheme.
 | 
			
		||||
 * @author Sergiu Dotenco
 | 
			
		||||
 * @date April 18, 2009
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cctype>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "PropSetSimple.h"
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "Accessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
	bool IsAlphabetic(unsigned int ch)
 | 
			
		||||
	{
 | 
			
		||||
		return IsASCII(ch) && std::isalpha(ch) != 0;
 | 
			
		||||
	}
 | 
			
		||||
	bool IsAlphaNumeric(char ch)
 | 
			
		||||
	{
 | 
			
		||||
	    return IsASCII(ch) && std::isalnum(ch);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool EqualCaseInsensitive(const char* a, const char* b)
 | 
			
		||||
	{
 | 
			
		||||
		return CompareCaseInsensitive(a, b) == 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool EntryWithoutKey(const char* name)
 | 
			
		||||
	{
 | 
			
		||||
		return EqualCaseInsensitive(name,"string");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char GetClosingBrace(char openbrace)
 | 
			
		||||
	{
 | 
			
		||||
		char result = openbrace;
 | 
			
		||||
 | 
			
		||||
		switch (openbrace) {
 | 
			
		||||
			case '(': result = ')'; break;
 | 
			
		||||
			case '{': result = '}'; break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool IsEntryStart(char prev, char ch)
 | 
			
		||||
	{
 | 
			
		||||
		return prev != '\\' && ch == '@';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool IsEntryStart(const StyleContext& sc)
 | 
			
		||||
	{
 | 
			
		||||
		return IsEntryStart(sc.chPrev, sc.ch);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void ColorizeBibTeX(Sci_PositionU start_pos, Sci_Position length, int /*init_style*/, WordList* keywordlists[], Accessor& styler)
 | 
			
		||||
	{
 | 
			
		||||
	    WordList &EntryNames = *keywordlists[0];
 | 
			
		||||
		bool fold_compact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
 | 
			
		||||
		std::string buffer;
 | 
			
		||||
		buffer.reserve(25);
 | 
			
		||||
 | 
			
		||||
		// We always colorize a section from the beginning, so let's
 | 
			
		||||
		// search for the @ character which isn't escaped, i.e. \@
 | 
			
		||||
		while (start_pos > 0 && !IsEntryStart(styler.SafeGetCharAt(start_pos - 1),
 | 
			
		||||
			styler.SafeGetCharAt(start_pos))) {
 | 
			
		||||
			--start_pos; ++length;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		styler.StartAt(start_pos);
 | 
			
		||||
		styler.StartSegment(start_pos);
 | 
			
		||||
 | 
			
		||||
		Sci_Position current_line = styler.GetLine(start_pos);
 | 
			
		||||
		int prev_level = styler.LevelAt(current_line) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
		int current_level = prev_level;
 | 
			
		||||
		int visible_chars = 0;
 | 
			
		||||
 | 
			
		||||
		bool in_comment = false ;
 | 
			
		||||
		StyleContext sc(start_pos, length, SCE_BIBTEX_DEFAULT, styler);
 | 
			
		||||
 | 
			
		||||
		bool going = sc.More(); // needed because of a fuzzy end of file state
 | 
			
		||||
		char closing_brace = 0;
 | 
			
		||||
		bool collect_entry_name = false;
 | 
			
		||||
 | 
			
		||||
		for (; going; sc.Forward()) {
 | 
			
		||||
			if (!sc.More())
 | 
			
		||||
				going = false; // we need to go one behind the end of text
 | 
			
		||||
 | 
			
		||||
			if (in_comment) {
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.SetState(SCE_BIBTEX_DEFAULT);
 | 
			
		||||
					in_comment = false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				// Found @entry
 | 
			
		||||
				if (IsEntryStart(sc)) {
 | 
			
		||||
					sc.SetState(SCE_BIBTEX_UNKNOWN_ENTRY);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					++current_level;
 | 
			
		||||
 | 
			
		||||
					buffer.clear();
 | 
			
		||||
					collect_entry_name = true;
 | 
			
		||||
				}
 | 
			
		||||
				else if ((sc.state == SCE_BIBTEX_ENTRY || sc.state == SCE_BIBTEX_UNKNOWN_ENTRY)
 | 
			
		||||
					&& (sc.ch == '{' || sc.ch == '(')) {
 | 
			
		||||
					// Entry name colorization done
 | 
			
		||||
					// Found either a { or a ( after entry's name, e.g. @entry(...) @entry{...}
 | 
			
		||||
					// Closing counterpart needs to be stored.
 | 
			
		||||
					closing_brace = GetClosingBrace(sc.ch);
 | 
			
		||||
 | 
			
		||||
					sc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize { (
 | 
			
		||||
 | 
			
		||||
					// @string doesn't have any key
 | 
			
		||||
					if (EntryWithoutKey(buffer.c_str()))
 | 
			
		||||
						sc.ForwardSetState(SCE_BIBTEX_PARAMETER);
 | 
			
		||||
					else
 | 
			
		||||
						sc.ForwardSetState(SCE_BIBTEX_KEY); // Key/label colorization
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Need to handle the case where entry's key is empty
 | 
			
		||||
				// e.g. @book{,...}
 | 
			
		||||
				if (sc.state == SCE_BIBTEX_KEY && sc.ch == ',') {
 | 
			
		||||
					// Key/label colorization done
 | 
			
		||||
					sc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize the ,
 | 
			
		||||
					sc.ForwardSetState(SCE_BIBTEX_PARAMETER); // Parameter colorization
 | 
			
		||||
				}
 | 
			
		||||
				else if (sc.state == SCE_BIBTEX_PARAMETER && sc.ch == '=') {
 | 
			
		||||
					sc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize the =
 | 
			
		||||
					sc.ForwardSetState(SCE_BIBTEX_VALUE); // Parameter value colorization
 | 
			
		||||
 | 
			
		||||
					Sci_Position start = sc.currentPos;
 | 
			
		||||
 | 
			
		||||
					// We need to handle multiple situations:
 | 
			
		||||
					// 1. name"one two {three}"
 | 
			
		||||
					// 2. name={one {one two {two}} three}
 | 
			
		||||
					// 3. year=2005
 | 
			
		||||
 | 
			
		||||
					// Skip ", { until we encounter the first alphanumerical character
 | 
			
		||||
					while (sc.More() && !(IsAlphaNumeric(sc.ch) || sc.ch == '"' || sc.ch == '{'))
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
 | 
			
		||||
					if (sc.More()) {
 | 
			
		||||
						// Store " or {
 | 
			
		||||
						char ch = sc.ch;
 | 
			
		||||
 | 
			
		||||
						// Not interested in alphanumerical characters
 | 
			
		||||
						if (IsAlphaNumeric(ch))
 | 
			
		||||
							ch = 0;
 | 
			
		||||
 | 
			
		||||
						int skipped = 0;
 | 
			
		||||
 | 
			
		||||
						if (ch) {
 | 
			
		||||
							// Skip preceding " or { such as in name={{test}}.
 | 
			
		||||
							// Remember how many characters have been skipped
 | 
			
		||||
							// Make sure that empty values, i.e. "" are also handled correctly
 | 
			
		||||
							while (sc.More() && (sc.ch == ch && (ch != '"' || skipped < 1))) {
 | 
			
		||||
								sc.Forward();
 | 
			
		||||
								++skipped;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						// Closing counterpart for " is the same character
 | 
			
		||||
						if (ch == '{')
 | 
			
		||||
							ch = '}';
 | 
			
		||||
 | 
			
		||||
						// We have reached the parameter value
 | 
			
		||||
						// In case the open character was a alnum char, skip until , is found
 | 
			
		||||
						// otherwise until skipped == 0
 | 
			
		||||
						while (sc.More() && (skipped > 0 || (!ch && !(sc.ch == ',' || sc.ch == closing_brace)))) {
 | 
			
		||||
							// Make sure the character isn't escaped
 | 
			
		||||
							if (sc.chPrev != '\\') {
 | 
			
		||||
								// Parameter value contains a { which is the 2nd case described above
 | 
			
		||||
								if (sc.ch == '{')
 | 
			
		||||
									++skipped; // Remember it
 | 
			
		||||
								else if (sc.ch == '}')
 | 
			
		||||
									--skipped;
 | 
			
		||||
								else if (skipped == 1 && sc.ch == ch && ch == '"') // Don't ignore cases like {"o}
 | 
			
		||||
									skipped = 0;
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							sc.Forward();
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// Don't colorize the ,
 | 
			
		||||
					sc.SetState(SCE_BIBTEX_DEFAULT);
 | 
			
		||||
 | 
			
		||||
					// Skip until the , or entry's closing closing_brace is found
 | 
			
		||||
					// since this parameter might be the last one
 | 
			
		||||
					while (sc.More() && !(sc.ch == ',' || sc.ch == closing_brace))
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
 | 
			
		||||
					int state = SCE_BIBTEX_PARAMETER; // The might be more parameters
 | 
			
		||||
 | 
			
		||||
					// We've reached the closing closing_brace for the bib entry
 | 
			
		||||
					// in case no " or {} has been used to enclose the value,
 | 
			
		||||
					// as in 3rd case described above
 | 
			
		||||
					if (sc.ch == closing_brace) {
 | 
			
		||||
						--current_level;
 | 
			
		||||
						// Make sure the text between entries is not colored
 | 
			
		||||
						// using parameter's style
 | 
			
		||||
						state = SCE_BIBTEX_DEFAULT;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					Sci_Position end = sc.currentPos;
 | 
			
		||||
					current_line = styler.GetLine(end);
 | 
			
		||||
 | 
			
		||||
					// We have possibly skipped some lines, so the folding levels
 | 
			
		||||
					// have to be adjusted separately
 | 
			
		||||
					for (Sci_Position i = styler.GetLine(start); i <= styler.GetLine(end); ++i)
 | 
			
		||||
						styler.SetLevel(i, prev_level);
 | 
			
		||||
 | 
			
		||||
					sc.ForwardSetState(state);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (sc.state == SCE_BIBTEX_PARAMETER && sc.ch == closing_brace) {
 | 
			
		||||
					sc.SetState(SCE_BIBTEX_DEFAULT);
 | 
			
		||||
					--current_level;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Non escaped % found which represents a comment until the end of the line
 | 
			
		||||
				if (sc.chPrev != '\\' && sc.ch == '%') {
 | 
			
		||||
					in_comment = true;
 | 
			
		||||
					sc.SetState(SCE_BIBTEX_COMMENT);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (sc.state == SCE_BIBTEX_UNKNOWN_ENTRY || sc.state == SCE_BIBTEX_ENTRY) {
 | 
			
		||||
				if (!IsAlphabetic(sc.ch) && collect_entry_name)
 | 
			
		||||
					collect_entry_name = false;
 | 
			
		||||
 | 
			
		||||
				if (collect_entry_name) {
 | 
			
		||||
					buffer += static_cast<char>(tolower(sc.ch));
 | 
			
		||||
                    if (EntryNames.InList(buffer.c_str()))
 | 
			
		||||
                        sc.ChangeState(SCE_BIBTEX_ENTRY);
 | 
			
		||||
                    else
 | 
			
		||||
                        sc.ChangeState(SCE_BIBTEX_UNKNOWN_ENTRY);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				int level = prev_level;
 | 
			
		||||
 | 
			
		||||
				if (visible_chars == 0 && fold_compact)
 | 
			
		||||
					level |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
 | 
			
		||||
				if ((current_level > prev_level))
 | 
			
		||||
					level |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
				// else if (current_level < prev_level)
 | 
			
		||||
				//	level |= SC_FOLDLEVELBOXFOOTERFLAG; // Deprecated
 | 
			
		||||
 | 
			
		||||
				if (level != styler.LevelAt(current_line)) {
 | 
			
		||||
					styler.SetLevel(current_line, level);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				++current_line;
 | 
			
		||||
				prev_level = current_level;
 | 
			
		||||
				visible_chars = 0;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (!isspacechar(sc.ch))
 | 
			
		||||
				++visible_chars;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sc.Complete();
 | 
			
		||||
 | 
			
		||||
		// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
		int flagsNext = styler.LevelAt(current_line) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
		styler.SetLevel(current_line, prev_level | flagsNext);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
static const char * const BibTeXWordLists[] = {
 | 
			
		||||
            "Entry Names",
 | 
			
		||||
            0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmBibTeX(SCLEX_BIBTEX, ColorizeBibTeX, "bib", 0, BibTeXWordLists);
 | 
			
		||||
 | 
			
		||||
// Entry Names
 | 
			
		||||
//    article, book, booklet, conference, inbook,
 | 
			
		||||
//    incollection, inproceedings, manual, mastersthesis,
 | 
			
		||||
//    misc, phdthesis, proceedings, techreport, unpublished,
 | 
			
		||||
//    string, url
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										234
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBullant.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								3rdparty/lexilla540/lexilla/lexers/LexBullant.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,234 @@
 | 
			
		||||
// SciTE - Scintilla based Text Editor
 | 
			
		||||
// LexBullant.cxx - lexer for Bullant
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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;
 | 
			
		||||
 | 
			
		||||
static int classifyWordBullant(Sci_PositionU start, Sci_PositionU end, WordList &keywords, Accessor &styler) {
 | 
			
		||||
	char s[100];
 | 
			
		||||
	s[0] = '\0';
 | 
			
		||||
	for (Sci_PositionU i = 0; i < end - start + 1 && i < 30; i++) {
 | 
			
		||||
		s[i] = static_cast<char>(tolower(styler[start + i]));
 | 
			
		||||
		s[i + 1] = '\0';
 | 
			
		||||
	}
 | 
			
		||||
	int lev= 0;
 | 
			
		||||
	char chAttr = SCE_C_IDENTIFIER;
 | 
			
		||||
	if (isdigit(s[0]) || (s[0] == '.')){
 | 
			
		||||
		chAttr = SCE_C_NUMBER;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		if (keywords.InList(s)) {
 | 
			
		||||
			chAttr = SCE_C_WORD;
 | 
			
		||||
			if (strcmp(s, "end") == 0)
 | 
			
		||||
				lev = -1;
 | 
			
		||||
			else if (strcmp(s, "method") == 0 ||
 | 
			
		||||
				strcmp(s, "case") == 0 ||
 | 
			
		||||
				strcmp(s, "class") == 0 ||
 | 
			
		||||
				strcmp(s, "debug") == 0 ||
 | 
			
		||||
				strcmp(s, "test") == 0 ||
 | 
			
		||||
				strcmp(s, "if") == 0 ||
 | 
			
		||||
				strcmp(s, "lock") == 0 ||
 | 
			
		||||
				strcmp(s, "transaction") == 0 ||
 | 
			
		||||
				strcmp(s, "trap") == 0 ||
 | 
			
		||||
				strcmp(s, "until") == 0 ||
 | 
			
		||||
				strcmp(s, "while") == 0)
 | 
			
		||||
				lev = 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	styler.ColourTo(end, chAttr);
 | 
			
		||||
	return lev;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseBullantDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
	Accessor &styler) {
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
 | 
			
		||||
	bool fold = styler.GetPropertyInt("fold") != 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
 | 
			
		||||
	int state = initStyle;
 | 
			
		||||
	if (state == SCE_C_STRINGEOL)	// Does not leak onto next line
 | 
			
		||||
		state = SCE_C_DEFAULT;
 | 
			
		||||
	char chPrev = ' ';
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	Sci_PositionU lengthDoc = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
	int endFoundThisLine = 0;
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
 | 
			
		||||
			// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
 | 
			
		||||
			// Avoid triggering two times on Dos/Win
 | 
			
		||||
			// End of line
 | 
			
		||||
			endFoundThisLine = 0;
 | 
			
		||||
			if (state == SCE_C_STRINGEOL) {
 | 
			
		||||
				styler.ColourTo(i, state);
 | 
			
		||||
				state = SCE_C_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
			if (fold) {
 | 
			
		||||
				int lev = levelPrev;
 | 
			
		||||
				if (visibleChars == 0)
 | 
			
		||||
					lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
				if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
					lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
				lineCurrent++;
 | 
			
		||||
				levelPrev = levelCurrent;
 | 
			
		||||
			}
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
 | 
			
		||||
/*			int indentBlock = GetLineIndentation(lineCurrent);
 | 
			
		||||
			if (blockChange==1){
 | 
			
		||||
				lineCurrent++;
 | 
			
		||||
				int pos=SetLineIndentation(lineCurrent, indentBlock + indentSize);
 | 
			
		||||
			} else if (blockChange==-1) {
 | 
			
		||||
				indentBlock -= indentSize;
 | 
			
		||||
				if (indentBlock < 0)
 | 
			
		||||
					indentBlock = 0;
 | 
			
		||||
				SetLineIndentation(lineCurrent, indentBlock);
 | 
			
		||||
				lineCurrent++;
 | 
			
		||||
			}
 | 
			
		||||
			blockChange=0;
 | 
			
		||||
*/		}
 | 
			
		||||
		if (!(IsASCII(ch) && isspace(ch)))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
 | 
			
		||||
		if (styler.IsLeadByte(ch)) {
 | 
			
		||||
			chNext = styler.SafeGetCharAt(i + 2);
 | 
			
		||||
			chPrev = ' ';
 | 
			
		||||
			i += 1;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (state == SCE_C_DEFAULT) {
 | 
			
		||||
			if (iswordstart(ch)) {
 | 
			
		||||
				styler.ColourTo(i-1, state);
 | 
			
		||||
					state = SCE_C_IDENTIFIER;
 | 
			
		||||
			} else if (ch == '@' && chNext == 'o') {
 | 
			
		||||
				if ((styler.SafeGetCharAt(i+2) =='f') && (styler.SafeGetCharAt(i+3) == 'f')) {
 | 
			
		||||
					styler.ColourTo(i-1, state);
 | 
			
		||||
					state = SCE_C_COMMENT;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (ch == '#') {
 | 
			
		||||
				styler.ColourTo(i-1, state);
 | 
			
		||||
				state = SCE_C_COMMENTLINE;
 | 
			
		||||
			} else if (ch == '\"') {
 | 
			
		||||
				styler.ColourTo(i-1, state);
 | 
			
		||||
				state = SCE_C_STRING;
 | 
			
		||||
			} else if (ch == '\'') {
 | 
			
		||||
				styler.ColourTo(i-1, state);
 | 
			
		||||
				state = SCE_C_CHARACTER;
 | 
			
		||||
			} else if (isoperator(ch)) {
 | 
			
		||||
				styler.ColourTo(i-1, state);
 | 
			
		||||
				styler.ColourTo(i, SCE_C_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_C_IDENTIFIER) {
 | 
			
		||||
			if (!iswordchar(ch)) {
 | 
			
		||||
				int levelChange = classifyWordBullant(styler.GetStartSegment(), i - 1, keywords, styler);
 | 
			
		||||
				state = SCE_C_DEFAULT;
 | 
			
		||||
				chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				if (ch == '#') {
 | 
			
		||||
					state = SCE_C_COMMENTLINE;
 | 
			
		||||
				} else if (ch == '\"') {
 | 
			
		||||
					state = SCE_C_STRING;
 | 
			
		||||
				} else if (ch == '\'') {
 | 
			
		||||
					state = SCE_C_CHARACTER;
 | 
			
		||||
				} else if (isoperator(ch)) {
 | 
			
		||||
					styler.ColourTo(i, SCE_C_OPERATOR);
 | 
			
		||||
				}
 | 
			
		||||
				if (endFoundThisLine == 0)
 | 
			
		||||
					levelCurrent+=levelChange;
 | 
			
		||||
				if (levelChange == -1)
 | 
			
		||||
					endFoundThisLine=1;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_C_COMMENT) {
 | 
			
		||||
			if (ch == '@' && chNext == 'o') {
 | 
			
		||||
				if (styler.SafeGetCharAt(i+2) == 'n') {
 | 
			
		||||
					styler.ColourTo(i+2, state);
 | 
			
		||||
					state = SCE_C_DEFAULT;
 | 
			
		||||
					i+=2;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_C_COMMENTLINE) {
 | 
			
		||||
			if (ch == '\r' || ch == '\n') {
 | 
			
		||||
				endFoundThisLine = 0;
 | 
			
		||||
				styler.ColourTo(i-1, state);
 | 
			
		||||
				state = SCE_C_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_C_STRING) {
 | 
			
		||||
			if (ch == '\\') {
 | 
			
		||||
				if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
 | 
			
		||||
					i++;
 | 
			
		||||
					ch = chNext;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (ch == '\"') {
 | 
			
		||||
				styler.ColourTo(i, state);
 | 
			
		||||
				state = SCE_C_DEFAULT;
 | 
			
		||||
			} else if (chNext == '\r' || chNext == '\n') {
 | 
			
		||||
				endFoundThisLine = 0;
 | 
			
		||||
				styler.ColourTo(i-1, SCE_C_STRINGEOL);
 | 
			
		||||
				state = SCE_C_STRINGEOL;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_C_CHARACTER) {
 | 
			
		||||
			if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
 | 
			
		||||
				endFoundThisLine = 0;
 | 
			
		||||
				styler.ColourTo(i-1, SCE_C_STRINGEOL);
 | 
			
		||||
				state = SCE_C_STRINGEOL;
 | 
			
		||||
			} else if (ch == '\\') {
 | 
			
		||||
				if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
 | 
			
		||||
					i++;
 | 
			
		||||
					ch = chNext;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (ch == '\'') {
 | 
			
		||||
				styler.ColourTo(i, state);
 | 
			
		||||
				state = SCE_C_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		chPrev = ch;
 | 
			
		||||
	}
 | 
			
		||||
	styler.ColourTo(lengthDoc - 1, state);
 | 
			
		||||
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
	if (fold) {
 | 
			
		||||
		int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
		//styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
 | 
			
		||||
		styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const bullantWordListDesc[] = {
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc);
 | 
			
		||||
							
								
								
									
										410
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCIL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										410
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCIL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,410 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexCIL.cxx
 | 
			
		||||
 ** Lexer for Common Intermediate Language
 | 
			
		||||
 ** Written by Jad Altahan (github.com/xv)
 | 
			
		||||
 ** CIL manual: https://www.ecma-international.org/publications/standards/Ecma-335.htm
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.h>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "StringCopy.h"
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "Accessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "OptionSet.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
    // Use an unnamed namespace to protect the functions and classes from name conflicts
 | 
			
		||||
 | 
			
		||||
bool IsAWordChar(const int ch) {
 | 
			
		||||
    return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool IsOperator(const int ch) {
 | 
			
		||||
    if ((ch < 0x80) && (isalnum(ch)))
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    if (strchr("!%&*+-/<=>@^|~()[]{}", ch)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr bool IsStreamCommentStyle(const int style) noexcept {
 | 
			
		||||
    return style == SCE_CIL_COMMENT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct OptionsCIL {
 | 
			
		||||
    bool fold;
 | 
			
		||||
    bool foldComment;
 | 
			
		||||
    bool foldCommentMultiline;
 | 
			
		||||
    bool foldCompact;
 | 
			
		||||
 | 
			
		||||
    OptionsCIL() {
 | 
			
		||||
        fold = true;
 | 
			
		||||
        foldComment = false;
 | 
			
		||||
        foldCommentMultiline = true;
 | 
			
		||||
        foldCompact = true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char *const cilWordListDesc[] = {
 | 
			
		||||
    "Primary CIL keywords",
 | 
			
		||||
    "Metadata",
 | 
			
		||||
    "Opcode instructions",
 | 
			
		||||
    0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct OptionSetCIL : public OptionSet<OptionsCIL> {
 | 
			
		||||
    OptionSetCIL() {
 | 
			
		||||
        DefineProperty("fold", &OptionsCIL::fold);
 | 
			
		||||
        DefineProperty("fold.comment", &OptionsCIL::foldComment);
 | 
			
		||||
 | 
			
		||||
        DefineProperty("fold.cil.comment.multiline", &OptionsCIL::foldCommentMultiline,
 | 
			
		||||
            "Set this property to 0 to disable folding multi-line comments when fold.comment=1.");
 | 
			
		||||
 | 
			
		||||
        DefineProperty("fold.compact", &OptionsCIL::foldCompact);
 | 
			
		||||
 | 
			
		||||
        DefineWordListSets(cilWordListDesc);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
LexicalClass lexicalClasses[] = {
 | 
			
		||||
    // Lexer CIL SCLEX_CIL SCE_CIL_:
 | 
			
		||||
    0,  "SCE_CIL_DEFAULT",     "default",              "White space",
 | 
			
		||||
    1,  "SCE_CIL_COMMENT",     "comment",              "Multi-line comment",
 | 
			
		||||
    2,  "SCE_CIL_COMMENTLINE", "comment line",         "Line comment",
 | 
			
		||||
    3,  "SCE_CIL_WORD",        "keyword",              "Keyword 1",
 | 
			
		||||
    4,  "SCE_CIL_WORD2",       "keyword",              "Keyword 2",
 | 
			
		||||
    5,  "SCE_CIL_WORD3",       "keyword",              "Keyword 3",
 | 
			
		||||
    6,  "SCE_CIL_STRING",      "literal string",       "Double quoted string",
 | 
			
		||||
    7,  "SCE_CIL_LABEL",       "label",                "Code label",
 | 
			
		||||
    8,  "SCE_CIL_OPERATOR",    "operator",             "Operators",
 | 
			
		||||
    9,  "SCE_CIL_STRINGEOL",   "error literal string", "String is not closed",
 | 
			
		||||
    10, "SCE_CIL_IDENTIFIER",  "identifier",           "Identifiers",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class LexerCIL : public DefaultLexer {
 | 
			
		||||
    WordList keywords, keywords2, keywords3;
 | 
			
		||||
    OptionsCIL options;
 | 
			
		||||
    OptionSetCIL osCIL;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    LexerCIL() : DefaultLexer("cil", SCLEX_CIL, lexicalClasses, ELEMENTS(lexicalClasses)) { }
 | 
			
		||||
 | 
			
		||||
    virtual ~LexerCIL() { }
 | 
			
		||||
 | 
			
		||||
    void SCI_METHOD Release() override {
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int SCI_METHOD Version() const override {
 | 
			
		||||
        return lvRelease5;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char * SCI_METHOD PropertyNames() override {
 | 
			
		||||
        return osCIL.PropertyNames();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int SCI_METHOD PropertyType(const char *name) override {
 | 
			
		||||
        return osCIL.PropertyType(name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char * SCI_METHOD DescribeProperty(const char *name) override {
 | 
			
		||||
        return osCIL.DescribeProperty(name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
 | 
			
		||||
 | 
			
		||||
	const char * SCI_METHOD PropertyGet(const char* key) override {
 | 
			
		||||
		return osCIL.PropertyGet(key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    const char * SCI_METHOD DescribeWordListSets() override {
 | 
			
		||||
        return osCIL.DescribeWordListSets();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
 | 
			
		||||
 | 
			
		||||
    void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
    void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
 | 
			
		||||
    void * SCI_METHOD PrivateCall(int, void *) override {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int SCI_METHOD LineEndTypesSupported() override {
 | 
			
		||||
        return SC_LINE_END_TYPE_UNICODE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int SCI_METHOD PrimaryStyleFromStyle(int style) override {
 | 
			
		||||
        return style;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static ILexer5 *LexerFactoryCIL() {
 | 
			
		||||
        return new LexerCIL();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerCIL::PropertySet(const char *key, const char *val) {
 | 
			
		||||
    if (osCIL.PropertySet(&options, key, val)) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerCIL::WordListSet(int n, const char *wl) {
 | 
			
		||||
    WordList *wordListN = 0;
 | 
			
		||||
 | 
			
		||||
    switch (n) {
 | 
			
		||||
        case 0:
 | 
			
		||||
            wordListN = &keywords;
 | 
			
		||||
            break;
 | 
			
		||||
        case 1:
 | 
			
		||||
            wordListN = &keywords2;
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            wordListN = &keywords3;
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Sci_Position firstModification = -1;
 | 
			
		||||
 | 
			
		||||
    if (wordListN) {
 | 
			
		||||
        WordList wlNew;
 | 
			
		||||
        wlNew.Set(wl);
 | 
			
		||||
 | 
			
		||||
        if (*wordListN != wlNew) {
 | 
			
		||||
            wordListN->Set(wl);
 | 
			
		||||
            firstModification = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return firstModification;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerCIL::Lex(Sci_PositionU startPos, Sci_Position length,
 | 
			
		||||
                              int initStyle, IDocument *pAccess) {
 | 
			
		||||
    if (initStyle == SCE_CIL_STRINGEOL) {
 | 
			
		||||
        initStyle = SCE_CIL_DEFAULT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Accessor styler(pAccess, NULL);
 | 
			
		||||
    StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
    bool identAtLineStart = false, // Checks if an identifier is at line start (ignoring spaces)
 | 
			
		||||
         canStyleLabels = false;   // Checks if conditions are met to style SCE_CIL_LABEL
 | 
			
		||||
 | 
			
		||||
    for (; sc.More(); sc.Forward()) {
 | 
			
		||||
        if (sc.atLineStart) {
 | 
			
		||||
            if (sc.state == SCE_CIL_STRING) {
 | 
			
		||||
                sc.SetState(SCE_CIL_STRING);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            identAtLineStart = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Handle string line continuation
 | 
			
		||||
        if (sc.ch == '\\' && (sc.chNext == '\n' || sc.chNext == '\r') &&
 | 
			
		||||
           (sc.state == SCE_CIL_STRING)) {
 | 
			
		||||
            sc.Forward();
 | 
			
		||||
 | 
			
		||||
            if (sc.ch == '\r' && sc.chNext == '\n') {
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch (sc.state) {
 | 
			
		||||
            case SCE_CIL_OPERATOR:
 | 
			
		||||
                sc.SetState(SCE_CIL_DEFAULT);
 | 
			
		||||
                break;
 | 
			
		||||
            case SCE_CIL_IDENTIFIER:
 | 
			
		||||
                if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
                    if (canStyleLabels && (sc.ch == ':' && sc.chNext != ':')) {
 | 
			
		||||
                        sc.ChangeState(SCE_CIL_LABEL);
 | 
			
		||||
                        sc.ForwardSetState(SCE_CIL_DEFAULT);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        char kwSize[100];
 | 
			
		||||
                        sc.GetCurrent(kwSize, sizeof(kwSize));
 | 
			
		||||
                        int style = SCE_CIL_IDENTIFIER;
 | 
			
		||||
 | 
			
		||||
                        if (keywords.InList(kwSize)) {
 | 
			
		||||
                            style = SCE_CIL_WORD;
 | 
			
		||||
                        } else if (keywords2.InList(kwSize)) {
 | 
			
		||||
                            style = SCE_CIL_WORD2;
 | 
			
		||||
                        } else if (keywords3.InList(kwSize)) {
 | 
			
		||||
                            style = SCE_CIL_WORD3;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        sc.ChangeState(style);
 | 
			
		||||
                        sc.SetState(SCE_CIL_DEFAULT);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case SCE_CIL_COMMENT:
 | 
			
		||||
                if (sc.Match('*', '/')) {
 | 
			
		||||
                    sc.Forward();
 | 
			
		||||
                    sc.ForwardSetState(SCE_CIL_DEFAULT);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case SCE_CIL_COMMENTLINE:
 | 
			
		||||
                if (sc.atLineStart) {
 | 
			
		||||
                    sc.SetState(SCE_CIL_DEFAULT);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case SCE_CIL_STRING:
 | 
			
		||||
                if (sc.ch == '\\') {
 | 
			
		||||
                    if (sc.chNext == '"' || sc.chNext == '\\') {
 | 
			
		||||
                        sc.Forward();
 | 
			
		||||
                    }
 | 
			
		||||
                } else if (sc.ch == '"') {
 | 
			
		||||
                    sc.ForwardSetState(SCE_CIL_DEFAULT);
 | 
			
		||||
                } else if (sc.atLineEnd) {
 | 
			
		||||
                    sc.ChangeState(SCE_CIL_STRINGEOL);
 | 
			
		||||
                    sc.ForwardSetState(SCE_CIL_DEFAULT);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (sc.state == SCE_CIL_DEFAULT) {
 | 
			
		||||
            // String
 | 
			
		||||
            if (sc.ch == '"') {
 | 
			
		||||
                sc.SetState(SCE_CIL_STRING);
 | 
			
		||||
            }
 | 
			
		||||
            // Keyword
 | 
			
		||||
            else if (IsAWordChar(sc.ch)) {
 | 
			
		||||
                // Allow setting SCE_CIL_LABEL style only if the label is the
 | 
			
		||||
                // first token in the line and does not start with a dot or a digit
 | 
			
		||||
                canStyleLabels = identAtLineStart && !(sc.ch == '.' || IsADigit(sc.ch));
 | 
			
		||||
                sc.SetState(SCE_CIL_IDENTIFIER);
 | 
			
		||||
            }
 | 
			
		||||
            // Multi-line comment
 | 
			
		||||
            else if (sc.Match('/', '*')) {
 | 
			
		||||
                sc.SetState(SCE_CIL_COMMENT);
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
            }
 | 
			
		||||
            // Line comment
 | 
			
		||||
            else if (sc.Match('/', '/')) {
 | 
			
		||||
                sc.SetState(SCE_CIL_COMMENTLINE);
 | 
			
		||||
            }
 | 
			
		||||
            // Operators
 | 
			
		||||
            else if (IsOperator(sc.ch)) {
 | 
			
		||||
                sc.SetState(SCE_CIL_OPERATOR);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!IsASpace(sc.ch)) {
 | 
			
		||||
            identAtLineStart = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerCIL::Fold(Sci_PositionU startPos, Sci_Position length, 
 | 
			
		||||
                               int initStyle, IDocument *pAccess) {
 | 
			
		||||
    if (!options.fold) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LexAccessor styler(pAccess);
 | 
			
		||||
 | 
			
		||||
    const Sci_PositionU endPos = startPos + length;
 | 
			
		||||
    Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
 | 
			
		||||
    int levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
    if (lineCurrent > 0)
 | 
			
		||||
        levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
 | 
			
		||||
    
 | 
			
		||||
    int style = initStyle;
 | 
			
		||||
    int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
    int levelNext = levelCurrent;
 | 
			
		||||
    int visibleChars = 0;
 | 
			
		||||
 | 
			
		||||
    char chNext = styler[startPos];
 | 
			
		||||
 | 
			
		||||
    for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
        const char ch = chNext;
 | 
			
		||||
        int stylePrev = style;
 | 
			
		||||
 | 
			
		||||
        chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
        style = styleNext;
 | 
			
		||||
        styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
 | 
			
		||||
        const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
 | 
			
		||||
        if (options.foldComment && 
 | 
			
		||||
            options.foldCommentMultiline && IsStreamCommentStyle(style)) {
 | 
			
		||||
            if (!IsStreamCommentStyle(stylePrev)) {
 | 
			
		||||
                levelNext++;
 | 
			
		||||
            } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
 | 
			
		||||
                levelNext--;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (style == SCE_CIL_OPERATOR) {
 | 
			
		||||
            if (ch == '{') {
 | 
			
		||||
                levelNext++;
 | 
			
		||||
            } else if (ch == '}') {
 | 
			
		||||
                levelNext--;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!IsASpace(ch)) {
 | 
			
		||||
            visibleChars++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (atEOL || (i == endPos - 1)) {
 | 
			
		||||
            int lev = levelCurrent | levelNext << 16;
 | 
			
		||||
            if (visibleChars == 0 && options.foldCompact)
 | 
			
		||||
                lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
            if (levelCurrent < levelNext)
 | 
			
		||||
                lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
            if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
                styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            lineCurrent++;
 | 
			
		||||
            levelCurrent = levelNext;
 | 
			
		||||
            
 | 
			
		||||
            if (options.foldCompact &&
 | 
			
		||||
                i == static_cast<Sci_PositionU>(styler.Length() - 1)) {
 | 
			
		||||
                styler.SetLevel(lineCurrent, lev | SC_FOLDLEVELWHITEFLAG);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            visibleChars = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmCIL(SCLEX_CIL, LexerCIL::LexerFactoryCIL, "cil", cilWordListDesc);
 | 
			
		||||
							
								
								
									
										683
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCLW.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										683
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCLW.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,683 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexCLW.cxx
 | 
			
		||||
 ** Lexer for Clarion.
 | 
			
		||||
 ** 2004/12/17 Updated Lexer
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2003-2004 by Ron Schofield <ron@schofieldcomputer.com>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
// Is an end of line character
 | 
			
		||||
inline bool IsEOL(const int ch) {
 | 
			
		||||
 | 
			
		||||
	return(ch == '\n');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Convert character to uppercase
 | 
			
		||||
static char CharacterUpper(char chChar) {
 | 
			
		||||
 | 
			
		||||
	if (chChar < 'a' || chChar > 'z') {
 | 
			
		||||
		return(chChar);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		return(static_cast<char>(chChar - 'a' + 'A'));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Convert string to uppercase
 | 
			
		||||
static void StringUpper(char *szString) {
 | 
			
		||||
 | 
			
		||||
	while (*szString) {
 | 
			
		||||
		*szString = CharacterUpper(*szString);
 | 
			
		||||
		szString++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Is a label start character
 | 
			
		||||
inline bool IsALabelStart(const int iChar) {
 | 
			
		||||
 | 
			
		||||
	return(isalpha(iChar) || iChar == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Is a label character
 | 
			
		||||
inline bool IsALabelCharacter(const int iChar) {
 | 
			
		||||
 | 
			
		||||
	return(isalnum(iChar) || iChar == '_' || iChar == ':');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Is the character is a ! and the the next character is not a !
 | 
			
		||||
inline bool IsACommentStart(const int iChar) {
 | 
			
		||||
 | 
			
		||||
	return(iChar == '!');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Is the character a Clarion hex character (ABCDEF)
 | 
			
		||||
inline bool IsAHexCharacter(const int iChar, bool bCaseSensitive) {
 | 
			
		||||
 | 
			
		||||
	// Case insensitive.
 | 
			
		||||
	if (!bCaseSensitive) {
 | 
			
		||||
		if (strchr("ABCDEFabcdef", iChar) != NULL) {
 | 
			
		||||
			return(true);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Case sensitive
 | 
			
		||||
	else {
 | 
			
		||||
		if (strchr("ABCDEF", iChar) != NULL) {
 | 
			
		||||
			return(true);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Is the character a Clarion base character (B=Binary, O=Octal, H=Hex)
 | 
			
		||||
inline bool IsANumericBaseCharacter(const int iChar, bool bCaseSensitive) {
 | 
			
		||||
 | 
			
		||||
	// Case insensitive.
 | 
			
		||||
	if (!bCaseSensitive) {
 | 
			
		||||
		// If character is a numeric base character
 | 
			
		||||
		if (strchr("BOHboh", iChar) != NULL) {
 | 
			
		||||
			return(true);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Case sensitive
 | 
			
		||||
	else {
 | 
			
		||||
		// If character is a numeric base character
 | 
			
		||||
		if (strchr("BOH", iChar) != NULL) {
 | 
			
		||||
			return(true);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set the correct numeric constant state
 | 
			
		||||
inline bool SetNumericConstantState(StyleContext &scDoc) {
 | 
			
		||||
 | 
			
		||||
	int iPoints = 0;			// Point counter
 | 
			
		||||
	char cNumericString[512];	// Numeric string buffer
 | 
			
		||||
 | 
			
		||||
	// Buffer the current numberic string
 | 
			
		||||
	scDoc.GetCurrent(cNumericString, sizeof(cNumericString));
 | 
			
		||||
	// Loop through the string until end of string (NULL termination)
 | 
			
		||||
	for (int iIndex = 0; cNumericString[iIndex] != '\0'; iIndex++) {
 | 
			
		||||
		// Depending on the character
 | 
			
		||||
		switch (cNumericString[iIndex]) {
 | 
			
		||||
			// Is a . (point)
 | 
			
		||||
			case '.' :
 | 
			
		||||
				// Increment point counter
 | 
			
		||||
				iPoints++;
 | 
			
		||||
				break;
 | 
			
		||||
			default :
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// If points found (can be more than one for improper formatted number
 | 
			
		||||
	if (iPoints > 0) {
 | 
			
		||||
		return(true);
 | 
			
		||||
	}
 | 
			
		||||
	// Else no points found
 | 
			
		||||
	else {
 | 
			
		||||
		return(false);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get the next word in uppercase from the current position (keyword lookahead)
 | 
			
		||||
inline bool GetNextWordUpper(Accessor &styler, Sci_PositionU uiStartPos, Sci_Position iLength, char *cWord) {
 | 
			
		||||
 | 
			
		||||
	Sci_PositionU iIndex = 0;		// Buffer Index
 | 
			
		||||
 | 
			
		||||
	// Loop through the remaining string from the current position
 | 
			
		||||
	for (Sci_Position iOffset = uiStartPos; iOffset < iLength; iOffset++) {
 | 
			
		||||
		// Get the character from the buffer using the offset
 | 
			
		||||
		char cCharacter = styler[iOffset];
 | 
			
		||||
		if (IsEOL(cCharacter)) {
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		// If the character is alphabet character
 | 
			
		||||
		if (isalpha(cCharacter)) {
 | 
			
		||||
			// Add UPPERCASE character to the word buffer
 | 
			
		||||
			cWord[iIndex++] = CharacterUpper(cCharacter);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Add null termination
 | 
			
		||||
	cWord[iIndex] = '\0';
 | 
			
		||||
	// If no word was found
 | 
			
		||||
	if (iIndex == 0) {
 | 
			
		||||
		// Return failure
 | 
			
		||||
		return(false);
 | 
			
		||||
	}
 | 
			
		||||
	// Else word was found
 | 
			
		||||
	else {
 | 
			
		||||
		// Return success
 | 
			
		||||
		return(true);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Clarion Language Colouring Procedure
 | 
			
		||||
static void ColouriseClarionDoc(Sci_PositionU uiStartPos, Sci_Position iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) {
 | 
			
		||||
 | 
			
		||||
	int iParenthesesLevel = 0;		// Parenthese Level
 | 
			
		||||
	int iColumn1Label = false;		// Label starts in Column 1
 | 
			
		||||
 | 
			
		||||
	WordList &wlClarionKeywords = *wlKeywords[0];			// Clarion Keywords
 | 
			
		||||
	WordList &wlCompilerDirectives = *wlKeywords[1];		// Compiler Directives
 | 
			
		||||
	WordList &wlRuntimeExpressions = *wlKeywords[2];		// Runtime Expressions
 | 
			
		||||
	WordList &wlBuiltInProcsFuncs = *wlKeywords[3];			// Builtin Procedures and Functions
 | 
			
		||||
	WordList &wlStructsDataTypes = *wlKeywords[4];			// Structures and Data Types
 | 
			
		||||
	WordList &wlAttributes = *wlKeywords[5];				// Procedure Attributes
 | 
			
		||||
	WordList &wlStandardEquates = *wlKeywords[6];			// Standard Equates
 | 
			
		||||
	WordList &wlLabelReservedWords = *wlKeywords[7];		// Clarion Reserved Keywords (Labels)
 | 
			
		||||
	WordList &wlProcLabelReservedWords = *wlKeywords[8];	// Clarion Reserved Keywords (Procedure Labels)
 | 
			
		||||
 | 
			
		||||
	const char wlProcReservedKeywordList[] =
 | 
			
		||||
	"PROCEDURE FUNCTION";
 | 
			
		||||
	WordList wlProcReservedKeywords;
 | 
			
		||||
	wlProcReservedKeywords.Set(wlProcReservedKeywordList);
 | 
			
		||||
 | 
			
		||||
	const char wlCompilerKeywordList[] =
 | 
			
		||||
	"COMPILE OMIT";
 | 
			
		||||
	WordList wlCompilerKeywords;
 | 
			
		||||
	wlCompilerKeywords.Set(wlCompilerKeywordList);
 | 
			
		||||
 | 
			
		||||
	const char wlLegacyStatementsList[] =
 | 
			
		||||
	"BOF EOF FUNCTION POINTER SHARE";
 | 
			
		||||
	WordList wlLegacyStatements;
 | 
			
		||||
	wlLegacyStatements.Set(wlLegacyStatementsList);
 | 
			
		||||
 | 
			
		||||
	StyleContext scDoc(uiStartPos, iLength, iInitStyle, accStyler);
 | 
			
		||||
 | 
			
		||||
	// lex source code
 | 
			
		||||
    for (; scDoc.More(); scDoc.Forward())
 | 
			
		||||
	{
 | 
			
		||||
		//
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		//
 | 
			
		||||
 | 
			
		||||
		// Label State Handling
 | 
			
		||||
		if (scDoc.state == SCE_CLW_LABEL) {
 | 
			
		||||
			// If the character is not a valid label
 | 
			
		||||
			if (!IsALabelCharacter(scDoc.ch)) {
 | 
			
		||||
				// If the character is a . (dot syntax)
 | 
			
		||||
				if (scDoc.ch == '.') {
 | 
			
		||||
					// Turn off column 1 label flag as label now cannot be reserved work
 | 
			
		||||
					iColumn1Label = false;
 | 
			
		||||
					// Uncolour the . (dot) to default state, move forward one character,
 | 
			
		||||
					// and change back to the label state.
 | 
			
		||||
					scDoc.SetState(SCE_CLW_DEFAULT);
 | 
			
		||||
					scDoc.Forward();
 | 
			
		||||
					scDoc.SetState(SCE_CLW_LABEL);
 | 
			
		||||
				}
 | 
			
		||||
				// Else check label
 | 
			
		||||
				else {
 | 
			
		||||
					char cLabel[512];		// Label buffer
 | 
			
		||||
					// Buffer the current label string
 | 
			
		||||
					scDoc.GetCurrent(cLabel,sizeof(cLabel));
 | 
			
		||||
					// If case insensitive, convert string to UPPERCASE to match passed keywords.
 | 
			
		||||
					if (!bCaseSensitive) {
 | 
			
		||||
						StringUpper(cLabel);
 | 
			
		||||
					}
 | 
			
		||||
					// Else if UPPERCASE label string is in the Clarion compiler keyword list
 | 
			
		||||
					if (wlCompilerKeywords.InList(cLabel) && iColumn1Label){
 | 
			
		||||
						// change the label to error state
 | 
			
		||||
						scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
 | 
			
		||||
					}
 | 
			
		||||
					// Else if UPPERCASE label string is in the Clarion reserved keyword list
 | 
			
		||||
					else if (wlLabelReservedWords.InList(cLabel) && iColumn1Label){
 | 
			
		||||
						// change the label to error state
 | 
			
		||||
						scDoc.ChangeState(SCE_CLW_ERROR);
 | 
			
		||||
					}
 | 
			
		||||
					// Else if UPPERCASE label string is
 | 
			
		||||
					else if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) {
 | 
			
		||||
						char cWord[512];	// Word buffer
 | 
			
		||||
						// Get the next word from the current position
 | 
			
		||||
						if (GetNextWordUpper(accStyler,scDoc.currentPos,uiStartPos+iLength,cWord)) {
 | 
			
		||||
							// If the next word is a procedure reserved word
 | 
			
		||||
							if (wlProcReservedKeywords.InList(cWord)) {
 | 
			
		||||
								// Change the label to error state
 | 
			
		||||
								scDoc.ChangeState(SCE_CLW_ERROR);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					// Else if label string is in the compiler directive keyword list
 | 
			
		||||
					else if (wlCompilerDirectives.InList(cLabel)) {
 | 
			
		||||
						// change the state to compiler directive state
 | 
			
		||||
						scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
 | 
			
		||||
					}
 | 
			
		||||
					// Terminate the label state and set to default state
 | 
			
		||||
					scDoc.SetState(SCE_CLW_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// Keyword State Handling
 | 
			
		||||
		else if (scDoc.state == SCE_CLW_KEYWORD) {
 | 
			
		||||
			// If character is : (colon)
 | 
			
		||||
			if (scDoc.ch == ':') {
 | 
			
		||||
				char cEquate[512];		// Equate buffer
 | 
			
		||||
				// Move forward to include : (colon) in buffer
 | 
			
		||||
				scDoc.Forward();
 | 
			
		||||
				// Buffer the equate string
 | 
			
		||||
				scDoc.GetCurrent(cEquate,sizeof(cEquate));
 | 
			
		||||
				// If case insensitive, convert string to UPPERCASE to match passed keywords.
 | 
			
		||||
				if (!bCaseSensitive) {
 | 
			
		||||
					StringUpper(cEquate);
 | 
			
		||||
				}
 | 
			
		||||
				// If statement string is in the equate list
 | 
			
		||||
				if (wlStandardEquates.InList(cEquate)) {
 | 
			
		||||
					// Change to equate state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// If the character is not a valid label character
 | 
			
		||||
			else if (!IsALabelCharacter(scDoc.ch)) {
 | 
			
		||||
				char cStatement[512];		// Statement buffer
 | 
			
		||||
				// Buffer the statement string
 | 
			
		||||
				scDoc.GetCurrent(cStatement,sizeof(cStatement));
 | 
			
		||||
				// If case insensitive, convert string to UPPERCASE to match passed keywords.
 | 
			
		||||
				if (!bCaseSensitive) {
 | 
			
		||||
					StringUpper(cStatement);
 | 
			
		||||
				}
 | 
			
		||||
				// If statement string is in the Clarion keyword list
 | 
			
		||||
				if (wlClarionKeywords.InList(cStatement)) {
 | 
			
		||||
					// Change the statement string to the Clarion keyword state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_KEYWORD);
 | 
			
		||||
				}
 | 
			
		||||
				// Else if statement string is in the compiler directive keyword list
 | 
			
		||||
				else if (wlCompilerDirectives.InList(cStatement)) {
 | 
			
		||||
					// Change the statement string to the compiler directive state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
 | 
			
		||||
				}
 | 
			
		||||
				// Else if statement string is in the runtime expressions keyword list
 | 
			
		||||
				else if (wlRuntimeExpressions.InList(cStatement)) {
 | 
			
		||||
					// Change the statement string to the runtime expressions state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_RUNTIME_EXPRESSIONS);
 | 
			
		||||
				}
 | 
			
		||||
				// Else if statement string is in the builtin procedures and functions keyword list
 | 
			
		||||
				else if (wlBuiltInProcsFuncs.InList(cStatement)) {
 | 
			
		||||
					// Change the statement string to the builtin procedures and functions state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_BUILTIN_PROCEDURES_FUNCTION);
 | 
			
		||||
				}
 | 
			
		||||
				// Else if statement string is in the tructures and data types keyword list
 | 
			
		||||
				else if (wlStructsDataTypes.InList(cStatement)) {
 | 
			
		||||
					// Change the statement string to the structures and data types state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_STRUCTURE_DATA_TYPE);
 | 
			
		||||
				}
 | 
			
		||||
				// Else if statement string is in the procedure attribute keyword list
 | 
			
		||||
				else if (wlAttributes.InList(cStatement)) {
 | 
			
		||||
					// Change the statement string to the procedure attribute state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_ATTRIBUTE);
 | 
			
		||||
				}
 | 
			
		||||
				// Else if statement string is in the standard equate keyword list
 | 
			
		||||
				else if (wlStandardEquates.InList(cStatement)) {
 | 
			
		||||
					// Change the statement string to the standard equate state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
 | 
			
		||||
				}
 | 
			
		||||
				// Else if statement string is in the deprecated or legacy keyword list
 | 
			
		||||
				else if (wlLegacyStatements.InList(cStatement)) {
 | 
			
		||||
					// Change the statement string to the standard equate state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_DEPRECATED);
 | 
			
		||||
				}
 | 
			
		||||
				// Else the statement string doesn't match any work list
 | 
			
		||||
				else {
 | 
			
		||||
					// Change the statement string to the default state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				// Terminate the keyword state and set to default state
 | 
			
		||||
				scDoc.SetState(SCE_CLW_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// String State Handling
 | 
			
		||||
		else if (scDoc.state == SCE_CLW_STRING) {
 | 
			
		||||
			// If the character is an ' (single quote)
 | 
			
		||||
			if (scDoc.ch == '\'') {
 | 
			
		||||
				// Set the state to default and move forward colouring
 | 
			
		||||
				// the ' (single quote) as default state
 | 
			
		||||
				// terminating the string state
 | 
			
		||||
				scDoc.SetState(SCE_CLW_DEFAULT);
 | 
			
		||||
				scDoc.Forward();
 | 
			
		||||
			}
 | 
			
		||||
			// If the next character is an ' (single quote)
 | 
			
		||||
			if (scDoc.chNext == '\'') {
 | 
			
		||||
				// Move forward one character and set to default state
 | 
			
		||||
				// colouring the next ' (single quote) as default state
 | 
			
		||||
				// terminating the string state
 | 
			
		||||
				scDoc.ForwardSetState(SCE_CLW_DEFAULT);
 | 
			
		||||
				scDoc.Forward();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// Picture String State Handling
 | 
			
		||||
		else if (scDoc.state == SCE_CLW_PICTURE_STRING) {
 | 
			
		||||
			// If the character is an ( (open parenthese)
 | 
			
		||||
			if (scDoc.ch == '(') {
 | 
			
		||||
				// Increment the parenthese level
 | 
			
		||||
				iParenthesesLevel++;
 | 
			
		||||
			}
 | 
			
		||||
			// Else if the character is a ) (close parenthese)
 | 
			
		||||
			else if (scDoc.ch == ')') {
 | 
			
		||||
				// If the parenthese level is set to zero
 | 
			
		||||
				// parentheses matched
 | 
			
		||||
				if (!iParenthesesLevel) {
 | 
			
		||||
					scDoc.SetState(SCE_CLW_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				// Else parenthese level is greater than zero
 | 
			
		||||
				// still looking for matching parentheses
 | 
			
		||||
				else {
 | 
			
		||||
					// Decrement the parenthese level
 | 
			
		||||
					iParenthesesLevel--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// Standard Equate State Handling
 | 
			
		||||
		else if (scDoc.state == SCE_CLW_STANDARD_EQUATE) {
 | 
			
		||||
			if (!isalnum(scDoc.ch)) {
 | 
			
		||||
				scDoc.SetState(SCE_CLW_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// Integer Constant State Handling
 | 
			
		||||
		else if (scDoc.state == SCE_CLW_INTEGER_CONSTANT) {
 | 
			
		||||
			// If the character is not a digit (0-9)
 | 
			
		||||
			// or character is not a hexidecimal character (A-F)
 | 
			
		||||
			// or character is not a . (point)
 | 
			
		||||
			// or character is not a numberic base character (B,O,H)
 | 
			
		||||
			if (!(isdigit(scDoc.ch)
 | 
			
		||||
			|| IsAHexCharacter(scDoc.ch, bCaseSensitive)
 | 
			
		||||
			|| scDoc.ch == '.'
 | 
			
		||||
			|| IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) {
 | 
			
		||||
				// If the number was a real
 | 
			
		||||
				if (SetNumericConstantState(scDoc)) {
 | 
			
		||||
					// Colour the matched string to the real constant state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_REAL_CONSTANT);
 | 
			
		||||
				}
 | 
			
		||||
				// Else the number was an integer
 | 
			
		||||
				else {
 | 
			
		||||
					// Colour the matched string to an integer constant state
 | 
			
		||||
					scDoc.ChangeState(SCE_CLW_INTEGER_CONSTANT);
 | 
			
		||||
				}
 | 
			
		||||
				// Terminate the integer constant state and set to default state
 | 
			
		||||
				scDoc.SetState(SCE_CLW_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		//
 | 
			
		||||
 | 
			
		||||
		// Beginning of Line Handling
 | 
			
		||||
		if (scDoc.atLineStart) {
 | 
			
		||||
			// Reset the column 1 label flag
 | 
			
		||||
			iColumn1Label = false;
 | 
			
		||||
			// If column 1 character is a label start character
 | 
			
		||||
			if (IsALabelStart(scDoc.ch)) {
 | 
			
		||||
				// Label character is found in column 1
 | 
			
		||||
				// so set column 1 label flag and clear last column 1 label
 | 
			
		||||
				iColumn1Label = true;
 | 
			
		||||
				// Set the state to label
 | 
			
		||||
				scDoc.SetState(SCE_CLW_LABEL);
 | 
			
		||||
			}
 | 
			
		||||
			// else if character is a space or tab
 | 
			
		||||
			else if (IsASpace(scDoc.ch)){
 | 
			
		||||
				// Set to default state
 | 
			
		||||
				scDoc.SetState(SCE_CLW_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			// else if comment start (!) or is an * (asterisk)
 | 
			
		||||
			else if (IsACommentStart(scDoc.ch) || scDoc.ch == '*' ) {
 | 
			
		||||
				// then set the state to comment.
 | 
			
		||||
				scDoc.SetState(SCE_CLW_COMMENT);
 | 
			
		||||
			}
 | 
			
		||||
			// else the character is a ? (question mark)
 | 
			
		||||
			else if (scDoc.ch == '?') {
 | 
			
		||||
				// Change to the compiler directive state, move forward,
 | 
			
		||||
				// colouring the ? (question mark), change back to default state.
 | 
			
		||||
				scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
 | 
			
		||||
				scDoc.Forward();
 | 
			
		||||
				scDoc.SetState(SCE_CLW_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			// else an invalid character in column 1
 | 
			
		||||
			else {
 | 
			
		||||
				// Set to error state
 | 
			
		||||
				scDoc.SetState(SCE_CLW_ERROR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// End of Line Handling
 | 
			
		||||
		else if (scDoc.atLineEnd) {
 | 
			
		||||
			// Reset to the default state at the end of each line.
 | 
			
		||||
			scDoc.SetState(SCE_CLW_DEFAULT);
 | 
			
		||||
		}
 | 
			
		||||
		// Default Handling
 | 
			
		||||
		else {
 | 
			
		||||
			// If in default state
 | 
			
		||||
			if (scDoc.state == SCE_CLW_DEFAULT) {
 | 
			
		||||
				// If is a letter could be a possible statement
 | 
			
		||||
				if (isalpha(scDoc.ch)) {
 | 
			
		||||
					// Set the state to Clarion Keyword and verify later
 | 
			
		||||
					scDoc.SetState(SCE_CLW_KEYWORD);
 | 
			
		||||
				}
 | 
			
		||||
				// else is a number
 | 
			
		||||
				else if (isdigit(scDoc.ch)) {
 | 
			
		||||
					// Set the state to Integer Constant and verify later
 | 
			
		||||
					scDoc.SetState(SCE_CLW_INTEGER_CONSTANT);
 | 
			
		||||
				}
 | 
			
		||||
				// else if the start of a comment or a | (line continuation)
 | 
			
		||||
				else if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') {
 | 
			
		||||
					// then set the state to comment.
 | 
			
		||||
					scDoc.SetState(SCE_CLW_COMMENT);
 | 
			
		||||
				}
 | 
			
		||||
				// else if the character is a ' (single quote)
 | 
			
		||||
				else if (scDoc.ch == '\'') {
 | 
			
		||||
					// If the character is also a ' (single quote)
 | 
			
		||||
					// Embedded Apostrophe
 | 
			
		||||
					if (scDoc.chNext == '\'') {
 | 
			
		||||
						// Move forward colouring it as default state
 | 
			
		||||
						scDoc.ForwardSetState(SCE_CLW_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						// move to the next character and then set the state to comment.
 | 
			
		||||
						scDoc.ForwardSetState(SCE_CLW_STRING);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				// else the character is an @ (ampersand)
 | 
			
		||||
				else if (scDoc.ch == '@') {
 | 
			
		||||
					// Case insensitive.
 | 
			
		||||
					if (!bCaseSensitive) {
 | 
			
		||||
						// If character is a valid picture token character
 | 
			
		||||
						if (strchr("DEKNPSTdeknpst", scDoc.chNext) != NULL) {
 | 
			
		||||
							// Set to the picture string state
 | 
			
		||||
							scDoc.SetState(SCE_CLW_PICTURE_STRING);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					// Case sensitive
 | 
			
		||||
					else {
 | 
			
		||||
						// If character is a valid picture token character
 | 
			
		||||
						if (strchr("DEKNPST", scDoc.chNext) != NULL) {
 | 
			
		||||
							// Set the picture string state
 | 
			
		||||
							scDoc.SetState(SCE_CLW_PICTURE_STRING);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// lexing complete
 | 
			
		||||
	scDoc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Clarion Language Case Sensitive Colouring Procedure
 | 
			
		||||
static void ColouriseClarionDocSensitive(Sci_PositionU uiStartPos, Sci_Position iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
 | 
			
		||||
 | 
			
		||||
	ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Clarion Language Case Insensitive Colouring Procedure
 | 
			
		||||
static void ColouriseClarionDocInsensitive(Sci_PositionU uiStartPos, Sci_Position iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
 | 
			
		||||
 | 
			
		||||
	ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fill Buffer
 | 
			
		||||
 | 
			
		||||
static void FillBuffer(Sci_PositionU uiStart, Sci_PositionU uiEnd, Accessor &accStyler, char *szBuffer, Sci_PositionU uiLength) {
 | 
			
		||||
 | 
			
		||||
	Sci_PositionU uiPos = 0;
 | 
			
		||||
 | 
			
		||||
	while ((uiPos < uiEnd - uiStart + 1) && (uiPos < uiLength-1)) {
 | 
			
		||||
		szBuffer[uiPos] = static_cast<char>(toupper(accStyler[uiStart + uiPos]));
 | 
			
		||||
		uiPos++;
 | 
			
		||||
	}
 | 
			
		||||
	szBuffer[uiPos] = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Classify Clarion Fold Point
 | 
			
		||||
 | 
			
		||||
static int ClassifyClarionFoldPoint(int iLevel, const char* szString) {
 | 
			
		||||
 | 
			
		||||
	if (!(isdigit(szString[0]) || (szString[0] == '.'))) {
 | 
			
		||||
		if (strcmp(szString, "PROCEDURE") == 0) {
 | 
			
		||||
	//		iLevel = SC_FOLDLEVELBASE + 1;
 | 
			
		||||
		}
 | 
			
		||||
		else if (strcmp(szString, "MAP") == 0 ||
 | 
			
		||||
			strcmp(szString,"ACCEPT") == 0 ||
 | 
			
		||||
			strcmp(szString,"BEGIN") == 0 ||
 | 
			
		||||
			strcmp(szString,"CASE") == 0 ||
 | 
			
		||||
			strcmp(szString,"EXECUTE") == 0 ||
 | 
			
		||||
			strcmp(szString,"IF") == 0 ||
 | 
			
		||||
			strcmp(szString,"ITEMIZE") == 0 ||
 | 
			
		||||
			strcmp(szString,"INTERFACE") == 0 ||
 | 
			
		||||
			strcmp(szString,"JOIN") == 0 ||
 | 
			
		||||
			strcmp(szString,"LOOP") == 0 ||
 | 
			
		||||
			strcmp(szString,"MODULE") == 0 ||
 | 
			
		||||
			strcmp(szString,"RECORD") == 0) {
 | 
			
		||||
			iLevel++;
 | 
			
		||||
		}
 | 
			
		||||
		else if (strcmp(szString, "APPLICATION") == 0 ||
 | 
			
		||||
			strcmp(szString, "CLASS") == 0 ||
 | 
			
		||||
			strcmp(szString, "DETAIL") == 0 ||
 | 
			
		||||
			strcmp(szString, "FILE") == 0 ||
 | 
			
		||||
			strcmp(szString, "FOOTER") == 0 ||
 | 
			
		||||
			strcmp(szString, "FORM") == 0 ||
 | 
			
		||||
			strcmp(szString, "GROUP") == 0 ||
 | 
			
		||||
			strcmp(szString, "HEADER") == 0 ||
 | 
			
		||||
			strcmp(szString, "INTERFACE") == 0 ||
 | 
			
		||||
			strcmp(szString, "MENU") == 0 ||
 | 
			
		||||
			strcmp(szString, "MENUBAR") == 0 ||
 | 
			
		||||
			strcmp(szString, "OLE") == 0 ||
 | 
			
		||||
			strcmp(szString, "OPTION") == 0 ||
 | 
			
		||||
			strcmp(szString, "QUEUE") == 0 ||
 | 
			
		||||
			strcmp(szString, "REPORT") == 0 ||
 | 
			
		||||
			strcmp(szString, "SHEET") == 0 ||
 | 
			
		||||
			strcmp(szString, "TAB") == 0 ||
 | 
			
		||||
			strcmp(szString, "TOOLBAR") == 0 ||
 | 
			
		||||
			strcmp(szString, "VIEW") == 0 ||
 | 
			
		||||
			strcmp(szString, "WINDOW") == 0) {
 | 
			
		||||
			iLevel++;
 | 
			
		||||
		}
 | 
			
		||||
		else if (strcmp(szString, "END") == 0 ||
 | 
			
		||||
			strcmp(szString, "UNTIL") == 0 ||
 | 
			
		||||
			strcmp(szString, "WHILE") == 0) {
 | 
			
		||||
			iLevel--;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return(iLevel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Clarion Language Folding Procedure
 | 
			
		||||
static void FoldClarionDoc(Sci_PositionU uiStartPos, Sci_Position iLength, int iInitStyle, WordList *[], Accessor &accStyler) {
 | 
			
		||||
 | 
			
		||||
	Sci_PositionU uiEndPos = uiStartPos + iLength;
 | 
			
		||||
	Sci_Position iLineCurrent = accStyler.GetLine(uiStartPos);
 | 
			
		||||
	int iLevelPrev = accStyler.LevelAt(iLineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int iLevelCurrent = iLevelPrev;
 | 
			
		||||
	char chNext = accStyler[uiStartPos];
 | 
			
		||||
	int iStyle = iInitStyle;
 | 
			
		||||
	int iStyleNext = accStyler.StyleAt(uiStartPos);
 | 
			
		||||
	int iVisibleChars = 0;
 | 
			
		||||
	Sci_Position iLastStart = 0;
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU uiPos = uiStartPos; uiPos < uiEndPos; uiPos++) {
 | 
			
		||||
 | 
			
		||||
		char chChar = chNext;
 | 
			
		||||
		chNext = accStyler.SafeGetCharAt(uiPos + 1);
 | 
			
		||||
		int iStylePrev = iStyle;
 | 
			
		||||
		iStyle = iStyleNext;
 | 
			
		||||
		iStyleNext = accStyler.StyleAt(uiPos + 1);
 | 
			
		||||
		bool bEOL = (chChar == '\r' && chNext != '\n') || (chChar == '\n');
 | 
			
		||||
 | 
			
		||||
		if (iStylePrev == SCE_CLW_DEFAULT) {
 | 
			
		||||
			if (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) {
 | 
			
		||||
				// Store last word start point.
 | 
			
		||||
				iLastStart = uiPos;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (iStylePrev == SCE_CLW_KEYWORD || iStylePrev == SCE_CLW_STRUCTURE_DATA_TYPE) {
 | 
			
		||||
			if(iswordchar(chChar) && !iswordchar(chNext)) {
 | 
			
		||||
				char chBuffer[100];
 | 
			
		||||
				FillBuffer(iLastStart, uiPos, accStyler, chBuffer, sizeof(chBuffer));
 | 
			
		||||
				iLevelCurrent = ClassifyClarionFoldPoint(iLevelCurrent,chBuffer);
 | 
			
		||||
			//	if ((iLevelCurrent == SC_FOLDLEVELBASE + 1) && iLineCurrent > 1) {
 | 
			
		||||
			//		accStyler.SetLevel(iLineCurrent-1,SC_FOLDLEVELBASE);
 | 
			
		||||
			//		iLevelPrev = SC_FOLDLEVELBASE;
 | 
			
		||||
			//	}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (bEOL) {
 | 
			
		||||
			int iLevel = iLevelPrev;
 | 
			
		||||
			if ((iLevelCurrent > iLevelPrev) && (iVisibleChars > 0))
 | 
			
		||||
				iLevel |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (iLevel != accStyler.LevelAt(iLineCurrent)) {
 | 
			
		||||
				accStyler.SetLevel(iLineCurrent,iLevel);
 | 
			
		||||
			}
 | 
			
		||||
			iLineCurrent++;
 | 
			
		||||
			iLevelPrev = iLevelCurrent;
 | 
			
		||||
			iVisibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!isspacechar(chChar))
 | 
			
		||||
			iVisibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags
 | 
			
		||||
	// as they will be filled in later.
 | 
			
		||||
	int iFlagsNext = accStyler.LevelAt(iLineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	accStyler.SetLevel(iLineCurrent, iLevelPrev | iFlagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Word List Descriptions
 | 
			
		||||
static const char * const rgWordListDescriptions[] = {
 | 
			
		||||
	"Clarion Keywords",
 | 
			
		||||
	"Compiler Directives",
 | 
			
		||||
	"Built-in Procedures and Functions",
 | 
			
		||||
	"Runtime Expressions",
 | 
			
		||||
	"Structure and Data Types",
 | 
			
		||||
	"Attributes",
 | 
			
		||||
	"Standard Equates",
 | 
			
		||||
	"Reserved Words (Labels)",
 | 
			
		||||
	"Reserved Words (Procedure Labels)",
 | 
			
		||||
	0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Case Sensitive Clarion Language Lexer
 | 
			
		||||
extern const LexerModule lmClw(SCLEX_CLW, ColouriseClarionDocSensitive, "clarion", FoldClarionDoc, rgWordListDescriptions);
 | 
			
		||||
 | 
			
		||||
// Case Insensitive Clarion Language Lexer
 | 
			
		||||
extern const LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClarionDocInsensitive, "clarionnocase", FoldClarionDoc, rgWordListDescriptions);
 | 
			
		||||
							
								
								
									
										387
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCOBOL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										387
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCOBOL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,387 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexCOBOL.cxx
 | 
			
		||||
 ** Lexer for COBOL
 | 
			
		||||
 ** Based on LexPascal.cxx
 | 
			
		||||
 ** Written by Laurent le Tynevez
 | 
			
		||||
 ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
 | 
			
		||||
 ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
 | 
			
		||||
 ** Updated by Rod Falck, Aug 2006 Converted to COBOL
 | 
			
		||||
 **/
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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;
 | 
			
		||||
 | 
			
		||||
#define IN_DIVISION 0x01
 | 
			
		||||
#define IN_DECLARATIVES 0x02
 | 
			
		||||
#define IN_SECTION 0x04
 | 
			
		||||
#define IN_PARAGRAPH 0x08
 | 
			
		||||
#define IN_FLAGS 0xF
 | 
			
		||||
#define NOT_HEADER 0x10
 | 
			
		||||
 | 
			
		||||
inline bool isCOBOLoperator(char ch)
 | 
			
		||||
    {
 | 
			
		||||
    return isoperator(ch);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
inline bool isCOBOLwordchar(char ch)
 | 
			
		||||
    {
 | 
			
		||||
    return IsASCII(ch) && (isalnum(ch) || ch == '-');
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
inline bool isCOBOLwordstart(char ch)
 | 
			
		||||
    {
 | 
			
		||||
    return IsASCII(ch) && isalnum(ch);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
static int CountBits(int nBits)
 | 
			
		||||
    {
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    for (int i = 0; i < 32; ++i)
 | 
			
		||||
        {
 | 
			
		||||
        count += nBits & 1;
 | 
			
		||||
        nBits >>= 1;
 | 
			
		||||
        }
 | 
			
		||||
    return count;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
static void getRange(Sci_PositionU start,
 | 
			
		||||
        Sci_PositionU end,
 | 
			
		||||
        Accessor &styler,
 | 
			
		||||
        char *s,
 | 
			
		||||
        Sci_PositionU len) {
 | 
			
		||||
    Sci_PositionU i = 0;
 | 
			
		||||
    while ((i < end - start + 1) && (i < len-1)) {
 | 
			
		||||
        s[i] = static_cast<char>(tolower(styler[start + i]));
 | 
			
		||||
        i++;
 | 
			
		||||
    }
 | 
			
		||||
    s[i] = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColourTo(Accessor &styler, Sci_PositionU end, unsigned int attr) {
 | 
			
		||||
    styler.ColourTo(end, attr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int classifyWordCOBOL(Sci_PositionU start, Sci_PositionU end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) {
 | 
			
		||||
    int ret = 0;
 | 
			
		||||
 | 
			
		||||
    char s[100];
 | 
			
		||||
    s[0] = '\0';
 | 
			
		||||
    s[1] = '\0';
 | 
			
		||||
    getRange(start, end, styler, s, sizeof(s));
 | 
			
		||||
 | 
			
		||||
    int chAttr = SCE_C_IDENTIFIER;
 | 
			
		||||
    if (isdigit(s[0]) || (s[0] == '.') || (s[0] == 'v')) {
 | 
			
		||||
        chAttr = SCE_C_NUMBER;
 | 
			
		||||
        char *p = s + 1;
 | 
			
		||||
        while (*p) {
 | 
			
		||||
            if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) {
 | 
			
		||||
                chAttr = SCE_C_IDENTIFIER;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            ++p;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (chAttr == SCE_C_IDENTIFIER) {
 | 
			
		||||
        WordList& a_keywords = *keywordlists[0];
 | 
			
		||||
        WordList& b_keywords = *keywordlists[1];
 | 
			
		||||
        WordList& c_keywords = *keywordlists[2];
 | 
			
		||||
 | 
			
		||||
        if (a_keywords.InList(s)) {
 | 
			
		||||
            chAttr = SCE_C_WORD;
 | 
			
		||||
        }
 | 
			
		||||
        else if (b_keywords.InList(s)) {
 | 
			
		||||
            chAttr = SCE_C_WORD2;
 | 
			
		||||
        }
 | 
			
		||||
        else if (c_keywords.InList(s)) {
 | 
			
		||||
            chAttr = SCE_C_UUID;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (*bAarea) {
 | 
			
		||||
        if (strcmp(s, "division") == 0) {
 | 
			
		||||
            ret = IN_DIVISION;
 | 
			
		||||
            // we've determined the containment, anything else is just ignored for those purposes
 | 
			
		||||
            *bAarea = false;
 | 
			
		||||
        } else if (strcmp(s, "declaratives") == 0) {
 | 
			
		||||
            ret = IN_DIVISION | IN_DECLARATIVES;
 | 
			
		||||
            if (nContainment & IN_DECLARATIVES)
 | 
			
		||||
                ret |= NOT_HEADER | IN_SECTION;
 | 
			
		||||
            // we've determined the containment, anything else is just ignored for those purposes
 | 
			
		||||
            *bAarea = false;
 | 
			
		||||
        } else if (strcmp(s, "section") == 0) {
 | 
			
		||||
            ret = (nContainment &~ IN_PARAGRAPH) | IN_SECTION;
 | 
			
		||||
            // we've determined the containment, anything else is just ignored for those purposes
 | 
			
		||||
            *bAarea = false;
 | 
			
		||||
        } else if (strcmp(s, "end") == 0 && (nContainment & IN_DECLARATIVES)) {
 | 
			
		||||
            ret = IN_DIVISION | IN_DECLARATIVES | IN_SECTION | NOT_HEADER;
 | 
			
		||||
        } else {
 | 
			
		||||
            ret = nContainment | IN_PARAGRAPH;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    ColourTo(styler, end, chAttr);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
    Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
    styler.StartAt(startPos);
 | 
			
		||||
 | 
			
		||||
    int state = initStyle;
 | 
			
		||||
    if (state == SCE_C_CHARACTER)   // Does not leak onto next line
 | 
			
		||||
        state = SCE_C_DEFAULT;
 | 
			
		||||
    char chPrev = ' ';
 | 
			
		||||
    char chNext = styler[startPos];
 | 
			
		||||
    Sci_PositionU lengthDoc = startPos + length;
 | 
			
		||||
 | 
			
		||||
    int nContainment;
 | 
			
		||||
 | 
			
		||||
    Sci_Position currentLine = styler.GetLine(startPos);
 | 
			
		||||
    if (currentLine > 0) {
 | 
			
		||||
        styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
 | 
			
		||||
        nContainment = styler.GetLineState(currentLine);
 | 
			
		||||
        nContainment &= ~NOT_HEADER;
 | 
			
		||||
    } else {
 | 
			
		||||
        styler.SetLineState(currentLine, 0);
 | 
			
		||||
        nContainment = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    styler.StartSegment(startPos);
 | 
			
		||||
    bool bNewLine = true;
 | 
			
		||||
    bool bAarea = !isspacechar(chNext);
 | 
			
		||||
    int column = 0;
 | 
			
		||||
    for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
        char ch = chNext;
 | 
			
		||||
 | 
			
		||||
        chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
        ++column;
 | 
			
		||||
 | 
			
		||||
        if (bNewLine) {
 | 
			
		||||
            column = 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (column <= 1 && !bAarea) {
 | 
			
		||||
            bAarea = !isspacechar(ch);
 | 
			
		||||
        }
 | 
			
		||||
        bool bSetNewLine = false;
 | 
			
		||||
        if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
 | 
			
		||||
            // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
 | 
			
		||||
            // Avoid triggering two times on Dos/Win
 | 
			
		||||
            // End of line
 | 
			
		||||
            if (state == SCE_C_CHARACTER) {
 | 
			
		||||
                ColourTo(styler, i, state);
 | 
			
		||||
                state = SCE_C_DEFAULT;
 | 
			
		||||
            }
 | 
			
		||||
            styler.SetLineState(currentLine, nContainment);
 | 
			
		||||
            currentLine++;
 | 
			
		||||
            bSetNewLine = true;
 | 
			
		||||
            if (nContainment & NOT_HEADER)
 | 
			
		||||
                nContainment &= ~(NOT_HEADER | IN_DECLARATIVES | IN_SECTION);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (styler.IsLeadByte(ch)) {
 | 
			
		||||
            chNext = styler.SafeGetCharAt(i + 2);
 | 
			
		||||
            chPrev = ' ';
 | 
			
		||||
            i += 1;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (state == SCE_C_DEFAULT) {
 | 
			
		||||
            if (isCOBOLwordstart(ch) || (ch == '$' && IsASCII(chNext) && isalpha(chNext))) {
 | 
			
		||||
                ColourTo(styler, i-1, state);
 | 
			
		||||
                state = SCE_C_IDENTIFIER;
 | 
			
		||||
            } else if (column == 6 && (ch == '*' || ch == '/')) {
 | 
			
		||||
            // Cobol comment line: asterisk in column 7.
 | 
			
		||||
                ColourTo(styler, i-1, state);
 | 
			
		||||
                state = SCE_C_COMMENTLINE;
 | 
			
		||||
            } else if (ch == '*' && chNext == '>') {
 | 
			
		||||
            // Cobol inline comment: asterisk, followed by greater than.
 | 
			
		||||
                ColourTo(styler, i-1, state);
 | 
			
		||||
                state = SCE_C_COMMENTLINE;
 | 
			
		||||
            } else if (column == 0 && ch == '*' && chNext != '*') {
 | 
			
		||||
                ColourTo(styler, i-1, state);
 | 
			
		||||
                state = SCE_C_COMMENTLINE;
 | 
			
		||||
            } else if (column == 0 && ch == '/' && chNext != '*') {
 | 
			
		||||
                ColourTo(styler, i-1, state);
 | 
			
		||||
                state = SCE_C_COMMENTLINE;
 | 
			
		||||
            } else if (column == 0 && ch == '*' && chNext == '*') {
 | 
			
		||||
                ColourTo(styler, i-1, state);
 | 
			
		||||
                state = SCE_C_COMMENTDOC;
 | 
			
		||||
            } else if (column == 0 && ch == '/' && chNext == '*') {
 | 
			
		||||
                ColourTo(styler, i-1, state);
 | 
			
		||||
                state = SCE_C_COMMENTDOC;
 | 
			
		||||
            } else if (ch == '"') {
 | 
			
		||||
                ColourTo(styler, i-1, state);
 | 
			
		||||
                state = SCE_C_STRING;
 | 
			
		||||
            } else if (ch == '\'') {
 | 
			
		||||
                ColourTo(styler, i-1, state);
 | 
			
		||||
                state = SCE_C_CHARACTER;
 | 
			
		||||
            } else if (ch == '?' && column == 0) {
 | 
			
		||||
                ColourTo(styler, i-1, state);
 | 
			
		||||
                state = SCE_C_PREPROCESSOR;
 | 
			
		||||
            } else if (isCOBOLoperator(ch)) {
 | 
			
		||||
                ColourTo(styler, i-1, state);
 | 
			
		||||
                ColourTo(styler, i, SCE_C_OPERATOR);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (state == SCE_C_IDENTIFIER) {
 | 
			
		||||
            if (!isCOBOLwordchar(ch)) {
 | 
			
		||||
                int lStateChange = classifyWordCOBOL(styler.GetStartSegment(), i - 1, keywordlists, styler, nContainment, &bAarea);
 | 
			
		||||
 | 
			
		||||
                if(lStateChange != 0) {
 | 
			
		||||
                    styler.SetLineState(currentLine, lStateChange);
 | 
			
		||||
                    nContainment = lStateChange;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                state = SCE_C_DEFAULT;
 | 
			
		||||
                chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
                if (column == 6 && (ch == '*' || ch == '/')) {
 | 
			
		||||
                    state = SCE_C_COMMENTLINE;
 | 
			
		||||
                } else if (ch == '"') {
 | 
			
		||||
                    state = SCE_C_STRING;
 | 
			
		||||
                } else if (ch == '\'') {
 | 
			
		||||
                    state = SCE_C_CHARACTER;
 | 
			
		||||
                } else if (isCOBOLoperator(ch)) {
 | 
			
		||||
                    ColourTo(styler, i, SCE_C_OPERATOR);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if (state == SCE_C_PREPROCESSOR) {
 | 
			
		||||
                if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
 | 
			
		||||
                    ColourTo(styler, i-1, state);
 | 
			
		||||
                    state = SCE_C_DEFAULT;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (state == SCE_C_COMMENT) {
 | 
			
		||||
                if (ch == '\r' || ch == '\n') {
 | 
			
		||||
                    ColourTo(styler, i-1, state);
 | 
			
		||||
                    state = SCE_C_DEFAULT;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (state == SCE_C_COMMENTDOC) {
 | 
			
		||||
                if (ch == '\r' || ch == '\n') {
 | 
			
		||||
                    if (((i > styler.GetStartSegment() + 2) || (
 | 
			
		||||
                        (initStyle == SCE_C_COMMENTDOC) &&
 | 
			
		||||
                        (styler.GetStartSegment() == static_cast<Sci_PositionU>(startPos))))) {
 | 
			
		||||
                            ColourTo(styler, i-1, state);
 | 
			
		||||
                            state = SCE_C_DEFAULT;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else if (state == SCE_C_COMMENTLINE) {
 | 
			
		||||
                if (ch == '\r' || ch == '\n') {
 | 
			
		||||
                    ColourTo(styler, i-1, state);
 | 
			
		||||
                    state = SCE_C_DEFAULT;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (state == SCE_C_STRING) {
 | 
			
		||||
                if (ch == '"') {
 | 
			
		||||
                    ColourTo(styler, i, state);
 | 
			
		||||
                    state = SCE_C_DEFAULT;
 | 
			
		||||
                } else if (ch == '\r' || ch == '\n') {
 | 
			
		||||
                    ColourTo(styler, i-1, state);
 | 
			
		||||
                    state = SCE_C_DEFAULT;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (state == SCE_C_CHARACTER) {
 | 
			
		||||
                if (ch == '\'') {
 | 
			
		||||
                    ColourTo(styler, i, state);
 | 
			
		||||
                    state = SCE_C_DEFAULT;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        chPrev = ch;
 | 
			
		||||
        bNewLine = bSetNewLine;
 | 
			
		||||
        if (bNewLine)
 | 
			
		||||
            {
 | 
			
		||||
            bAarea = false;
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
    ColourTo(styler, lengthDoc - 1, state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
    bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
    Sci_PositionU endPos = startPos + length;
 | 
			
		||||
    int visibleChars = 0;
 | 
			
		||||
    Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
    int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK : 0xFFF;
 | 
			
		||||
    char chNext = styler[startPos];
 | 
			
		||||
 | 
			
		||||
    bool bNewLine = true;
 | 
			
		||||
    bool bAarea = !isspacechar(chNext);
 | 
			
		||||
    int column = 0;
 | 
			
		||||
    bool bComment = false;
 | 
			
		||||
    for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
        char ch = chNext;
 | 
			
		||||
        chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
        ++column;
 | 
			
		||||
 | 
			
		||||
        if (bNewLine) {
 | 
			
		||||
            column = 0;
 | 
			
		||||
            bComment = (ch == '*' || ch == '/' || ch == '?');
 | 
			
		||||
        }
 | 
			
		||||
        if (column <= 1 && !bAarea) {
 | 
			
		||||
            bAarea = !isspacechar(ch);
 | 
			
		||||
        }
 | 
			
		||||
        bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
        if (atEOL) {
 | 
			
		||||
            int nContainment = styler.GetLineState(lineCurrent);
 | 
			
		||||
            int lev = CountBits(nContainment & IN_FLAGS) | SC_FOLDLEVELBASE;
 | 
			
		||||
            if (bAarea && !bComment)
 | 
			
		||||
                --lev;
 | 
			
		||||
            if (visibleChars == 0 && foldCompact)
 | 
			
		||||
                lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
            if ((bAarea) && (visibleChars > 0) && !(nContainment & NOT_HEADER) && !bComment)
 | 
			
		||||
                lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
            if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
                styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
            }
 | 
			
		||||
            if ((lev & SC_FOLDLEVELNUMBERMASK) <= (levelPrev & SC_FOLDLEVELNUMBERMASK)) {
 | 
			
		||||
                // this level is at the same level or less than the previous line
 | 
			
		||||
                // therefore these is nothing for the previous header to collapse, so remove the header
 | 
			
		||||
                styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
 | 
			
		||||
            }
 | 
			
		||||
            levelPrev = lev;
 | 
			
		||||
            visibleChars = 0;
 | 
			
		||||
            bAarea = false;
 | 
			
		||||
            bNewLine = true;
 | 
			
		||||
            lineCurrent++;
 | 
			
		||||
        } else {
 | 
			
		||||
            bNewLine = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if (!isspacechar(ch))
 | 
			
		||||
            visibleChars++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
    int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
    styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const COBOLWordListDesc[] = {
 | 
			
		||||
    "A Keywords",
 | 
			
		||||
    "B Keywords",
 | 
			
		||||
    "Extended Keywords",
 | 
			
		||||
    0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, "COBOL", FoldCOBOLDoc, COBOLWordListDesc);
 | 
			
		||||
							
								
								
									
										1845
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCPP.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1845
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCPP.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										570
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCSS.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										570
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCSS.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,570 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
// Encoding: UTF-8
 | 
			
		||||
/** @file LexCSS.cxx
 | 
			
		||||
 ** Lexer for Cascading Style Sheets
 | 
			
		||||
 ** Written by Jakub Vrána
 | 
			
		||||
 ** Improved by Philippe Lhoste (CSS2)
 | 
			
		||||
 ** Improved by Ross McKay (SCSS mode; see http://sass-lang.com/ )
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
// TODO: handle SCSS nested properties like font: { weight: bold; size: 1em; }
 | 
			
		||||
// TODO: handle SCSS interpolation: #{}
 | 
			
		||||
// TODO: add features for Less if somebody feels like contributing; http://lesscss.org/
 | 
			
		||||
// TODO: refactor this monster so that the next poor slob can read it!
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(const unsigned int ch) {
 | 
			
		||||
	/* FIXME:
 | 
			
		||||
	 * The CSS spec allows "ISO 10646 characters U+00A1 and higher" to be treated as word chars.
 | 
			
		||||
	 * Unfortunately, we are only getting string bytes here, and not full unicode characters. We cannot guarantee
 | 
			
		||||
	 * that our byte is between U+0080 - U+00A0 (to return false), so we have to allow all characters U+0080 and higher
 | 
			
		||||
	 */
 | 
			
		||||
	return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool IsCssOperator(const int ch) {
 | 
			
		||||
	if (!((ch < 0x80) && isalnum(ch)) &&
 | 
			
		||||
		(ch == '{' || ch == '}' || ch == ':' || ch == ',' || ch == ';' ||
 | 
			
		||||
		 ch == '.' || ch == '#' || ch == '!' || ch == '@' ||
 | 
			
		||||
		 /* CSS2 */
 | 
			
		||||
		 ch == '*' || ch == '>' || ch == '+' || ch == '=' || ch == '~' || ch == '|' ||
 | 
			
		||||
		 ch == '[' || ch == ']' || ch == '(' || ch == ')')) {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// look behind (from start of document to our start position) to determine current nesting level
 | 
			
		||||
inline int NestingLevelLookBehind(Sci_PositionU startPos, Accessor &styler) {
 | 
			
		||||
	int ch;
 | 
			
		||||
	int nestingLevel = 0;
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = 0; i < startPos; i++) {
 | 
			
		||||
		ch = styler.SafeGetCharAt(i);
 | 
			
		||||
		if (ch == '{')
 | 
			
		||||
			nestingLevel++;
 | 
			
		||||
		else if (ch == '}')
 | 
			
		||||
			nestingLevel--;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nestingLevel;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseCssDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
	WordList &css1Props = *keywordlists[0];
 | 
			
		||||
	WordList &pseudoClasses = *keywordlists[1];
 | 
			
		||||
	WordList &css2Props = *keywordlists[2];
 | 
			
		||||
	WordList &css3Props = *keywordlists[3];
 | 
			
		||||
	WordList &pseudoElements = *keywordlists[4];
 | 
			
		||||
	WordList &exProps = *keywordlists[5];
 | 
			
		||||
	WordList &exPseudoClasses = *keywordlists[6];
 | 
			
		||||
	WordList &exPseudoElements = *keywordlists[7];
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	int lastState = -1; // before operator
 | 
			
		||||
	int lastStateC = -1; // before comment
 | 
			
		||||
	int lastStateS = -1; // before single-quoted/double-quoted string
 | 
			
		||||
	int lastStateVar = -1; // before variable (SCSS)
 | 
			
		||||
	int lastStateVal = -1; // before value (SCSS)
 | 
			
		||||
	int op = ' '; // last operator
 | 
			
		||||
	int opPrev = ' '; // last operator
 | 
			
		||||
	bool insideParentheses = false; // true if currently in a CSS url() or similar construct
 | 
			
		||||
 | 
			
		||||
	// property lexer.css.scss.language
 | 
			
		||||
	//	Set to 1 for Sassy CSS (.scss)
 | 
			
		||||
	bool isScssDocument = styler.GetPropertyInt("lexer.css.scss.language") != 0;
 | 
			
		||||
 | 
			
		||||
	// property lexer.css.less.language
 | 
			
		||||
	// Set to 1 for Less CSS (.less)
 | 
			
		||||
	bool isLessDocument = styler.GetPropertyInt("lexer.css.less.language") != 0;
 | 
			
		||||
 | 
			
		||||
	// property lexer.css.hss.language
 | 
			
		||||
	// Set to 1 for HSS (.hss)
 | 
			
		||||
	bool isHssDocument = styler.GetPropertyInt("lexer.css.hss.language") != 0;
 | 
			
		||||
 | 
			
		||||
	// SCSS/LESS/HSS have the concept of variable
 | 
			
		||||
	bool hasVariables = isScssDocument || isLessDocument || isHssDocument;
 | 
			
		||||
	char varPrefix = 0;
 | 
			
		||||
	if (hasVariables)
 | 
			
		||||
		varPrefix = isLessDocument ? '@' : '$';
 | 
			
		||||
 | 
			
		||||
	// SCSS/LESS/HSS support single-line comments
 | 
			
		||||
	typedef enum _CommentModes { eCommentBlock = 0, eCommentLine = 1} CommentMode;
 | 
			
		||||
	CommentMode comment_mode = eCommentBlock;
 | 
			
		||||
	bool hasSingleLineComments = isScssDocument || isLessDocument || isHssDocument;
 | 
			
		||||
 | 
			
		||||
	// must keep track of nesting level in document types that support it (SCSS/LESS/HSS)
 | 
			
		||||
	bool hasNesting = false;
 | 
			
		||||
	int nestingLevel = 0;
 | 
			
		||||
	if (isScssDocument || isLessDocument || isHssDocument) {
 | 
			
		||||
		hasNesting = true;
 | 
			
		||||
		nestingLevel = NestingLevelLookBehind(startPos, styler);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// "the loop"
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
		if (sc.state == SCE_CSS_COMMENT && ((comment_mode == eCommentBlock && sc.Match('*', '/')) || (comment_mode == eCommentLine && sc.atLineEnd))) {
 | 
			
		||||
			if (lastStateC == -1) {
 | 
			
		||||
				// backtrack to get last state:
 | 
			
		||||
				// comments are like whitespace, so we must return to the previous state
 | 
			
		||||
				Sci_PositionU i = startPos;
 | 
			
		||||
				for (; i > 0; i--) {
 | 
			
		||||
					if ((lastStateC = styler.StyleAt(i-1)) != SCE_CSS_COMMENT) {
 | 
			
		||||
						if (lastStateC == SCE_CSS_OPERATOR) {
 | 
			
		||||
							op = styler.SafeGetCharAt(i-1);
 | 
			
		||||
							opPrev = styler.SafeGetCharAt(i-2);
 | 
			
		||||
							while (--i) {
 | 
			
		||||
								lastState = styler.StyleAt(i-1);
 | 
			
		||||
								if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
 | 
			
		||||
									break;
 | 
			
		||||
							}
 | 
			
		||||
							if (i == 0)
 | 
			
		||||
								lastState = SCE_CSS_DEFAULT;
 | 
			
		||||
						}
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (i == 0)
 | 
			
		||||
					lastStateC = SCE_CSS_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
			if (comment_mode == eCommentBlock) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.ForwardSetState(lastStateC);
 | 
			
		||||
			} else /* eCommentLine */ {
 | 
			
		||||
				sc.SetState(lastStateC);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.state == SCE_CSS_COMMENT)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (sc.state == SCE_CSS_DOUBLESTRING || sc.state == SCE_CSS_SINGLESTRING) {
 | 
			
		||||
			if (sc.ch != (sc.state == SCE_CSS_DOUBLESTRING ? '\"' : '\''))
 | 
			
		||||
				continue;
 | 
			
		||||
			Sci_PositionU i = sc.currentPos;
 | 
			
		||||
			while (i && styler[i-1] == '\\')
 | 
			
		||||
				i--;
 | 
			
		||||
			if ((sc.currentPos - i) % 2 == 1)
 | 
			
		||||
				continue;
 | 
			
		||||
			sc.ForwardSetState(lastStateS);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.state == SCE_CSS_OPERATOR) {
 | 
			
		||||
			if (op == ' ') {
 | 
			
		||||
				Sci_PositionU i = startPos;
 | 
			
		||||
				op = styler.SafeGetCharAt(i-1);
 | 
			
		||||
				opPrev = styler.SafeGetCharAt(i-2);
 | 
			
		||||
				while (--i) {
 | 
			
		||||
					lastState = styler.StyleAt(i-1);
 | 
			
		||||
					if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			switch (op) {
 | 
			
		||||
			case '@':
 | 
			
		||||
				if (lastState == SCE_CSS_DEFAULT || hasNesting)
 | 
			
		||||
					sc.SetState(SCE_CSS_DIRECTIVE);
 | 
			
		||||
				break;
 | 
			
		||||
			case '>':
 | 
			
		||||
			case '+':
 | 
			
		||||
				if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
 | 
			
		||||
					lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
 | 
			
		||||
					sc.SetState(SCE_CSS_DEFAULT);
 | 
			
		||||
				break;
 | 
			
		||||
			case '[':
 | 
			
		||||
				if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
 | 
			
		||||
					lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
 | 
			
		||||
					sc.SetState(SCE_CSS_ATTRIBUTE);
 | 
			
		||||
				break;
 | 
			
		||||
			case ']':
 | 
			
		||||
				if (lastState == SCE_CSS_ATTRIBUTE)
 | 
			
		||||
					sc.SetState(SCE_CSS_TAG);
 | 
			
		||||
				break;
 | 
			
		||||
			case '{':
 | 
			
		||||
				nestingLevel++;
 | 
			
		||||
				switch (lastState) {
 | 
			
		||||
				case SCE_CSS_GROUP_RULE:
 | 
			
		||||
					sc.SetState(SCE_CSS_DEFAULT);
 | 
			
		||||
					break;
 | 
			
		||||
				case SCE_CSS_TAG:
 | 
			
		||||
				case SCE_CSS_DIRECTIVE:
 | 
			
		||||
					sc.SetState(SCE_CSS_IDENTIFIER);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '}':
 | 
			
		||||
				if (--nestingLevel < 0)
 | 
			
		||||
					nestingLevel = 0;
 | 
			
		||||
				switch (lastState) {
 | 
			
		||||
				case SCE_CSS_DEFAULT:
 | 
			
		||||
				case SCE_CSS_VALUE:
 | 
			
		||||
				case SCE_CSS_IMPORTANT:
 | 
			
		||||
				case SCE_CSS_IDENTIFIER:
 | 
			
		||||
				case SCE_CSS_IDENTIFIER2:
 | 
			
		||||
				case SCE_CSS_IDENTIFIER3:
 | 
			
		||||
					if (hasNesting)
 | 
			
		||||
						sc.SetState(nestingLevel > 0 ? SCE_CSS_IDENTIFIER : SCE_CSS_DEFAULT);
 | 
			
		||||
					else
 | 
			
		||||
						sc.SetState(SCE_CSS_DEFAULT);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '(':
 | 
			
		||||
				if (lastState == SCE_CSS_PSEUDOCLASS)
 | 
			
		||||
					sc.SetState(SCE_CSS_TAG);
 | 
			
		||||
				else if (lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)
 | 
			
		||||
					sc.SetState(SCE_CSS_EXTENDED_PSEUDOCLASS);
 | 
			
		||||
				break;
 | 
			
		||||
			case ')':
 | 
			
		||||
				if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
 | 
			
		||||
					lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
 | 
			
		||||
					lastState == SCE_CSS_PSEUDOELEMENT || lastState == SCE_CSS_EXTENDED_PSEUDOELEMENT)
 | 
			
		||||
					sc.SetState(SCE_CSS_TAG);
 | 
			
		||||
				break;
 | 
			
		||||
			case ':':
 | 
			
		||||
				switch (lastState) {
 | 
			
		||||
				case SCE_CSS_TAG:
 | 
			
		||||
				case SCE_CSS_DEFAULT:
 | 
			
		||||
				case SCE_CSS_CLASS:
 | 
			
		||||
				case SCE_CSS_ID:
 | 
			
		||||
				case SCE_CSS_PSEUDOCLASS:
 | 
			
		||||
				case SCE_CSS_EXTENDED_PSEUDOCLASS:
 | 
			
		||||
				case SCE_CSS_UNKNOWN_PSEUDOCLASS:
 | 
			
		||||
				case SCE_CSS_PSEUDOELEMENT:
 | 
			
		||||
				case SCE_CSS_EXTENDED_PSEUDOELEMENT:
 | 
			
		||||
					sc.SetState(SCE_CSS_PSEUDOCLASS);
 | 
			
		||||
					break;
 | 
			
		||||
				case SCE_CSS_IDENTIFIER:
 | 
			
		||||
				case SCE_CSS_IDENTIFIER2:
 | 
			
		||||
				case SCE_CSS_IDENTIFIER3:
 | 
			
		||||
				case SCE_CSS_EXTENDED_IDENTIFIER:
 | 
			
		||||
				case SCE_CSS_UNKNOWN_IDENTIFIER:
 | 
			
		||||
				case SCE_CSS_VARIABLE:
 | 
			
		||||
					sc.SetState(SCE_CSS_VALUE);
 | 
			
		||||
					lastStateVal = lastState;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '.':
 | 
			
		||||
				if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
 | 
			
		||||
					lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
 | 
			
		||||
					sc.SetState(SCE_CSS_CLASS);
 | 
			
		||||
				break;
 | 
			
		||||
			case '#':
 | 
			
		||||
				if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
 | 
			
		||||
					lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
 | 
			
		||||
					sc.SetState(SCE_CSS_ID);
 | 
			
		||||
				break;
 | 
			
		||||
			case ',':
 | 
			
		||||
			case '|':
 | 
			
		||||
			case '~':
 | 
			
		||||
				if (lastState == SCE_CSS_TAG)
 | 
			
		||||
					sc.SetState(SCE_CSS_DEFAULT);
 | 
			
		||||
				break;
 | 
			
		||||
			case ';':
 | 
			
		||||
				switch (lastState) {
 | 
			
		||||
				case SCE_CSS_DIRECTIVE:
 | 
			
		||||
					if (hasNesting) {
 | 
			
		||||
						sc.SetState(nestingLevel > 0 ? SCE_CSS_IDENTIFIER : SCE_CSS_DEFAULT);
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.SetState(SCE_CSS_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case SCE_CSS_VALUE:
 | 
			
		||||
				case SCE_CSS_IMPORTANT:
 | 
			
		||||
					// data URLs can have semicolons; simplistically check for wrapping parentheses and move along
 | 
			
		||||
					if (insideParentheses) {
 | 
			
		||||
						sc.SetState(lastState);
 | 
			
		||||
					} else {
 | 
			
		||||
						if (lastStateVal == SCE_CSS_VARIABLE) {
 | 
			
		||||
							sc.SetState(SCE_CSS_DEFAULT);
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.SetState(SCE_CSS_IDENTIFIER);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case SCE_CSS_VARIABLE:
 | 
			
		||||
					if (lastStateVar == SCE_CSS_VALUE) {
 | 
			
		||||
						// data URLs can have semicolons; simplistically check for wrapping parentheses and move along
 | 
			
		||||
						if (insideParentheses) {
 | 
			
		||||
							sc.SetState(SCE_CSS_VALUE);
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.SetState(SCE_CSS_IDENTIFIER);
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.SetState(SCE_CSS_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '!':
 | 
			
		||||
				if (lastState == SCE_CSS_VALUE)
 | 
			
		||||
					sc.SetState(SCE_CSS_IMPORTANT);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.ch == '*' && sc.state == SCE_CSS_DEFAULT) {
 | 
			
		||||
			sc.SetState(SCE_CSS_TAG);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// check for inside parentheses (whether part of an "operator" or not)
 | 
			
		||||
		if (sc.ch == '(')
 | 
			
		||||
			insideParentheses = true;
 | 
			
		||||
		else if (sc.ch == ')')
 | 
			
		||||
			insideParentheses = false;
 | 
			
		||||
 | 
			
		||||
		// SCSS special modes
 | 
			
		||||
		if (hasVariables) {
 | 
			
		||||
			// variable name
 | 
			
		||||
			if (sc.ch == varPrefix) {
 | 
			
		||||
				switch (sc.state) {
 | 
			
		||||
				case SCE_CSS_DEFAULT:
 | 
			
		||||
					if (isLessDocument) // give priority to pseudo elements
 | 
			
		||||
						break;
 | 
			
		||||
					// Falls through.
 | 
			
		||||
				case SCE_CSS_VALUE:
 | 
			
		||||
					lastStateVar = sc.state;
 | 
			
		||||
					sc.SetState(SCE_CSS_VARIABLE);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (sc.state == SCE_CSS_VARIABLE) {
 | 
			
		||||
				if (IsAWordChar(sc.ch)) {
 | 
			
		||||
					// still looking at the variable name
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				if (lastStateVar == SCE_CSS_VALUE) {
 | 
			
		||||
					// not looking at the variable name any more, and it was part of a value
 | 
			
		||||
					sc.SetState(SCE_CSS_VALUE);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// nested rule parent selector
 | 
			
		||||
			if (sc.ch == '&') {
 | 
			
		||||
				switch (sc.state) {
 | 
			
		||||
				case SCE_CSS_DEFAULT:
 | 
			
		||||
				case SCE_CSS_IDENTIFIER:
 | 
			
		||||
					sc.SetState(SCE_CSS_TAG);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// nesting rules that apply to SCSS and Less
 | 
			
		||||
		if (hasNesting) {
 | 
			
		||||
			// check for nested rule selector
 | 
			
		||||
			if (sc.state == SCE_CSS_IDENTIFIER && (IsAWordChar(sc.ch) || sc.ch == ':' || sc.ch == '.' || sc.ch == '#')) {
 | 
			
		||||
				// look ahead to see whether { comes before next ; and }
 | 
			
		||||
				Sci_PositionU endPos = startPos + length;
 | 
			
		||||
				int ch;
 | 
			
		||||
 | 
			
		||||
				for (Sci_PositionU i = sc.currentPos; i < endPos; i++) {
 | 
			
		||||
					ch = styler.SafeGetCharAt(i);
 | 
			
		||||
					if (ch == ';' || ch == '}')
 | 
			
		||||
						break;
 | 
			
		||||
					if (ch == '{') {
 | 
			
		||||
						sc.SetState(SCE_CSS_DEFAULT);
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (IsAWordChar(sc.ch)) {
 | 
			
		||||
			if (sc.state == SCE_CSS_DEFAULT)
 | 
			
		||||
				sc.SetState(SCE_CSS_TAG);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (IsAWordChar(sc.chPrev) && (
 | 
			
		||||
			sc.state == SCE_CSS_IDENTIFIER || sc.state == SCE_CSS_IDENTIFIER2 ||
 | 
			
		||||
			sc.state == SCE_CSS_IDENTIFIER3 || sc.state == SCE_CSS_EXTENDED_IDENTIFIER ||
 | 
			
		||||
			sc.state == SCE_CSS_UNKNOWN_IDENTIFIER ||
 | 
			
		||||
			sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
 | 
			
		||||
			sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
 | 
			
		||||
			sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
 | 
			
		||||
			sc.state == SCE_CSS_IMPORTANT ||
 | 
			
		||||
			sc.state == SCE_CSS_DIRECTIVE
 | 
			
		||||
		)) {
 | 
			
		||||
			char s[100];
 | 
			
		||||
			sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
			char *s2 = s;
 | 
			
		||||
			while (*s2 && !IsAWordChar(*s2))
 | 
			
		||||
				s2++;
 | 
			
		||||
			switch (sc.state) {
 | 
			
		||||
			case SCE_CSS_IDENTIFIER:
 | 
			
		||||
			case SCE_CSS_IDENTIFIER2:
 | 
			
		||||
			case SCE_CSS_IDENTIFIER3:
 | 
			
		||||
			case SCE_CSS_EXTENDED_IDENTIFIER:
 | 
			
		||||
			case SCE_CSS_UNKNOWN_IDENTIFIER:
 | 
			
		||||
				if (css1Props.InList(s2))
 | 
			
		||||
					sc.ChangeState(SCE_CSS_IDENTIFIER);
 | 
			
		||||
				else if (css2Props.InList(s2))
 | 
			
		||||
					sc.ChangeState(SCE_CSS_IDENTIFIER2);
 | 
			
		||||
				else if (css3Props.InList(s2))
 | 
			
		||||
					sc.ChangeState(SCE_CSS_IDENTIFIER3);
 | 
			
		||||
				else if (exProps.InList(s2))
 | 
			
		||||
					sc.ChangeState(SCE_CSS_EXTENDED_IDENTIFIER);
 | 
			
		||||
				else
 | 
			
		||||
					sc.ChangeState(SCE_CSS_UNKNOWN_IDENTIFIER);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_CSS_PSEUDOCLASS:
 | 
			
		||||
			case SCE_CSS_PSEUDOELEMENT:
 | 
			
		||||
			case SCE_CSS_EXTENDED_PSEUDOCLASS:
 | 
			
		||||
			case SCE_CSS_EXTENDED_PSEUDOELEMENT:
 | 
			
		||||
			case SCE_CSS_UNKNOWN_PSEUDOCLASS:
 | 
			
		||||
				if (op == ':' && opPrev != ':' && pseudoClasses.InList(s2))
 | 
			
		||||
					sc.ChangeState(SCE_CSS_PSEUDOCLASS);
 | 
			
		||||
				else if (opPrev == ':' && pseudoElements.InList(s2))
 | 
			
		||||
					sc.ChangeState(SCE_CSS_PSEUDOELEMENT);
 | 
			
		||||
				else if ((op == ':' || (op == '(' && lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)) && opPrev != ':' && exPseudoClasses.InList(s2))
 | 
			
		||||
					sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOCLASS);
 | 
			
		||||
				else if (opPrev == ':' && exPseudoElements.InList(s2))
 | 
			
		||||
					sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOELEMENT);
 | 
			
		||||
				else
 | 
			
		||||
					sc.ChangeState(SCE_CSS_UNKNOWN_PSEUDOCLASS);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_CSS_IMPORTANT:
 | 
			
		||||
				if (strcmp(s2, "important") != 0)
 | 
			
		||||
					sc.ChangeState(SCE_CSS_VALUE);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_CSS_DIRECTIVE:
 | 
			
		||||
				if (op == '@' && (strcmp(s2, "media") == 0 || strcmp(s2, "supports") == 0 || strcmp(s2, "document") == 0 || strcmp(s2, "-moz-document") == 0))
 | 
			
		||||
					sc.ChangeState(SCE_CSS_GROUP_RULE);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.ch != '.' && sc.ch != ':' && sc.ch != '#' && (
 | 
			
		||||
			sc.state == SCE_CSS_CLASS || sc.state == SCE_CSS_ID ||
 | 
			
		||||
			(sc.ch != '(' && sc.ch != ')' && ( /* This line of the condition makes it possible to extend pseudo-classes with parentheses */
 | 
			
		||||
				sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
 | 
			
		||||
				sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
 | 
			
		||||
				sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS
 | 
			
		||||
			))
 | 
			
		||||
		))
 | 
			
		||||
			sc.SetState(SCE_CSS_TAG);
 | 
			
		||||
 | 
			
		||||
		if (sc.Match('/', '*')) {
 | 
			
		||||
			lastStateC = sc.state;
 | 
			
		||||
			comment_mode = eCommentBlock;
 | 
			
		||||
			sc.SetState(SCE_CSS_COMMENT);
 | 
			
		||||
			sc.Forward();
 | 
			
		||||
		} else if (hasSingleLineComments && sc.Match('/', '/') && !insideParentheses) {
 | 
			
		||||
			// note that we've had to treat ([...]// as the start of a URL not a comment, e.g. url(http://example.com), url(//example.com)
 | 
			
		||||
			lastStateC = sc.state;
 | 
			
		||||
			comment_mode = eCommentLine;
 | 
			
		||||
			sc.SetState(SCE_CSS_COMMENT);
 | 
			
		||||
			sc.Forward();
 | 
			
		||||
		} else if ((sc.state == SCE_CSS_VALUE || sc.state == SCE_CSS_ATTRIBUTE)
 | 
			
		||||
			&& (sc.ch == '\"' || sc.ch == '\'')) {
 | 
			
		||||
			lastStateS = sc.state;
 | 
			
		||||
			sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING));
 | 
			
		||||
		} else if (IsCssOperator(sc.ch)
 | 
			
		||||
			&& (sc.state != SCE_CSS_ATTRIBUTE || sc.ch == ']')
 | 
			
		||||
			&& (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
 | 
			
		||||
			&& ((sc.state != SCE_CSS_DIRECTIVE && sc.state != SCE_CSS_GROUP_RULE) || sc.ch == ';' || sc.ch == '{')
 | 
			
		||||
		) {
 | 
			
		||||
			if (sc.state != SCE_CSS_OPERATOR)
 | 
			
		||||
				lastState = sc.state;
 | 
			
		||||
			sc.SetState(SCE_CSS_OPERATOR);
 | 
			
		||||
			op = sc.ch;
 | 
			
		||||
			opPrev = sc.chPrev;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldCSSDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
 | 
			
		||||
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	bool inComment = (styler.StyleAt(startPos-1) == SCE_CSS_COMMENT);
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int style = styler.StyleAt(i);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if (foldComment) {
 | 
			
		||||
			if (!inComment && (style == SCE_CSS_COMMENT))
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			else if (inComment && (style != SCE_CSS_COMMENT))
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			inComment = (style == SCE_CSS_COMMENT);
 | 
			
		||||
		}
 | 
			
		||||
		if (style == SCE_CSS_OPERATOR) {
 | 
			
		||||
			if (ch == '{') {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			} else if (ch == '}') {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const cssWordListDesc[] = {
 | 
			
		||||
	"CSS1 Properties",
 | 
			
		||||
	"Pseudo-classes",
 | 
			
		||||
	"CSS2 Properties",
 | 
			
		||||
	"CSS3 Properties",
 | 
			
		||||
	"Pseudo-elements",
 | 
			
		||||
	"Browser-Specific CSS Properties",
 | 
			
		||||
	"Browser-Specific Pseudo-classes",
 | 
			
		||||
	"Browser-Specific Pseudo-elements",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc, cssWordListDesc);
 | 
			
		||||
							
								
								
									
										329
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCaml.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										329
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCaml.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,329 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexCaml.cxx
 | 
			
		||||
 ** Lexer for Objective Caml.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2005-2009 by Robert Roessler <robertr@rftp.com>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
/*	Release History
 | 
			
		||||
	20050204 Initial release.
 | 
			
		||||
	20050205 Quick compiler standards/"cleanliness" adjustment.
 | 
			
		||||
	20050206 Added cast for IsLeadByte().
 | 
			
		||||
	20050209 Changes to "external" build support.
 | 
			
		||||
	20050306 Fix for 1st-char-in-doc "corner" case.
 | 
			
		||||
	20050502 Fix for [harmless] one-past-the-end coloring.
 | 
			
		||||
	20050515 Refined numeric token recognition logic.
 | 
			
		||||
	20051125 Added 2nd "optional" keywords class.
 | 
			
		||||
	20051129 Support "magic" (read-only) comments for RCaml.
 | 
			
		||||
	20051204 Swtich to using StyleContext infrastructure.
 | 
			
		||||
	20090629 Add full Standard ML '97 support.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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"
 | 
			
		||||
 | 
			
		||||
#if defined(__clang__)
 | 
			
		||||
#pragma clang diagnostic ignored "-Wcomma"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//	Since the Microsoft __iscsym[f] funcs are not ANSI...
 | 
			
		||||
inline int  iscaml(int c) {return isalnum(c) || c == '_';}
 | 
			
		||||
inline int iscamlf(int c) {return isalpha(c) || c == '_';}
 | 
			
		||||
 | 
			
		||||
static const int baseT[24] = {
 | 
			
		||||
	0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* A - L */
 | 
			
		||||
	0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16	/* M - X */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
static void ColouriseCamlDoc(
 | 
			
		||||
	Sci_PositionU startPos, Sci_Position length,
 | 
			
		||||
	int initStyle,
 | 
			
		||||
	WordList *keywordlists[],
 | 
			
		||||
	Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
	// initialize styler
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	Sci_PositionU chToken = 0;
 | 
			
		||||
	int chBase = 0, chLit = 0;
 | 
			
		||||
	WordList& keywords  = *keywordlists[0];
 | 
			
		||||
	WordList& keywords2 = *keywordlists[1];
 | 
			
		||||
	WordList& keywords3 = *keywordlists[2];
 | 
			
		||||
	const bool isSML = keywords.InList("andalso");
 | 
			
		||||
	const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
 | 
			
		||||
 | 
			
		||||
	// set up [initial] state info (terminating states that shouldn't "bleed")
 | 
			
		||||
	const int state_ = sc.state & 0x0f;
 | 
			
		||||
	if (state_ <= SCE_CAML_CHAR
 | 
			
		||||
		|| (isSML && state_ == SCE_CAML_STRING))
 | 
			
		||||
		sc.state = SCE_CAML_DEFAULT;
 | 
			
		||||
	int nesting = (state_ >= SCE_CAML_COMMENT)? (state_ - SCE_CAML_COMMENT): 0;
 | 
			
		||||
 | 
			
		||||
	// foreach char in range...
 | 
			
		||||
	while (sc.More()) {
 | 
			
		||||
		// set up [per-char] state info
 | 
			
		||||
		int state2 = -1;				// (ASSUME no state change)
 | 
			
		||||
		Sci_Position chColor = sc.currentPos - 1;// (ASSUME standard coloring range)
 | 
			
		||||
		bool advance = true;			// (ASSUME scanner "eats" 1 char)
 | 
			
		||||
 | 
			
		||||
		// step state machine
 | 
			
		||||
		switch (sc.state & 0x0f) {
 | 
			
		||||
		case SCE_CAML_DEFAULT:
 | 
			
		||||
			chToken = sc.currentPos;	// save [possible] token start (JIC)
 | 
			
		||||
			// it's wide open; what do we have?
 | 
			
		||||
			if (iscamlf(sc.ch))
 | 
			
		||||
				state2 = SCE_CAML_IDENTIFIER;
 | 
			
		||||
			else if (!isSML && sc.Match('`') && iscamlf(sc.chNext))
 | 
			
		||||
				state2 = SCE_CAML_TAGNAME;
 | 
			
		||||
			else if (!isSML && sc.Match('#') && isdigit(sc.chNext))
 | 
			
		||||
				state2 = SCE_CAML_LINENUM;
 | 
			
		||||
			else if (isdigit(sc.ch)) {
 | 
			
		||||
				// it's a number, assume base 10
 | 
			
		||||
				state2 = SCE_CAML_NUMBER, chBase = 10;
 | 
			
		||||
				if (sc.Match('0')) {
 | 
			
		||||
					// there MAY be a base specified...
 | 
			
		||||
					const char* baseC = "bBoOxX";
 | 
			
		||||
					if (isSML) {
 | 
			
		||||
						if (sc.chNext == 'w')
 | 
			
		||||
							sc.Forward();	// (consume SML "word" indicator)
 | 
			
		||||
						baseC = "x";
 | 
			
		||||
					}
 | 
			
		||||
					// ... change to specified base AS REQUIRED
 | 
			
		||||
					if (strchr(baseC, sc.chNext))
 | 
			
		||||
						chBase = baseT[tolower(sc.chNext) - 'a'], sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
			} else if (!isSML && sc.Match('\''))	// (Caml char literal?)
 | 
			
		||||
				state2 = SCE_CAML_CHAR, chLit = 0;
 | 
			
		||||
			else if (isSML && sc.Match('#', '"'))	// (SML char literal?)
 | 
			
		||||
				state2 = SCE_CAML_CHAR, sc.Forward();
 | 
			
		||||
			else if (sc.Match('"'))
 | 
			
		||||
				state2 = SCE_CAML_STRING;
 | 
			
		||||
			else if (sc.Match('(', '*'))
 | 
			
		||||
				state2 = SCE_CAML_COMMENT, sc.Forward(), sc.ch = ' '; // (*)...
 | 
			
		||||
			else if (strchr("!?~"			/* Caml "prefix-symbol" */
 | 
			
		||||
					"=<>@^|&+-*/$%"			/* Caml "infix-symbol" */
 | 
			
		||||
					"()[]{};,:.#", sc.ch)	// Caml "bracket" or ;,:.#
 | 
			
		||||
											// SML "extra" ident chars
 | 
			
		||||
				|| (isSML && (sc.Match('\\') || sc.Match('`'))))
 | 
			
		||||
				state2 = SCE_CAML_OPERATOR;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_CAML_IDENTIFIER:
 | 
			
		||||
			// [try to] interpret as [additional] identifier char
 | 
			
		||||
			if (!(iscaml(sc.ch) || sc.Match('\''))) {
 | 
			
		||||
				const Sci_Position n = sc.currentPos - chToken;
 | 
			
		||||
				if (n < 24) {
 | 
			
		||||
					// length is believable as keyword, [re-]construct token
 | 
			
		||||
					char t[24];
 | 
			
		||||
					for (Sci_Position i = -n; i < 0; i++)
 | 
			
		||||
						t[n + i] = static_cast<char>(sc.GetRelative(i));
 | 
			
		||||
					t[n] = '\0';
 | 
			
		||||
					// special-case "_" token as KEYWORD
 | 
			
		||||
					if ((n == 1 && sc.chPrev == '_') || keywords.InList(t))
 | 
			
		||||
						sc.ChangeState(SCE_CAML_KEYWORD);
 | 
			
		||||
					else if (keywords2.InList(t))
 | 
			
		||||
						sc.ChangeState(SCE_CAML_KEYWORD2);
 | 
			
		||||
					else if (keywords3.InList(t))
 | 
			
		||||
						sc.ChangeState(SCE_CAML_KEYWORD3);
 | 
			
		||||
				}
 | 
			
		||||
				state2 = SCE_CAML_DEFAULT, advance = false;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_CAML_TAGNAME:
 | 
			
		||||
			// [try to] interpret as [additional] tagname char
 | 
			
		||||
			if (!(iscaml(sc.ch) || sc.Match('\'')))
 | 
			
		||||
				state2 = SCE_CAML_DEFAULT, advance = false;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		/*case SCE_CAML_KEYWORD:
 | 
			
		||||
		case SCE_CAML_KEYWORD2:
 | 
			
		||||
		case SCE_CAML_KEYWORD3:
 | 
			
		||||
			// [try to] interpret as [additional] keyword char
 | 
			
		||||
			if (!iscaml(ch))
 | 
			
		||||
				state2 = SCE_CAML_DEFAULT, advance = false;
 | 
			
		||||
			break;*/
 | 
			
		||||
 | 
			
		||||
		case SCE_CAML_LINENUM:
 | 
			
		||||
			// [try to] interpret as [additional] linenum directive char
 | 
			
		||||
			if (!isdigit(sc.ch))
 | 
			
		||||
				state2 = SCE_CAML_DEFAULT, advance = false;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_CAML_OPERATOR: {
 | 
			
		||||
			// [try to] interpret as [additional] operator char
 | 
			
		||||
			const char* o = 0;
 | 
			
		||||
			if (iscaml(sc.ch) || isspace(sc.ch)			// ident or whitespace
 | 
			
		||||
				|| (o = strchr(")]};,\'\"#", sc.ch),o)	// "termination" chars
 | 
			
		||||
				|| (!isSML && sc.Match('`'))			// Caml extra term char
 | 
			
		||||
				|| (!strchr("!$%&*+-./:<=>?@^|~", sc.ch)// "operator" chars
 | 
			
		||||
														// SML extra ident chars
 | 
			
		||||
					&& !(isSML && (sc.Match('\\') || sc.Match('`'))))) {
 | 
			
		||||
				// check for INCLUSIVE termination
 | 
			
		||||
				if (o && strchr(")]};,", sc.ch)) {
 | 
			
		||||
					if ((sc.Match(')') && sc.chPrev == '(')
 | 
			
		||||
						|| (sc.Match(']') && sc.chPrev == '['))
 | 
			
		||||
						// special-case "()" and "[]" tokens as KEYWORDS
 | 
			
		||||
						sc.ChangeState(SCE_CAML_KEYWORD);
 | 
			
		||||
					chColor++;
 | 
			
		||||
				} else
 | 
			
		||||
					advance = false;
 | 
			
		||||
				state2 = SCE_CAML_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		case SCE_CAML_NUMBER:
 | 
			
		||||
			// [try to] interpret as [additional] numeric literal char
 | 
			
		||||
			if ((!isSML && sc.Match('_')) || IsADigit(sc.ch, chBase))
 | 
			
		||||
				break;
 | 
			
		||||
			// how about an integer suffix?
 | 
			
		||||
			if (!isSML && (sc.Match('l') || sc.Match('L') || sc.Match('n'))
 | 
			
		||||
				&& (sc.chPrev == '_' || IsADigit(sc.chPrev, chBase)))
 | 
			
		||||
				break;
 | 
			
		||||
			// or a floating-point literal?
 | 
			
		||||
			if (chBase == 10) {
 | 
			
		||||
				// with a decimal point?
 | 
			
		||||
				if (sc.Match('.')
 | 
			
		||||
					&& ((!isSML && sc.chPrev == '_')
 | 
			
		||||
						|| IsADigit(sc.chPrev, chBase)))
 | 
			
		||||
					break;
 | 
			
		||||
				// with an exponent? (I)
 | 
			
		||||
				if ((sc.Match('e') || sc.Match('E'))
 | 
			
		||||
					&& ((!isSML && (sc.chPrev == '.' || sc.chPrev == '_'))
 | 
			
		||||
						|| IsADigit(sc.chPrev, chBase)))
 | 
			
		||||
					break;
 | 
			
		||||
				// with an exponent? (II)
 | 
			
		||||
				if (((!isSML && (sc.Match('+') || sc.Match('-')))
 | 
			
		||||
						|| (isSML && sc.Match('~')))
 | 
			
		||||
					&& (sc.chPrev == 'e' || sc.chPrev == 'E'))
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			// it looks like we have run out of number
 | 
			
		||||
			state2 = SCE_CAML_DEFAULT, advance = false;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_CAML_CHAR:
 | 
			
		||||
			if (!isSML) {
 | 
			
		||||
				// [try to] interpret as [additional] char literal char
 | 
			
		||||
				if (sc.Match('\\')) {
 | 
			
		||||
					chLit = 1;	// (definitely IS a char literal)
 | 
			
		||||
					if (sc.chPrev == '\\')
 | 
			
		||||
						sc.ch = ' ';	// (...\\')
 | 
			
		||||
				// should we be terminating - one way or another?
 | 
			
		||||
				} else if ((sc.Match('\'') && sc.chPrev != '\\')
 | 
			
		||||
					|| sc.atLineEnd) {
 | 
			
		||||
					state2 = SCE_CAML_DEFAULT;
 | 
			
		||||
					if (sc.Match('\''))
 | 
			
		||||
						chColor++;
 | 
			
		||||
					else
 | 
			
		||||
						sc.ChangeState(SCE_CAML_IDENTIFIER);
 | 
			
		||||
				// ... maybe a char literal, maybe not
 | 
			
		||||
				} else if (chLit < 1 && sc.currentPos - chToken >= 2)
 | 
			
		||||
					sc.ChangeState(SCE_CAML_IDENTIFIER), advance = false;
 | 
			
		||||
				break;
 | 
			
		||||
			}/* else
 | 
			
		||||
				// fall through for SML char literal (handle like string) */
 | 
			
		||||
			// Falls through.
 | 
			
		||||
 | 
			
		||||
		case SCE_CAML_STRING:
 | 
			
		||||
			// [try to] interpret as [additional] [SML char/] string literal char
 | 
			
		||||
			if (isSML && sc.Match('\\') && sc.chPrev != '\\' && isspace(sc.chNext))
 | 
			
		||||
				state2 = SCE_CAML_WHITE;
 | 
			
		||||
			else if (sc.Match('\\') && sc.chPrev == '\\')
 | 
			
		||||
				sc.ch = ' ';	// (...\\")
 | 
			
		||||
			// should we be terminating - one way or another?
 | 
			
		||||
			else if ((sc.Match('"') && sc.chPrev != '\\')
 | 
			
		||||
				|| (isSML && sc.atLineEnd)) {
 | 
			
		||||
				state2 = SCE_CAML_DEFAULT;
 | 
			
		||||
				if (sc.Match('"'))
 | 
			
		||||
					chColor++;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_CAML_WHITE:
 | 
			
		||||
			// [try to] interpret as [additional] SML embedded whitespace char
 | 
			
		||||
			if (sc.Match('\\')) {
 | 
			
		||||
				// style this puppy NOW...
 | 
			
		||||
				state2 = SCE_CAML_STRING, sc.ch = ' ' /* (...\") */, chColor++,
 | 
			
		||||
					styler.ColourTo(chColor, SCE_CAML_WHITE), styler.Flush();
 | 
			
		||||
				// ... then backtrack to determine original SML literal type
 | 
			
		||||
				Sci_Position p = chColor - 2;
 | 
			
		||||
				for (; p >= 0 && styler.StyleAt(p) == SCE_CAML_WHITE; p--) ;
 | 
			
		||||
				if (p >= 0)
 | 
			
		||||
					state2 = static_cast<int>(styler.StyleAt(p));
 | 
			
		||||
				// take care of state change NOW
 | 
			
		||||
				sc.ChangeState(state2), state2 = -1;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_CAML_COMMENT:
 | 
			
		||||
		case SCE_CAML_COMMENT1:
 | 
			
		||||
		case SCE_CAML_COMMENT2:
 | 
			
		||||
		case SCE_CAML_COMMENT3:
 | 
			
		||||
			// we're IN a comment - does this start a NESTED comment?
 | 
			
		||||
			if (sc.Match('(', '*'))
 | 
			
		||||
				state2 = sc.state + 1, chToken = sc.currentPos,
 | 
			
		||||
					sc.Forward(), sc.ch = ' ' /* (*)... */, nesting++;
 | 
			
		||||
			// [try to] interpret as [additional] comment char
 | 
			
		||||
			else if (sc.Match(')') && sc.chPrev == '*') {
 | 
			
		||||
				if (nesting)
 | 
			
		||||
					state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;
 | 
			
		||||
				else
 | 
			
		||||
					state2 = SCE_CAML_DEFAULT;
 | 
			
		||||
				chColor++;
 | 
			
		||||
			// enable "magic" (read-only) comment AS REQUIRED
 | 
			
		||||
			} else if (useMagic && sc.currentPos - chToken == 4
 | 
			
		||||
				&& sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')
 | 
			
		||||
				sc.state |= 0x10;	// (switch to read-only comment style)
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// handle state change and char coloring AS REQUIRED
 | 
			
		||||
		if (state2 >= 0)
 | 
			
		||||
			styler.ColourTo(chColor, sc.state), sc.ChangeState(state2);
 | 
			
		||||
		// move to next char UNLESS re-scanning current char
 | 
			
		||||
		if (advance)
 | 
			
		||||
			sc.Forward();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// do any required terminal char coloring (JIC)
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void FoldCamlDoc(
 | 
			
		||||
	Sci_PositionU, Sci_Position,
 | 
			
		||||
	int,
 | 
			
		||||
	WordList *[],
 | 
			
		||||
	Accessor &)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const camlWordListDesc[] = {
 | 
			
		||||
	"Keywords",		// primary Objective Caml keywords
 | 
			
		||||
	"Keywords2",	// "optional" keywords (typically from Pervasives)
 | 
			
		||||
	"Keywords3",	// "optional" keywords (typically typenames)
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmCaml(SCLEX_CAML, ColouriseCamlDoc, "caml", FoldCamlDoc, camlWordListDesc);
 | 
			
		||||
							
								
								
									
										459
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCmake.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										459
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCmake.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,459 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexCmake.cxx
 | 
			
		||||
 ** Lexer for Cmake
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2007 by Cristian Adam <cristian [dot] adam [at] gmx [dot] net>
 | 
			
		||||
// based on the NSIS lexer
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static bool isCmakeNumber(char ch)
 | 
			
		||||
{
 | 
			
		||||
    return(ch >= '0' && ch <= '9');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool isCmakeChar(char ch)
 | 
			
		||||
{
 | 
			
		||||
    return(ch == '.' ) || (ch == '_' ) || isCmakeNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool isCmakeLetter(char ch)
 | 
			
		||||
{
 | 
			
		||||
    return(ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool CmakeNextLineHasElse(Sci_PositionU start, Sci_PositionU end, Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
    Sci_Position nNextLine = -1;
 | 
			
		||||
    for ( Sci_PositionU i = start; i < end; i++ ) {
 | 
			
		||||
        char cNext = styler.SafeGetCharAt( i );
 | 
			
		||||
        if ( cNext == '\n' ) {
 | 
			
		||||
            nNextLine = i+1;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( nNextLine == -1 ) // We never foudn the next line...
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    for ( Sci_PositionU firstChar = nNextLine; firstChar < end; firstChar++ ) {
 | 
			
		||||
        char cNext = styler.SafeGetCharAt( firstChar );
 | 
			
		||||
        if ( cNext == ' ' )
 | 
			
		||||
            continue;
 | 
			
		||||
        if ( cNext == '\t' )
 | 
			
		||||
            continue;
 | 
			
		||||
        if ( styler.Match(firstChar, "ELSE")  || styler.Match(firstChar, "else"))
 | 
			
		||||
            return true;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int calculateFoldCmake(Sci_PositionU start, Sci_PositionU end, int foldlevel, Accessor &styler, bool bElse)
 | 
			
		||||
{
 | 
			
		||||
    // If the word is too long, it is not what we are looking for
 | 
			
		||||
    if ( end - start > 20 )
 | 
			
		||||
        return foldlevel;
 | 
			
		||||
 | 
			
		||||
    int newFoldlevel = foldlevel;
 | 
			
		||||
 | 
			
		||||
    char s[20]; // The key word we are looking for has atmost 13 characters
 | 
			
		||||
    for (unsigned int i = 0; i < end - start + 1 && i < 19; i++) {
 | 
			
		||||
        s[i] = static_cast<char>( styler[ start + i ] );
 | 
			
		||||
        s[i + 1] = '\0';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( CompareCaseInsensitive(s, "IF") == 0 || CompareCaseInsensitive(s, "WHILE") == 0
 | 
			
		||||
         || CompareCaseInsensitive(s, "MACRO") == 0 || CompareCaseInsensitive(s, "FOREACH") == 0
 | 
			
		||||
         || CompareCaseInsensitive(s, "FUNCTION") == 0)
 | 
			
		||||
        newFoldlevel++;
 | 
			
		||||
    else if ( CompareCaseInsensitive(s, "ENDIF") == 0 || CompareCaseInsensitive(s, "ENDWHILE") == 0
 | 
			
		||||
              || CompareCaseInsensitive(s, "ENDMACRO") == 0 || CompareCaseInsensitive(s, "ENDFOREACH") == 0
 | 
			
		||||
              || CompareCaseInsensitive(s, "ENDFUNCTION") == 0)
 | 
			
		||||
        newFoldlevel--;
 | 
			
		||||
    else if ( bElse && CompareCaseInsensitive(s, "ELSEIF") == 0 )
 | 
			
		||||
        newFoldlevel++;
 | 
			
		||||
    else if ( bElse && CompareCaseInsensitive(s, "ELSE") == 0 )
 | 
			
		||||
        newFoldlevel++;
 | 
			
		||||
 | 
			
		||||
    return newFoldlevel;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int classifyWordCmake(Sci_PositionU start, Sci_PositionU end, WordList *keywordLists[], Accessor &styler )
 | 
			
		||||
{
 | 
			
		||||
    char word[100] = {0};
 | 
			
		||||
    char lowercaseWord[100] = {0};
 | 
			
		||||
 | 
			
		||||
    WordList &Commands = *keywordLists[0];
 | 
			
		||||
    WordList &Parameters = *keywordLists[1];
 | 
			
		||||
    WordList &UserDefined = *keywordLists[2];
 | 
			
		||||
 | 
			
		||||
    for (Sci_PositionU i = 0; i < end - start + 1 && i < 99; i++) {
 | 
			
		||||
        word[i] = static_cast<char>( styler[ start + i ] );
 | 
			
		||||
        lowercaseWord[i] = static_cast<char>(tolower(word[i]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Check for special words...
 | 
			
		||||
    if ( CompareCaseInsensitive(word, "MACRO") == 0 || CompareCaseInsensitive(word, "ENDMACRO") == 0 )
 | 
			
		||||
        return SCE_CMAKE_MACRODEF;
 | 
			
		||||
 | 
			
		||||
    if ( CompareCaseInsensitive(word, "IF") == 0 ||  CompareCaseInsensitive(word, "ENDIF") == 0 )
 | 
			
		||||
        return SCE_CMAKE_IFDEFINEDEF;
 | 
			
		||||
 | 
			
		||||
    if ( CompareCaseInsensitive(word, "ELSEIF") == 0  || CompareCaseInsensitive(word, "ELSE") == 0 )
 | 
			
		||||
        return SCE_CMAKE_IFDEFINEDEF;
 | 
			
		||||
 | 
			
		||||
    if ( CompareCaseInsensitive(word, "WHILE") == 0 || CompareCaseInsensitive(word, "ENDWHILE") == 0)
 | 
			
		||||
        return SCE_CMAKE_WHILEDEF;
 | 
			
		||||
 | 
			
		||||
    if ( CompareCaseInsensitive(word, "FOREACH") == 0 || CompareCaseInsensitive(word, "ENDFOREACH") == 0)
 | 
			
		||||
        return SCE_CMAKE_FOREACHDEF;
 | 
			
		||||
 | 
			
		||||
    if ( Commands.InList(lowercaseWord) )
 | 
			
		||||
        return SCE_CMAKE_COMMANDS;
 | 
			
		||||
 | 
			
		||||
    if ( Parameters.InList(word) )
 | 
			
		||||
        return SCE_CMAKE_PARAMETERS;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if ( UserDefined.InList(word) )
 | 
			
		||||
        return SCE_CMAKE_USERDEFINED;
 | 
			
		||||
 | 
			
		||||
    if ( strlen(word) > 3 ) {
 | 
			
		||||
        if ( word[1] == '{' && word[strlen(word)-1] == '}' )
 | 
			
		||||
            return SCE_CMAKE_VARIABLE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // To check for numbers
 | 
			
		||||
    if ( isCmakeNumber( word[0] ) ) {
 | 
			
		||||
        bool bHasSimpleCmakeNumber = true;
 | 
			
		||||
        for (unsigned int j = 1; j < end - start + 1 && j < 99; j++) {
 | 
			
		||||
            if ( !isCmakeNumber( word[j] ) ) {
 | 
			
		||||
                bHasSimpleCmakeNumber = false;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ( bHasSimpleCmakeNumber )
 | 
			
		||||
            return SCE_CMAKE_NUMBER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return SCE_CMAKE_DEFAULT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseCmakeDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordLists[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
    int state = SCE_CMAKE_DEFAULT;
 | 
			
		||||
    if ( startPos > 0 )
 | 
			
		||||
        state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
 | 
			
		||||
 | 
			
		||||
    styler.StartAt( startPos );
 | 
			
		||||
    styler.GetLine( startPos );
 | 
			
		||||
 | 
			
		||||
    Sci_PositionU nLengthDoc = startPos + length;
 | 
			
		||||
    styler.StartSegment( startPos );
 | 
			
		||||
 | 
			
		||||
    char cCurrChar;
 | 
			
		||||
    bool bVarInString = false;
 | 
			
		||||
    bool bClassicVarInString = false;
 | 
			
		||||
 | 
			
		||||
    Sci_PositionU i;
 | 
			
		||||
    for ( i = startPos; i < nLengthDoc; i++ ) {
 | 
			
		||||
        cCurrChar = styler.SafeGetCharAt( i );
 | 
			
		||||
        char cNextChar = styler.SafeGetCharAt(i+1);
 | 
			
		||||
 | 
			
		||||
        switch (state) {
 | 
			
		||||
        case SCE_CMAKE_DEFAULT:
 | 
			
		||||
            if ( cCurrChar == '#' ) { // we have a comment line
 | 
			
		||||
                styler.ColourTo(i-1, state );
 | 
			
		||||
                state = SCE_CMAKE_COMMENT;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            if ( cCurrChar == '"' ) {
 | 
			
		||||
                styler.ColourTo(i-1, state );
 | 
			
		||||
                state = SCE_CMAKE_STRINGDQ;
 | 
			
		||||
                bVarInString = false;
 | 
			
		||||
                bClassicVarInString = false;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            if ( cCurrChar == '\'' ) {
 | 
			
		||||
                styler.ColourTo(i-1, state );
 | 
			
		||||
                state = SCE_CMAKE_STRINGRQ;
 | 
			
		||||
                bVarInString = false;
 | 
			
		||||
                bClassicVarInString = false;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            if ( cCurrChar == '`' ) {
 | 
			
		||||
                styler.ColourTo(i-1, state );
 | 
			
		||||
                state = SCE_CMAKE_STRINGLQ;
 | 
			
		||||
                bVarInString = false;
 | 
			
		||||
                bClassicVarInString = false;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // CMake Variable
 | 
			
		||||
            if ( cCurrChar == '$' || isCmakeChar(cCurrChar)) {
 | 
			
		||||
                styler.ColourTo(i-1,state);
 | 
			
		||||
                state = SCE_CMAKE_VARIABLE;
 | 
			
		||||
 | 
			
		||||
                // If it is a number, we must check and set style here first...
 | 
			
		||||
                if ( isCmakeNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) )
 | 
			
		||||
                    styler.ColourTo( i, SCE_CMAKE_NUMBER);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            break;
 | 
			
		||||
        case SCE_CMAKE_COMMENT:
 | 
			
		||||
            if ( cCurrChar == '\n' || cCurrChar == '\r' ) {
 | 
			
		||||
                if ( styler.SafeGetCharAt(i-1) == '\\' ) {
 | 
			
		||||
                    styler.ColourTo(i-2,state);
 | 
			
		||||
                    styler.ColourTo(i-1,SCE_CMAKE_DEFAULT);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    styler.ColourTo(i-1,state);
 | 
			
		||||
                    state = SCE_CMAKE_DEFAULT;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case SCE_CMAKE_STRINGDQ:
 | 
			
		||||
        case SCE_CMAKE_STRINGLQ:
 | 
			
		||||
        case SCE_CMAKE_STRINGRQ:
 | 
			
		||||
 | 
			
		||||
            if ( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
 | 
			
		||||
                break; // Ignore the next character, even if it is a quote of some sort
 | 
			
		||||
 | 
			
		||||
            if ( cCurrChar == '"' && state == SCE_CMAKE_STRINGDQ ) {
 | 
			
		||||
                styler.ColourTo(i,state);
 | 
			
		||||
                state = SCE_CMAKE_DEFAULT;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ( cCurrChar == '`' && state == SCE_CMAKE_STRINGLQ ) {
 | 
			
		||||
                styler.ColourTo(i,state);
 | 
			
		||||
                state = SCE_CMAKE_DEFAULT;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ( cCurrChar == '\'' && state == SCE_CMAKE_STRINGRQ ) {
 | 
			
		||||
                styler.ColourTo(i,state);
 | 
			
		||||
                state = SCE_CMAKE_DEFAULT;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ( cNextChar == '\r' || cNextChar == '\n' ) {
 | 
			
		||||
                Sci_Position nCurLine = styler.GetLine(i+1);
 | 
			
		||||
                Sci_Position nBack = i;
 | 
			
		||||
                // We need to check if the previous line has a \ in it...
 | 
			
		||||
                bool bNextLine = false;
 | 
			
		||||
 | 
			
		||||
                while ( nBack > 0 ) {
 | 
			
		||||
                    if ( styler.GetLine(nBack) != nCurLine )
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
 | 
			
		||||
 | 
			
		||||
                    if ( cTemp == '\\' ) {
 | 
			
		||||
                        bNextLine = true;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    if ( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    nBack--;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if ( bNextLine ) {
 | 
			
		||||
                    styler.ColourTo(i+1,state);
 | 
			
		||||
                }
 | 
			
		||||
                if ( bNextLine == false ) {
 | 
			
		||||
                    styler.ColourTo(i,state);
 | 
			
		||||
                    state = SCE_CMAKE_DEFAULT;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case SCE_CMAKE_VARIABLE:
 | 
			
		||||
 | 
			
		||||
            // CMake Variable:
 | 
			
		||||
            if ( cCurrChar == '$' )
 | 
			
		||||
                state = SCE_CMAKE_DEFAULT;
 | 
			
		||||
            else if ( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
 | 
			
		||||
                state = SCE_CMAKE_DEFAULT;
 | 
			
		||||
            else if ( (isCmakeChar(cCurrChar) && !isCmakeChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' ) {
 | 
			
		||||
                state = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler );
 | 
			
		||||
                styler.ColourTo( i, state);
 | 
			
		||||
                state = SCE_CMAKE_DEFAULT;
 | 
			
		||||
            }
 | 
			
		||||
            else if ( !isCmakeChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' ) {
 | 
			
		||||
                if ( classifyWordCmake( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_CMAKE_NUMBER )
 | 
			
		||||
                    styler.ColourTo( i-1, SCE_CMAKE_NUMBER );
 | 
			
		||||
 | 
			
		||||
                state = SCE_CMAKE_DEFAULT;
 | 
			
		||||
 | 
			
		||||
                if ( cCurrChar == '"' ) {
 | 
			
		||||
                    state = SCE_CMAKE_STRINGDQ;
 | 
			
		||||
                    bVarInString = false;
 | 
			
		||||
                    bClassicVarInString = false;
 | 
			
		||||
                }
 | 
			
		||||
                else if ( cCurrChar == '`' ) {
 | 
			
		||||
                    state = SCE_CMAKE_STRINGLQ;
 | 
			
		||||
                    bVarInString = false;
 | 
			
		||||
                    bClassicVarInString = false;
 | 
			
		||||
                }
 | 
			
		||||
                else if ( cCurrChar == '\'' ) {
 | 
			
		||||
                    state = SCE_CMAKE_STRINGRQ;
 | 
			
		||||
                    bVarInString = false;
 | 
			
		||||
                    bClassicVarInString = false;
 | 
			
		||||
                }
 | 
			
		||||
                else if ( cCurrChar == '#' ) {
 | 
			
		||||
                    state = SCE_CMAKE_COMMENT;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ( state == SCE_CMAKE_STRINGDQ || state == SCE_CMAKE_STRINGLQ || state == SCE_CMAKE_STRINGRQ ) {
 | 
			
		||||
            bool bIngoreNextDollarSign = false;
 | 
			
		||||
 | 
			
		||||
            if ( bVarInString && cCurrChar == '$' ) {
 | 
			
		||||
                bVarInString = false;
 | 
			
		||||
                bIngoreNextDollarSign = true;
 | 
			
		||||
            }
 | 
			
		||||
            else if ( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) ) {
 | 
			
		||||
                styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR);
 | 
			
		||||
                bVarInString = false;
 | 
			
		||||
                bIngoreNextDollarSign = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else if ( bVarInString && !isCmakeChar(cNextChar) ) {
 | 
			
		||||
                int nWordState = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler);
 | 
			
		||||
                if ( nWordState == SCE_CMAKE_VARIABLE )
 | 
			
		||||
                    styler.ColourTo( i, SCE_CMAKE_STRINGVAR);
 | 
			
		||||
                bVarInString = false;
 | 
			
		||||
            }
 | 
			
		||||
            // Covers "${TEST}..."
 | 
			
		||||
            else if ( bClassicVarInString && cNextChar == '}' ) {
 | 
			
		||||
                styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR);
 | 
			
		||||
                bClassicVarInString = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Start of var in string
 | 
			
		||||
            if ( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' ) {
 | 
			
		||||
                styler.ColourTo( i-1, state);
 | 
			
		||||
                bClassicVarInString = true;
 | 
			
		||||
                bVarInString = false;
 | 
			
		||||
            }
 | 
			
		||||
            else if ( !bIngoreNextDollarSign && cCurrChar == '$' ) {
 | 
			
		||||
                styler.ColourTo( i-1, state);
 | 
			
		||||
                bVarInString = true;
 | 
			
		||||
                bClassicVarInString = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Colourise remaining document
 | 
			
		||||
    styler.ColourTo(nLengthDoc-1,state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldCmakeDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
    // No folding enabled, no reason to continue...
 | 
			
		||||
    if ( styler.GetPropertyInt("fold") == 0 )
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
 | 
			
		||||
 | 
			
		||||
    Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
    Sci_PositionU safeStartPos = styler.LineStart( lineCurrent );
 | 
			
		||||
 | 
			
		||||
    bool bArg1 = true;
 | 
			
		||||
    Sci_Position nWordStart = -1;
 | 
			
		||||
 | 
			
		||||
    int levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
    if (lineCurrent > 0)
 | 
			
		||||
        levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 | 
			
		||||
    int levelNext = levelCurrent;
 | 
			
		||||
 | 
			
		||||
    for (Sci_PositionU i = safeStartPos; i < startPos + length; i++) {
 | 
			
		||||
        char chCurr = styler.SafeGetCharAt(i);
 | 
			
		||||
 | 
			
		||||
        if ( bArg1 ) {
 | 
			
		||||
            if ( nWordStart == -1 && (isCmakeLetter(chCurr)) ) {
 | 
			
		||||
                nWordStart = i;
 | 
			
		||||
            }
 | 
			
		||||
            else if ( isCmakeLetter(chCurr) == false && nWordStart > -1 ) {
 | 
			
		||||
                int newLevel = calculateFoldCmake( nWordStart, i-1, levelNext, styler, foldAtElse);
 | 
			
		||||
 | 
			
		||||
                if ( newLevel == levelNext ) {
 | 
			
		||||
                    if ( foldAtElse ) {
 | 
			
		||||
                        if ( CmakeNextLineHasElse(i, startPos + length, styler) )
 | 
			
		||||
                            levelNext--;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    levelNext = newLevel;
 | 
			
		||||
                bArg1 = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ( chCurr == '\n' ) {
 | 
			
		||||
            if ( bArg1 && foldAtElse) {
 | 
			
		||||
                if ( CmakeNextLineHasElse(i, startPos + length, styler) )
 | 
			
		||||
                    levelNext--;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // If we are on a new line...
 | 
			
		||||
            int levelUse = levelCurrent;
 | 
			
		||||
            int lev = levelUse | levelNext << 16;
 | 
			
		||||
            if (levelUse < levelNext )
 | 
			
		||||
                lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
            if (lev != styler.LevelAt(lineCurrent))
 | 
			
		||||
                styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
 | 
			
		||||
            lineCurrent++;
 | 
			
		||||
            levelCurrent = levelNext;
 | 
			
		||||
            bArg1 = true; // New line, lets look at first argument again
 | 
			
		||||
            nWordStart = -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int levelUse = levelCurrent;
 | 
			
		||||
    int lev = levelUse | levelNext << 16;
 | 
			
		||||
    if (levelUse < levelNext)
 | 
			
		||||
        lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
    if (lev != styler.LevelAt(lineCurrent))
 | 
			
		||||
        styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const cmakeWordLists[] = {
 | 
			
		||||
    "Commands",
 | 
			
		||||
    "Parameters",
 | 
			
		||||
    "UserDefined",
 | 
			
		||||
    0,
 | 
			
		||||
    0,};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmCmake(SCLEX_CMAKE, ColouriseCmakeDoc, "cmake", FoldCmakeDoc, cmakeWordLists);
 | 
			
		||||
							
								
								
									
										494
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCoffeeScript.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										494
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCoffeeScript.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,494 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexCoffeeScript.cxx
 | 
			
		||||
 ** Lexer for CoffeeScript.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// Based on the Scintilla C++ Lexer
 | 
			
		||||
// Written by Eric Promislow <ericp@activestate.com> in 2011 for the Komodo IDE
 | 
			
		||||
// 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 <ctype.h>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
static bool IsSpaceEquiv(int state) {
 | 
			
		||||
	return (state == SCE_COFFEESCRIPT_DEFAULT
 | 
			
		||||
	    || state == SCE_COFFEESCRIPT_COMMENTLINE
 | 
			
		||||
	    || state == SCE_COFFEESCRIPT_COMMENTBLOCK
 | 
			
		||||
	    || state == SCE_COFFEESCRIPT_VERBOSE_REGEX
 | 
			
		||||
	    || state == SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT
 | 
			
		||||
	    || state == SCE_COFFEESCRIPT_WORD
 | 
			
		||||
	    || state == SCE_COFFEESCRIPT_REGEX);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Store the current lexer state and brace count prior to starting a new
 | 
			
		||||
// `#{}` interpolation level.
 | 
			
		||||
// Based on LexRuby.cxx.
 | 
			
		||||
static void enterInnerExpression(int  *p_inner_string_types,
 | 
			
		||||
                                 int  *p_inner_expn_brace_counts,
 | 
			
		||||
                                 int&  inner_string_count,
 | 
			
		||||
                                 int   state,
 | 
			
		||||
                                 int&  brace_counts
 | 
			
		||||
                                 ) {
 | 
			
		||||
	p_inner_string_types[inner_string_count] = state;
 | 
			
		||||
	p_inner_expn_brace_counts[inner_string_count] = brace_counts;
 | 
			
		||||
	brace_counts = 0;
 | 
			
		||||
	++inner_string_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Restore the lexer state and brace count for the previous `#{}` interpolation
 | 
			
		||||
// level upon returning to it.
 | 
			
		||||
// Note the previous lexer state is the return value and needs to be restored
 | 
			
		||||
// manually by the StyleContext.
 | 
			
		||||
// Based on LexRuby.cxx.
 | 
			
		||||
static int exitInnerExpression(int  *p_inner_string_types,
 | 
			
		||||
                               int  *p_inner_expn_brace_counts,
 | 
			
		||||
                               int&  inner_string_count,
 | 
			
		||||
                               int&  brace_counts
 | 
			
		||||
                              ) {
 | 
			
		||||
	--inner_string_count;
 | 
			
		||||
	brace_counts = p_inner_expn_brace_counts[inner_string_count];
 | 
			
		||||
	return p_inner_string_types[inner_string_count];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Preconditions: sc.currentPos points to a character after '+' or '-'.
 | 
			
		||||
// The test for pos reaching 0 should be redundant,
 | 
			
		||||
// and is in only for safety measures.
 | 
			
		||||
// Limitation: this code will give the incorrect answer for code like
 | 
			
		||||
// a = b+++/ptn/...
 | 
			
		||||
// Putting a space between the '++' post-inc operator and the '+' binary op
 | 
			
		||||
// fixes this, and is highly recommended for readability anyway.
 | 
			
		||||
static bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) {
 | 
			
		||||
	Sci_Position pos = (Sci_Position) sc.currentPos;
 | 
			
		||||
	while (--pos > 0) {
 | 
			
		||||
		char ch = styler[pos];
 | 
			
		||||
		if (ch == '+' || ch == '-') {
 | 
			
		||||
			return styler[pos - 1] == ch;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool followsKeyword(StyleContext &sc, Accessor &styler) {
 | 
			
		||||
	Sci_Position pos = (Sci_Position) sc.currentPos;
 | 
			
		||||
	Sci_Position currentLine = styler.GetLine(pos);
 | 
			
		||||
	Sci_Position lineStartPos = styler.LineStart(currentLine);
 | 
			
		||||
	while (--pos > lineStartPos) {
 | 
			
		||||
		char ch = styler.SafeGetCharAt(pos);
 | 
			
		||||
		if (ch != ' ' && ch != '\t') {
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	styler.Flush();
 | 
			
		||||
	return styler.StyleAt(pos) == SCE_COFFEESCRIPT_WORD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(__clang__)
 | 
			
		||||
#if __has_warning("-Wunused-but-set-variable")
 | 
			
		||||
// Disable warning for visibleChars
 | 
			
		||||
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void ColouriseCoffeeScriptDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
	WordList &keywords2 = *keywordlists[1];
 | 
			
		||||
	WordList &keywords4 = *keywordlists[3];
 | 
			
		||||
 | 
			
		||||
	CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
 | 
			
		||||
	CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
 | 
			
		||||
 | 
			
		||||
	CharacterSet setWordStart(CharacterSet::setAlpha, "_$@", 0x80, true);
 | 
			
		||||
	CharacterSet setWord(CharacterSet::setAlphaNum, "._$", 0x80, true);
 | 
			
		||||
 | 
			
		||||
	int chPrevNonWhite = ' ';
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
 | 
			
		||||
	// String/Regex interpolation variables, based on LexRuby.cxx.
 | 
			
		||||
	// In most cases a value of 2 should be ample for the code the user is
 | 
			
		||||
	// likely to enter. For example,
 | 
			
		||||
	//   "Filling the #{container} with #{liquid}..."
 | 
			
		||||
	// from the CoffeeScript homepage nests to a level of 2
 | 
			
		||||
	// If the user actually hits a 6th occurrence of '#{' in a double-quoted
 | 
			
		||||
	// string (including regexes), it will stay as a string.  The problem with
 | 
			
		||||
	// this is that quotes might flip, a 7th '#{' will look like a comment,
 | 
			
		||||
	// and code-folding might be wrong.
 | 
			
		||||
#define INNER_STRINGS_MAX_COUNT 5
 | 
			
		||||
	// These vars track our instances of "...#{,,,'..#{,,,}...',,,}..."
 | 
			
		||||
	int inner_string_types[INNER_STRINGS_MAX_COUNT];
 | 
			
		||||
	// Track # braces when we push a new #{ thing
 | 
			
		||||
	int inner_expn_brace_counts[INNER_STRINGS_MAX_COUNT];
 | 
			
		||||
	int inner_string_count = 0;
 | 
			
		||||
	int brace_counts = 0;   // Number of #{ ... } things within an expression
 | 
			
		||||
	for (int i = 0; i < INNER_STRINGS_MAX_COUNT; i++) {
 | 
			
		||||
		inner_string_types[i] = 0;
 | 
			
		||||
		inner_expn_brace_counts[i] = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// look back to set chPrevNonWhite properly for better regex colouring
 | 
			
		||||
	Sci_Position endPos = startPos + length;
 | 
			
		||||
        if (startPos > 0 && IsSpaceEquiv(initStyle)) {
 | 
			
		||||
		Sci_PositionU back = startPos;
 | 
			
		||||
		styler.Flush();
 | 
			
		||||
		while (back > 0 && IsSpaceEquiv(styler.StyleAt(--back)))
 | 
			
		||||
			;
 | 
			
		||||
		if (styler.StyleAt(back) == SCE_COFFEESCRIPT_OPERATOR) {
 | 
			
		||||
			chPrevNonWhite = styler.SafeGetCharAt(back);
 | 
			
		||||
		}
 | 
			
		||||
		if (startPos != back) {
 | 
			
		||||
			initStyle = styler.StyleAt(back);
 | 
			
		||||
			if (IsSpaceEquiv(initStyle)) {
 | 
			
		||||
				initStyle = SCE_COFFEESCRIPT_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		startPos = back;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, endPos - startPos, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More();) {
 | 
			
		||||
 | 
			
		||||
		if (sc.atLineStart) {
 | 
			
		||||
			// Reset states to beginning of colourise so no surprises
 | 
			
		||||
			// if different sets of lines lexed.
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		switch (sc.state) {
 | 
			
		||||
			case SCE_COFFEESCRIPT_OPERATOR:
 | 
			
		||||
				sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_COFFEESCRIPT_NUMBER:
 | 
			
		||||
				// We accept almost anything because of hex. and number suffixes
 | 
			
		||||
				if (!setWord.Contains(sc.ch) || sc.Match('.', '.')) {
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_COFFEESCRIPT_IDENTIFIER:
 | 
			
		||||
				if (!setWord.Contains(sc.ch) || (sc.ch == '.') || (sc.ch == '$')) {
 | 
			
		||||
					char s[1000];
 | 
			
		||||
					sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
					if (keywords.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_COFFEESCRIPT_WORD);
 | 
			
		||||
					} else if (keywords2.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_COFFEESCRIPT_WORD2);
 | 
			
		||||
					} else if (keywords4.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_COFFEESCRIPT_GLOBALCLASS);
 | 
			
		||||
					} else if (sc.LengthCurrent() > 0 && s[0] == '@') {
 | 
			
		||||
						sc.ChangeState(SCE_COFFEESCRIPT_INSTANCEPROPERTY);
 | 
			
		||||
					}
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_COFFEESCRIPT_WORD:
 | 
			
		||||
			case SCE_COFFEESCRIPT_WORD2:
 | 
			
		||||
			case SCE_COFFEESCRIPT_GLOBALCLASS:
 | 
			
		||||
			case SCE_COFFEESCRIPT_INSTANCEPROPERTY:
 | 
			
		||||
				if (!setWord.Contains(sc.ch)) {
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_COFFEESCRIPT_COMMENTLINE:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_COFFEESCRIPT_STRING:
 | 
			
		||||
				if (sc.ch == '\\') {
 | 
			
		||||
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.ch == '\"') {
 | 
			
		||||
					sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				} else if (sc.ch == '#' && sc.chNext == '{' && inner_string_count < INNER_STRINGS_MAX_COUNT) {
 | 
			
		||||
					// process interpolated code #{ ... }
 | 
			
		||||
					enterInnerExpression(inner_string_types,
 | 
			
		||||
					                     inner_expn_brace_counts,
 | 
			
		||||
					                     inner_string_count,
 | 
			
		||||
					                     sc.state,
 | 
			
		||||
					                     brace_counts);
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_OPERATOR);
 | 
			
		||||
					sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_COFFEESCRIPT_CHARACTER:
 | 
			
		||||
				if (sc.ch == '\\') {
 | 
			
		||||
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.ch == '\'') {
 | 
			
		||||
					sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_COFFEESCRIPT_REGEX:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				} else if (sc.ch == '/') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					while ((sc.ch < 0x80) && islower(sc.ch))
 | 
			
		||||
						sc.Forward();    // gobble regex flags
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				} else if (sc.ch == '\\') {
 | 
			
		||||
					// Gobble up the quoted character
 | 
			
		||||
					if (sc.chNext == '\\' || sc.chNext == '/') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_COFFEESCRIPT_STRINGEOL:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_COFFEESCRIPT_COMMENTBLOCK:
 | 
			
		||||
				if (sc.Match("###")) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				} else if (sc.ch == '\\') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_COFFEESCRIPT_VERBOSE_REGEX:
 | 
			
		||||
				if (sc.Match("///")) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
 | 
			
		||||
				} else if (sc.Match('#')) {
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT);
 | 
			
		||||
				} else if (sc.ch == '\\') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_COFFEESCRIPT_DEFAULT) {
 | 
			
		||||
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_COFFEESCRIPT_NUMBER);
 | 
			
		||||
			} else if (setWordStart.Contains(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_COFFEESCRIPT_IDENTIFIER);
 | 
			
		||||
			} else if (sc.Match("///")) {
 | 
			
		||||
				sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.ch == '/'
 | 
			
		||||
				   && (setOKBeforeRE.Contains(chPrevNonWhite)
 | 
			
		||||
				       || followsKeyword(sc, styler))
 | 
			
		||||
				   && (!setCouldBePostOp.Contains(chPrevNonWhite)
 | 
			
		||||
				       || !FollowsPostfixOperator(sc, styler))) {
 | 
			
		||||
				sc.SetState(SCE_COFFEESCRIPT_REGEX);	// JavaScript's RegEx
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_COFFEESCRIPT_STRING);
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(SCE_COFFEESCRIPT_CHARACTER);
 | 
			
		||||
			} else if (sc.ch == '#') {
 | 
			
		||||
				if (sc.Match("###")) {
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_COMMENTBLOCK);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_COFFEESCRIPT_COMMENTLINE);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (isoperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_COFFEESCRIPT_OPERATOR);
 | 
			
		||||
				// Handle '..' and '...' operators correctly.
 | 
			
		||||
				if (sc.ch == '.') {
 | 
			
		||||
					for (int i = 0; i < 2 && sc.chNext == '.'; i++, sc.Forward()) ;
 | 
			
		||||
				} else if (sc.ch == '{') {
 | 
			
		||||
					++brace_counts;
 | 
			
		||||
				} else if (sc.ch == '}' && --brace_counts <= 0 && inner_string_count > 0) {
 | 
			
		||||
					// Return to previous state before #{ ... }
 | 
			
		||||
					sc.ForwardSetState(exitInnerExpression(inner_string_types,
 | 
			
		||||
					                                       inner_expn_brace_counts,
 | 
			
		||||
					                                       inner_string_count,
 | 
			
		||||
					                                       brace_counts));
 | 
			
		||||
					continue; // skip sc.Forward() at loop end
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
 | 
			
		||||
			chPrevNonWhite = sc.ch;
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
		sc.Forward();
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsCommentLine(Sci_Position line, Accessor &styler) {
 | 
			
		||||
	Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
	Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
	for (Sci_Position i = pos; i < eol_pos; i++) {
 | 
			
		||||
		char ch = styler[i];
 | 
			
		||||
		if (ch == '#')
 | 
			
		||||
			return true;
 | 
			
		||||
		else if (ch != ' ' && ch != '\t')
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldCoffeeScriptDoc(Sci_PositionU startPos, Sci_Position length, int,
 | 
			
		||||
				WordList *[], Accessor &styler) {
 | 
			
		||||
	// A simplified version of FoldPyDoc
 | 
			
		||||
	const Sci_Position maxPos = startPos + length;
 | 
			
		||||
	const Sci_Position maxLines = styler.GetLine(maxPos - 1);             // Requested last line
 | 
			
		||||
	const Sci_Position docLines = styler.GetLine(styler.Length() - 1);  // Available last line
 | 
			
		||||
 | 
			
		||||
	// property fold.coffeescript.comment
 | 
			
		||||
	// Set to 1 to allow folding of comment blocks in CoffeeScript.
 | 
			
		||||
	const bool foldComment = styler.GetPropertyInt("fold.coffeescript.comment") != 0;
 | 
			
		||||
 | 
			
		||||
	const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;
 | 
			
		||||
 | 
			
		||||
	// Backtrack to previous non-blank line so we can determine indent level
 | 
			
		||||
	// for any white space lines
 | 
			
		||||
	// and so we can fix any preceding fold level (which is why we go back
 | 
			
		||||
	// at least one line in all cases)
 | 
			
		||||
	int spaceFlags = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
 | 
			
		||||
	while (lineCurrent > 0) {
 | 
			
		||||
		lineCurrent--;
 | 
			
		||||
		indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
 | 
			
		||||
		if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)
 | 
			
		||||
		    && !IsCommentLine(lineCurrent, styler))
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
 | 
			
		||||
	// Set up initial loop state
 | 
			
		||||
	int prevComment = 0;
 | 
			
		||||
	if (lineCurrent >= 1)
 | 
			
		||||
		prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);
 | 
			
		||||
 | 
			
		||||
	// Process all characters to end of requested range
 | 
			
		||||
	// or comment that hangs over the end of the range.  Cap processing in all cases
 | 
			
		||||
	// to end of document (in case of comment at end).
 | 
			
		||||
	while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevComment)) {
 | 
			
		||||
 | 
			
		||||
		// Gather info
 | 
			
		||||
		int lev = indentCurrent;
 | 
			
		||||
		Sci_Position lineNext = lineCurrent + 1;
 | 
			
		||||
		int indentNext = indentCurrent;
 | 
			
		||||
		if (lineNext <= docLines) {
 | 
			
		||||
			// Information about next line is only available if not at end of document
 | 
			
		||||
			indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		const int comment = foldComment && IsCommentLine(lineCurrent, styler);
 | 
			
		||||
		const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
 | 
			
		||||
		                           IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE));
 | 
			
		||||
		const int comment_continue = (comment && prevComment);
 | 
			
		||||
		if (!comment)
 | 
			
		||||
			indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
		if (indentNext & SC_FOLDLEVELWHITEFLAG)
 | 
			
		||||
			indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
 | 
			
		||||
 | 
			
		||||
		if (comment_start) {
 | 
			
		||||
			// Place fold point at start of a block of comments
 | 
			
		||||
			lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		} else if (comment_continue) {
 | 
			
		||||
			// Add level to rest of lines in the block
 | 
			
		||||
			lev = lev + 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Skip past any blank lines for next indent level info; we skip also
 | 
			
		||||
		// comments (all comments, not just those starting in column 0)
 | 
			
		||||
		// which effectively folds them into surrounding code rather
 | 
			
		||||
		// than screwing up folding.
 | 
			
		||||
 | 
			
		||||
		while ((lineNext < docLines) &&
 | 
			
		||||
		        ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
 | 
			
		||||
		         (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
 | 
			
		||||
 | 
			
		||||
			lineNext++;
 | 
			
		||||
			indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
		const int levelBeforeComments = std::max(indentCurrentLevel,levelAfterComments);
 | 
			
		||||
 | 
			
		||||
		// Now set all the indent levels on the lines we skipped
 | 
			
		||||
		// Do this from end to start.  Once we encounter one line
 | 
			
		||||
		// which is indented more than the line after the end of
 | 
			
		||||
		// the comment-block, use the level of the block before
 | 
			
		||||
 | 
			
		||||
		Sci_Position skipLine = lineNext;
 | 
			
		||||
		int skipLevel = levelAfterComments;
 | 
			
		||||
 | 
			
		||||
		while (--skipLine > lineCurrent) {
 | 
			
		||||
			int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
 | 
			
		||||
 | 
			
		||||
			if (foldCompact) {
 | 
			
		||||
				if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
 | 
			
		||||
					skipLevel = levelBeforeComments;
 | 
			
		||||
 | 
			
		||||
				int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
 | 
			
		||||
				styler.SetLevel(skipLine, skipLevel | whiteFlag);
 | 
			
		||||
			} else {
 | 
			
		||||
				if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&
 | 
			
		||||
					!(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
 | 
			
		||||
					!IsCommentLine(skipLine, styler))
 | 
			
		||||
					skipLevel = levelBeforeComments;
 | 
			
		||||
 | 
			
		||||
				styler.SetLevel(skipLine, skipLevel);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Set fold header on non-comment line
 | 
			
		||||
		if (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
 | 
			
		||||
			if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Keep track of block comment state of previous line
 | 
			
		||||
		prevComment = comment_start || comment_continue;
 | 
			
		||||
 | 
			
		||||
		// Set fold level for this line and move to next line
 | 
			
		||||
		styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
		indentCurrent = indentNext;
 | 
			
		||||
		lineCurrent = lineNext;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *const csWordLists[] = {
 | 
			
		||||
            "Keywords",
 | 
			
		||||
            "Secondary keywords",
 | 
			
		||||
            "Unused",
 | 
			
		||||
            "Global classes",
 | 
			
		||||
            0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmCoffeeScript(SCLEX_COFFEESCRIPT, ColouriseCoffeeScriptDoc, "coffeescript", FoldCoffeeScriptDoc, csWordLists);
 | 
			
		||||
							
								
								
									
										193
									
								
								3rdparty/lexilla540/lexilla/lexers/LexConf.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								3rdparty/lexilla540/lexilla/lexers/LexConf.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,193 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexConf.cxx
 | 
			
		||||
 ** Lexer for Apache Configuration Files.
 | 
			
		||||
 **
 | 
			
		||||
 ** First working version contributed by Ahmad Zawawi <ahmad.zawawi@gmail.com> on October 28, 2000.
 | 
			
		||||
 ** i created this lexer because i needed something pretty when dealing
 | 
			
		||||
 ** when Apache Configuration files...
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static void ColouriseConfDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordLists[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
	int state = SCE_CONF_DEFAULT;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	Sci_Position lengthDoc = startPos + length;
 | 
			
		||||
	// create a buffer large enough to take the largest chunk...
 | 
			
		||||
	char *buffer = new char[length+1];
 | 
			
		||||
	Sci_Position bufferCount = 0;
 | 
			
		||||
 | 
			
		||||
	// this assumes that we have 2 keyword list in conf.properties
 | 
			
		||||
	WordList &directives = *keywordLists[0];
 | 
			
		||||
	WordList ¶ms = *keywordLists[1];
 | 
			
		||||
 | 
			
		||||
	// go through all provided text segment
 | 
			
		||||
	// using the hand-written state machine shown below
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
	for (Sci_Position i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
		if (styler.IsLeadByte(ch)) {
 | 
			
		||||
			chNext = styler.SafeGetCharAt(i + 2);
 | 
			
		||||
			i++;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		switch(state) {
 | 
			
		||||
			case SCE_CONF_DEFAULT:
 | 
			
		||||
				if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
 | 
			
		||||
					// whitespace is simply ignored here...
 | 
			
		||||
					styler.ColourTo(i,SCE_CONF_DEFAULT);
 | 
			
		||||
					break;
 | 
			
		||||
				} else if( ch == '#' ) {
 | 
			
		||||
					// signals the start of a comment...
 | 
			
		||||
					state = SCE_CONF_COMMENT;
 | 
			
		||||
					styler.ColourTo(i,SCE_CONF_COMMENT);
 | 
			
		||||
				} else if( ch == '.' /*|| ch == '/'*/) {
 | 
			
		||||
					// signals the start of a file...
 | 
			
		||||
					state = SCE_CONF_EXTENSION;
 | 
			
		||||
					styler.ColourTo(i,SCE_CONF_EXTENSION);
 | 
			
		||||
				} else if( ch == '"') {
 | 
			
		||||
					state = SCE_CONF_STRING;
 | 
			
		||||
					styler.ColourTo(i,SCE_CONF_STRING);
 | 
			
		||||
				} else if( IsASCII(ch) && ispunct(ch) ) {
 | 
			
		||||
					// signals an operator...
 | 
			
		||||
					// no state jump necessary for this
 | 
			
		||||
					// simple case...
 | 
			
		||||
					styler.ColourTo(i,SCE_CONF_OPERATOR);
 | 
			
		||||
				} else if( IsASCII(ch) && isalpha(ch) ) {
 | 
			
		||||
					// signals the start of an identifier
 | 
			
		||||
					bufferCount = 0;
 | 
			
		||||
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
 | 
			
		||||
					state = SCE_CONF_IDENTIFIER;
 | 
			
		||||
				} else if( IsASCII(ch) && isdigit(ch) ) {
 | 
			
		||||
					// signals the start of a number
 | 
			
		||||
					bufferCount = 0;
 | 
			
		||||
					buffer[bufferCount++] = ch;
 | 
			
		||||
					//styler.ColourTo(i,SCE_CONF_NUMBER);
 | 
			
		||||
					state = SCE_CONF_NUMBER;
 | 
			
		||||
				} else {
 | 
			
		||||
					// style it the default style..
 | 
			
		||||
					styler.ColourTo(i,SCE_CONF_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_CONF_COMMENT:
 | 
			
		||||
				// if we find a newline here,
 | 
			
		||||
				// we simply go to default state
 | 
			
		||||
				// else continue to work on it...
 | 
			
		||||
				if( ch == '\n' || ch == '\r' ) {
 | 
			
		||||
					state = SCE_CONF_DEFAULT;
 | 
			
		||||
				} else {
 | 
			
		||||
					styler.ColourTo(i,SCE_CONF_COMMENT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_CONF_EXTENSION:
 | 
			
		||||
				// if we find a non-alphanumeric char,
 | 
			
		||||
				// we simply go to default state
 | 
			
		||||
				// else we're still dealing with an extension...
 | 
			
		||||
				if( (IsASCII(ch) && isalnum(ch)) || (ch == '_') ||
 | 
			
		||||
					(ch == '-') || (ch == '$') ||
 | 
			
		||||
					(ch == '/') || (ch == '.') || (ch == '*') )
 | 
			
		||||
				{
 | 
			
		||||
					styler.ColourTo(i,SCE_CONF_EXTENSION);
 | 
			
		||||
				} else {
 | 
			
		||||
					state = SCE_CONF_DEFAULT;
 | 
			
		||||
					chNext = styler[i--];
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_CONF_STRING:
 | 
			
		||||
				// if we find the end of a string char, we simply go to default state
 | 
			
		||||
				// else we're still dealing with an string...
 | 
			
		||||
				if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') || (ch == '\n') || (ch == '\r') ) {
 | 
			
		||||
					state = SCE_CONF_DEFAULT;
 | 
			
		||||
				}
 | 
			
		||||
				styler.ColourTo(i,SCE_CONF_STRING);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_CONF_IDENTIFIER:
 | 
			
		||||
				// stay  in CONF_IDENTIFIER state until we find a non-alphanumeric
 | 
			
		||||
				if( (IsASCII(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
 | 
			
		||||
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
 | 
			
		||||
				} else {
 | 
			
		||||
					state = SCE_CONF_DEFAULT;
 | 
			
		||||
					buffer[bufferCount] = '\0';
 | 
			
		||||
 | 
			
		||||
					// check if the buffer contains a keyword, and highlight it if it is a keyword...
 | 
			
		||||
					if(directives.InList(buffer)) {
 | 
			
		||||
						styler.ColourTo(i-1,SCE_CONF_DIRECTIVE );
 | 
			
		||||
					} else if(params.InList(buffer)) {
 | 
			
		||||
						styler.ColourTo(i-1,SCE_CONF_PARAMETER );
 | 
			
		||||
					} else if(strchr(buffer,'/') || strchr(buffer,'.')) {
 | 
			
		||||
						styler.ColourTo(i-1,SCE_CONF_EXTENSION);
 | 
			
		||||
					} else {
 | 
			
		||||
						styler.ColourTo(i-1,SCE_CONF_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// push back the faulty character
 | 
			
		||||
					chNext = styler[i--];
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_CONF_NUMBER:
 | 
			
		||||
				// stay  in CONF_NUMBER state until we find a non-numeric
 | 
			
		||||
				if( (IsASCII(ch) && isdigit(ch)) || ch == '.') {
 | 
			
		||||
					buffer[bufferCount++] = ch;
 | 
			
		||||
				} else {
 | 
			
		||||
					state = SCE_CONF_DEFAULT;
 | 
			
		||||
					buffer[bufferCount] = '\0';
 | 
			
		||||
 | 
			
		||||
					// Colourize here...
 | 
			
		||||
					if( strchr(buffer,'.') ) {
 | 
			
		||||
						// it is an IP address...
 | 
			
		||||
						styler.ColourTo(i-1,SCE_CONF_IP);
 | 
			
		||||
					} else {
 | 
			
		||||
						// normal number
 | 
			
		||||
						styler.ColourTo(i-1,SCE_CONF_NUMBER);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// push back a character
 | 
			
		||||
					chNext = styler[i--];
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	delete []buffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const confWordListDesc[] = {
 | 
			
		||||
	"Directives",
 | 
			
		||||
	"Parameters",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);
 | 
			
		||||
							
								
								
									
										227
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCrontab.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCrontab.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,227 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexCrontab.cxx
 | 
			
		||||
 ** Lexer to use with extended crontab files used by a powerful
 | 
			
		||||
 ** Windows scheduler/event monitor/automation manager nnCron.
 | 
			
		||||
 ** (http://nemtsev.eserv.ru/)
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static void ColouriseNncrontabDoc(Sci_PositionU startPos, Sci_Position length, int, WordList
 | 
			
		||||
*keywordLists[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
	int state = SCE_NNCRONTAB_DEFAULT;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	Sci_Position lengthDoc = startPos + length;
 | 
			
		||||
	// create a buffer large enough to take the largest chunk...
 | 
			
		||||
	char *buffer = new char[length+1];
 | 
			
		||||
	Sci_Position bufferCount = 0;
 | 
			
		||||
	// used when highliting environment variables inside quoted string:
 | 
			
		||||
	bool insideString = false;
 | 
			
		||||
 | 
			
		||||
	// this assumes that we have 3 keyword list in conf.properties
 | 
			
		||||
	WordList §ion = *keywordLists[0];
 | 
			
		||||
	WordList &keyword = *keywordLists[1];
 | 
			
		||||
	WordList &modifier = *keywordLists[2];
 | 
			
		||||
 | 
			
		||||
	// go through all provided text segment
 | 
			
		||||
	// using the hand-written state machine shown below
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
	for (Sci_Position i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
		if (styler.IsLeadByte(ch)) {
 | 
			
		||||
			chNext = styler.SafeGetCharAt(i + 2);
 | 
			
		||||
			i++;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		switch(state) {
 | 
			
		||||
			case SCE_NNCRONTAB_DEFAULT:
 | 
			
		||||
				if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
 | 
			
		||||
					// whitespace is simply ignored here...
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);
 | 
			
		||||
					break;
 | 
			
		||||
				} else if( ch == '#' && styler.SafeGetCharAt(i+1) == '(') {
 | 
			
		||||
					// signals the start of a task...
 | 
			
		||||
					state = SCE_NNCRONTAB_TASK;
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_TASK);
 | 
			
		||||
				}
 | 
			
		||||
				  else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' ||
 | 
			
		||||
										 styler.SafeGetCharAt(i+1) == '\t')) {
 | 
			
		||||
					// signals the start of an extended comment...
 | 
			
		||||
					state = SCE_NNCRONTAB_COMMENT;
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
 | 
			
		||||
				} else if( ch == '#' ) {
 | 
			
		||||
					// signals the start of a plain comment...
 | 
			
		||||
					state = SCE_NNCRONTAB_COMMENT;
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
 | 
			
		||||
				} else if( ch == ')' && styler.SafeGetCharAt(i+1) == '#') {
 | 
			
		||||
					// signals the end of a task...
 | 
			
		||||
					state = SCE_NNCRONTAB_TASK;
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_TASK);
 | 
			
		||||
				} else if( ch == '"') {
 | 
			
		||||
					state = SCE_NNCRONTAB_STRING;
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_STRING);
 | 
			
		||||
				} else if( ch == '%') {
 | 
			
		||||
					// signals environment variables
 | 
			
		||||
					state = SCE_NNCRONTAB_ENVIRONMENT;
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
 | 
			
		||||
				} else if( ch == '<' && styler.SafeGetCharAt(i+1) == '%') {
 | 
			
		||||
					// signals environment variables
 | 
			
		||||
					state = SCE_NNCRONTAB_ENVIRONMENT;
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
 | 
			
		||||
				} else if( ch == '*' ) {
 | 
			
		||||
					// signals an asterisk
 | 
			
		||||
					// no state jump necessary for this simple case...
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_ASTERISK);
 | 
			
		||||
				} else if( (IsASCII(ch) && isalpha(ch)) || ch == '<' ) {
 | 
			
		||||
					// signals the start of an identifier
 | 
			
		||||
					bufferCount = 0;
 | 
			
		||||
					buffer[bufferCount++] = ch;
 | 
			
		||||
					state = SCE_NNCRONTAB_IDENTIFIER;
 | 
			
		||||
				} else if( IsASCII(ch) && isdigit(ch) ) {
 | 
			
		||||
					// signals the start of a number
 | 
			
		||||
					bufferCount = 0;
 | 
			
		||||
					buffer[bufferCount++] = ch;
 | 
			
		||||
					state = SCE_NNCRONTAB_NUMBER;
 | 
			
		||||
				} else {
 | 
			
		||||
					// style it the default style..
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_NNCRONTAB_COMMENT:
 | 
			
		||||
				// if we find a newline here,
 | 
			
		||||
				// we simply go to default state
 | 
			
		||||
				// else continue to work on it...
 | 
			
		||||
				if( ch == '\n' || ch == '\r' ) {
 | 
			
		||||
					state = SCE_NNCRONTAB_DEFAULT;
 | 
			
		||||
				} else {
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_NNCRONTAB_TASK:
 | 
			
		||||
				// if we find a newline here,
 | 
			
		||||
				// we simply go to default state
 | 
			
		||||
				// else continue to work on it...
 | 
			
		||||
				if( ch == '\n' || ch == '\r' ) {
 | 
			
		||||
					state = SCE_NNCRONTAB_DEFAULT;
 | 
			
		||||
				} else {
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_TASK);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_NNCRONTAB_STRING:
 | 
			
		||||
				if( ch == '%' ) {
 | 
			
		||||
					state = SCE_NNCRONTAB_ENVIRONMENT;
 | 
			
		||||
					insideString = true;
 | 
			
		||||
					styler.ColourTo(i-1,SCE_NNCRONTAB_STRING);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				// if we find the end of a string char, we simply go to default state
 | 
			
		||||
				// else we're still dealing with an string...
 | 
			
		||||
				if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') ||
 | 
			
		||||
					(ch == '\n') || (ch == '\r') ) {
 | 
			
		||||
					state = SCE_NNCRONTAB_DEFAULT;
 | 
			
		||||
				}
 | 
			
		||||
				styler.ColourTo(i,SCE_NNCRONTAB_STRING);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_NNCRONTAB_ENVIRONMENT:
 | 
			
		||||
				// if we find the end of a string char, we simply go to default state
 | 
			
		||||
				// else we're still dealing with an string...
 | 
			
		||||
				if( ch == '%' && insideString ) {
 | 
			
		||||
					state = SCE_NNCRONTAB_STRING;
 | 
			
		||||
					insideString = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				if( (ch == '%' && styler.SafeGetCharAt(i-1)!='\\')
 | 
			
		||||
					|| (ch == '\n') || (ch == '\r') || (ch == '>') ) {
 | 
			
		||||
					state = SCE_NNCRONTAB_DEFAULT;
 | 
			
		||||
					styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				styler.ColourTo(i+1,SCE_NNCRONTAB_ENVIRONMENT);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_NNCRONTAB_IDENTIFIER:
 | 
			
		||||
				// stay  in CONF_IDENTIFIER state until we find a non-alphanumeric
 | 
			
		||||
				if( (IsASCII(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') ||
 | 
			
		||||
					(ch == '$') || (ch == '.') || (ch == '<') || (ch == '>') ||
 | 
			
		||||
					(ch == '@') ) {
 | 
			
		||||
					buffer[bufferCount++] = ch;
 | 
			
		||||
				} else {
 | 
			
		||||
					state = SCE_NNCRONTAB_DEFAULT;
 | 
			
		||||
					buffer[bufferCount] = '\0';
 | 
			
		||||
 | 
			
		||||
					// check if the buffer contains a keyword,
 | 
			
		||||
					// and highlight it if it is a keyword...
 | 
			
		||||
					if(section.InList(buffer)) {
 | 
			
		||||
						styler.ColourTo(i,SCE_NNCRONTAB_SECTION );
 | 
			
		||||
					} else if(keyword.InList(buffer)) {
 | 
			
		||||
						styler.ColourTo(i-1,SCE_NNCRONTAB_KEYWORD );
 | 
			
		||||
					} // else if(strchr(buffer,'/') || strchr(buffer,'.')) {
 | 
			
		||||
					//	styler.ColourTo(i-1,SCE_NNCRONTAB_EXTENSION);
 | 
			
		||||
					// }
 | 
			
		||||
					  else if(modifier.InList(buffer)) {
 | 
			
		||||
						styler.ColourTo(i-1,SCE_NNCRONTAB_MODIFIER );
 | 
			
		||||
					  }	else {
 | 
			
		||||
						styler.ColourTo(i-1,SCE_NNCRONTAB_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
					// push back the faulty character
 | 
			
		||||
					chNext = styler[i--];
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_NNCRONTAB_NUMBER:
 | 
			
		||||
				// stay  in CONF_NUMBER state until we find a non-numeric
 | 
			
		||||
				if( IsASCII(ch) && isdigit(ch) /* || ch == '.' */ ) {
 | 
			
		||||
					buffer[bufferCount++] = ch;
 | 
			
		||||
				} else {
 | 
			
		||||
					state = SCE_NNCRONTAB_DEFAULT;
 | 
			
		||||
					buffer[bufferCount] = '\0';
 | 
			
		||||
					// Colourize here... (normal number)
 | 
			
		||||
					styler.ColourTo(i-1,SCE_NNCRONTAB_NUMBER);
 | 
			
		||||
					// push back a character
 | 
			
		||||
					chNext = styler[i--];
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	delete []buffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const cronWordListDesc[] = {
 | 
			
		||||
	"Section keywords and Forth words",
 | 
			
		||||
	"nnCrontab keywords",
 | 
			
		||||
	"Modifiers",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab", 0, cronWordListDesc);
 | 
			
		||||
							
								
								
									
										215
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCsound.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								3rdparty/lexilla540/lexilla/lexers/LexCsound.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,215 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexCsound.cxx
 | 
			
		||||
 ** Lexer for Csound (Orchestra & Score)
 | 
			
		||||
 ** Written by Georg Ritter - <ritterfuture A T gmail D O T com>
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
 | 
			
		||||
		ch == '_' || ch == '?');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordStart(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
 | 
			
		||||
		ch == '%' || ch == '@' || ch == '$' || ch == '?');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsCsoundOperator(char ch) {
 | 
			
		||||
	if (IsASCII(ch) && isalnum(ch))
 | 
			
		||||
		return false;
 | 
			
		||||
	// '.' left out as it is used to make up numbers
 | 
			
		||||
	if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
 | 
			
		||||
		ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
 | 
			
		||||
		ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
 | 
			
		||||
		ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
 | 
			
		||||
		ch == '%' || ch == ':')
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseCsoundDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
				Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &opcode = *keywordlists[0];
 | 
			
		||||
	WordList &headerStmt = *keywordlists[1];
 | 
			
		||||
	WordList &otherKeyword = *keywordlists[2];
 | 
			
		||||
 | 
			
		||||
	// Do not leak onto next line
 | 
			
		||||
	if (initStyle == SCE_CSOUND_STRINGEOL)
 | 
			
		||||
		initStyle = SCE_CSOUND_DEFAULT;
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward())
 | 
			
		||||
	{
 | 
			
		||||
		// Handle line continuation generically.
 | 
			
		||||
		if (sc.ch == '\\') {
 | 
			
		||||
			if (sc.chNext == '\n' || sc.chNext == '\r') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				if (sc.ch == '\r' && sc.chNext == '\n') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		if (sc.state == SCE_CSOUND_OPERATOR) {
 | 
			
		||||
			if (!IsCsoundOperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
			    sc.SetState(SCE_CSOUND_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}else if (sc.state == SCE_CSOUND_NUMBER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_CSOUND_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_CSOUND_IDENTIFIER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch) ) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
 | 
			
		||||
				if (opcode.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_CSOUND_OPCODE);
 | 
			
		||||
				} else if (headerStmt.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_CSOUND_HEADERSTMT);
 | 
			
		||||
				} else if (otherKeyword.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_CSOUND_USERKEYWORD);
 | 
			
		||||
				} else if (s[0] == 'p') {
 | 
			
		||||
					sc.ChangeState(SCE_CSOUND_PARAM);
 | 
			
		||||
				} else if (s[0] == 'a') {
 | 
			
		||||
					sc.ChangeState(SCE_CSOUND_ARATE_VAR);
 | 
			
		||||
				} else if (s[0] == 'k') {
 | 
			
		||||
					sc.ChangeState(SCE_CSOUND_KRATE_VAR);
 | 
			
		||||
				} else if (s[0] == 'i') { // covers both i-rate variables and i-statements
 | 
			
		||||
					sc.ChangeState(SCE_CSOUND_IRATE_VAR);
 | 
			
		||||
				} else if (s[0] == 'g') {
 | 
			
		||||
					sc.ChangeState(SCE_CSOUND_GLOBAL_VAR);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_CSOUND_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (sc.state == SCE_CSOUND_COMMENT ) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_CSOUND_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if ((sc.state == SCE_CSOUND_ARATE_VAR) ||
 | 
			
		||||
			(sc.state == SCE_CSOUND_KRATE_VAR) ||
 | 
			
		||||
		(sc.state == SCE_CSOUND_IRATE_VAR)) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_CSOUND_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_CSOUND_DEFAULT) {
 | 
			
		||||
			if (sc.ch == ';'){
 | 
			
		||||
				sc.SetState(SCE_CSOUND_COMMENT);
 | 
			
		||||
			} else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_CSOUND_NUMBER);
 | 
			
		||||
			} else if (IsAWordStart(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_CSOUND_IDENTIFIER);
 | 
			
		||||
			} else if (IsCsoundOperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_CSOUND_OPERATOR);
 | 
			
		||||
			} else if (sc.ch == 'p') {
 | 
			
		||||
				sc.SetState(SCE_CSOUND_PARAM);
 | 
			
		||||
			} else if (sc.ch == 'a') {
 | 
			
		||||
				sc.SetState(SCE_CSOUND_ARATE_VAR);
 | 
			
		||||
			} else if (sc.ch == 'k') {
 | 
			
		||||
				sc.SetState(SCE_CSOUND_KRATE_VAR);
 | 
			
		||||
			} else if (sc.ch == 'i') { // covers both i-rate variables and i-statements
 | 
			
		||||
				sc.SetState(SCE_CSOUND_IRATE_VAR);
 | 
			
		||||
			} else if (sc.ch == 'g') {
 | 
			
		||||
				sc.SetState(SCE_CSOUND_GLOBAL_VAR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldCsoundInstruments(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[],
 | 
			
		||||
		Accessor &styler) {
 | 
			
		||||
	Sci_PositionU lengthDoc = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int stylePrev = 0;
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if ((stylePrev != SCE_CSOUND_OPCODE) && (style == SCE_CSOUND_OPCODE)) {
 | 
			
		||||
			char s[20];
 | 
			
		||||
			unsigned int j = 0;
 | 
			
		||||
			while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
 | 
			
		||||
				s[j] = styler[i + j];
 | 
			
		||||
				j++;
 | 
			
		||||
			}
 | 
			
		||||
			s[j] = '\0';
 | 
			
		||||
 | 
			
		||||
			if (strcmp(s, "instr") == 0)
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			if (strcmp(s, "endin") == 0)
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		stylePrev = style;
 | 
			
		||||
	}
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const char * const csoundWordListDesc[] = {
 | 
			
		||||
	"Opcodes",
 | 
			
		||||
	"Header Statements",
 | 
			
		||||
	"User keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmCsound(SCLEX_CSOUND, ColouriseCsoundDoc, "csound", FoldCsoundInstruments, csoundWordListDesc);
 | 
			
		||||
							
								
								
									
										571
									
								
								3rdparty/lexilla540/lexilla/lexers/LexD.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										571
									
								
								3rdparty/lexilla540/lexilla/lexers/LexD.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,571 @@
 | 
			
		||||
/** @file LexD.cxx
 | 
			
		||||
 ** Lexer for D.
 | 
			
		||||
 **
 | 
			
		||||
 ** Copyright (c) 2006 by Waldemar Augustyn <waldemar@wdmsys.com>
 | 
			
		||||
 ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.h>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "OptionSet.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
/* Nested comments require keeping the value of the nesting level for every
 | 
			
		||||
   position in the document.  But since scintilla always styles line by line,
 | 
			
		||||
   we only need to store one value per line. The non-negative number indicates
 | 
			
		||||
   nesting level at the end of the line.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// Underscore, letter, digit and universal alphas from C99 Appendix D.
 | 
			
		||||
 | 
			
		||||
static bool IsWordStart(int ch) {
 | 
			
		||||
	return (IsASCII(ch) && (isalpha(ch) || ch == '_')) || !IsASCII(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsWord(int ch) {
 | 
			
		||||
	return (IsASCII(ch) && (isalnum(ch) || ch == '_')) || !IsASCII(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsDoxygen(int ch) {
 | 
			
		||||
	if (IsASCII(ch) && islower(ch))
 | 
			
		||||
		return true;
 | 
			
		||||
	if (ch == '$' || ch == '@' || ch == '\\' ||
 | 
			
		||||
		ch == '&' || ch == '#' || ch == '<' || ch == '>' ||
 | 
			
		||||
		ch == '{' || ch == '}' || ch == '[' || ch == ']')
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsStringSuffix(int ch) {
 | 
			
		||||
	return ch == 'c' || ch == 'w' || ch == 'd';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsStreamCommentStyle(int style) {
 | 
			
		||||
	return style == SCE_D_COMMENT ||
 | 
			
		||||
		style == SCE_D_COMMENTDOC ||
 | 
			
		||||
		style == SCE_D_COMMENTDOCKEYWORD ||
 | 
			
		||||
		style == SCE_D_COMMENTDOCKEYWORDERROR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// An individual named option for use in an OptionSet
 | 
			
		||||
 | 
			
		||||
// Options used for LexerD
 | 
			
		||||
struct OptionsD {
 | 
			
		||||
	bool fold;
 | 
			
		||||
	bool foldSyntaxBased;
 | 
			
		||||
	bool foldComment;
 | 
			
		||||
	bool foldCommentMultiline;
 | 
			
		||||
	bool foldCommentExplicit;
 | 
			
		||||
	std::string foldExplicitStart;
 | 
			
		||||
	std::string foldExplicitEnd;
 | 
			
		||||
	bool foldExplicitAnywhere;
 | 
			
		||||
	bool foldCompact;
 | 
			
		||||
	int  foldAtElseInt;
 | 
			
		||||
	bool foldAtElse;
 | 
			
		||||
	OptionsD() {
 | 
			
		||||
		fold = false;
 | 
			
		||||
		foldSyntaxBased = true;
 | 
			
		||||
		foldComment = false;
 | 
			
		||||
		foldCommentMultiline = true;
 | 
			
		||||
		foldCommentExplicit = true;
 | 
			
		||||
		foldExplicitStart = "";
 | 
			
		||||
		foldExplicitEnd   = "";
 | 
			
		||||
		foldExplicitAnywhere = false;
 | 
			
		||||
		foldCompact = true;
 | 
			
		||||
		foldAtElseInt = -1;
 | 
			
		||||
		foldAtElse = false;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char * const dWordLists[] = {
 | 
			
		||||
			"Primary keywords and identifiers",
 | 
			
		||||
			"Secondary keywords and identifiers",
 | 
			
		||||
			"Documentation comment keywords",
 | 
			
		||||
			"Type definitions and aliases",
 | 
			
		||||
			"Keywords 5",
 | 
			
		||||
			"Keywords 6",
 | 
			
		||||
			"Keywords 7",
 | 
			
		||||
			0,
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
struct OptionSetD : public OptionSet<OptionsD> {
 | 
			
		||||
	OptionSetD() {
 | 
			
		||||
		DefineProperty("fold", &OptionsD::fold);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.d.syntax.based", &OptionsD::foldSyntaxBased,
 | 
			
		||||
			"Set this property to 0 to disable syntax based folding.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.comment", &OptionsD::foldComment);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.d.comment.multiline", &OptionsD::foldCommentMultiline,
 | 
			
		||||
			"Set this property to 0 to disable folding multi-line comments when fold.comment=1.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.d.comment.explicit", &OptionsD::foldCommentExplicit,
 | 
			
		||||
			"Set this property to 0 to disable folding explicit fold points when fold.comment=1.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.d.explicit.start", &OptionsD::foldExplicitStart,
 | 
			
		||||
			"The string to use for explicit fold start points, replacing the standard //{.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.d.explicit.end", &OptionsD::foldExplicitEnd,
 | 
			
		||||
			"The string to use for explicit fold end points, replacing the standard //}.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.d.explicit.anywhere", &OptionsD::foldExplicitAnywhere,
 | 
			
		||||
			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.compact", &OptionsD::foldCompact);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("lexer.d.fold.at.else", &OptionsD::foldAtElseInt,
 | 
			
		||||
			"This option enables D folding on a \"} else {\" line of an if statement.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.at.else", &OptionsD::foldAtElse);
 | 
			
		||||
 | 
			
		||||
		DefineWordListSets(dWordLists);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LexerD : public DefaultLexer {
 | 
			
		||||
	bool caseSensitive;
 | 
			
		||||
	WordList keywords;
 | 
			
		||||
	WordList keywords2;
 | 
			
		||||
	WordList keywords3;
 | 
			
		||||
	WordList keywords4;
 | 
			
		||||
	WordList keywords5;
 | 
			
		||||
	WordList keywords6;
 | 
			
		||||
	WordList keywords7;
 | 
			
		||||
	OptionsD options;
 | 
			
		||||
	OptionSetD osD;
 | 
			
		||||
public:
 | 
			
		||||
	LexerD(bool caseSensitive_) :
 | 
			
		||||
		DefaultLexer("D", SCLEX_D),
 | 
			
		||||
		caseSensitive(caseSensitive_) {
 | 
			
		||||
	}
 | 
			
		||||
	virtual ~LexerD() {
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD Release() override {
 | 
			
		||||
		delete this;
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD Version() const override {
 | 
			
		||||
		return lvRelease5;
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD PropertyNames() override {
 | 
			
		||||
		return osD.PropertyNames();
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD PropertyType(const char *name) override {
 | 
			
		||||
		return osD.PropertyType(name);
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD DescribeProperty(const char *name) override {
 | 
			
		||||
		return osD.DescribeProperty(name);
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
 | 
			
		||||
	const char * SCI_METHOD PropertyGet(const char *key) override {
 | 
			
		||||
		return osD.PropertyGet(key);
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD DescribeWordListSets() override {
 | 
			
		||||
		return osD.DescribeWordListSets();
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
 | 
			
		||||
	void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
	void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
 | 
			
		||||
	void * SCI_METHOD PrivateCall(int, void *) override {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static ILexer5 *LexerFactoryD() {
 | 
			
		||||
		return new LexerD(true);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerD::PropertySet(const char *key, const char *val) {
 | 
			
		||||
	if (osD.PropertySet(&options, key, val)) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerD::WordListSet(int n, const char *wl) {
 | 
			
		||||
	WordList *wordListN = 0;
 | 
			
		||||
	switch (n) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		wordListN = &keywords;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		wordListN = &keywords2;
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		wordListN = &keywords3;
 | 
			
		||||
		break;
 | 
			
		||||
	case 3:
 | 
			
		||||
		wordListN = &keywords4;
 | 
			
		||||
		break;
 | 
			
		||||
	case 4:
 | 
			
		||||
		wordListN = &keywords5;
 | 
			
		||||
		break;
 | 
			
		||||
	case 5:
 | 
			
		||||
		wordListN = &keywords6;
 | 
			
		||||
		break;
 | 
			
		||||
	case 6:
 | 
			
		||||
		wordListN = &keywords7;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position firstModification = -1;
 | 
			
		||||
	if (wordListN) {
 | 
			
		||||
		WordList wlNew;
 | 
			
		||||
		wlNew.Set(wl);
 | 
			
		||||
		if (*wordListN != wlNew) {
 | 
			
		||||
			wordListN->Set(wl);
 | 
			
		||||
			firstModification = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return firstModification;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerD::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
 | 
			
		||||
	int styleBeforeDCKeyword = SCE_D_DEFAULT;
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	Sci_Position curLine = styler.GetLine(startPos);
 | 
			
		||||
	int curNcLevel = curLine > 0? styler.GetLineState(curLine-1): 0;
 | 
			
		||||
	bool numFloat = false; // Float literals have '+' and '-' signs
 | 
			
		||||
	bool numHex = false;
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
		if (sc.atLineStart) {
 | 
			
		||||
			curLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
			styler.SetLineState(curLine, curNcLevel);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		switch (sc.state) {
 | 
			
		||||
			case SCE_D_OPERATOR:
 | 
			
		||||
				sc.SetState(SCE_D_DEFAULT);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_NUMBER:
 | 
			
		||||
				// We accept almost anything because of hex. and number suffixes
 | 
			
		||||
				if (IsASCII(sc.ch) && (isalnum(sc.ch) || sc.ch == '_')) {
 | 
			
		||||
					continue;
 | 
			
		||||
				} else if (sc.ch == '.' && sc.chNext != '.' && !numFloat) {
 | 
			
		||||
					// Don't parse 0..2 as number.
 | 
			
		||||
					numFloat=true;
 | 
			
		||||
					continue;
 | 
			
		||||
				} else if ( ( sc.ch == '-' || sc.ch == '+' ) && (		/*sign and*/
 | 
			
		||||
					( !numHex && ( sc.chPrev == 'e' || sc.chPrev == 'E' ) ) || /*decimal or*/
 | 
			
		||||
					( sc.chPrev == 'p' || sc.chPrev == 'P' ) ) ) {		/*hex*/
 | 
			
		||||
					// Parse exponent sign in float literals: 2e+10 0x2e+10
 | 
			
		||||
					continue;
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_D_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_IDENTIFIER:
 | 
			
		||||
				if (!IsWord(sc.ch)) {
 | 
			
		||||
					char s[1000];
 | 
			
		||||
					if (caseSensitive) {
 | 
			
		||||
						sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
					}
 | 
			
		||||
					if (keywords.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_D_WORD);
 | 
			
		||||
					} else if (keywords2.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_D_WORD2);
 | 
			
		||||
					} else if (keywords4.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_D_TYPEDEF);
 | 
			
		||||
					} else if (keywords5.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_D_WORD5);
 | 
			
		||||
					} else if (keywords6.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_D_WORD6);
 | 
			
		||||
					} else if (keywords7.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_D_WORD7);
 | 
			
		||||
					}
 | 
			
		||||
					sc.SetState(SCE_D_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_COMMENT:
 | 
			
		||||
				if (sc.Match('*', '/')) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_D_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_COMMENTDOC:
 | 
			
		||||
				if (sc.Match('*', '/')) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_D_DEFAULT);
 | 
			
		||||
				} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
 | 
			
		||||
					// Verify that we have the conditions to mark a comment-doc-keyword
 | 
			
		||||
					if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
 | 
			
		||||
						styleBeforeDCKeyword = SCE_D_COMMENTDOC;
 | 
			
		||||
						sc.SetState(SCE_D_COMMENTDOCKEYWORD);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_COMMENTLINE:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_D_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_COMMENTLINEDOC:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_D_DEFAULT);
 | 
			
		||||
				} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
 | 
			
		||||
					// Verify that we have the conditions to mark a comment-doc-keyword
 | 
			
		||||
					if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
 | 
			
		||||
						styleBeforeDCKeyword = SCE_D_COMMENTLINEDOC;
 | 
			
		||||
						sc.SetState(SCE_D_COMMENTDOCKEYWORD);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_COMMENTDOCKEYWORD:
 | 
			
		||||
				if ((styleBeforeDCKeyword == SCE_D_COMMENTDOC) && sc.Match('*', '/')) {
 | 
			
		||||
					sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_D_DEFAULT);
 | 
			
		||||
				} else if (!IsDoxygen(sc.ch)) {
 | 
			
		||||
					char s[100];
 | 
			
		||||
					if (caseSensitive) {
 | 
			
		||||
						sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
					}
 | 
			
		||||
					if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
 | 
			
		||||
						sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
 | 
			
		||||
					}
 | 
			
		||||
					sc.SetState(styleBeforeDCKeyword);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_COMMENTNESTED:
 | 
			
		||||
				if (sc.Match('+', '/')) {
 | 
			
		||||
					if (curNcLevel > 0)
 | 
			
		||||
						curNcLevel -= 1;
 | 
			
		||||
					curLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
					styler.SetLineState(curLine, curNcLevel);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					if (curNcLevel == 0) {
 | 
			
		||||
						sc.ForwardSetState(SCE_D_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.Match('/','+')) {
 | 
			
		||||
					curNcLevel += 1;
 | 
			
		||||
					curLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
					styler.SetLineState(curLine, curNcLevel);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_STRING:
 | 
			
		||||
				if (sc.ch == '\\') {
 | 
			
		||||
					if (sc.chNext == '"' || sc.chNext == '\\') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.ch == '"') {
 | 
			
		||||
					if(IsStringSuffix(sc.chNext))
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_D_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_CHARACTER:
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.ChangeState(SCE_D_STRINGEOL);
 | 
			
		||||
				} else if (sc.ch == '\\') {
 | 
			
		||||
					if (sc.chNext == '\'' || sc.chNext == '\\') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.ch == '\'') {
 | 
			
		||||
					// Char has no suffixes
 | 
			
		||||
					sc.ForwardSetState(SCE_D_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_STRINGEOL:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_D_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_STRINGB:
 | 
			
		||||
				if (sc.ch == '`') {
 | 
			
		||||
					if(IsStringSuffix(sc.chNext))
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_D_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_D_STRINGR:
 | 
			
		||||
				if (sc.ch == '"') {
 | 
			
		||||
					if(IsStringSuffix(sc.chNext))
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_D_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_D_DEFAULT) {
 | 
			
		||||
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_D_NUMBER);
 | 
			
		||||
				numFloat = sc.ch == '.';
 | 
			
		||||
				// Remember hex literal
 | 
			
		||||
				numHex = sc.ch == '0' && ( sc.chNext == 'x' || sc.chNext == 'X' );
 | 
			
		||||
			} else if ( (sc.ch == 'r' || sc.ch == 'x' || sc.ch == 'q')
 | 
			
		||||
				&& sc.chNext == '"' ) {
 | 
			
		||||
				// Limited support for hex and delimited strings: parse as r""
 | 
			
		||||
				sc.SetState(SCE_D_STRINGR);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (IsWordStart(sc.ch) || sc.ch == '$') {
 | 
			
		||||
				sc.SetState(SCE_D_IDENTIFIER);
 | 
			
		||||
			} else if (sc.Match('/','+')) {
 | 
			
		||||
				curNcLevel += 1;
 | 
			
		||||
				curLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
				styler.SetLineState(curLine, curNcLevel);
 | 
			
		||||
				sc.SetState(SCE_D_COMMENTNESTED);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.Match('/', '*')) {
 | 
			
		||||
				if (sc.Match("/**") || sc.Match("/*!")) {   // Support of Qt/Doxygen doc. style
 | 
			
		||||
					sc.SetState(SCE_D_COMMENTDOC);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_D_COMMENT);
 | 
			
		||||
				}
 | 
			
		||||
				sc.Forward();   // Eat the * so it isn't used for the end of the comment
 | 
			
		||||
			} else if (sc.Match('/', '/')) {
 | 
			
		||||
				if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
 | 
			
		||||
					// Support of Qt/Doxygen doc. style
 | 
			
		||||
					sc.SetState(SCE_D_COMMENTLINEDOC);
 | 
			
		||||
				else
 | 
			
		||||
					sc.SetState(SCE_D_COMMENTLINE);
 | 
			
		||||
			} else if (sc.ch == '"') {
 | 
			
		||||
				sc.SetState(SCE_D_STRING);
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(SCE_D_CHARACTER);
 | 
			
		||||
			} else if (sc.ch == '`') {
 | 
			
		||||
				sc.SetState(SCE_D_STRINGB);
 | 
			
		||||
			} else if (isoperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_D_OPERATOR);
 | 
			
		||||
				if (sc.ch == '.' && sc.chNext == '.') sc.Forward(); // Range operator
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Store both the current line's fold level and the next lines in the
 | 
			
		||||
// level store to make it easy to pick up with each increment
 | 
			
		||||
// and to make it possible to fiddle the current level for "} else {".
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerD::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
 | 
			
		||||
	if (!options.fold)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
	if (lineCurrent > 0)
 | 
			
		||||
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 | 
			
		||||
	int levelMinCurrent = levelCurrent;
 | 
			
		||||
	int levelNext = levelCurrent;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
	bool foldAtElse = options.foldAtElseInt >= 0 ? options.foldAtElseInt != 0 : options.foldAtElse;
 | 
			
		||||
	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int stylePrev = style;
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
 | 
			
		||||
			if (!IsStreamCommentStyle(stylePrev)) {
 | 
			
		||||
				levelNext++;
 | 
			
		||||
			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
 | 
			
		||||
				// Comments don't end at end of line and the next character may be unstyled.
 | 
			
		||||
				levelNext--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (options.foldComment && options.foldCommentExplicit && ((style == SCE_D_COMMENTLINE) || options.foldExplicitAnywhere)) {
 | 
			
		||||
			if (userDefinedFoldMarkers) {
 | 
			
		||||
				if (styler.Match(i, options.foldExplicitStart.c_str())) {
 | 
			
		||||
 					levelNext++;
 | 
			
		||||
				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
 | 
			
		||||
 					levelNext--;
 | 
			
		||||
 				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if ((ch == '/') && (chNext == '/')) {
 | 
			
		||||
					char chNext2 = styler.SafeGetCharAt(i + 2);
 | 
			
		||||
					if (chNext2 == '{') {
 | 
			
		||||
						levelNext++;
 | 
			
		||||
					} else if (chNext2 == '}') {
 | 
			
		||||
						levelNext--;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 			}
 | 
			
		||||
 		}
 | 
			
		||||
		if (options.foldSyntaxBased && (style == SCE_D_OPERATOR)) {
 | 
			
		||||
			if (ch == '{') {
 | 
			
		||||
				// Measure the minimum before a '{' to allow
 | 
			
		||||
				// folding on "} else {"
 | 
			
		||||
				if (levelMinCurrent > levelNext) {
 | 
			
		||||
					levelMinCurrent = levelNext;
 | 
			
		||||
				}
 | 
			
		||||
				levelNext++;
 | 
			
		||||
			} else if (ch == '}') {
 | 
			
		||||
				levelNext--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (atEOL || (i == endPos-1)) {
 | 
			
		||||
			if (options.foldComment && options.foldCommentMultiline) {  // Handle nested comments
 | 
			
		||||
				int nc;
 | 
			
		||||
				nc =  styler.GetLineState(lineCurrent);
 | 
			
		||||
				nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
 | 
			
		||||
				levelNext += nc;
 | 
			
		||||
			}
 | 
			
		||||
			int levelUse = levelCurrent;
 | 
			
		||||
			if (options.foldSyntaxBased && foldAtElse) {
 | 
			
		||||
				levelUse = levelMinCurrent;
 | 
			
		||||
			}
 | 
			
		||||
			int lev = levelUse | levelNext << 16;
 | 
			
		||||
			if (visibleChars == 0 && options.foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if (levelUse < levelNext)
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelCurrent = levelNext;
 | 
			
		||||
			levelMinCurrent = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!IsASpace(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmD(SCLEX_D, LexerD::LexerFactoryD, "d", dWordLists);
 | 
			
		||||
							
								
								
									
										236
									
								
								3rdparty/lexilla540/lexilla/lexers/LexDMAP.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								3rdparty/lexilla540/lexilla/lexers/LexDMAP.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,236 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexDMAP.cxx
 | 
			
		||||
 ** Lexer for MSC Nastran DMAP.
 | 
			
		||||
 ** Written by Mark Robinson, based on the Fortran lexer by Chuan-jian Shen, Last changed Aug. 2013
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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"
 | 
			
		||||
/***************************************/
 | 
			
		||||
 | 
			
		||||
#if defined(__clang__)
 | 
			
		||||
#if __has_warning("-Wunused-but-set-variable")
 | 
			
		||||
// Disable warning for numNonBlank
 | 
			
		||||
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
/***********************************************/
 | 
			
		||||
static inline bool IsAWordChar(const int ch) {
 | 
			
		||||
    return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');
 | 
			
		||||
}
 | 
			
		||||
/**********************************************/
 | 
			
		||||
static inline bool IsAWordStart(const int ch) {
 | 
			
		||||
    return (ch < 0x80) && (isalnum(ch));
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static void ColouriseDMAPDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
            WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
    WordList &keywords = *keywordlists[0];
 | 
			
		||||
    WordList &keywords2 = *keywordlists[1];
 | 
			
		||||
    WordList &keywords3 = *keywordlists[2];
 | 
			
		||||
    /***************************************/
 | 
			
		||||
    Sci_Position posLineStart = 0, numNonBlank = 0;
 | 
			
		||||
    Sci_Position endPos = startPos + length;
 | 
			
		||||
    /***************************************/
 | 
			
		||||
    // backtrack to the nearest keyword
 | 
			
		||||
    while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_DMAP_WORD)) {
 | 
			
		||||
        startPos--;
 | 
			
		||||
    }
 | 
			
		||||
    startPos = styler.LineStart(styler.GetLine(startPos));
 | 
			
		||||
    initStyle = styler.StyleAt(startPos - 1);
 | 
			
		||||
    StyleContext sc(startPos, endPos-startPos, initStyle, styler);
 | 
			
		||||
    /***************************************/
 | 
			
		||||
    for (; sc.More(); sc.Forward()) {
 | 
			
		||||
        // remember the start position of the line
 | 
			
		||||
        if (sc.atLineStart) {
 | 
			
		||||
            posLineStart = sc.currentPos;
 | 
			
		||||
            numNonBlank = 0;
 | 
			
		||||
            sc.SetState(SCE_DMAP_DEFAULT);
 | 
			
		||||
        }
 | 
			
		||||
        if (!IsASpaceOrTab(sc.ch)) numNonBlank ++;
 | 
			
		||||
        /***********************************************/
 | 
			
		||||
        // Handle data appearing after column 72; it is ignored
 | 
			
		||||
        Sci_Position toLineStart = sc.currentPos - posLineStart;
 | 
			
		||||
        if (toLineStart >= 72 || sc.ch == '$') {
 | 
			
		||||
            sc.SetState(SCE_DMAP_COMMENT);
 | 
			
		||||
            while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        /***************************************/
 | 
			
		||||
        // Determine if the current state should terminate.
 | 
			
		||||
        if (sc.state == SCE_DMAP_OPERATOR) {
 | 
			
		||||
            sc.SetState(SCE_DMAP_DEFAULT);
 | 
			
		||||
        } else if (sc.state == SCE_DMAP_NUMBER) {
 | 
			
		||||
            if (!(IsAWordChar(sc.ch) || sc.ch=='\'' || sc.ch=='\"' || sc.ch=='.')) {
 | 
			
		||||
                sc.SetState(SCE_DMAP_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (sc.state == SCE_DMAP_IDENTIFIER) {
 | 
			
		||||
            if (!IsAWordChar(sc.ch) || (sc.ch == '%')) {
 | 
			
		||||
                char s[100];
 | 
			
		||||
                sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
                if (keywords.InList(s)) {
 | 
			
		||||
                    sc.ChangeState(SCE_DMAP_WORD);
 | 
			
		||||
                } else if (keywords2.InList(s)) {
 | 
			
		||||
                    sc.ChangeState(SCE_DMAP_WORD2);
 | 
			
		||||
                } else if (keywords3.InList(s)) {
 | 
			
		||||
                    sc.ChangeState(SCE_DMAP_WORD3);
 | 
			
		||||
                }
 | 
			
		||||
                sc.SetState(SCE_DMAP_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (sc.state == SCE_DMAP_COMMENT) {
 | 
			
		||||
            if (sc.ch == '\r' || sc.ch == '\n') {
 | 
			
		||||
                sc.SetState(SCE_DMAP_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (sc.state == SCE_DMAP_STRING1) {
 | 
			
		||||
            if (sc.ch == '\'') {
 | 
			
		||||
                if (sc.chNext == '\'') {
 | 
			
		||||
                    sc.Forward();
 | 
			
		||||
                } else {
 | 
			
		||||
                    sc.ForwardSetState(SCE_DMAP_DEFAULT);
 | 
			
		||||
                }
 | 
			
		||||
            } else if (sc.atLineEnd) {
 | 
			
		||||
                sc.ChangeState(SCE_DMAP_STRINGEOL);
 | 
			
		||||
                sc.ForwardSetState(SCE_DMAP_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (sc.state == SCE_DMAP_STRING2) {
 | 
			
		||||
            if (sc.atLineEnd) {
 | 
			
		||||
                sc.ChangeState(SCE_DMAP_STRINGEOL);
 | 
			
		||||
                sc.ForwardSetState(SCE_DMAP_DEFAULT);
 | 
			
		||||
            } else if (sc.ch == '\"') {
 | 
			
		||||
                if (sc.chNext == '\"') {
 | 
			
		||||
                    sc.Forward();
 | 
			
		||||
                } else {
 | 
			
		||||
                    sc.ForwardSetState(SCE_DMAP_DEFAULT);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        /***************************************/
 | 
			
		||||
        // Determine if a new state should be entered.
 | 
			
		||||
        if (sc.state == SCE_DMAP_DEFAULT) {
 | 
			
		||||
            if (sc.ch == '$') {
 | 
			
		||||
                sc.SetState(SCE_DMAP_COMMENT);
 | 
			
		||||
            } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)) || (sc.ch == '-' && IsADigit(sc.chNext))) {
 | 
			
		||||
                sc.SetState(SCE_F_NUMBER);
 | 
			
		||||
            } else if (IsAWordStart(sc.ch)) {
 | 
			
		||||
                sc.SetState(SCE_DMAP_IDENTIFIER);
 | 
			
		||||
            } else if (sc.ch == '\"') {
 | 
			
		||||
                sc.SetState(SCE_DMAP_STRING2);
 | 
			
		||||
            } else if (sc.ch == '\'') {
 | 
			
		||||
                sc.SetState(SCE_DMAP_STRING1);
 | 
			
		||||
            } else if (isoperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
                sc.SetState(SCE_DMAP_OPERATOR);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
// To determine the folding level depending on keywords
 | 
			
		||||
static int classifyFoldPointDMAP(const char* s, const char* prevWord) {
 | 
			
		||||
    int lev = 0;
 | 
			
		||||
    if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "enddo") == 0 || strcmp(s, "endif") == 0) {
 | 
			
		||||
        lev = -1;
 | 
			
		||||
    } else if ((strcmp(prevWord, "do") == 0 && strcmp(s, "while") == 0) || strcmp(s, "then") == 0) {
 | 
			
		||||
        lev = 1;
 | 
			
		||||
    }
 | 
			
		||||
    return lev;
 | 
			
		||||
}
 | 
			
		||||
// Folding the code
 | 
			
		||||
static void FoldDMAPDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                           WordList *[], Accessor &styler) {
 | 
			
		||||
    //
 | 
			
		||||
    // bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 | 
			
		||||
    // Do not know how to fold the comment at the moment.
 | 
			
		||||
    //
 | 
			
		||||
    bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
    Sci_PositionU endPos = startPos + length;
 | 
			
		||||
    int visibleChars = 0;
 | 
			
		||||
    Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
    int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
    int levelCurrent = levelPrev;
 | 
			
		||||
    char chNext = styler[startPos];
 | 
			
		||||
    int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
    int style = initStyle;
 | 
			
		||||
    /***************************************/
 | 
			
		||||
    Sci_Position lastStart = 0;
 | 
			
		||||
    char prevWord[32] = "";
 | 
			
		||||
    /***************************************/
 | 
			
		||||
    for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
        char ch = chNext;
 | 
			
		||||
        chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
        int stylePrev = style;
 | 
			
		||||
        style = styleNext;
 | 
			
		||||
        styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
        bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
        //
 | 
			
		||||
        if ((stylePrev == SCE_DMAP_DEFAULT || stylePrev == SCE_DMAP_OPERATOR || stylePrev == SCE_DMAP_COMMENT) && (style == SCE_DMAP_WORD)) {
 | 
			
		||||
            // Store last word and label start point.
 | 
			
		||||
            lastStart = i;
 | 
			
		||||
        }
 | 
			
		||||
        /***************************************/
 | 
			
		||||
        if (style == SCE_DMAP_WORD) {
 | 
			
		||||
            if(iswordchar(ch) && !iswordchar(chNext)) {
 | 
			
		||||
                char s[32];
 | 
			
		||||
                Sci_PositionU k;
 | 
			
		||||
                for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {
 | 
			
		||||
                    s[k] = static_cast<char>(tolower(styler[lastStart+k]));
 | 
			
		||||
                }
 | 
			
		||||
                s[k] = '\0';
 | 
			
		||||
                levelCurrent += classifyFoldPointDMAP(s, prevWord);
 | 
			
		||||
                strcpy(prevWord, s);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (atEOL) {
 | 
			
		||||
            int lev = levelPrev;
 | 
			
		||||
            if (visibleChars == 0 && foldCompact)
 | 
			
		||||
                lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
            if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
                lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
            if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
                styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
            }
 | 
			
		||||
            lineCurrent++;
 | 
			
		||||
            levelPrev = levelCurrent;
 | 
			
		||||
            visibleChars = 0;
 | 
			
		||||
            strcpy(prevWord, "");
 | 
			
		||||
        }
 | 
			
		||||
        /***************************************/
 | 
			
		||||
        if (!isspacechar(ch)) visibleChars++;
 | 
			
		||||
    }
 | 
			
		||||
    /***************************************/
 | 
			
		||||
    // Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
    int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
    styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static const char * const DMAPWordLists[] = {
 | 
			
		||||
    "Primary keywords and identifiers",
 | 
			
		||||
    "Intrinsic functions",
 | 
			
		||||
    "Extended and user defined functions",
 | 
			
		||||
    0,
 | 
			
		||||
};
 | 
			
		||||
/***************************************/
 | 
			
		||||
extern const LexerModule lmDMAP(SCLEX_DMAP, ColouriseDMAPDoc, "DMAP", FoldDMAPDoc, DMAPWordLists);
 | 
			
		||||
							
								
								
									
										367
									
								
								3rdparty/lexilla540/lexilla/lexers/LexDMIS.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								3rdparty/lexilla540/lexilla/lexers/LexDMIS.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,367 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexDMIS.cxx
 | 
			
		||||
 ** Lexer for DMIS.
 | 
			
		||||
  **/
 | 
			
		||||
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// Copyright 2013-2014 by Andreas Tscharner <andy@vis.ethz.ch>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cctype>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const char *const DMISWordListDesc[] = {
 | 
			
		||||
	"DMIS Major Words",
 | 
			
		||||
	"DMIS Minor Words",
 | 
			
		||||
	"Unsupported DMIS Major Words",
 | 
			
		||||
	"Unsupported DMIS Minor Words",
 | 
			
		||||
	"Keywords for code folding start",
 | 
			
		||||
	"Corresponding keywords for code folding end",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LexerDMIS : public DefaultLexer
 | 
			
		||||
{
 | 
			
		||||
	private:
 | 
			
		||||
		char *m_wordListSets;
 | 
			
		||||
		WordList m_majorWords;
 | 
			
		||||
		WordList m_minorWords;
 | 
			
		||||
		WordList m_unsupportedMajor;
 | 
			
		||||
		WordList m_unsupportedMinor;
 | 
			
		||||
		WordList m_codeFoldingStart;
 | 
			
		||||
		WordList m_codeFoldingEnd;
 | 
			
		||||
 | 
			
		||||
		char * SCI_METHOD UpperCase(char *item);
 | 
			
		||||
		void SCI_METHOD InitWordListSets(void);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		LexerDMIS(void);
 | 
			
		||||
		virtual ~LexerDMIS(void);
 | 
			
		||||
 | 
			
		||||
		int SCI_METHOD Version() const override {
 | 
			
		||||
			return Scintilla::lvRelease5;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void SCI_METHOD Release() override {
 | 
			
		||||
			delete this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const char * SCI_METHOD PropertyNames() override {
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		int SCI_METHOD PropertyType(const char *) override {
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const char * SCI_METHOD DescribeProperty(const char *) override {
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Sci_Position SCI_METHOD PropertySet(const char *, const char *) override {
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const char * SCI_METHOD PropertyGet(const char *) override {
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
 | 
			
		||||
 | 
			
		||||
		void * SCI_METHOD PrivateCall(int, void *) override {
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static ILexer5 *LexerFactoryDMIS() {
 | 
			
		||||
			return new LexerDMIS;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const char * SCI_METHOD DescribeWordListSets() override;
 | 
			
		||||
		void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override;
 | 
			
		||||
		void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
char * SCI_METHOD LexerDMIS::UpperCase(char *item)
 | 
			
		||||
{
 | 
			
		||||
	char *itemStart;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	itemStart = item;
 | 
			
		||||
	while (item && *item) {
 | 
			
		||||
		*item = toupper(*item);
 | 
			
		||||
		item++;
 | 
			
		||||
	};
 | 
			
		||||
	return itemStart;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerDMIS::InitWordListSets(void)
 | 
			
		||||
{
 | 
			
		||||
	size_t totalLen = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	for (int i=0; DMISWordListDesc[i]; i++) {
 | 
			
		||||
		totalLen += strlen(DMISWordListDesc[i]);
 | 
			
		||||
		totalLen++;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	totalLen++;
 | 
			
		||||
	this->m_wordListSets = new char[totalLen];
 | 
			
		||||
	memset(this->m_wordListSets, 0, totalLen);
 | 
			
		||||
 | 
			
		||||
	for (int i=0; DMISWordListDesc[i]; i++) {
 | 
			
		||||
		strcat(this->m_wordListSets, DMISWordListDesc[i]);
 | 
			
		||||
		strcat(this->m_wordListSets, "\n");
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LexerDMIS::LexerDMIS(void) : DefaultLexer("DMIS", SCLEX_DMIS) {
 | 
			
		||||
	this->InitWordListSets();
 | 
			
		||||
 | 
			
		||||
	this->m_majorWords.Clear();
 | 
			
		||||
	this->m_minorWords.Clear();
 | 
			
		||||
	this->m_unsupportedMajor.Clear();
 | 
			
		||||
	this->m_unsupportedMinor.Clear();
 | 
			
		||||
	this->m_codeFoldingStart.Clear();
 | 
			
		||||
	this->m_codeFoldingEnd.Clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LexerDMIS::~LexerDMIS(void) {
 | 
			
		||||
	delete[] this->m_wordListSets;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerDMIS::WordListSet(int n, const char *wl)
 | 
			
		||||
{
 | 
			
		||||
	switch (n) {
 | 
			
		||||
		case 0:
 | 
			
		||||
			this->m_majorWords.Clear();
 | 
			
		||||
			this->m_majorWords.Set(wl);
 | 
			
		||||
			break;
 | 
			
		||||
		case 1:
 | 
			
		||||
			this->m_minorWords.Clear();
 | 
			
		||||
			this->m_minorWords.Set(wl);
 | 
			
		||||
			break;
 | 
			
		||||
		case 2:
 | 
			
		||||
			this->m_unsupportedMajor.Clear();
 | 
			
		||||
			this->m_unsupportedMajor.Set(wl);
 | 
			
		||||
			break;
 | 
			
		||||
		case 3:
 | 
			
		||||
			this->m_unsupportedMinor.Clear();
 | 
			
		||||
			this->m_unsupportedMinor.Set(wl);
 | 
			
		||||
			break;
 | 
			
		||||
		case 4:
 | 
			
		||||
			this->m_codeFoldingStart.Clear();
 | 
			
		||||
			this->m_codeFoldingStart.Set(wl);
 | 
			
		||||
			break;
 | 
			
		||||
		case 5:
 | 
			
		||||
			this->m_codeFoldingEnd.Clear();
 | 
			
		||||
			this->m_codeFoldingEnd.Set(wl);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			return -1;
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char * SCI_METHOD LexerDMIS::DescribeWordListSets()
 | 
			
		||||
{
 | 
			
		||||
	return this->m_wordListSets;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerDMIS::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess)
 | 
			
		||||
{
 | 
			
		||||
	const Sci_PositionU MAX_STR_LEN = 100;
 | 
			
		||||
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
	StyleContext scCTX(startPos, lengthDoc, initStyle, styler);
 | 
			
		||||
	CharacterSet setDMISNumber(CharacterSet::setDigits, ".-+eE");
 | 
			
		||||
	CharacterSet setDMISWordStart(CharacterSet::setAlpha, "-234", 0x80, true);
 | 
			
		||||
	CharacterSet setDMISWord(CharacterSet::setAlpha);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	bool isIFLine = false;
 | 
			
		||||
 | 
			
		||||
	for (; scCTX.More(); scCTX.Forward()) {
 | 
			
		||||
		if (scCTX.atLineEnd) {
 | 
			
		||||
			isIFLine = false;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		switch (scCTX.state) {
 | 
			
		||||
			case SCE_DMIS_DEFAULT:
 | 
			
		||||
				if (scCTX.Match('$', '$')) {
 | 
			
		||||
					scCTX.SetState(SCE_DMIS_COMMENT);
 | 
			
		||||
					scCTX.Forward();
 | 
			
		||||
				};
 | 
			
		||||
				if (scCTX.Match('\'')) {
 | 
			
		||||
					scCTX.SetState(SCE_DMIS_STRING);
 | 
			
		||||
				};
 | 
			
		||||
				if (IsADigit(scCTX.ch) || ((scCTX.Match('-') || scCTX.Match('+')) && IsADigit(scCTX.chNext))) {
 | 
			
		||||
					scCTX.SetState(SCE_DMIS_NUMBER);
 | 
			
		||||
					break;
 | 
			
		||||
				};
 | 
			
		||||
				if (setDMISWordStart.Contains(scCTX.ch)) {
 | 
			
		||||
					scCTX.SetState(SCE_DMIS_KEYWORD);
 | 
			
		||||
				};
 | 
			
		||||
				if (scCTX.Match('(') && (!isIFLine)) {
 | 
			
		||||
					scCTX.SetState(SCE_DMIS_LABEL);
 | 
			
		||||
				};
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_DMIS_COMMENT:
 | 
			
		||||
				if (scCTX.atLineEnd) {
 | 
			
		||||
					scCTX.SetState(SCE_DMIS_DEFAULT);
 | 
			
		||||
				};
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_DMIS_STRING:
 | 
			
		||||
				if (scCTX.Match('\'')) {
 | 
			
		||||
					scCTX.SetState(SCE_DMIS_DEFAULT);
 | 
			
		||||
				};
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_DMIS_NUMBER:
 | 
			
		||||
				if (!setDMISNumber.Contains(scCTX.ch)) {
 | 
			
		||||
					scCTX.SetState(SCE_DMIS_DEFAULT);
 | 
			
		||||
				};
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_DMIS_KEYWORD:
 | 
			
		||||
				if (!setDMISWord.Contains(scCTX.ch)) {
 | 
			
		||||
					char tmpStr[MAX_STR_LEN];
 | 
			
		||||
					memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
 | 
			
		||||
					scCTX.GetCurrent(tmpStr, (MAX_STR_LEN-1));
 | 
			
		||||
					// The following strncpy is copying from a string back onto itself which is weird and causes warnings
 | 
			
		||||
					// but is harmless so turn off the warning
 | 
			
		||||
#if defined(__GNUC__) && !defined(__clang__)
 | 
			
		||||
// Disable warning for strncpy
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wrestrict"
 | 
			
		||||
#endif
 | 
			
		||||
					strncpy(tmpStr, this->UpperCase(tmpStr), (MAX_STR_LEN-1));
 | 
			
		||||
 | 
			
		||||
					if (this->m_minorWords.InList(tmpStr)) {
 | 
			
		||||
						scCTX.ChangeState(SCE_DMIS_MINORWORD);
 | 
			
		||||
					};
 | 
			
		||||
					if (this->m_majorWords.InList(tmpStr)) {
 | 
			
		||||
						isIFLine = (strcmp(tmpStr, "IF") == 0);
 | 
			
		||||
						scCTX.ChangeState(SCE_DMIS_MAJORWORD);
 | 
			
		||||
					};
 | 
			
		||||
					if (this->m_unsupportedMajor.InList(tmpStr)) {
 | 
			
		||||
						scCTX.ChangeState(SCE_DMIS_UNSUPPORTED_MAJOR);
 | 
			
		||||
					};
 | 
			
		||||
					if (this->m_unsupportedMinor.InList(tmpStr)) {
 | 
			
		||||
						scCTX.ChangeState(SCE_DMIS_UNSUPPORTED_MINOR);
 | 
			
		||||
					};
 | 
			
		||||
 | 
			
		||||
					if (scCTX.Match('(') && (!isIFLine)) {
 | 
			
		||||
						scCTX.SetState(SCE_DMIS_LABEL);
 | 
			
		||||
					} else {
 | 
			
		||||
						scCTX.SetState(SCE_DMIS_DEFAULT);
 | 
			
		||||
					};
 | 
			
		||||
				};
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_DMIS_LABEL:
 | 
			
		||||
				if (scCTX.Match(')')) {
 | 
			
		||||
					scCTX.SetState(SCE_DMIS_DEFAULT);
 | 
			
		||||
				};
 | 
			
		||||
				break;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	scCTX.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerDMIS::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int, Scintilla::IDocument *pAccess)
 | 
			
		||||
{
 | 
			
		||||
	const int MAX_STR_LEN = 100;
 | 
			
		||||
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
	Sci_PositionU endPos = startPos + lengthDoc;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	int strPos = 0;
 | 
			
		||||
	bool foldWordPossible = false;
 | 
			
		||||
	CharacterSet setDMISFoldWord(CharacterSet::setAlpha);
 | 
			
		||||
	char *tmpStr;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	tmpStr = new char[MAX_STR_LEN];
 | 
			
		||||
	memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i=startPos; i<endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i+1);
 | 
			
		||||
 | 
			
		||||
		bool atEOL = ((ch == '\r' && chNext != '\n') || (ch == '\n'));
 | 
			
		||||
 | 
			
		||||
		if (strPos >= (MAX_STR_LEN-1)) {
 | 
			
		||||
			strPos = MAX_STR_LEN-1;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		int style = styler.StyleAt(i);
 | 
			
		||||
		bool noFoldPos = ((style == SCE_DMIS_COMMENT) || (style == SCE_DMIS_STRING));
 | 
			
		||||
 | 
			
		||||
		if (foldWordPossible) {
 | 
			
		||||
			if (setDMISFoldWord.Contains(ch)) {
 | 
			
		||||
				tmpStr[strPos++] = ch;
 | 
			
		||||
			} else {
 | 
			
		||||
				tmpStr = this->UpperCase(tmpStr);
 | 
			
		||||
				if (this->m_codeFoldingStart.InList(tmpStr) && (!noFoldPos)) {
 | 
			
		||||
					levelCurrent++;
 | 
			
		||||
				};
 | 
			
		||||
				if (this->m_codeFoldingEnd.InList(tmpStr) && (!noFoldPos)) {
 | 
			
		||||
					levelCurrent--;
 | 
			
		||||
				};
 | 
			
		||||
				memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
 | 
			
		||||
				strPos = 0;
 | 
			
		||||
				foldWordPossible = false;
 | 
			
		||||
			};
 | 
			
		||||
		} else {
 | 
			
		||||
			if (setDMISFoldWord.Contains(ch)) {
 | 
			
		||||
				tmpStr[strPos++] = ch;
 | 
			
		||||
				foldWordPossible = true;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		if (atEOL || (i == (endPos-1))) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
 | 
			
		||||
			if (levelCurrent > levelPrev) {
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			};
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			};
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	delete[] tmpStr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmDMIS(SCLEX_DMIS, LexerDMIS::LexerFactoryDMIS, "DMIS", DMISWordListDesc);
 | 
			
		||||
							
								
								
									
										611
									
								
								3rdparty/lexilla540/lexilla/lexers/LexDataflex.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										611
									
								
								3rdparty/lexilla540/lexilla/lexers/LexDataflex.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,611 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexDataflex.cxx
 | 
			
		||||
 ** Lexer for DataFlex.
 | 
			
		||||
 ** Based on LexPascal.cxx
 | 
			
		||||
 ** Written by Wil van Antwerpen, June 2019
 | 
			
		||||
 **/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
A few words about features of LexDataflex...
 | 
			
		||||
 | 
			
		||||
Generally speaking LexDataflex tries to support all available DataFlex features (up
 | 
			
		||||
to DataFlex 19.1 at this time).
 | 
			
		||||
 | 
			
		||||
~ FOLDING:
 | 
			
		||||
 | 
			
		||||
Folding is supported in the following cases:
 | 
			
		||||
 | 
			
		||||
- Folding of stream-like comments
 | 
			
		||||
- Folding of groups of consecutive line comments
 | 
			
		||||
- Folding of preprocessor blocks (the following preprocessor blocks are
 | 
			
		||||
supported: #IFDEF, #IFNDEF, #ENDIF and #HEADER / #ENDHEADER 
 | 
			
		||||
blocks), 
 | 
			
		||||
- Folding of code blocks on appropriate keywords (the following code blocks are
 | 
			
		||||
supported: "begin, struct, type, case / end" blocks, class & object
 | 
			
		||||
declarations and interface declarations)
 | 
			
		||||
 | 
			
		||||
Remarks:
 | 
			
		||||
 | 
			
		||||
- We pass 4 arrays to the lexer:
 | 
			
		||||
1. The DataFlex keyword list, these are normal DataFlex keywords
 | 
			
		||||
2. The Scope Open list, for example, begin / procedure / while
 | 
			
		||||
3. The Scope Close list, for example, end / end_procedure / loop
 | 
			
		||||
4. Operator list, for ex. + / - / * / Lt / iand
 | 
			
		||||
These lists are all mutually exclusive, scope open words should not be in the keyword list and vice versa
 | 
			
		||||
 | 
			
		||||
- Folding of code blocks tries to handle all special cases in which folding
 | 
			
		||||
should not occur. 
 | 
			
		||||
 | 
			
		||||
~ KEYWORDS:
 | 
			
		||||
 | 
			
		||||
The list of keywords that can be used in dataflex.properties file (up to DataFlex
 | 
			
		||||
19.1):
 | 
			
		||||
 | 
			
		||||
- Keywords: .. snipped .. see dataflex.properties file.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void GetRangeLowered(Sci_PositionU start,
 | 
			
		||||
		Sci_PositionU end,
 | 
			
		||||
		Accessor &styler,
 | 
			
		||||
		char *s,
 | 
			
		||||
		Sci_PositionU len) {
 | 
			
		||||
	Sci_PositionU i = 0;
 | 
			
		||||
	while ((i < end - start + 1) && (i < len-1)) {
 | 
			
		||||
		s[i] = static_cast<char>(tolower(styler[start + i]));
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	s[i] = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void GetForwardRangeLowered(Sci_PositionU start,
 | 
			
		||||
		CharacterSet &charSet,
 | 
			
		||||
		Accessor &styler,
 | 
			
		||||
		char *s,
 | 
			
		||||
		Sci_PositionU len) {
 | 
			
		||||
	Sci_PositionU i = 0;
 | 
			
		||||
	while ((i < len-1) && charSet.Contains(styler.SafeGetCharAt(start + i))) {
 | 
			
		||||
		s[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i)));
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	s[i] = '\0';
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	stateInICode = 0x1000,
 | 
			
		||||
	stateSingleQuoteOpen = 0x2000,
 | 
			
		||||
	stateDoubleQuoteOpen = 0x4000,
 | 
			
		||||
	stateFoldInPreprocessor = 0x0100,
 | 
			
		||||
	stateFoldInCaseStatement = 0x0200,
 | 
			
		||||
	stateFoldInPreprocessorLevelMask = 0x00FF,
 | 
			
		||||
	stateFoldMaskAll = 0x0FFF
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool IsFirstDataFlexWord(Sci_Position pos, Accessor &styler) {
 | 
			
		||||
	Sci_Position line = styler.GetLine(pos);
 | 
			
		||||
	Sci_Position start_pos = styler.LineStart(line);
 | 
			
		||||
	for (Sci_Position i = start_pos; i < pos; i++) {
 | 
			
		||||
		char ch = styler.SafeGetCharAt(i);
 | 
			
		||||
		if (!(ch == ' ' || ch == '\t'))
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline bool IsADataFlexField(int ch) {
 | 
			
		||||
	return (ch == '.');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void ClassifyDataFlexWord(WordList *keywordlists[], StyleContext &sc, Accessor &styler) {
 | 
			
		||||
	WordList& keywords = *keywordlists[0];
 | 
			
		||||
	WordList& scopeOpen   = *keywordlists[1];
 | 
			
		||||
	WordList& scopeClosed = *keywordlists[2];
 | 
			
		||||
	WordList& operators   = *keywordlists[3];
 | 
			
		||||
 | 
			
		||||
	char s[100];
 | 
			
		||||
	int oldState;
 | 
			
		||||
	int newState;
 | 
			
		||||
	size_t tokenlen;
 | 
			
		||||
 | 
			
		||||
    oldState = sc.state;
 | 
			
		||||
	newState = oldState;
 | 
			
		||||
	sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
	tokenlen = strnlen(s,sizeof(s));
 | 
			
		||||
	if (keywords.InList(s)) {
 | 
			
		||||
		// keywords in DataFlex can be used as table column names (file.field) and as such they
 | 
			
		||||
		// should not be characterized as a keyword. So test for that.
 | 
			
		||||
		// for ex. somebody using date as field name.
 | 
			
		||||
        if (!IsADataFlexField(sc.GetRelative(-static_cast<int>(tokenlen+1)))) {
 | 
			
		||||
	      newState = SCE_DF_WORD;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
	if (oldState == newState) {
 | 
			
		||||
		if ((scopeOpen.InList(s) || scopeClosed.InList(s)) && (strcmp(s, "for") != 0) && (strcmp(s, "repeat") != 0)) {
 | 
			
		||||
			// scope words in DataFlex can be used as table column names (file.field) and as such they
 | 
			
		||||
			// should not be characterized as a scope word. So test for that.
 | 
			
		||||
			// for ex. somebody using procedure for field name.
 | 
			
		||||
			if (!IsADataFlexField(sc.GetRelative(-static_cast<int>(tokenlen+1)))) {
 | 
			
		||||
				newState = SCE_DF_SCOPEWORD;
 | 
			
		||||
			}
 | 
			
		||||
		} 
 | 
			
		||||
		// no code folding on the next words, but just want to paint them like keywords (as they are) (??? doesn't the code to the opposite?)
 | 
			
		||||
		if (strcmp(s, "if") == 0 ||  
 | 
			
		||||
			strcmp(s, "ifnot") == 0 ||
 | 
			
		||||
			strcmp(s, "case") == 0 ||
 | 
			
		||||
			strcmp(s, "else") == 0 ) {
 | 
			
		||||
				newState = SCE_DF_SCOPEWORD;
 | 
			
		||||
		} 
 | 
			
		||||
	}
 | 
			
		||||
	if (oldState != newState && newState == SCE_DF_WORD) {
 | 
			
		||||
		// a for loop must have for at the start of the line, for is also used in "define abc for 123"
 | 
			
		||||
		if ( (strcmp(s, "for") == 0) && (IsFirstDataFlexWord(sc.currentPos-3, styler)) ) {   
 | 
			
		||||
				newState = SCE_DF_SCOPEWORD;
 | 
			
		||||
		} 
 | 
			
		||||
	}
 | 
			
		||||
	if (oldState != newState && newState == SCE_DF_WORD) {
 | 
			
		||||
		// a repeat loop must have repeat at the start of the line, repeat is also used in 'move (repeat("d",5)) to sFoo'
 | 
			
		||||
		if ( (strcmp(s, "repeat") == 0) && (IsFirstDataFlexWord(sc.currentPos-6, styler)) ) {   
 | 
			
		||||
				newState = SCE_DF_SCOPEWORD;
 | 
			
		||||
		} 
 | 
			
		||||
	}
 | 
			
		||||
	if (oldState == newState)  {
 | 
			
		||||
	  if (operators.InList(s)) {
 | 
			
		||||
		  newState = SCE_DF_OPERATOR;
 | 
			
		||||
		} 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (oldState != newState) {
 | 
			
		||||
		sc.ChangeState(newState);
 | 
			
		||||
	}
 | 
			
		||||
	sc.SetState(SCE_DF_DEFAULT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseDataFlexDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
		Accessor &styler) {
 | 
			
		||||
//	bool bSmartHighlighting = styler.GetPropertyInt("lexer.dataflex.smart.highlighting", 1) != 0;
 | 
			
		||||
 | 
			
		||||
			CharacterSet setWordStart(CharacterSet::setAlpha, "_$#@", 0x80, true);
 | 
			
		||||
			CharacterSet setWord(CharacterSet::setAlphaNum, "_$#@", 0x80, true);
 | 
			
		||||
	CharacterSet setNumber(CharacterSet::setDigits, ".-+eE");
 | 
			
		||||
	CharacterSet setHexNumber(CharacterSet::setDigits, "abcdefABCDEF");
 | 
			
		||||
	CharacterSet setOperator(CharacterSet::setNone, "*+-/<=>^");
 | 
			
		||||
 | 
			
		||||
	Sci_Position curLine = styler.GetLine(startPos);
 | 
			
		||||
	int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
		if (sc.atLineEnd) {
 | 
			
		||||
			// Update the line state, so it can be seen by next line
 | 
			
		||||
			curLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
			styler.SetLineState(curLine, curLineState);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		switch (sc.state) {
 | 
			
		||||
			case SCE_DF_NUMBER:
 | 
			
		||||
				if (!setNumber.Contains(sc.ch) || (sc.ch == '.' && sc.chNext == '.')) {
 | 
			
		||||
					sc.SetState(SCE_DF_DEFAULT);
 | 
			
		||||
				} else if (sc.ch == '-' || sc.ch == '+') {
 | 
			
		||||
					if (sc.chPrev != 'E' && sc.chPrev != 'e') {
 | 
			
		||||
						sc.SetState(SCE_DF_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_IDENTIFIER:
 | 
			
		||||
				if (!setWord.Contains(sc.ch)) {
 | 
			
		||||
					ClassifyDataFlexWord(keywordlists, sc, styler);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_HEXNUMBER:
 | 
			
		||||
				if (!(setHexNumber.Contains(sc.ch) || sc.ch == 'I') ) { // in |CI$22a we also want to color the "I"
 | 
			
		||||
					sc.SetState(SCE_DF_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_METATAG:
 | 
			
		||||
				if (sc.atLineStart || sc.chPrev == '}') {
 | 
			
		||||
					sc.SetState(SCE_DF_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_PREPROCESSOR:
 | 
			
		||||
				if (sc.atLineStart || IsASpaceOrTab(sc.ch)) {
 | 
			
		||||
					sc.SetState(SCE_DF_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_IMAGE:
 | 
			
		||||
				if (sc.atLineStart && sc.Match("/*")) {
 | 
			
		||||
					sc.Forward();  // these characters are still part of the DF Image
 | 
			
		||||
					sc.ForwardSetState(SCE_DF_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_PREPROCESSOR2:
 | 
			
		||||
				// we don't have inline comments or preprocessor2 commands
 | 
			
		||||
				//if (sc.Match('*', ')')) {
 | 
			
		||||
				//	sc.Forward();
 | 
			
		||||
				//	sc.ForwardSetState(SCE_DF_DEFAULT);
 | 
			
		||||
				//}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_COMMENTLINE:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_DF_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_STRING:
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.ChangeState(SCE_DF_STRINGEOL);
 | 
			
		||||
				} else if (sc.ch == '\'' && sc.chNext == '\'') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} else if (sc.ch == '\"' && sc.chNext == '\"') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} else if (sc.ch == '\'' || sc.ch == '\"') {
 | 
			
		||||
					if (sc.ch == '\'' && (curLineState & stateSingleQuoteOpen) ) {
 | 
			
		||||
 				    curLineState &= ~(stateSingleQuoteOpen);
 | 
			
		||||
					sc.ForwardSetState(SCE_DF_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
					else if (sc.ch == '\"' && (curLineState & stateDoubleQuoteOpen) ) {
 | 
			
		||||
 				    curLineState &= ~(stateDoubleQuoteOpen);
 | 
			
		||||
					sc.ForwardSetState(SCE_DF_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_STRINGEOL:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_DF_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_SCOPEWORD:
 | 
			
		||||
				//if (!setHexNumber.Contains(sc.ch) && sc.ch != '$') {
 | 
			
		||||
				//	sc.SetState(SCE_DF_DEFAULT);
 | 
			
		||||
				//}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_OPERATOR:
 | 
			
		||||
//				if (bSmartHighlighting && sc.chPrev == ';') {
 | 
			
		||||
//					curLineState &= ~(stateInProperty | stateInExport);
 | 
			
		||||
//				}
 | 
			
		||||
				sc.SetState(SCE_DF_DEFAULT);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_DF_ICODE:
 | 
			
		||||
				if (sc.atLineStart || IsASpace(sc.ch) || isoperator(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_DF_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_DF_DEFAULT) {
 | 
			
		||||
			if (IsADigit(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_DF_NUMBER);
 | 
			
		||||
			} else if (sc.Match('/', '/') || sc.Match("#REM")) {
 | 
			
		||||
				sc.SetState(SCE_DF_COMMENTLINE);
 | 
			
		||||
			} else if ((sc.ch == '#' && !sc.Match("#REM")) && IsFirstDataFlexWord(sc.currentPos, styler)) {
 | 
			
		||||
				sc.SetState(SCE_DF_PREPROCESSOR);
 | 
			
		||||
			// || (sc.ch == '|' && sc.chNext == 'C' && sc.GetRelativeCharacter(2) == 'I' && sc.GetRelativeCharacter(3) == '$') ) {
 | 
			
		||||
			} else if ((sc.ch == '$' && ((!setWord.Contains(sc.chPrev)) || sc.chPrev == 'I' ) ) || (sc.Match("|CI$")) ) {
 | 
			
		||||
				sc.SetState(SCE_DF_HEXNUMBER); // start with $ and previous character not in a..zA..Z0..9 excluding "I" OR start with |CI$
 | 
			
		||||
			} else if (setWordStart.Contains(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_DF_IDENTIFIER);
 | 
			
		||||
			} else if (sc.ch == '{') {
 | 
			
		||||
				sc.SetState(SCE_DF_METATAG);
 | 
			
		||||
			//} else if (sc.Match("(*$")) {
 | 
			
		||||
			//	sc.SetState(SCE_DF_PREPROCESSOR2);
 | 
			
		||||
			} else if (sc.ch == '/' && setWord.Contains(sc.chNext) &&  sc.atLineStart) {
 | 
			
		||||
				sc.SetState(SCE_DF_IMAGE);
 | 
			
		||||
			//	sc.Forward();	// Eat the * so it isn't used for the end of the comment
 | 
			
		||||
			} else if (sc.ch == '\'' || sc.ch == '\"') {
 | 
			
		||||
				if (sc.ch == '\'' && !(curLineState & stateDoubleQuoteOpen)) {
 | 
			
		||||
				  curLineState |= stateSingleQuoteOpen;
 | 
			
		||||
				} else if (sc.ch == '\"' && !(curLineState & stateSingleQuoteOpen)) {
 | 
			
		||||
				  curLineState |= stateDoubleQuoteOpen;
 | 
			
		||||
				}
 | 
			
		||||
			    sc.SetState(SCE_DF_STRING);
 | 
			
		||||
			} else if (setOperator.Contains(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_DF_OPERATOR);
 | 
			
		||||
//			} else if (curLineState & stateInICode) {
 | 
			
		||||
				// ICode start ! in a string followed by close string mark is not icode
 | 
			
		||||
			} else if ((sc.ch == '!') && !(sc.ch == '!' && ((sc.chNext == '\"') || (sc.ch == '\'')) )) {
 | 
			
		||||
				sc.SetState(SCE_DF_ICODE);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (sc.state == SCE_DF_IDENTIFIER && setWord.Contains(sc.chPrev)) {
 | 
			
		||||
		ClassifyDataFlexWord(keywordlists, sc, styler);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsStreamCommentStyle(int style) {
 | 
			
		||||
	return style == SCE_DF_IMAGE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsCommentLine(Sci_Position line, Accessor &styler) {
 | 
			
		||||
	Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
	Sci_Position eolPos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
	for (Sci_Position i = pos; i < eolPos; i++) {
 | 
			
		||||
		char ch = styler[i];
 | 
			
		||||
		char chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int style = styler.StyleAt(i);
 | 
			
		||||
		if (ch == '/' && chNext == '/' && style == SCE_DF_COMMENTLINE) {
 | 
			
		||||
			return true;
 | 
			
		||||
		} else if (!IsASpaceOrTab(ch)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static unsigned int GetFoldInPreprocessorLevelFlag(int lineFoldStateCurrent) {
 | 
			
		||||
	return lineFoldStateCurrent & stateFoldInPreprocessorLevelMask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned int nestLevel) {
 | 
			
		||||
	lineFoldStateCurrent &= ~stateFoldInPreprocessorLevelMask;
 | 
			
		||||
	lineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int ClassifyDataFlexPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
 | 
			
		||||
		Sci_PositionU startPos, Accessor &styler) {
 | 
			
		||||
	CharacterSet setWord(CharacterSet::setAlpha);
 | 
			
		||||
 | 
			
		||||
	char s[100];	// Size of the longest possible keyword + one additional character + null
 | 
			
		||||
	GetForwardRangeLowered(startPos, setWord, styler, s, sizeof(s));
 | 
			
		||||
	size_t iLen = strnlen(s,sizeof(s));
 | 
			
		||||
	size_t iWordSize = 0;
 | 
			
		||||
 | 
			
		||||
	unsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent);
 | 
			
		||||
 | 
			
		||||
	if (strcmp(s, "command") == 0 ||
 | 
			
		||||
		// The #if/#ifdef etcetera commands are not currently foldable as it is easy to write code that
 | 
			
		||||
		// breaks the collaps logic, so we keep things simple and not include that for now.
 | 
			
		||||
		strcmp(s, "header") == 0) {
 | 
			
		||||
		nestLevel++;
 | 
			
		||||
		SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
 | 
			
		||||
		lineFoldStateCurrent |= stateFoldInPreprocessor;
 | 
			
		||||
		levelCurrent++;
 | 
			
		||||
		iWordSize = iLen;
 | 
			
		||||
	} else if (strcmp(s, "endcommand") == 0 ||
 | 
			
		||||
		strcmp(s, "endheader") == 0) {
 | 
			
		||||
		nestLevel--;
 | 
			
		||||
		SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
 | 
			
		||||
		if (nestLevel == 0) {
 | 
			
		||||
			lineFoldStateCurrent &= ~stateFoldInPreprocessor;
 | 
			
		||||
		}
 | 
			
		||||
		levelCurrent--;
 | 
			
		||||
		iWordSize = iLen;
 | 
			
		||||
		if (levelCurrent < SC_FOLDLEVELBASE) {
 | 
			
		||||
			levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return static_cast<int>(iWordSize);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void ClassifyDataFlexWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
 | 
			
		||||
		Sci_PositionU lastStart, Sci_PositionU currentPos, WordList *[], Accessor &styler) {
 | 
			
		||||
	char s[100];
 | 
			
		||||
 | 
			
		||||
	// property fold.dataflex.compilerlist
 | 
			
		||||
	//	Set to 1 for enabling the code folding feature in *.prn files
 | 
			
		||||
	bool foldPRN = styler.GetPropertyInt("fold.dataflex.compilerlist",0) != 0;
 | 
			
		||||
 | 
			
		||||
	GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));
 | 
			
		||||
 | 
			
		||||
	if (strcmp(s, "case") == 0) {
 | 
			
		||||
		lineFoldStateCurrent |= stateFoldInCaseStatement;
 | 
			
		||||
	} else if (strcmp(s, "begin") == 0) {
 | 
			
		||||
		levelCurrent++;
 | 
			
		||||
	} else if (strcmp(s, "for") == 0 ||
 | 
			
		||||
		strcmp(s, "while") == 0 ||
 | 
			
		||||
		strcmp(s, "repeat") == 0 ||
 | 
			
		||||
		strcmp(s, "for_all") == 0 ||
 | 
			
		||||
		strcmp(s, "struct") == 0 ||
 | 
			
		||||
		strcmp(s, "type") == 0 ||
 | 
			
		||||
		strcmp(s, "begin_row") == 0 ||
 | 
			
		||||
		strcmp(s, "item_list") == 0 ||
 | 
			
		||||
		strcmp(s, "begin_constraints") == 0 ||
 | 
			
		||||
		strcmp(s, "begin_transaction") == 0 ||
 | 
			
		||||
		strcmp(s, "enum_list") == 0 ||
 | 
			
		||||
		strcmp(s, "class") == 0 || 
 | 
			
		||||
		strcmp(s, "object") == 0 ||
 | 
			
		||||
		strcmp(s, "cd_popup_object") == 0 ||
 | 
			
		||||
		strcmp(s, "procedure") == 0 ||
 | 
			
		||||
		strcmp(s, "procedure_section") == 0 ||
 | 
			
		||||
		strcmp(s, "function") == 0 ) {
 | 
			
		||||
			if ((IsFirstDataFlexWord(lastStart, styler )) || foldPRN) {
 | 
			
		||||
			levelCurrent++;
 | 
			
		||||
			}
 | 
			
		||||
	} else if (strcmp(s, "end") == 0) {  // end is not always the first keyword, for example "case end"
 | 
			
		||||
		levelCurrent--;
 | 
			
		||||
		if (levelCurrent < SC_FOLDLEVELBASE) {
 | 
			
		||||
			levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
		}
 | 
			
		||||
	} else if (strcmp(s, "loop") == 0 ||
 | 
			
		||||
				   strcmp(s, "until") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_class") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_object") == 0 ||
 | 
			
		||||
				   strcmp(s, "cd_end_object") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_procedure") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_function") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_for_all") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_struct") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_type") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_row") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_item_list") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_constraints") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_transaction") == 0 ||
 | 
			
		||||
				   strcmp(s, "end_enum_list") == 0 ) {
 | 
			
		||||
	//		lineFoldStateCurrent &= ~stateFoldInRecord;
 | 
			
		||||
			if ((IsFirstDataFlexWord(lastStart, styler )) || foldPRN) {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
				if (levelCurrent < SC_FOLDLEVELBASE) {
 | 
			
		||||
					levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void ClassifyDataFlexMetaDataFoldPoint(int &levelCurrent, 
 | 
			
		||||
		Sci_PositionU lastStart, Sci_PositionU currentPos, WordList *[], Accessor &styler) {
 | 
			
		||||
	char s[100];
 | 
			
		||||
 | 
			
		||||
	GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));
 | 
			
		||||
 | 
			
		||||
    if (strcmp(s, "#beginsection") == 0) {
 | 
			
		||||
		levelCurrent++;
 | 
			
		||||
	} else if (strcmp(s, "#endsection") == 0) {
 | 
			
		||||
			levelCurrent--;
 | 
			
		||||
			if (levelCurrent < SC_FOLDLEVELBASE) {
 | 
			
		||||
				levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
			}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldDataFlexDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
		Accessor &styler) {
 | 
			
		||||
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 | 
			
		||||
	bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	int lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
	int iWordSize;
 | 
			
		||||
 | 
			
		||||
	Sci_Position lastStart = 0;
 | 
			
		||||
	CharacterSet setWord(CharacterSet::setAlphaNum, "_$#@", 0x80, true);
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int stylePrev = style;
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
 | 
			
		||||
		if (foldComment && IsStreamCommentStyle(style)) {
 | 
			
		||||
			if (!IsStreamCommentStyle(stylePrev)) {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			} else if (!IsStreamCommentStyle(styleNext)) {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
 | 
			
		||||
		{
 | 
			
		||||
			if (!IsCommentLine(lineCurrent - 1, styler)
 | 
			
		||||
			    && IsCommentLine(lineCurrent + 1, styler))
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			else if (IsCommentLine(lineCurrent - 1, styler)
 | 
			
		||||
			         && !IsCommentLine(lineCurrent+1, styler))
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
		}
 | 
			
		||||
		if (foldPreprocessor) {
 | 
			
		||||
			if (style == SCE_DF_PREPROCESSOR) {
 | 
			
		||||
				iWordSize = ClassifyDataFlexPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 1, styler);
 | 
			
		||||
			//} else if (style == SCE_DF_PREPROCESSOR2 && ch == '(' && chNext == '*'
 | 
			
		||||
			//           && styler.SafeGetCharAt(i + 2) == '$') {
 | 
			
		||||
			//	ClassifyDataFlexPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler);
 | 
			
		||||
				i = i + iWordSize;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (stylePrev != SCE_DF_SCOPEWORD && style == SCE_DF_SCOPEWORD)
 | 
			
		||||
		{
 | 
			
		||||
			// Store last word start point.
 | 
			
		||||
			lastStart = i;
 | 
			
		||||
		}
 | 
			
		||||
		if (stylePrev == SCE_DF_SCOPEWORD) {
 | 
			
		||||
			if(setWord.Contains(ch) && !setWord.Contains(chNext)) {
 | 
			
		||||
				ClassifyDataFlexWordFoldPoint(levelCurrent, lineFoldStateCurrent, lastStart, i, keywordlists, styler);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (stylePrev == SCE_DF_METATAG && ch == '#')
 | 
			
		||||
		{
 | 
			
		||||
			// Store last word start point.
 | 
			
		||||
			lastStart = i;
 | 
			
		||||
		}
 | 
			
		||||
		if (stylePrev == SCE_DF_METATAG) {
 | 
			
		||||
			if(setWord.Contains(ch) && !setWord.Contains(chNext)) {
 | 
			
		||||
				ClassifyDataFlexMetaDataFoldPoint(levelCurrent, lastStart, i, keywordlists, styler);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!IsASpace(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			int newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent;
 | 
			
		||||
			styler.SetLineState(lineCurrent, newLineState);
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If we didn't reach the EOL in previous loop, store line level and whitespace information.
 | 
			
		||||
	// The rest will be filled in later...
 | 
			
		||||
	int lev = levelPrev;
 | 
			
		||||
	if (visibleChars == 0 && foldCompact)
 | 
			
		||||
		lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
	styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const dataflexWordListDesc[] = {
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	"Scope open",
 | 
			
		||||
	"Scope close",
 | 
			
		||||
	"Operators",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmDataflex(SCLEX_DATAFLEX, ColouriseDataFlexDoc, "dataflex", FoldDataFlexDoc, dataflexWordListDesc);
 | 
			
		||||
							
								
								
									
										155
									
								
								3rdparty/lexilla540/lexilla/lexers/LexDiff.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								3rdparty/lexilla540/lexilla/lexers/LexDiff.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,155 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexDiff.cxx
 | 
			
		||||
 ** Lexer for diff results.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cctype>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cstdarg>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
 | 
			
		||||
	return (styler[i] == '\n') ||
 | 
			
		||||
	       ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ColouriseDiffLine(const char *lineBuffer, Sci_Position endLine, Accessor &styler) {
 | 
			
		||||
	// It is needed to remember the current state to recognize starting
 | 
			
		||||
	// comment lines before the first "diff " or "--- ". If a real
 | 
			
		||||
	// difference starts then each line starting with ' ' is a whitespace
 | 
			
		||||
	// otherwise it is considered a comment (Only in..., Binary file...)
 | 
			
		||||
	if (0 == strncmp(lineBuffer, "diff ", 5)) {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_COMMAND);
 | 
			
		||||
	} else if (0 == strncmp(lineBuffer, "Index: ", 7)) {  // For subversion's diff
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_COMMAND);
 | 
			
		||||
	} else if (0 == strncmp(lineBuffer, "---", 3) && lineBuffer[3] != '-') {
 | 
			
		||||
		// In a context diff, --- appears in both the header and the position markers
 | 
			
		||||
		if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))
 | 
			
		||||
			styler.ColourTo(endLine, SCE_DIFF_POSITION);
 | 
			
		||||
		else if (lineBuffer[3] == '\r' || lineBuffer[3] == '\n')
 | 
			
		||||
			styler.ColourTo(endLine, SCE_DIFF_POSITION);
 | 
			
		||||
		else if (lineBuffer[3] == ' ')
 | 
			
		||||
			styler.ColourTo(endLine, SCE_DIFF_HEADER);
 | 
			
		||||
		else
 | 
			
		||||
			styler.ColourTo(endLine, SCE_DIFF_DELETED);
 | 
			
		||||
	} else if (0 == strncmp(lineBuffer, "+++ ", 4)) {
 | 
			
		||||
		// I don't know of any diff where "+++ " is a position marker, but for
 | 
			
		||||
		// consistency, do the same as with "--- " and "*** ".
 | 
			
		||||
		if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
 | 
			
		||||
			styler.ColourTo(endLine, SCE_DIFF_POSITION);
 | 
			
		||||
		else
 | 
			
		||||
			styler.ColourTo(endLine, SCE_DIFF_HEADER);
 | 
			
		||||
	} else if (0 == strncmp(lineBuffer, "====", 4)) {  // For p4's diff
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_HEADER);
 | 
			
		||||
	} else if (0 == strncmp(lineBuffer, "***", 3)) {
 | 
			
		||||
		// In a context diff, *** appears in both the header and the position markers.
 | 
			
		||||
		// Also ******** is a chunk header, but here it's treated as part of the
 | 
			
		||||
		// position marker since there is no separate style for a chunk header.
 | 
			
		||||
		if (lineBuffer[3] == ' ' && atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
 | 
			
		||||
			styler.ColourTo(endLine, SCE_DIFF_POSITION);
 | 
			
		||||
		else if (lineBuffer[3] == '*')
 | 
			
		||||
			styler.ColourTo(endLine, SCE_DIFF_POSITION);
 | 
			
		||||
		else
 | 
			
		||||
			styler.ColourTo(endLine, SCE_DIFF_HEADER);
 | 
			
		||||
	} else if (0 == strncmp(lineBuffer, "? ", 2)) {    // For difflib
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_HEADER);
 | 
			
		||||
	} else if (lineBuffer[0] == '@') {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_POSITION);
 | 
			
		||||
	} else if (lineBuffer[0] >= '0' && lineBuffer[0] <= '9') {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_POSITION);
 | 
			
		||||
	} else if (0 == strncmp(lineBuffer, "++", 2)) {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_PATCH_ADD);
 | 
			
		||||
	} else if (0 == strncmp(lineBuffer, "+-", 2)) {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_PATCH_DELETE);
 | 
			
		||||
	} else if (0 == strncmp(lineBuffer, "-+", 2)) {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_REMOVED_PATCH_ADD);
 | 
			
		||||
	} else if (0 == strncmp(lineBuffer, "--", 2)) {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_REMOVED_PATCH_DELETE);
 | 
			
		||||
	} else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_DELETED);
 | 
			
		||||
	} else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_ADDED);
 | 
			
		||||
	} else if (lineBuffer[0] == '!') {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_CHANGED);
 | 
			
		||||
	} else if (lineBuffer[0] != ' ') {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_COMMENT);
 | 
			
		||||
	} else {
 | 
			
		||||
		styler.ColourTo(endLine, SCE_DIFF_DEFAULT);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ColouriseDiffDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
 | 
			
		||||
	std::string lineBuffer;
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < startPos + length; i++) {
 | 
			
		||||
		if (AtEOL(styler, i)) {
 | 
			
		||||
			ColouriseDiffLine(lineBuffer.c_str(), i, styler);
 | 
			
		||||
			lineBuffer.clear();
 | 
			
		||||
		} else {
 | 
			
		||||
			lineBuffer.push_back(styler[i]);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (!lineBuffer.empty()) {	// Last line does not have ending characters
 | 
			
		||||
		ColouriseDiffLine(lineBuffer.c_str(), startPos + length - 1, styler);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FoldDiffDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
 | 
			
		||||
	Sci_Position curLine = styler.GetLine(startPos);
 | 
			
		||||
	Sci_Position curLineStart = styler.LineStart(curLine);
 | 
			
		||||
	int prevLevel = curLine > 0 ? styler.LevelAt(curLine - 1) : SC_FOLDLEVELBASE;
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		int nextLevel = 0;
 | 
			
		||||
		const int lineType = styler.StyleAt(curLineStart);
 | 
			
		||||
		if (lineType == SCE_DIFF_COMMAND)
 | 
			
		||||
			nextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		else if (lineType == SCE_DIFF_HEADER)
 | 
			
		||||
			nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		else if (lineType == SCE_DIFF_POSITION && styler[curLineStart] != '-')
 | 
			
		||||
			nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		else if (prevLevel & SC_FOLDLEVELHEADERFLAG)
 | 
			
		||||
			nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;
 | 
			
		||||
		else
 | 
			
		||||
			nextLevel = prevLevel;
 | 
			
		||||
 | 
			
		||||
		if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel))
 | 
			
		||||
			styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
 | 
			
		||||
 | 
			
		||||
		styler.SetLevel(curLine, nextLevel);
 | 
			
		||||
		prevLevel = nextLevel;
 | 
			
		||||
 | 
			
		||||
		curLineStart = styler.LineStart(++curLine);
 | 
			
		||||
	} while (static_cast<Sci_Position>(startPos)+length > curLineStart);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *const emptyWordListDesc[] = {
 | 
			
		||||
	nullptr
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc);
 | 
			
		||||
							
								
								
									
										521
									
								
								3rdparty/lexilla540/lexilla/lexers/LexECL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										521
									
								
								3rdparty/lexilla540/lexilla/lexers/LexECL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,521 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexECL.cxx
 | 
			
		||||
 ** Lexer for ECL.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.h>
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#pragma warning(disable: 4786)
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
// Borland C++ displays warnings in vector header without this
 | 
			
		||||
#pragma option -w-ccc -w-rch
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "PropSetSimple.h"
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "Accessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "OptionSet.h"
 | 
			
		||||
 | 
			
		||||
#define SET_LOWER "abcdefghijklmnopqrstuvwxyz"
 | 
			
		||||
#define SET_UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 | 
			
		||||
#define SET_DIGITS "0123456789"
 | 
			
		||||
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
static bool IsSpaceEquiv(int state) {
 | 
			
		||||
	switch (state) {
 | 
			
		||||
	case SCE_ECL_DEFAULT:
 | 
			
		||||
	case SCE_ECL_COMMENT:
 | 
			
		||||
	case SCE_ECL_COMMENTLINE:
 | 
			
		||||
	case SCE_ECL_COMMENTLINEDOC:
 | 
			
		||||
	case SCE_ECL_COMMENTDOCKEYWORD:
 | 
			
		||||
	case SCE_ECL_COMMENTDOCKEYWORDERROR:
 | 
			
		||||
	case SCE_ECL_COMMENTDOC:
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseEclDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
	WordList &keywords0 = *keywordlists[0];
 | 
			
		||||
	WordList &keywords1 = *keywordlists[1];
 | 
			
		||||
	WordList &keywords2 = *keywordlists[2];
 | 
			
		||||
	WordList &keywords3 = *keywordlists[3]; //Value Types
 | 
			
		||||
	WordList &keywords4 = *keywordlists[4];
 | 
			
		||||
	WordList &keywords5 = *keywordlists[5];
 | 
			
		||||
	WordList &keywords6 = *keywordlists[6];	//Javadoc Tags
 | 
			
		||||
	WordList cplusplus;
 | 
			
		||||
	cplusplus.Set("beginc endc");
 | 
			
		||||
 | 
			
		||||
	bool stylingWithinPreprocessor = false;
 | 
			
		||||
 | 
			
		||||
	CharacterSet setOKBeforeRE(CharacterSet::setNone, "(=,");
 | 
			
		||||
	CharacterSet setDoxygen(CharacterSet::setLower, "$@\\&<>#{}[]");
 | 
			
		||||
	CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
 | 
			
		||||
	CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
 | 
			
		||||
	CharacterSet setQualified(CharacterSet::setNone, "uUxX");
 | 
			
		||||
 | 
			
		||||
	int chPrevNonWhite = ' ';
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	bool lastWordWasUUID = false;
 | 
			
		||||
	int styleBeforeDCKeyword = SCE_ECL_DEFAULT;
 | 
			
		||||
	bool continuationLine = false;
 | 
			
		||||
 | 
			
		||||
	if (initStyle == SCE_ECL_PREPROCESSOR) {
 | 
			
		||||
		// Set continuationLine if last character of previous line is '\'
 | 
			
		||||
		Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
		if (lineCurrent > 0) {
 | 
			
		||||
			int chBack = styler.SafeGetCharAt(startPos-1, 0);
 | 
			
		||||
			int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
 | 
			
		||||
			int lineEndChar = '!';
 | 
			
		||||
			if (chBack2 == '\r' && chBack == '\n') {
 | 
			
		||||
				lineEndChar = styler.SafeGetCharAt(startPos-3, 0);
 | 
			
		||||
			} else if (chBack == '\n' || chBack == '\r') {
 | 
			
		||||
				lineEndChar = chBack2;
 | 
			
		||||
			}
 | 
			
		||||
			continuationLine = lineEndChar == '\\';
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// look back to set chPrevNonWhite properly for better regex colouring
 | 
			
		||||
	if (startPos > 0) {
 | 
			
		||||
		Sci_Position back = startPos;
 | 
			
		||||
		while (--back && IsSpaceEquiv(styler.StyleAt(back)))
 | 
			
		||||
			;
 | 
			
		||||
		if (styler.StyleAt(back) == SCE_ECL_OPERATOR) {
 | 
			
		||||
			chPrevNonWhite = styler.SafeGetCharAt(back);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
		if (sc.atLineStart) {
 | 
			
		||||
			if (sc.state == SCE_ECL_STRING) {
 | 
			
		||||
				// Prevent SCE_ECL_STRINGEOL from leaking back to previous line which
 | 
			
		||||
				// ends with a line continuation by locking in the state upto this position.
 | 
			
		||||
				sc.SetState(SCE_ECL_STRING);
 | 
			
		||||
			}
 | 
			
		||||
			// Reset states to begining of colourise so no surprises
 | 
			
		||||
			// if different sets of lines lexed.
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
			lastWordWasUUID = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Handle line continuation generically.
 | 
			
		||||
		if (sc.ch == '\\') {
 | 
			
		||||
			if (sc.chNext == '\n' || sc.chNext == '\r') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				if (sc.ch == '\r' && sc.chNext == '\n') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				continuationLine = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		switch (sc.state) {
 | 
			
		||||
			case SCE_ECL_ADDED:
 | 
			
		||||
			case SCE_ECL_DELETED:
 | 
			
		||||
			case SCE_ECL_CHANGED:
 | 
			
		||||
			case SCE_ECL_MOVED:
 | 
			
		||||
			if (sc.atLineStart)
 | 
			
		||||
					sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_OPERATOR:
 | 
			
		||||
				sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_NUMBER:
 | 
			
		||||
				// We accept almost anything because of hex. and number suffixes
 | 
			
		||||
				if (!setWord.Contains(sc.ch)) {
 | 
			
		||||
					sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_IDENTIFIER:
 | 
			
		||||
				if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
 | 
			
		||||
					char s[1000];
 | 
			
		||||
					sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
					if (keywords0.InList(s)) {
 | 
			
		||||
						lastWordWasUUID = strcmp(s, "uuid") == 0;
 | 
			
		||||
						sc.ChangeState(SCE_ECL_WORD0);
 | 
			
		||||
					} else if (keywords1.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_ECL_WORD1);
 | 
			
		||||
					} else if (keywords2.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_ECL_WORD2);
 | 
			
		||||
					} else if (keywords4.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_ECL_WORD4);
 | 
			
		||||
					} else if (keywords5.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_ECL_WORD5);
 | 
			
		||||
					}
 | 
			
		||||
					else	//Data types are of from KEYWORD##
 | 
			
		||||
					{
 | 
			
		||||
						int i = static_cast<int>(strlen(s)) - 1;
 | 
			
		||||
						while(i >= 0 && (isdigit(s[i]) || s[i] == '_'))
 | 
			
		||||
							--i;
 | 
			
		||||
 | 
			
		||||
						char s2[1000];
 | 
			
		||||
						strncpy(s2, s, i + 1);
 | 
			
		||||
						s2[i + 1] = 0;
 | 
			
		||||
						if (keywords3.InList(s2)) {
 | 
			
		||||
							sc.ChangeState(SCE_ECL_WORD3);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_PREPROCESSOR:
 | 
			
		||||
				if (sc.atLineStart && !continuationLine) {
 | 
			
		||||
					sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				} else if (stylingWithinPreprocessor) {
 | 
			
		||||
					if (IsASpace(sc.ch)) {
 | 
			
		||||
						sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					if (sc.Match('/', '*') || sc.Match('/', '/')) {
 | 
			
		||||
						sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_COMMENT:
 | 
			
		||||
				if (sc.Match('*', '/')) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_COMMENTDOC:
 | 
			
		||||
				if (sc.Match('*', '/')) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
 | 
			
		||||
					// Verify that we have the conditions to mark a comment-doc-keyword
 | 
			
		||||
					if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
 | 
			
		||||
						styleBeforeDCKeyword = SCE_ECL_COMMENTDOC;
 | 
			
		||||
						sc.SetState(SCE_ECL_COMMENTDOCKEYWORD);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_COMMENTLINE:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_COMMENTLINEDOC:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
 | 
			
		||||
					// Verify that we have the conditions to mark a comment-doc-keyword
 | 
			
		||||
					if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
 | 
			
		||||
						styleBeforeDCKeyword = SCE_ECL_COMMENTLINEDOC;
 | 
			
		||||
						sc.SetState(SCE_ECL_COMMENTDOCKEYWORD);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_COMMENTDOCKEYWORD:
 | 
			
		||||
				if ((styleBeforeDCKeyword == SCE_ECL_COMMENTDOC) && sc.Match('*', '/')) {
 | 
			
		||||
					sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				} else if (!setDoxygen.Contains(sc.ch)) {
 | 
			
		||||
					char s[1000];
 | 
			
		||||
					sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
					if (!IsASpace(sc.ch) || !keywords6.InList(s+1)) {
 | 
			
		||||
						sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR);
 | 
			
		||||
					}
 | 
			
		||||
					sc.SetState(styleBeforeDCKeyword);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_STRING:
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.ChangeState(SCE_ECL_STRINGEOL);
 | 
			
		||||
				} else if (sc.ch == '\\') {
 | 
			
		||||
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.ch == '\"') {
 | 
			
		||||
					sc.ForwardSetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_CHARACTER:
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.ChangeState(SCE_ECL_STRINGEOL);
 | 
			
		||||
				} else if (sc.ch == '\\') {
 | 
			
		||||
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.ch == '\'') {
 | 
			
		||||
					sc.ForwardSetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_REGEX:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				} else if (sc.ch == '/') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					while ((sc.ch < 0x80) && islower(sc.ch))
 | 
			
		||||
						sc.Forward();    // gobble regex flags
 | 
			
		||||
					sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				} else if (sc.ch == '\\') {
 | 
			
		||||
					// Gobble up the quoted character
 | 
			
		||||
					if (sc.chNext == '\\' || sc.chNext == '/') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_STRINGEOL:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_VERBATIM:
 | 
			
		||||
				if (sc.ch == '\"') {
 | 
			
		||||
					if (sc.chNext == '\"') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.ForwardSetState(SCE_ECL_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_ECL_UUID:
 | 
			
		||||
				if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
 | 
			
		||||
					sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		Sci_Position lineCurrent = styler.GetLine(sc.currentPos);
 | 
			
		||||
		int lineState = styler.GetLineState(lineCurrent);
 | 
			
		||||
		if (sc.state == SCE_ECL_DEFAULT) {
 | 
			
		||||
			if (lineState) {
 | 
			
		||||
				sc.SetState(lineState);
 | 
			
		||||
			}
 | 
			
		||||
			else if (sc.Match('@', '\"')) {
 | 
			
		||||
				sc.SetState(SCE_ECL_VERBATIM);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (setQualified.Contains(sc.ch) && sc.chNext == '\'') {
 | 
			
		||||
				sc.SetState(SCE_ECL_CHARACTER);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				if (lastWordWasUUID) {
 | 
			
		||||
					sc.SetState(SCE_ECL_UUID);
 | 
			
		||||
					lastWordWasUUID = false;
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_ECL_NUMBER);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
 | 
			
		||||
				if (lastWordWasUUID) {
 | 
			
		||||
					sc.SetState(SCE_ECL_UUID);
 | 
			
		||||
					lastWordWasUUID = false;
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_ECL_IDENTIFIER);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.Match('/', '*')) {
 | 
			
		||||
				if (sc.Match("/**") || sc.Match("/*!")) {	// Support of Qt/Doxygen doc. style
 | 
			
		||||
					sc.SetState(SCE_ECL_COMMENTDOC);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_ECL_COMMENT);
 | 
			
		||||
				}
 | 
			
		||||
				sc.Forward();	// Eat the * so it isn't used for the end of the comment
 | 
			
		||||
			} else if (sc.Match('/', '/')) {
 | 
			
		||||
				if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
 | 
			
		||||
					// Support of Qt/Doxygen doc. style
 | 
			
		||||
					sc.SetState(SCE_ECL_COMMENTLINEDOC);
 | 
			
		||||
				else
 | 
			
		||||
					sc.SetState(SCE_ECL_COMMENTLINE);
 | 
			
		||||
			} else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite)) {
 | 
			
		||||
				sc.SetState(SCE_ECL_REGEX);	// JavaScript's RegEx
 | 
			
		||||
//			} else if (sc.ch == '\"') {
 | 
			
		||||
//				sc.SetState(SCE_ECL_STRING);
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(SCE_ECL_CHARACTER);
 | 
			
		||||
			} else if (sc.ch == '#' && visibleChars == 0) {
 | 
			
		||||
				// Preprocessor commands are alone on their line
 | 
			
		||||
				sc.SetState(SCE_ECL_PREPROCESSOR);
 | 
			
		||||
				// Skip whitespace between # and preprocessor word
 | 
			
		||||
				do {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.SetState(SCE_ECL_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (isoperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_ECL_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
 | 
			
		||||
			chPrevNonWhite = sc.ch;
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
		continuationLine = false;
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsStreamCommentStyle(int style) {
 | 
			
		||||
	return style == SCE_ECL_COMMENT ||
 | 
			
		||||
		style == SCE_ECL_COMMENTDOC ||
 | 
			
		||||
		style == SCE_ECL_COMMENTDOCKEYWORD ||
 | 
			
		||||
		style == SCE_ECL_COMMENTDOCKEYWORDERROR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool MatchNoCase(Accessor & styler, Sci_PositionU & pos, const char *s) {
 | 
			
		||||
	Sci_Position i=0;
 | 
			
		||||
	for (; *s; i++) {
 | 
			
		||||
		char compare_char = tolower(*s);
 | 
			
		||||
		char styler_char = tolower(styler.SafeGetCharAt(pos+i));
 | 
			
		||||
		if (compare_char != styler_char)
 | 
			
		||||
			return false;
 | 
			
		||||
		s++;
 | 
			
		||||
	}
 | 
			
		||||
	pos+=i-1;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Store both the current line's fold level and the next lines in the
 | 
			
		||||
// level store to make it easy to pick up with each increment
 | 
			
		||||
// and to make it possible to fiddle the current level for "} else {".
 | 
			
		||||
static void FoldEclDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
					   WordList *[], Accessor &styler) {
 | 
			
		||||
	bool foldComment = true;
 | 
			
		||||
	bool foldPreprocessor = true;
 | 
			
		||||
	bool foldCompact = true;
 | 
			
		||||
	bool foldAtElse = true;
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
	if (lineCurrent > 0)
 | 
			
		||||
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 | 
			
		||||
	int levelMinCurrent = levelCurrent;
 | 
			
		||||
	int levelNext = levelCurrent;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int stylePrev = style;
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if (foldComment && IsStreamCommentStyle(style)) {
 | 
			
		||||
			if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_ECL_COMMENTLINEDOC)) {
 | 
			
		||||
				levelNext++;
 | 
			
		||||
			} else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_ECL_COMMENTLINEDOC) && !atEOL) {
 | 
			
		||||
				// Comments don't end at end of line and the next character may be unstyled.
 | 
			
		||||
				levelNext--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (foldComment && (style == SCE_ECL_COMMENTLINE)) {
 | 
			
		||||
			if ((ch == '/') && (chNext == '/')) {
 | 
			
		||||
				char chNext2 = styler.SafeGetCharAt(i + 2);
 | 
			
		||||
				if (chNext2 == '{') {
 | 
			
		||||
					levelNext++;
 | 
			
		||||
				} else if (chNext2 == '}') {
 | 
			
		||||
					levelNext--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (foldPreprocessor && (style == SCE_ECL_PREPROCESSOR)) {
 | 
			
		||||
			if (ch == '#') {
 | 
			
		||||
				Sci_PositionU j = i + 1;
 | 
			
		||||
				while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
 | 
			
		||||
					j++;
 | 
			
		||||
				}
 | 
			
		||||
				if (MatchNoCase(styler, j, "region") || MatchNoCase(styler, j, "if")) {
 | 
			
		||||
					levelNext++;
 | 
			
		||||
				} else if (MatchNoCase(styler, j, "endregion") || MatchNoCase(styler, j, "end")) {
 | 
			
		||||
					levelNext--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (style == SCE_ECL_OPERATOR) {
 | 
			
		||||
			if (ch == '{') {
 | 
			
		||||
				// Measure the minimum before a '{' to allow
 | 
			
		||||
				// folding on "} else {"
 | 
			
		||||
				if (levelMinCurrent > levelNext) {
 | 
			
		||||
					levelMinCurrent = levelNext;
 | 
			
		||||
				}
 | 
			
		||||
				levelNext++;
 | 
			
		||||
			} else if (ch == '}') {
 | 
			
		||||
				levelNext--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (style == SCE_ECL_WORD2) {
 | 
			
		||||
			if (MatchNoCase(styler, i, "record") || MatchNoCase(styler, i, "transform") || MatchNoCase(styler, i, "type") || MatchNoCase(styler, i, "function") ||
 | 
			
		||||
				MatchNoCase(styler, i, "module") || MatchNoCase(styler, i, "service") || MatchNoCase(styler, i, "interface") || MatchNoCase(styler, i, "ifblock") ||
 | 
			
		||||
				MatchNoCase(styler, i, "macro") || MatchNoCase(styler, i, "beginc++")) {
 | 
			
		||||
				levelNext++;
 | 
			
		||||
			} else if (MatchNoCase(styler, i, "endmacro") || MatchNoCase(styler, i, "endc++") || MatchNoCase(styler, i, "end")) {
 | 
			
		||||
				levelNext--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (atEOL || (i == endPos-1)) {
 | 
			
		||||
			int levelUse = levelCurrent;
 | 
			
		||||
			if (foldAtElse) {
 | 
			
		||||
				levelUse = levelMinCurrent;
 | 
			
		||||
			}
 | 
			
		||||
			int lev = levelUse | levelNext << 16;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if (levelUse < levelNext)
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelCurrent = levelNext;
 | 
			
		||||
			levelMinCurrent = levelCurrent;
 | 
			
		||||
			if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length()-1))) {
 | 
			
		||||
				// There is an empty line at end of file so give it same level and empty
 | 
			
		||||
				styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
 | 
			
		||||
			}
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!IsASpace(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const EclWordListDesc[] = {
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmECL(
 | 
			
		||||
   SCLEX_ECL,
 | 
			
		||||
   ColouriseEclDoc,
 | 
			
		||||
   "ecl",
 | 
			
		||||
   FoldEclDoc,
 | 
			
		||||
   EclWordListDesc);
 | 
			
		||||
							
								
								
									
										405
									
								
								3rdparty/lexilla540/lexilla/lexers/LexEDIFACT.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								3rdparty/lexilla540/lexilla/lexers/LexEDIFACT.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,405 @@
 | 
			
		||||
// Scintilla Lexer for EDIFACT
 | 
			
		||||
// @file LexEDIFACT.cxx
 | 
			
		||||
// Written by Iain Clarke, IMCSoft & Inobiz AB.
 | 
			
		||||
// EDIFACT documented here: https://www.unece.org/cefact/edifact/welcome.html
 | 
			
		||||
// and more readably here: https://en.wikipedia.org/wiki/EDIFACT
 | 
			
		||||
// This code is subject to the same license terms as the rest of the scintilla project:
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Header order must match order in scripts/HeaderOrder.txt
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cctype>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
class LexerEDIFACT : public DefaultLexer
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	LexerEDIFACT();
 | 
			
		||||
	virtual ~LexerEDIFACT() {} // virtual destructor, as we inherit from ILexer
 | 
			
		||||
 | 
			
		||||
	static ILexer5 *Factory() {
 | 
			
		||||
		return new LexerEDIFACT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int SCI_METHOD Version() const override
 | 
			
		||||
	{
 | 
			
		||||
		return lvRelease5;
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD Release() override
 | 
			
		||||
	{
 | 
			
		||||
		delete this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char * SCI_METHOD PropertyNames() override
 | 
			
		||||
	{
 | 
			
		||||
		return "fold\nlexer.edifact.highlight.un.all";
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD PropertyType(const char *) override
 | 
			
		||||
	{
 | 
			
		||||
		return SC_TYPE_BOOLEAN; // Only one property!
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD DescribeProperty(const char *name) override
 | 
			
		||||
	{
 | 
			
		||||
		if (!strcmp(name, "fold"))
 | 
			
		||||
			return "Whether to apply folding to document or not";
 | 
			
		||||
		if (!strcmp(name, "lexer.edifact.highlight.un.all"))
 | 
			
		||||
			return "Whether to apply UN* highlighting to all UN segments, or just to UNH";
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override
 | 
			
		||||
	{
 | 
			
		||||
		if (!strcmp(key, "fold"))
 | 
			
		||||
		{
 | 
			
		||||
			m_bFold = strcmp(val, "0") ? true : false;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!strcmp(key, "lexer.edifact.highlight.un.all"))	// GetProperty
 | 
			
		||||
		{
 | 
			
		||||
			m_bHighlightAllUN = strcmp(val, "0") ? true : false;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char * SCI_METHOD PropertyGet(const char *key) override
 | 
			
		||||
	{
 | 
			
		||||
		m_lastPropertyValue = "";
 | 
			
		||||
		if (!strcmp(key, "fold"))
 | 
			
		||||
		{
 | 
			
		||||
			m_lastPropertyValue = m_bFold ? "1" : "0";
 | 
			
		||||
		}
 | 
			
		||||
		if (!strcmp(key, "lexer.edifact.highlight.un.all"))	// GetProperty
 | 
			
		||||
		{
 | 
			
		||||
			m_lastPropertyValue = m_bHighlightAllUN ? "1" : "0";
 | 
			
		||||
		}
 | 
			
		||||
		return m_lastPropertyValue.c_str();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char * SCI_METHOD DescribeWordListSets() override
 | 
			
		||||
	{
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD WordListSet(int, const char *) override
 | 
			
		||||
	{
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
	void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
	void * SCI_METHOD PrivateCall(int, void *) override
 | 
			
		||||
	{
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	Sci_Position InitialiseFromUNA(IDocument *pAccess, Sci_PositionU MaxLength);
 | 
			
		||||
	Sci_Position FindPreviousEnd(IDocument *pAccess, Sci_Position startPos) const;
 | 
			
		||||
	Sci_Position ForwardPastWhitespace(IDocument *pAccess, Sci_Position startPos, Sci_Position MaxLength) const;
 | 
			
		||||
	int DetectSegmentHeader(char SegmentHeader[3]) const;
 | 
			
		||||
 | 
			
		||||
	bool m_bFold;
 | 
			
		||||
 | 
			
		||||
	// property lexer.edifact.highlight.un.all
 | 
			
		||||
	//	Set to 0 to highlight only UNA segments, or 1 to highlight all UNx segments.
 | 
			
		||||
	bool m_bHighlightAllUN;
 | 
			
		||||
 | 
			
		||||
	char m_chComponent;
 | 
			
		||||
	char m_chData;
 | 
			
		||||
	char m_chDecimal;
 | 
			
		||||
	char m_chRelease;
 | 
			
		||||
	char m_chSegment;
 | 
			
		||||
 | 
			
		||||
	std::string m_lastPropertyValue;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmEDIFACT(SCLEX_EDIFACT, LexerEDIFACT::Factory, "edifact");
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
LexerEDIFACT::LexerEDIFACT() : DefaultLexer("edifact", SCLEX_EDIFACT)
 | 
			
		||||
{
 | 
			
		||||
	m_bFold = false;
 | 
			
		||||
	m_bHighlightAllUN = false;
 | 
			
		||||
	m_chComponent = ':';
 | 
			
		||||
	m_chData = '+';
 | 
			
		||||
	m_chDecimal = '.';
 | 
			
		||||
	m_chRelease = '?';
 | 
			
		||||
	m_chSegment = '\'';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess)
 | 
			
		||||
{
 | 
			
		||||
	Sci_PositionU posFinish = startPos + length;
 | 
			
		||||
	InitialiseFromUNA(pAccess, posFinish);
 | 
			
		||||
 | 
			
		||||
	// Look backwards for a ' or a document beginning
 | 
			
		||||
	Sci_PositionU posCurrent = FindPreviousEnd(pAccess, startPos);
 | 
			
		||||
	// And jump past the ' if this was not the beginning of the document
 | 
			
		||||
	if (posCurrent != 0)
 | 
			
		||||
		posCurrent++;
 | 
			
		||||
 | 
			
		||||
	// Style buffer, so we're not issuing loads of notifications
 | 
			
		||||
	LexAccessor styler (pAccess);
 | 
			
		||||
	pAccess->StartStyling(posCurrent);
 | 
			
		||||
	styler.StartSegment(posCurrent);
 | 
			
		||||
	Sci_Position posSegmentStart = -1;
 | 
			
		||||
 | 
			
		||||
	while ((posCurrent < posFinish) && (posSegmentStart == -1))
 | 
			
		||||
	{
 | 
			
		||||
		posCurrent = ForwardPastWhitespace(pAccess, posCurrent, posFinish);
 | 
			
		||||
		// Mark whitespace as default
 | 
			
		||||
		styler.ColourTo(posCurrent - 1, SCE_EDI_DEFAULT);
 | 
			
		||||
		if (posCurrent >= posFinish)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		// Does is start with 3 charaters? ie, UNH
 | 
			
		||||
		char SegmentHeader[4] = { 0 };
 | 
			
		||||
		pAccess->GetCharRange(SegmentHeader, posCurrent, 3);
 | 
			
		||||
 | 
			
		||||
		int SegmentStyle = DetectSegmentHeader(SegmentHeader);
 | 
			
		||||
		if (SegmentStyle == SCE_EDI_BADSEGMENT)
 | 
			
		||||
			break;
 | 
			
		||||
		if (SegmentStyle == SCE_EDI_UNA)
 | 
			
		||||
		{
 | 
			
		||||
			posCurrent += 9;
 | 
			
		||||
			styler.ColourTo(posCurrent - 1, SCE_EDI_UNA); // UNA
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		posSegmentStart = posCurrent;
 | 
			
		||||
		posCurrent += 3;
 | 
			
		||||
 | 
			
		||||
		styler.ColourTo(posCurrent - 1, SegmentStyle); // UNH etc
 | 
			
		||||
 | 
			
		||||
		// Colour in the rest of the segment
 | 
			
		||||
		for (char c; posCurrent < posFinish; posCurrent++)
 | 
			
		||||
		{
 | 
			
		||||
			pAccess->GetCharRange(&c, posCurrent, 1);
 | 
			
		||||
 | 
			
		||||
			if (c == m_chRelease) // ? escape character, check first, in case of ?'
 | 
			
		||||
				posCurrent++;
 | 
			
		||||
			else if (c == m_chSegment) // '
 | 
			
		||||
			{
 | 
			
		||||
				// Make sure the whole segment is on one line. styler won't let us go back in time, so we'll settle for marking the ' as bad.
 | 
			
		||||
				Sci_Position lineSegmentStart = pAccess->LineFromPosition(posSegmentStart);
 | 
			
		||||
				Sci_Position lineSegmentEnd = pAccess->LineFromPosition(posCurrent);
 | 
			
		||||
				if (lineSegmentStart == lineSegmentEnd)
 | 
			
		||||
					styler.ColourTo(posCurrent, SCE_EDI_SEGMENTEND);
 | 
			
		||||
				else
 | 
			
		||||
					styler.ColourTo(posCurrent, SCE_EDI_BADSEGMENT);
 | 
			
		||||
				posSegmentStart = -1;
 | 
			
		||||
				posCurrent++;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			else if (c == m_chComponent) // :
 | 
			
		||||
				styler.ColourTo(posCurrent, SCE_EDI_SEP_COMPOSITE);
 | 
			
		||||
			else if (c == m_chData) // +
 | 
			
		||||
				styler.ColourTo(posCurrent, SCE_EDI_SEP_ELEMENT);
 | 
			
		||||
			else
 | 
			
		||||
				styler.ColourTo(posCurrent, SCE_EDI_DEFAULT);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	styler.Flush();
 | 
			
		||||
 | 
			
		||||
	if (posSegmentStart == -1)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	pAccess->StartStyling(posSegmentStart);
 | 
			
		||||
	pAccess->SetStyleFor(posFinish - posSegmentStart, SCE_EDI_BADSEGMENT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LexerEDIFACT::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess)
 | 
			
		||||
{
 | 
			
		||||
	if (!m_bFold)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	startPos = FindPreviousEnd(pAccess, startPos);
 | 
			
		||||
	char c;
 | 
			
		||||
	char SegmentHeader[4] = { 0 };
 | 
			
		||||
 | 
			
		||||
	bool AwaitingSegment = true;
 | 
			
		||||
	Sci_PositionU currLine = pAccess->LineFromPosition(startPos);
 | 
			
		||||
	int levelCurrentStyle = SC_FOLDLEVELBASE;
 | 
			
		||||
	if (currLine > 0)
 | 
			
		||||
		levelCurrentStyle = pAccess->GetLevel(currLine - 1); // bottom 12 bits are level
 | 
			
		||||
	int indentCurrent = levelCurrentStyle & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int indentNext = indentCurrent;
 | 
			
		||||
 | 
			
		||||
	while (startPos < endPos)
 | 
			
		||||
	{
 | 
			
		||||
		pAccess->GetCharRange(&c, startPos, 1);
 | 
			
		||||
		switch (c)
 | 
			
		||||
		{
 | 
			
		||||
		case '\t':
 | 
			
		||||
		case '\r':
 | 
			
		||||
		case ' ':
 | 
			
		||||
			startPos++;
 | 
			
		||||
			continue;
 | 
			
		||||
		case '\n':
 | 
			
		||||
			currLine = pAccess->LineFromPosition(startPos);
 | 
			
		||||
			pAccess->SetLevel(currLine, levelCurrentStyle | indentCurrent);
 | 
			
		||||
			startPos++;
 | 
			
		||||
			levelCurrentStyle = SC_FOLDLEVELBASE;
 | 
			
		||||
			indentCurrent = indentNext;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		if (c == m_chRelease)
 | 
			
		||||
		{
 | 
			
		||||
			startPos += 2;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		if (c == m_chSegment)
 | 
			
		||||
		{
 | 
			
		||||
			AwaitingSegment = true;
 | 
			
		||||
			startPos++;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!AwaitingSegment)
 | 
			
		||||
		{
 | 
			
		||||
			startPos++;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Segment!
 | 
			
		||||
		pAccess->GetCharRange(SegmentHeader, startPos, 3);
 | 
			
		||||
		if (SegmentHeader[0] != 'U' || SegmentHeader[1] != 'N')
 | 
			
		||||
		{
 | 
			
		||||
			startPos++;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		AwaitingSegment = false;
 | 
			
		||||
		switch (SegmentHeader[2])
 | 
			
		||||
		{
 | 
			
		||||
		case 'H':
 | 
			
		||||
		case 'G':
 | 
			
		||||
			indentNext++;
 | 
			
		||||
			levelCurrentStyle = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case 'T':
 | 
			
		||||
		case 'E':
 | 
			
		||||
			if (indentNext > 0)
 | 
			
		||||
				indentNext--;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		startPos += 3;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sci_Position LexerEDIFACT::InitialiseFromUNA(IDocument *pAccess, Sci_PositionU MaxLength)
 | 
			
		||||
{
 | 
			
		||||
	MaxLength -= 9; // drop 9 chars, to give us room for UNA:+.? '
 | 
			
		||||
 | 
			
		||||
	Sci_PositionU startPos = 0;
 | 
			
		||||
	startPos += ForwardPastWhitespace(pAccess, 0, MaxLength);
 | 
			
		||||
	if (startPos < MaxLength)
 | 
			
		||||
	{
 | 
			
		||||
		char bufUNA[9];
 | 
			
		||||
		pAccess->GetCharRange(bufUNA, startPos, 9);
 | 
			
		||||
 | 
			
		||||
		// Check it's UNA segment
 | 
			
		||||
		if (!memcmp(bufUNA, "UNA", 3))
 | 
			
		||||
		{
 | 
			
		||||
			m_chComponent = bufUNA[3];
 | 
			
		||||
			m_chData = bufUNA[4];
 | 
			
		||||
			m_chDecimal = bufUNA[5];
 | 
			
		||||
			m_chRelease = bufUNA[6];
 | 
			
		||||
			// bufUNA [7] should be space - reserved.
 | 
			
		||||
			m_chSegment = bufUNA[8];
 | 
			
		||||
 | 
			
		||||
			return 0; // success!
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// We failed to find a UNA, so drop to defaults
 | 
			
		||||
	m_chComponent = ':';
 | 
			
		||||
	m_chData = '+';
 | 
			
		||||
	m_chDecimal = '.';
 | 
			
		||||
	m_chRelease = '?';
 | 
			
		||||
	m_chSegment = '\'';
 | 
			
		||||
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sci_Position LexerEDIFACT::ForwardPastWhitespace(IDocument *pAccess, Sci_Position startPos, Sci_Position MaxLength) const
 | 
			
		||||
{
 | 
			
		||||
	char c;
 | 
			
		||||
 | 
			
		||||
	while (startPos < MaxLength)
 | 
			
		||||
	{
 | 
			
		||||
		pAccess->GetCharRange(&c, startPos, 1);
 | 
			
		||||
		switch (c)
 | 
			
		||||
		{
 | 
			
		||||
		case '\t':
 | 
			
		||||
		case '\r':
 | 
			
		||||
		case '\n':
 | 
			
		||||
		case ' ':
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			return startPos;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		startPos++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return MaxLength;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int LexerEDIFACT::DetectSegmentHeader(char SegmentHeader[3]) const
 | 
			
		||||
{
 | 
			
		||||
	if (
 | 
			
		||||
		SegmentHeader[0] < 'A' || SegmentHeader[0] > 'Z' ||
 | 
			
		||||
		SegmentHeader[1] < 'A' || SegmentHeader[1] > 'Z' ||
 | 
			
		||||
		SegmentHeader[2] < 'A' || SegmentHeader[2] > 'Z')
 | 
			
		||||
		return SCE_EDI_BADSEGMENT;
 | 
			
		||||
 | 
			
		||||
	if (!memcmp(SegmentHeader, "UNA", 3))
 | 
			
		||||
		return SCE_EDI_UNA;
 | 
			
		||||
 | 
			
		||||
	if (m_bHighlightAllUN && !memcmp(SegmentHeader, "UN", 2))
 | 
			
		||||
		return SCE_EDI_UNH;
 | 
			
		||||
	else if (!memcmp(SegmentHeader, "UNH", 3))
 | 
			
		||||
		return SCE_EDI_UNH;
 | 
			
		||||
	else if (!memcmp(SegmentHeader, "UNG", 3))
 | 
			
		||||
		return SCE_EDI_UNH;
 | 
			
		||||
 | 
			
		||||
	return SCE_EDI_SEGMENTSTART;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Look backwards for a ' or a document beginning
 | 
			
		||||
Sci_Position LexerEDIFACT::FindPreviousEnd(IDocument *pAccess, Sci_Position startPos) const
 | 
			
		||||
{
 | 
			
		||||
	for (char c; startPos > 0; startPos--)
 | 
			
		||||
	{
 | 
			
		||||
		pAccess->GetCharRange(&c, startPos, 1);
 | 
			
		||||
		if (c == m_chSegment)
 | 
			
		||||
			return startPos;
 | 
			
		||||
	}
 | 
			
		||||
	// We didn't find a ', so just go with the beginning
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										277
									
								
								3rdparty/lexilla540/lexilla/lexers/LexEScript.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										277
									
								
								3rdparty/lexilla540/lexilla/lexers/LexEScript.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,277 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexEScript.cxx
 | 
			
		||||
 ** Lexer for ESCRIPT
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2003 by Patrizio Bekerle (patrizio@bekerle.com)
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordStart(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void ColouriseESCRIPTDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
	WordList &keywords2 = *keywordlists[1];
 | 
			
		||||
	WordList &keywords3 = *keywordlists[2];
 | 
			
		||||
 | 
			
		||||
	// Do not leak onto next line
 | 
			
		||||
	/*if (initStyle == SCE_ESCRIPT_STRINGEOL)
 | 
			
		||||
		initStyle = SCE_ESCRIPT_DEFAULT;*/
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	bool caseSensitive = styler.GetPropertyInt("escript.case.sensitive", 0) != 0;
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
		/*if (sc.atLineStart && (sc.state == SCE_ESCRIPT_STRING)) {
 | 
			
		||||
			// Prevent SCE_ESCRIPT_STRINGEOL from leaking back to previous line
 | 
			
		||||
			sc.SetState(SCE_ESCRIPT_STRING);
 | 
			
		||||
		}*/
 | 
			
		||||
 | 
			
		||||
		// Handle line continuation generically.
 | 
			
		||||
		if (sc.ch == '\\') {
 | 
			
		||||
			if (sc.chNext == '\n' || sc.chNext == '\r') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				if (sc.ch == '\r' && sc.chNext == '\n') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		if (sc.state == SCE_ESCRIPT_OPERATOR || sc.state == SCE_ESCRIPT_BRACE) {
 | 
			
		||||
			sc.SetState(SCE_ESCRIPT_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_ESCRIPT_NUMBER) {
 | 
			
		||||
			if (!IsADigit(sc.ch) || sc.ch != '.') {
 | 
			
		||||
				sc.SetState(SCE_ESCRIPT_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_ESCRIPT_IDENTIFIER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				if (caseSensitive) {
 | 
			
		||||
					sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
//				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
 | 
			
		||||
                                if (keywords.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_ESCRIPT_WORD);
 | 
			
		||||
				} else if (keywords2.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_ESCRIPT_WORD2);
 | 
			
		||||
				} else if (keywords3.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_ESCRIPT_WORD3);
 | 
			
		||||
                                        // sc.state = SCE_ESCRIPT_IDENTIFIER;
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_ESCRIPT_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_ESCRIPT_COMMENT) {
 | 
			
		||||
			if (sc.Match('*', '/')) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_ESCRIPT_COMMENTDOC) {
 | 
			
		||||
			if (sc.Match('*', '/')) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_ESCRIPT_COMMENTLINE) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_ESCRIPT_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_ESCRIPT_STRING) {
 | 
			
		||||
			if (sc.ch == '\\') {
 | 
			
		||||
				if (sc.chNext == '\"' || sc.chNext == '\\') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_ESCRIPT_DEFAULT) {
 | 
			
		||||
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_ESCRIPT_NUMBER);
 | 
			
		||||
			} else if (IsAWordStart(sc.ch) || (sc.ch == '#')) {
 | 
			
		||||
				sc.SetState(SCE_ESCRIPT_IDENTIFIER);
 | 
			
		||||
			} else if (sc.Match('/', '*')) {
 | 
			
		||||
				sc.SetState(SCE_ESCRIPT_COMMENT);
 | 
			
		||||
				sc.Forward();	// Eat the * so it isn't used for the end of the comment
 | 
			
		||||
			} else if (sc.Match('/', '/')) {
 | 
			
		||||
				sc.SetState(SCE_ESCRIPT_COMMENTLINE);
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_ESCRIPT_STRING);
 | 
			
		||||
				//} else if (isoperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
			} else if (sc.ch == '+' || sc.ch == '-' || sc.ch == '*' || sc.ch == '/' || sc.ch == '=' || sc.ch == '<' || sc.ch == '>' || sc.ch == '&' || sc.ch == '|' || sc.ch == '!' || sc.ch == '?' || sc.ch == ':') {
 | 
			
		||||
				sc.SetState(SCE_ESCRIPT_OPERATOR);
 | 
			
		||||
			} else if (sc.ch == '{' || sc.ch == '}') {
 | 
			
		||||
				sc.SetState(SCE_ESCRIPT_BRACE);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int classifyFoldPointESCRIPT(const char* s, const char* prevWord) {
 | 
			
		||||
	int lev = 0;
 | 
			
		||||
	if (strcmp(prevWord, "end") == 0) return lev;
 | 
			
		||||
	if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
        if (strcmp(s, "for") == 0 || strcmp(s, "foreach") == 0
 | 
			
		||||
	    || strcmp(s, "program") == 0 || strcmp(s, "function") == 0
 | 
			
		||||
	    || strcmp(s, "while") == 0 || strcmp(s, "case") == 0
 | 
			
		||||
	    || strcmp(s, "if") == 0 ) {
 | 
			
		||||
		lev = 1;
 | 
			
		||||
	} else if ( strcmp(s, "endfor") == 0 || strcmp(s, "endforeach") == 0
 | 
			
		||||
	    || strcmp(s, "endprogram") == 0 || strcmp(s, "endfunction") == 0
 | 
			
		||||
	    || strcmp(s, "endwhile") == 0 || strcmp(s, "endcase") == 0
 | 
			
		||||
	    || strcmp(s, "endif") == 0 ) {
 | 
			
		||||
		lev = -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return lev;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool IsStreamCommentStyle(int style) {
 | 
			
		||||
	return style == SCE_ESCRIPT_COMMENT ||
 | 
			
		||||
	       style == SCE_ESCRIPT_COMMENTDOC ||
 | 
			
		||||
	       style == SCE_ESCRIPT_COMMENTLINE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldESCRIPTDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler) {
 | 
			
		||||
	//~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 | 
			
		||||
	// Do not know how to fold the comment at the moment.
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
        bool foldComment = true;
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
 | 
			
		||||
	Sci_Position lastStart = 0;
 | 
			
		||||
	char prevWord[32] = "";
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int stylePrev = style;
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		if (foldComment && IsStreamCommentStyle(style)) {
 | 
			
		||||
			if (!IsStreamCommentStyle(stylePrev)) {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
 | 
			
		||||
				// Comments don't end at end of line and the next character may be unstyled.
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (foldComment && (style == SCE_ESCRIPT_COMMENTLINE)) {
 | 
			
		||||
			if ((ch == '/') && (chNext == '/')) {
 | 
			
		||||
				char chNext2 = styler.SafeGetCharAt(i + 2);
 | 
			
		||||
				if (chNext2 == '{') {
 | 
			
		||||
					levelCurrent++;
 | 
			
		||||
				} else if (chNext2 == '}') {
 | 
			
		||||
					levelCurrent--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (stylePrev == SCE_ESCRIPT_DEFAULT && style == SCE_ESCRIPT_WORD3)
 | 
			
		||||
		{
 | 
			
		||||
			// Store last word start point.
 | 
			
		||||
			lastStart = i;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (style == SCE_ESCRIPT_WORD3) {
 | 
			
		||||
			if(iswordchar(ch) && !iswordchar(chNext)) {
 | 
			
		||||
				char s[32];
 | 
			
		||||
				Sci_PositionU j;
 | 
			
		||||
				for(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) {
 | 
			
		||||
					s[j] = static_cast<char>(tolower(styler[lastStart + j]));
 | 
			
		||||
				}
 | 
			
		||||
				s[j] = '\0';
 | 
			
		||||
				levelCurrent += classifyFoldPointESCRIPT(s, prevWord);
 | 
			
		||||
				strcpy(prevWord, s);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
			strcpy(prevWord, "");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const char * const ESCRIPTWordLists[] = {
 | 
			
		||||
	"Primary keywords and identifiers",
 | 
			
		||||
	"Intrinsic functions",
 | 
			
		||||
	"Extended and user defined functions",
 | 
			
		||||
	0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmESCRIPT(SCLEX_ESCRIPT, ColouriseESCRIPTDoc, "escript", FoldESCRIPTDoc, ESCRIPTWordLists);
 | 
			
		||||
							
								
								
									
										242
									
								
								3rdparty/lexilla540/lexilla/lexers/LexEiffel.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								3rdparty/lexilla540/lexilla/lexers/LexEiffel.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,242 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexEiffel.cxx
 | 
			
		||||
 ** Lexer for Eiffel.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static inline bool isEiffelOperator(unsigned int ch) {
 | 
			
		||||
	// '.' left out as it is used to make up numbers
 | 
			
		||||
	return ch == '*' || ch == '/' || ch == '\\' || ch == '-' || ch == '+' ||
 | 
			
		||||
	        ch == '(' || ch == ')' || ch == '=' ||
 | 
			
		||||
	        ch == '{' || ch == '}' || ch == '~' ||
 | 
			
		||||
	        ch == '[' || ch == ']' || ch == ';' ||
 | 
			
		||||
	        ch == '<' || ch == '>' || ch == ',' ||
 | 
			
		||||
	        ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
 | 
			
		||||
		ch == '!' || ch == '@' || ch == '?';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(unsigned int  ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordStart(unsigned int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseEiffelDoc(Sci_PositionU startPos,
 | 
			
		||||
                            Sci_Position length,
 | 
			
		||||
                            int initStyle,
 | 
			
		||||
                            WordList *keywordlists[],
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
		if (sc.state == SCE_EIFFEL_STRINGEOL) {
 | 
			
		||||
			if (sc.ch != '\r' && sc.ch != '\n') {
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_EIFFEL_OPERATOR) {
 | 
			
		||||
			sc.SetState(SCE_EIFFEL_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_EIFFEL_WORD) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
				if (!keywords.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_EIFFEL_IDENTIFIER);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_EIFFEL_NUMBER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_EIFFEL_COMMENTLINE) {
 | 
			
		||||
			if (sc.ch == '\r' || sc.ch == '\n') {
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_EIFFEL_STRING) {
 | 
			
		||||
			if (sc.ch == '%') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_EIFFEL_CHARACTER) {
 | 
			
		||||
			if (sc.ch == '\r' || sc.ch == '\n') {
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_STRINGEOL);
 | 
			
		||||
			} else if (sc.ch == '%') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.state == SCE_EIFFEL_DEFAULT) {
 | 
			
		||||
			if (sc.ch == '-' && sc.chNext == '-') {
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_COMMENTLINE);
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_STRING);
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_CHARACTER);
 | 
			
		||||
			} else if (IsADigit(sc.ch) || (sc.ch == '.')) {
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_NUMBER);
 | 
			
		||||
			} else if (IsAWordStart(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_WORD);
 | 
			
		||||
			} else if (isEiffelOperator(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_EIFFEL_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsEiffelComment(Accessor &styler, Sci_Position pos, Sci_Position len) {
 | 
			
		||||
	return len>1 && styler[pos]=='-' && styler[pos+1]=='-';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldEiffelDocIndent(Sci_PositionU startPos, Sci_Position length, int,
 | 
			
		||||
						   WordList *[], Accessor &styler) {
 | 
			
		||||
	Sci_Position lengthDoc = startPos + length;
 | 
			
		||||
 | 
			
		||||
	// Backtrack to previous line in case need to fix its fold status
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	if (startPos > 0) {
 | 
			
		||||
		if (lineCurrent > 0) {
 | 
			
		||||
			lineCurrent--;
 | 
			
		||||
			startPos = styler.LineStart(lineCurrent);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	int spaceFlags = 0;
 | 
			
		||||
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsEiffelComment);
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	for (Sci_Position i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
 | 
			
		||||
			int lev = indentCurrent;
 | 
			
		||||
			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsEiffelComment);
 | 
			
		||||
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
 | 
			
		||||
				// Only non whitespace lines can be headers
 | 
			
		||||
				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
 | 
			
		||||
					lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
 | 
			
		||||
					// Line after is blank so check the next - maybe should continue further?
 | 
			
		||||
					int spaceFlags2 = 0;
 | 
			
		||||
					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsEiffelComment);
 | 
			
		||||
					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
 | 
			
		||||
						lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			indentCurrent = indentNext;
 | 
			
		||||
			styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldEiffelDocKeyWords(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[],
 | 
			
		||||
                       Accessor &styler) {
 | 
			
		||||
	Sci_PositionU lengthDoc = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int stylePrev = 0;
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	// lastDeferred should be determined by looking back to last keyword in case
 | 
			
		||||
	// the "deferred" is on a line before "class"
 | 
			
		||||
	bool lastDeferred = false;
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if ((stylePrev != SCE_EIFFEL_WORD) && (style == SCE_EIFFEL_WORD)) {
 | 
			
		||||
			char s[20];
 | 
			
		||||
			Sci_PositionU j = 0;
 | 
			
		||||
			while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
 | 
			
		||||
				s[j] = styler[i + j];
 | 
			
		||||
				j++;
 | 
			
		||||
			}
 | 
			
		||||
			s[j] = '\0';
 | 
			
		||||
 | 
			
		||||
			if (
 | 
			
		||||
				(strcmp(s, "check") == 0) ||
 | 
			
		||||
				(strcmp(s, "debug") == 0) ||
 | 
			
		||||
				(strcmp(s, "deferred") == 0) ||
 | 
			
		||||
				(strcmp(s, "do") == 0) ||
 | 
			
		||||
				(strcmp(s, "from") == 0) ||
 | 
			
		||||
				(strcmp(s, "if") == 0) ||
 | 
			
		||||
				(strcmp(s, "inspect") == 0) ||
 | 
			
		||||
				(strcmp(s, "once") == 0)
 | 
			
		||||
			)
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			if (!lastDeferred && (strcmp(s, "class") == 0))
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			if (strcmp(s, "end") == 0)
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			lastDeferred = strcmp(s, "deferred") == 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		stylePrev = style;
 | 
			
		||||
	}
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const eiffelWordListDesc[] = {
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent, eiffelWordListDesc);
 | 
			
		||||
extern const LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords, eiffelWordListDesc);
 | 
			
		||||
							
								
								
									
										631
									
								
								3rdparty/lexilla540/lexilla/lexers/LexErlang.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										631
									
								
								3rdparty/lexilla540/lexilla/lexers/LexErlang.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,631 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
// Encoding: UTF-8
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
/** @file LexErlang.cxx
 | 
			
		||||
 ** Lexer for Erlang.
 | 
			
		||||
 ** Enhanced by Etienne 'Lenain' Girondel (lenaing@gmail.com)
 | 
			
		||||
 ** Originally wrote by Peter-Henry Mander,
 | 
			
		||||
 ** based on Matlab lexer by José Fonseca.
 | 
			
		||||
 **/
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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;
 | 
			
		||||
 | 
			
		||||
static int is_radix(int radix, int ch) {
 | 
			
		||||
	int digit;
 | 
			
		||||
 | 
			
		||||
	if (36 < radix || 2 > radix)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (isdigit(ch)) {
 | 
			
		||||
		digit = ch - '0';
 | 
			
		||||
	} else if (isalnum(ch)) {
 | 
			
		||||
		digit = toupper(ch) - 'A' + 10;
 | 
			
		||||
	} else {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (digit < radix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	STATE_NULL,
 | 
			
		||||
	COMMENT,
 | 
			
		||||
	COMMENT_FUNCTION,
 | 
			
		||||
	COMMENT_MODULE,
 | 
			
		||||
	COMMENT_DOC,
 | 
			
		||||
	COMMENT_DOC_MACRO,
 | 
			
		||||
	ATOM_UNQUOTED,
 | 
			
		||||
	ATOM_QUOTED,
 | 
			
		||||
	NODE_NAME_UNQUOTED,
 | 
			
		||||
	NODE_NAME_QUOTED,
 | 
			
		||||
	MACRO_START,
 | 
			
		||||
	MACRO_UNQUOTED,
 | 
			
		||||
	MACRO_QUOTED,
 | 
			
		||||
	RECORD_START,
 | 
			
		||||
	RECORD_UNQUOTED,
 | 
			
		||||
	RECORD_QUOTED,
 | 
			
		||||
	NUMERAL_START,
 | 
			
		||||
	NUMERAL_BASE_VALUE,
 | 
			
		||||
	NUMERAL_FLOAT,
 | 
			
		||||
	NUMERAL_EXPONENT,
 | 
			
		||||
	PREPROCESSOR
 | 
			
		||||
} atom_parse_state_t;
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (ch != ' ') && (isalnum(ch) || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseErlangDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
								WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
	WordList &reservedWords = *keywordlists[0];
 | 
			
		||||
	WordList &erlangBIFs = *keywordlists[1];
 | 
			
		||||
	WordList &erlangPreproc = *keywordlists[2];
 | 
			
		||||
	WordList &erlangModulesAtt = *keywordlists[3];
 | 
			
		||||
	WordList &erlangDoc = *keywordlists[4];
 | 
			
		||||
	WordList &erlangDocMacro = *keywordlists[5];
 | 
			
		||||
	int radix_digits = 0;
 | 
			
		||||
	int exponent_digits = 0;
 | 
			
		||||
	atom_parse_state_t parse_state = STATE_NULL;
 | 
			
		||||
	atom_parse_state_t old_parse_state = STATE_NULL;
 | 
			
		||||
	bool to_late_to_comment = false;
 | 
			
		||||
	char cur[100];
 | 
			
		||||
	int old_style = SCE_ERLANG_DEFAULT;
 | 
			
		||||
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
		int style = SCE_ERLANG_DEFAULT;
 | 
			
		||||
		if (STATE_NULL != parse_state) {
 | 
			
		||||
 | 
			
		||||
			switch (parse_state) {
 | 
			
		||||
 | 
			
		||||
				case STATE_NULL : sc.SetState(SCE_ERLANG_DEFAULT); break;
 | 
			
		||||
 | 
			
		||||
			/* COMMENTS ------------------------------------------------------*/
 | 
			
		||||
				case COMMENT : {
 | 
			
		||||
					if (sc.ch != '%') {
 | 
			
		||||
						to_late_to_comment = true;
 | 
			
		||||
					} else if (!to_late_to_comment && sc.ch == '%') {
 | 
			
		||||
						// Switch to comment level 2 (Function)
 | 
			
		||||
						sc.ChangeState(SCE_ERLANG_COMMENT_FUNCTION);
 | 
			
		||||
						old_style = SCE_ERLANG_COMMENT_FUNCTION;
 | 
			
		||||
						parse_state = COMMENT_FUNCTION;
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				// V--- Falling through!
 | 
			
		||||
				// Falls through.
 | 
			
		||||
				case COMMENT_FUNCTION : {
 | 
			
		||||
					if (sc.ch != '%') {
 | 
			
		||||
						to_late_to_comment = true;
 | 
			
		||||
					} else if (!to_late_to_comment && sc.ch == '%') {
 | 
			
		||||
						// Switch to comment level 3 (Module)
 | 
			
		||||
						sc.ChangeState(SCE_ERLANG_COMMENT_MODULE);
 | 
			
		||||
						old_style = SCE_ERLANG_COMMENT_MODULE;
 | 
			
		||||
						parse_state = COMMENT_MODULE;
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				// V--- Falling through!
 | 
			
		||||
				// Falls through.
 | 
			
		||||
				case COMMENT_MODULE : {
 | 
			
		||||
					if (parse_state != COMMENT) {
 | 
			
		||||
						// Search for comment documentation
 | 
			
		||||
						if (sc.chNext == '@') {
 | 
			
		||||
							old_parse_state = parse_state;
 | 
			
		||||
							parse_state = ('{' == sc.ch)
 | 
			
		||||
											? COMMENT_DOC_MACRO
 | 
			
		||||
											: COMMENT_DOC;
 | 
			
		||||
							sc.ForwardSetState(sc.state);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// All comments types fall here.
 | 
			
		||||
					if (sc.MatchLineEnd()) {
 | 
			
		||||
						to_late_to_comment = false;
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
				case COMMENT_DOC :
 | 
			
		||||
				// V--- Falling through!
 | 
			
		||||
				case COMMENT_DOC_MACRO : {
 | 
			
		||||
 | 
			
		||||
					if (!isalnum(sc.ch)) {
 | 
			
		||||
						// Try to match documentation comment
 | 
			
		||||
						sc.GetCurrent(cur, sizeof(cur));
 | 
			
		||||
 | 
			
		||||
						if (parse_state == COMMENT_DOC_MACRO
 | 
			
		||||
							&& erlangDocMacro.InList(cur)) {
 | 
			
		||||
								sc.ChangeState(SCE_ERLANG_COMMENT_DOC_MACRO);
 | 
			
		||||
								while (sc.ch != '}' && !sc.atLineEnd)
 | 
			
		||||
									sc.Forward();
 | 
			
		||||
						} else if (erlangDoc.InList(cur)) {
 | 
			
		||||
							sc.ChangeState(SCE_ERLANG_COMMENT_DOC);
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.ChangeState(old_style);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						// Switch back to old state
 | 
			
		||||
						sc.SetState(old_style);
 | 
			
		||||
						parse_state = old_parse_state;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (sc.MatchLineEnd()) {
 | 
			
		||||
						to_late_to_comment = false;
 | 
			
		||||
						sc.ChangeState(old_style);
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
			/* -------------------------------------------------------------- */
 | 
			
		||||
			/* Atoms ---------------------------------------------------------*/
 | 
			
		||||
				case ATOM_UNQUOTED : {
 | 
			
		||||
					if ('@' == sc.ch){
 | 
			
		||||
						parse_state = NODE_NAME_UNQUOTED;
 | 
			
		||||
					} else if (sc.ch == ':') {
 | 
			
		||||
						// Searching for module name
 | 
			
		||||
						if (sc.chNext == ' ') {
 | 
			
		||||
							// error
 | 
			
		||||
							sc.ChangeState(SCE_ERLANG_UNKNOWN);
 | 
			
		||||
							parse_state = STATE_NULL;
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.Forward();
 | 
			
		||||
							if (isalnum(sc.ch) || (sc.ch == '\''))  {
 | 
			
		||||
								sc.GetCurrent(cur, sizeof(cur));
 | 
			
		||||
								sc.ChangeState(SCE_ERLANG_MODULES);
 | 
			
		||||
								sc.SetState(SCE_ERLANG_MODULES);
 | 
			
		||||
							}
 | 
			
		||||
							if (sc.ch == '\'') {
 | 
			
		||||
								parse_state = ATOM_QUOTED;
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
						}
 | 
			
		||||
					} else if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
 | 
			
		||||
						sc.GetCurrent(cur, sizeof(cur));
 | 
			
		||||
						if (reservedWords.InList(cur)) {
 | 
			
		||||
							style = SCE_ERLANG_KEYWORD;
 | 
			
		||||
						} else if (erlangBIFs.InList(cur)
 | 
			
		||||
									&& strcmp(cur,"erlang:")){
 | 
			
		||||
							style = SCE_ERLANG_BIFS;
 | 
			
		||||
						} else if (sc.ch == '(' || '/' == sc.ch){
 | 
			
		||||
							style = SCE_ERLANG_FUNCTION_NAME;
 | 
			
		||||
						} else {
 | 
			
		||||
							style = SCE_ERLANG_ATOM;
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						sc.ChangeState(style);
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
				case ATOM_QUOTED : {
 | 
			
		||||
					if ( '@' == sc.ch ){
 | 
			
		||||
						parse_state = NODE_NAME_QUOTED;
 | 
			
		||||
					} else if ('\'' == sc.ch && '\\' != sc.chPrev) {
 | 
			
		||||
						sc.ChangeState(SCE_ERLANG_ATOM_QUOTED);
 | 
			
		||||
						sc.ForwardSetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
			/* -------------------------------------------------------------- */
 | 
			
		||||
			/* Node names ----------------------------------------------------*/
 | 
			
		||||
				case NODE_NAME_UNQUOTED : {
 | 
			
		||||
					if ('@' == sc.ch) {
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					} else if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
						sc.ChangeState(SCE_ERLANG_NODE_NAME);
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
				case NODE_NAME_QUOTED : {
 | 
			
		||||
					if ('@' == sc.ch) {
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					} else if ('\'' == sc.ch && '\\' != sc.chPrev) {
 | 
			
		||||
						sc.ChangeState(SCE_ERLANG_NODE_NAME_QUOTED);
 | 
			
		||||
						sc.ForwardSetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
			/* -------------------------------------------------------------- */
 | 
			
		||||
			/* Records -------------------------------------------------------*/
 | 
			
		||||
				case RECORD_START : {
 | 
			
		||||
					if ('\'' == sc.ch) {
 | 
			
		||||
						parse_state = RECORD_QUOTED;
 | 
			
		||||
					} else if (isalpha(sc.ch) && islower(sc.ch)) {
 | 
			
		||||
						parse_state = RECORD_UNQUOTED;
 | 
			
		||||
					} else { // error
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
				case RECORD_UNQUOTED : {
 | 
			
		||||
					if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
						sc.ChangeState(SCE_ERLANG_RECORD);
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
				case RECORD_QUOTED : {
 | 
			
		||||
					if ('\'' == sc.ch && '\\' != sc.chPrev) {
 | 
			
		||||
						sc.ChangeState(SCE_ERLANG_RECORD_QUOTED);
 | 
			
		||||
						sc.ForwardSetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
			/* -------------------------------------------------------------- */
 | 
			
		||||
			/* Macros --------------------------------------------------------*/
 | 
			
		||||
				case MACRO_START : {
 | 
			
		||||
					if ('\'' == sc.ch) {
 | 
			
		||||
						parse_state = MACRO_QUOTED;
 | 
			
		||||
					} else if (isalpha(sc.ch)) {
 | 
			
		||||
						parse_state = MACRO_UNQUOTED;
 | 
			
		||||
					} else { // error
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
				case MACRO_UNQUOTED : {
 | 
			
		||||
					if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
						sc.ChangeState(SCE_ERLANG_MACRO);
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
				case MACRO_QUOTED : {
 | 
			
		||||
					if ('\'' == sc.ch && '\\' != sc.chPrev) {
 | 
			
		||||
						sc.ChangeState(SCE_ERLANG_MACRO_QUOTED);
 | 
			
		||||
						sc.ForwardSetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
			/* -------------------------------------------------------------- */
 | 
			
		||||
			/* Numerics ------------------------------------------------------*/
 | 
			
		||||
			/* Simple integer */
 | 
			
		||||
				case NUMERAL_START : {
 | 
			
		||||
					if (isdigit(sc.ch)) {
 | 
			
		||||
						radix_digits *= 10;
 | 
			
		||||
						radix_digits += sc.ch - '0'; // Assuming ASCII here!
 | 
			
		||||
					} else if ('#' == sc.ch) {
 | 
			
		||||
						if (2 > radix_digits || 36 < radix_digits) {
 | 
			
		||||
							sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
							parse_state = STATE_NULL;
 | 
			
		||||
						} else {
 | 
			
		||||
							parse_state = NUMERAL_BASE_VALUE;
 | 
			
		||||
						}
 | 
			
		||||
					} else if ('.' == sc.ch && isdigit(sc.chNext)) {
 | 
			
		||||
						radix_digits = 0;
 | 
			
		||||
						parse_state = NUMERAL_FLOAT;
 | 
			
		||||
					} else if ('e' == sc.ch || 'E' == sc.ch) {
 | 
			
		||||
						exponent_digits = 0;
 | 
			
		||||
						parse_state = NUMERAL_EXPONENT;
 | 
			
		||||
					} else {
 | 
			
		||||
						radix_digits = 0;
 | 
			
		||||
						sc.ChangeState(SCE_ERLANG_NUMBER);
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
			/* Integer in other base than 10 (x#yyy) */
 | 
			
		||||
				case NUMERAL_BASE_VALUE : {
 | 
			
		||||
					if (!is_radix(radix_digits,sc.ch)) {
 | 
			
		||||
						radix_digits = 0;
 | 
			
		||||
 | 
			
		||||
						if (!isalnum(sc.ch))
 | 
			
		||||
							sc.ChangeState(SCE_ERLANG_NUMBER);
 | 
			
		||||
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
			/* Float (x.yyy) */
 | 
			
		||||
				case NUMERAL_FLOAT : {
 | 
			
		||||
					if ('e' == sc.ch || 'E' == sc.ch) {
 | 
			
		||||
						exponent_digits = 0;
 | 
			
		||||
						parse_state = NUMERAL_EXPONENT;
 | 
			
		||||
					} else if (!isdigit(sc.ch)) {
 | 
			
		||||
						sc.ChangeState(SCE_ERLANG_NUMBER);
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
			/* Exponent, either integer or float (xEyy, x.yyEzzz) */
 | 
			
		||||
				case NUMERAL_EXPONENT : {
 | 
			
		||||
					if (('-' == sc.ch || '+' == sc.ch)
 | 
			
		||||
							&& (isdigit(sc.chNext))) {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					} else if (!isdigit(sc.ch)) {
 | 
			
		||||
						if (0 < exponent_digits)
 | 
			
		||||
							sc.ChangeState(SCE_ERLANG_NUMBER);
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					} else {
 | 
			
		||||
						++exponent_digits;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
			/* -------------------------------------------------------------- */
 | 
			
		||||
			/* Preprocessor --------------------------------------------------*/
 | 
			
		||||
				case PREPROCESSOR : {
 | 
			
		||||
					if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
 | 
			
		||||
						sc.GetCurrent(cur, sizeof(cur));
 | 
			
		||||
						if (erlangPreproc.InList(cur)) {
 | 
			
		||||
							style = SCE_ERLANG_PREPROC;
 | 
			
		||||
						} else if (erlangModulesAtt.InList(cur)) {
 | 
			
		||||
							style = SCE_ERLANG_MODULES_ATT;
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						sc.ChangeState(style);
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						parse_state = STATE_NULL;
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		} /* End of : STATE_NULL != parse_state */
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			switch (sc.state) {
 | 
			
		||||
				case SCE_ERLANG_VARIABLE : {
 | 
			
		||||
					if (!IsAWordChar(sc.ch))
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
				} break;
 | 
			
		||||
				case SCE_ERLANG_STRING : {
 | 
			
		||||
					 if (sc.ch == '\"' && sc.chPrev != '\\')
 | 
			
		||||
						sc.ForwardSetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
				} break;
 | 
			
		||||
				case SCE_ERLANG_COMMENT : {
 | 
			
		||||
					 if (sc.atLineEnd)
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
				} break;
 | 
			
		||||
				case SCE_ERLANG_CHARACTER : {
 | 
			
		||||
					if (sc.chPrev == '\\') {
 | 
			
		||||
						sc.ForwardSetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
					} else if (sc.ch != '\\') {
 | 
			
		||||
						sc.ForwardSetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
				case SCE_ERLANG_OPERATOR : {
 | 
			
		||||
					if (sc.chPrev == '.') {
 | 
			
		||||
						if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\'
 | 
			
		||||
							|| sc.ch == '^') {
 | 
			
		||||
							sc.ForwardSetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						} else if (sc.ch == '\'') {
 | 
			
		||||
							sc.ForwardSetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.SetState(SCE_ERLANG_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.state == SCE_ERLANG_DEFAULT) {
 | 
			
		||||
			bool no_new_state = false;
 | 
			
		||||
 | 
			
		||||
			switch (sc.ch) {
 | 
			
		||||
				case '\"' : sc.SetState(SCE_ERLANG_STRING); break;
 | 
			
		||||
				case '$' : sc.SetState(SCE_ERLANG_CHARACTER); break;
 | 
			
		||||
				case '%' : {
 | 
			
		||||
					parse_state = COMMENT;
 | 
			
		||||
					sc.SetState(SCE_ERLANG_COMMENT);
 | 
			
		||||
				} break;
 | 
			
		||||
				case '#' : {
 | 
			
		||||
					parse_state = RECORD_START;
 | 
			
		||||
					sc.SetState(SCE_ERLANG_UNKNOWN);
 | 
			
		||||
				} break;
 | 
			
		||||
				case '?' : {
 | 
			
		||||
					parse_state = MACRO_START;
 | 
			
		||||
					sc.SetState(SCE_ERLANG_UNKNOWN);
 | 
			
		||||
				} break;
 | 
			
		||||
				case '\'' : {
 | 
			
		||||
					parse_state = ATOM_QUOTED;
 | 
			
		||||
					sc.SetState(SCE_ERLANG_UNKNOWN);
 | 
			
		||||
				} break;
 | 
			
		||||
				case '+' :
 | 
			
		||||
				case '-' : {
 | 
			
		||||
					if (IsADigit(sc.chNext)) {
 | 
			
		||||
						parse_state = NUMERAL_START;
 | 
			
		||||
						radix_digits = 0;
 | 
			
		||||
						sc.SetState(SCE_ERLANG_UNKNOWN);
 | 
			
		||||
					} else if (sc.ch != '+') {
 | 
			
		||||
						parse_state = PREPROCESSOR;
 | 
			
		||||
						sc.SetState(SCE_ERLANG_UNKNOWN);
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
				default : no_new_state = true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (no_new_state) {
 | 
			
		||||
				if (isdigit(sc.ch)) {
 | 
			
		||||
					parse_state = NUMERAL_START;
 | 
			
		||||
					radix_digits = sc.ch - '0';
 | 
			
		||||
					sc.SetState(SCE_ERLANG_UNKNOWN);
 | 
			
		||||
				} else if (isupper(sc.ch) || '_' == sc.ch) {
 | 
			
		||||
					sc.SetState(SCE_ERLANG_VARIABLE);
 | 
			
		||||
				} else if (isalpha(sc.ch)) {
 | 
			
		||||
					parse_state = ATOM_UNQUOTED;
 | 
			
		||||
					sc.SetState(SCE_ERLANG_UNKNOWN);
 | 
			
		||||
				} else if (isoperator(static_cast<char>(sc.ch))
 | 
			
		||||
							|| sc.ch == '\\') {
 | 
			
		||||
					sc.SetState(SCE_ERLANG_OPERATOR);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int ClassifyErlangFoldPoint(
 | 
			
		||||
	Accessor &styler,
 | 
			
		||||
	int styleNext,
 | 
			
		||||
	Sci_Position keyword_start
 | 
			
		||||
) {
 | 
			
		||||
	int lev = 0;
 | 
			
		||||
	if (styler.Match(keyword_start,"case")
 | 
			
		||||
		|| (
 | 
			
		||||
			styler.Match(keyword_start,"fun")
 | 
			
		||||
			&& (SCE_ERLANG_FUNCTION_NAME != styleNext)
 | 
			
		||||
			)
 | 
			
		||||
		|| styler.Match(keyword_start,"if")
 | 
			
		||||
		|| styler.Match(keyword_start,"query")
 | 
			
		||||
		|| styler.Match(keyword_start,"receive")
 | 
			
		||||
	) {
 | 
			
		||||
		++lev;
 | 
			
		||||
	} else if (styler.Match(keyword_start,"end")) {
 | 
			
		||||
		--lev;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return lev;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldErlangDoc(
 | 
			
		||||
	Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
	WordList** /*keywordlists*/, Accessor &styler
 | 
			
		||||
) {
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	Sci_Position currentLine = styler.GetLine(startPos);
 | 
			
		||||
	int lev;
 | 
			
		||||
	int previousLevel = styler.LevelAt(currentLine) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int currentLevel = previousLevel;
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
	int stylePrev;
 | 
			
		||||
	Sci_Position keyword_start = 0;
 | 
			
		||||
	char ch;
 | 
			
		||||
	char chNext = styler.SafeGetCharAt(startPos);
 | 
			
		||||
	bool atEOL;
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
		// Get styles
 | 
			
		||||
		stylePrev = style;
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		atEOL = ((ch == '\r') && (chNext != '\n')) || (ch == '\n');
 | 
			
		||||
 | 
			
		||||
		if (stylePrev != SCE_ERLANG_KEYWORD
 | 
			
		||||
			&& style == SCE_ERLANG_KEYWORD) {
 | 
			
		||||
			keyword_start = i;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Fold on keywords
 | 
			
		||||
		if (stylePrev == SCE_ERLANG_KEYWORD
 | 
			
		||||
			&& style != SCE_ERLANG_KEYWORD
 | 
			
		||||
			&& style != SCE_ERLANG_ATOM
 | 
			
		||||
		) {
 | 
			
		||||
			currentLevel += ClassifyErlangFoldPoint(styler,
 | 
			
		||||
													styleNext,
 | 
			
		||||
													keyword_start);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Fold on comments
 | 
			
		||||
		if (style == SCE_ERLANG_COMMENT
 | 
			
		||||
			|| style == SCE_ERLANG_COMMENT_MODULE
 | 
			
		||||
			|| style == SCE_ERLANG_COMMENT_FUNCTION) {
 | 
			
		||||
 | 
			
		||||
			if (ch == '%' && chNext == '{') {
 | 
			
		||||
				currentLevel++;
 | 
			
		||||
			} else if (ch == '%' && chNext == '}') {
 | 
			
		||||
				currentLevel--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Fold on braces
 | 
			
		||||
		if (style == SCE_ERLANG_OPERATOR) {
 | 
			
		||||
			if (ch == '{' || ch == '(' || ch == '[') {
 | 
			
		||||
				currentLevel++;
 | 
			
		||||
			} else if (ch == '}' || ch == ')' || ch == ']') {
 | 
			
		||||
				currentLevel--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			lev = previousLevel;
 | 
			
		||||
 | 
			
		||||
			if (currentLevel > previousLevel)
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
 | 
			
		||||
			if (lev != styler.LevelAt(currentLine))
 | 
			
		||||
				styler.SetLevel(currentLine, lev);
 | 
			
		||||
 | 
			
		||||
			currentLine++;
 | 
			
		||||
			previousLevel = currentLevel;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
	styler.SetLevel(currentLine,
 | 
			
		||||
					previousLevel
 | 
			
		||||
					| (styler.LevelAt(currentLine) & ~SC_FOLDLEVELNUMBERMASK));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const erlangWordListDesc[] = {
 | 
			
		||||
	"Erlang Reserved words",
 | 
			
		||||
	"Erlang BIFs",
 | 
			
		||||
	"Erlang Preprocessor",
 | 
			
		||||
	"Erlang Module Attributes",
 | 
			
		||||
	"Erlang Documentation",
 | 
			
		||||
	"Erlang Documentation Macro",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmErlang(
 | 
			
		||||
	SCLEX_ERLANG,
 | 
			
		||||
	ColouriseErlangDoc,
 | 
			
		||||
	"erlang",
 | 
			
		||||
	FoldErlangDoc,
 | 
			
		||||
	erlangWordListDesc);
 | 
			
		||||
							
								
								
									
										431
									
								
								3rdparty/lexilla540/lexilla/lexers/LexErrorList.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										431
									
								
								3rdparty/lexilla540/lexilla/lexers/LexErrorList.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,431 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexErrorList.cxx
 | 
			
		||||
 ** Lexer for error lists. Used for the output pane in SciTE.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cstdarg>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <initializer_list>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "InList.h"
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "Accessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
bool strstart(const char *haystack, const char *needle) noexcept {
 | 
			
		||||
	return strncmp(haystack, needle, strlen(needle)) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr bool Is0To9(char ch) noexcept {
 | 
			
		||||
	return (ch >= '0') && (ch <= '9');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr bool Is1To9(char ch) noexcept {
 | 
			
		||||
	return (ch >= '1') && (ch <= '9');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AtEOL(Accessor &styler, Sci_Position i) {
 | 
			
		||||
	return (styler[i] == '\n') ||
 | 
			
		||||
	       ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool IsGccExcerpt(const char *s) noexcept {
 | 
			
		||||
	while (*s) {
 | 
			
		||||
		if (s[0] == ' ' && s[1] == '|' && (s[2] == ' ' || s[2] == '+')) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		if (!(s[0] == ' ' || s[0] == '+' || Is0To9(s[0]))) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		s++;
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::string_view bashDiagnosticMark = ": line ";
 | 
			
		||||
bool IsBashDiagnostic(std::string_view sv) {
 | 
			
		||||
	const size_t mark = sv.find(bashDiagnosticMark);
 | 
			
		||||
	if (mark == std::string_view::npos) {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	std::string_view rest = sv.substr(mark + bashDiagnosticMark.length());
 | 
			
		||||
	if (rest.empty() || !Is0To9(rest.front())) {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	while (!rest.empty() && Is0To9(rest.front())) {
 | 
			
		||||
		rest.remove_prefix(1);
 | 
			
		||||
	}
 | 
			
		||||
	return !rest.empty() && (rest.front() == ':');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLine, Sci_Position &startValue) {
 | 
			
		||||
	if (lineBuffer[0] == '>') {
 | 
			
		||||
		// Command or return status
 | 
			
		||||
		return SCE_ERR_CMD;
 | 
			
		||||
	} else if (lineBuffer[0] == '<') {
 | 
			
		||||
		// Diff removal.
 | 
			
		||||
		return SCE_ERR_DIFF_DELETION;
 | 
			
		||||
	} else if (lineBuffer[0] == '!') {
 | 
			
		||||
		return SCE_ERR_DIFF_CHANGED;
 | 
			
		||||
	} else if (lineBuffer[0] == '+') {
 | 
			
		||||
		if (strstart(lineBuffer, "+++ ")) {
 | 
			
		||||
			return SCE_ERR_DIFF_MESSAGE;
 | 
			
		||||
		} else {
 | 
			
		||||
			return SCE_ERR_DIFF_ADDITION;
 | 
			
		||||
		}
 | 
			
		||||
	} else if (lineBuffer[0] == '-') {
 | 
			
		||||
		if (strstart(lineBuffer, "--- ")) {
 | 
			
		||||
			return SCE_ERR_DIFF_MESSAGE;
 | 
			
		||||
		} else {
 | 
			
		||||
			return SCE_ERR_DIFF_DELETION;
 | 
			
		||||
		}
 | 
			
		||||
	} else if (strstart(lineBuffer, "cf90-")) {
 | 
			
		||||
		// Absoft Pro Fortran 90/95 v8.2 error and/or warning message
 | 
			
		||||
		return SCE_ERR_ABSF;
 | 
			
		||||
	} else if (strstart(lineBuffer, "fortcom:")) {
 | 
			
		||||
		// Intel Fortran Compiler v8.0 error/warning message
 | 
			
		||||
		return SCE_ERR_IFORT;
 | 
			
		||||
	} else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) {
 | 
			
		||||
		return SCE_ERR_PYTHON;
 | 
			
		||||
	} else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) {
 | 
			
		||||
		return SCE_ERR_PHP;
 | 
			
		||||
	} else if ((strstart(lineBuffer, "Error ") ||
 | 
			
		||||
	            strstart(lineBuffer, "Warning ")) &&
 | 
			
		||||
	           strstr(lineBuffer, " at (") &&
 | 
			
		||||
	           strstr(lineBuffer, ") : ") &&
 | 
			
		||||
	           (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) {
 | 
			
		||||
		// Intel Fortran Compiler error/warning message
 | 
			
		||||
		return SCE_ERR_IFC;
 | 
			
		||||
	} else if (strstart(lineBuffer, "Error ")) {
 | 
			
		||||
		// Borland error message
 | 
			
		||||
		return SCE_ERR_BORLAND;
 | 
			
		||||
	} else if (strstart(lineBuffer, "Warning ")) {
 | 
			
		||||
		// Borland warning message
 | 
			
		||||
		return SCE_ERR_BORLAND;
 | 
			
		||||
	} else if (strstr(lineBuffer, "at line ") &&
 | 
			
		||||
	        (strstr(lineBuffer, "at line ") < (lineBuffer + lengthLine)) &&
 | 
			
		||||
	           strstr(lineBuffer, "file ") &&
 | 
			
		||||
	           (strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) {
 | 
			
		||||
		// Lua 4 error message
 | 
			
		||||
		return SCE_ERR_LUA;
 | 
			
		||||
	} else if (strstr(lineBuffer, " at ") &&
 | 
			
		||||
	        (strstr(lineBuffer, " at ") < (lineBuffer + lengthLine)) &&
 | 
			
		||||
	           strstr(lineBuffer, " line ") &&
 | 
			
		||||
	           (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
 | 
			
		||||
	        (strstr(lineBuffer, " at ") + 4 < (strstr(lineBuffer, " line ")))) {
 | 
			
		||||
		// perl error message:
 | 
			
		||||
		// <message> at <file> line <line>
 | 
			
		||||
		return SCE_ERR_PERL;
 | 
			
		||||
	} else if ((lengthLine >= 6) &&
 | 
			
		||||
	           (memcmp(lineBuffer, "   at ", 6) == 0) &&
 | 
			
		||||
	           strstr(lineBuffer, ":line ")) {
 | 
			
		||||
		// A .NET traceback
 | 
			
		||||
		return SCE_ERR_NET;
 | 
			
		||||
	} else if (strstart(lineBuffer, "Line ") &&
 | 
			
		||||
	           strstr(lineBuffer, ", file ")) {
 | 
			
		||||
		// Essential Lahey Fortran error message
 | 
			
		||||
		return SCE_ERR_ELF;
 | 
			
		||||
	} else if (strstart(lineBuffer, "line ") &&
 | 
			
		||||
	           strstr(lineBuffer, " column ")) {
 | 
			
		||||
		// HTML tidy style: line 42 column 1
 | 
			
		||||
		return SCE_ERR_TIDY;
 | 
			
		||||
	} else if (strstart(lineBuffer, "\tat ") &&
 | 
			
		||||
	           strchr(lineBuffer, '(') &&
 | 
			
		||||
	           strstr(lineBuffer, ".java:")) {
 | 
			
		||||
		// Java stack back trace
 | 
			
		||||
		return SCE_ERR_JAVA_STACK;
 | 
			
		||||
	} else if (strstart(lineBuffer, "In file included from ") ||
 | 
			
		||||
	           strstart(lineBuffer, "                 from ")) {
 | 
			
		||||
		// GCC showing include path to following error
 | 
			
		||||
		return SCE_ERR_GCC_INCLUDED_FROM;
 | 
			
		||||
	} else if (strstart(lineBuffer, "NMAKE : fatal error")) {
 | 
			
		||||
		// Microsoft nmake fatal error:
 | 
			
		||||
		// NMAKE : fatal error <code>: <program> : return code <return>
 | 
			
		||||
		return SCE_ERR_MS;
 | 
			
		||||
	} else if (strstr(lineBuffer, "warning LNK") ||
 | 
			
		||||
		strstr(lineBuffer, "error LNK")) {
 | 
			
		||||
		// Microsoft linker warning:
 | 
			
		||||
		// {<object> : } (warning|error) LNK9999
 | 
			
		||||
		return SCE_ERR_MS;
 | 
			
		||||
	} else if (IsBashDiagnostic(lineBuffer)) {
 | 
			
		||||
		// Bash diagnostic
 | 
			
		||||
		// <filename>: line <line>:<message>
 | 
			
		||||
		return SCE_ERR_BASH;
 | 
			
		||||
	} else if (IsGccExcerpt(lineBuffer)) {
 | 
			
		||||
		// GCC code excerpt and pointer to issue
 | 
			
		||||
		//    73 |   GTimeVal last_popdown;
 | 
			
		||||
		//       |            ^~~~~~~~~~~~
 | 
			
		||||
		return SCE_ERR_GCC_EXCERPT;
 | 
			
		||||
	} else {
 | 
			
		||||
		// Look for one of the following formats:
 | 
			
		||||
		// GCC: <filename>:<line>:<message>
 | 
			
		||||
		// Microsoft: <filename>(<line>) :<message>
 | 
			
		||||
		// Common: <filename>(<line>): warning|error|note|remark|catastrophic|fatal
 | 
			
		||||
		// Common: <filename>(<line>) warning|error|note|remark|catastrophic|fatal
 | 
			
		||||
		// Microsoft: <filename>(<line>,<column>)<message>
 | 
			
		||||
		// CTags: <identifier>\t<filename>\t<message>
 | 
			
		||||
		// Lua 5 traceback: \t<filename>:<line>:<message>
 | 
			
		||||
		// Lua 5.1: <exe>: <filename>:<line>:<message>
 | 
			
		||||
		const bool initialTab = (lineBuffer[0] == '\t');
 | 
			
		||||
		bool initialColonPart = false;
 | 
			
		||||
		bool canBeCtags = !initialTab;	// For ctags must have an identifier with no spaces then a tab
 | 
			
		||||
		enum { stInitial,
 | 
			
		||||
			stGccStart, stGccDigit, stGccColumn, stGcc,
 | 
			
		||||
			stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet,
 | 
			
		||||
			stCtagsStart, stCtagsFile, stCtagsStartString, stCtagsStringDollar, stCtags,
 | 
			
		||||
			stUnrecognized
 | 
			
		||||
		} state = stInitial;
 | 
			
		||||
		for (Sci_PositionU i = 0; i < lengthLine; i++) {
 | 
			
		||||
			const char ch = lineBuffer[i];
 | 
			
		||||
			char chNext = ' ';
 | 
			
		||||
			if ((i + 1) < lengthLine)
 | 
			
		||||
				chNext = lineBuffer[i + 1];
 | 
			
		||||
			if (state == stInitial) {
 | 
			
		||||
				if (ch == ':') {
 | 
			
		||||
					// May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix)
 | 
			
		||||
					if ((chNext != '\\') && (chNext != '/') && (chNext != ' ')) {
 | 
			
		||||
						// This check is not completely accurate as may be on
 | 
			
		||||
						// GTK+ with a file name that includes ':'.
 | 
			
		||||
						state = stGccStart;
 | 
			
		||||
					} else if (chNext == ' ') { // indicates a Lua 5.1 error message
 | 
			
		||||
						initialColonPart = true;
 | 
			
		||||
					}
 | 
			
		||||
				} else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) {
 | 
			
		||||
					// May be Microsoft
 | 
			
		||||
					// Check against '0' often removes phone numbers
 | 
			
		||||
					state = stMsStart;
 | 
			
		||||
				} else if ((ch == '\t') && canBeCtags) {
 | 
			
		||||
					// May be CTags
 | 
			
		||||
					state = stCtagsStart;
 | 
			
		||||
				} else if (ch == ' ') {
 | 
			
		||||
					canBeCtags = false;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (state == stGccStart) {	// <filename>:
 | 
			
		||||
				state = ((ch == '-') || Is0To9(ch)) ? stGccDigit : stUnrecognized;
 | 
			
		||||
			} else if (state == stGccDigit) {	// <filename>:<line>
 | 
			
		||||
				if (ch == ':') {
 | 
			
		||||
					state = stGccColumn;	// :9.*: is GCC
 | 
			
		||||
					startValue = i + 1;
 | 
			
		||||
				} else if (!Is0To9(ch)) {
 | 
			
		||||
					state = stUnrecognized;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (state == stGccColumn) {	// <filename>:<line>:<column>
 | 
			
		||||
				if (!Is0To9(ch)) {
 | 
			
		||||
					state = stGcc;
 | 
			
		||||
					if (ch == ':')
 | 
			
		||||
						startValue = i + 1;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (state == stMsStart) {	// <filename>(
 | 
			
		||||
				state = Is0To9(ch) ? stMsDigit : stUnrecognized;
 | 
			
		||||
			} else if (state == stMsDigit) {	// <filename>(<line>
 | 
			
		||||
				if (ch == ',') {
 | 
			
		||||
					state = stMsDigitComma;
 | 
			
		||||
				} else if (ch == ')') {
 | 
			
		||||
					state = stMsBracket;
 | 
			
		||||
				} else if ((ch != ' ') && !Is0To9(ch)) {
 | 
			
		||||
					state = stUnrecognized;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (state == stMsBracket) {	// <filename>(<line>)
 | 
			
		||||
				if ((ch == ' ') && (chNext == ':')) {
 | 
			
		||||
					state = stMsVc;
 | 
			
		||||
				} else if ((ch == ':' && chNext == ' ') || (ch == ' ')) {
 | 
			
		||||
					// Possibly Delphi.. don't test against chNext as it's one of the strings below.
 | 
			
		||||
					char word[512];
 | 
			
		||||
					unsigned numstep = 0;
 | 
			
		||||
					if (ch == ' ')
 | 
			
		||||
						numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i.
 | 
			
		||||
					else
 | 
			
		||||
						numstep = 2; // otherwise add 2.
 | 
			
		||||
					Sci_PositionU chPos = 0;
 | 
			
		||||
					for (Sci_PositionU j = i + numstep; j < lengthLine && IsUpperOrLowerCase(lineBuffer[j]) && chPos < sizeof(word) - 1; j++)
 | 
			
		||||
						word[chPos++] = lineBuffer[j];
 | 
			
		||||
					word[chPos] = 0;
 | 
			
		||||
					if (InListCaseInsensitive(word, {"error", "warning", "fatal", "catastrophic", "note", "remark"})) {
 | 
			
		||||
						state = stMsVc;
 | 
			
		||||
					} else {
 | 
			
		||||
						state = stUnrecognized;
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					state = stUnrecognized;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (state == stMsDigitComma) {	// <filename>(<line>,
 | 
			
		||||
				if (ch == ')') {
 | 
			
		||||
					state = stMsDotNet;
 | 
			
		||||
					break;
 | 
			
		||||
				} else if ((ch != ' ') && !Is0To9(ch)) {
 | 
			
		||||
					state = stUnrecognized;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (state == stCtagsStart) {
 | 
			
		||||
				if (ch == '\t') {
 | 
			
		||||
					state = stCtagsFile;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (state == stCtagsFile) {
 | 
			
		||||
				if ((lineBuffer[i - 1] == '\t') &&
 | 
			
		||||
				        ((ch == '/' && chNext == '^') || Is0To9(ch))) {
 | 
			
		||||
					state = stCtags;
 | 
			
		||||
					break;
 | 
			
		||||
				} else if ((ch == '/') && (chNext == '^')) {
 | 
			
		||||
					state = stCtagsStartString;
 | 
			
		||||
				}
 | 
			
		||||
			} else if ((state == stCtagsStartString) && ((lineBuffer[i] == '$') && (lineBuffer[i + 1] == '/'))) {
 | 
			
		||||
				state = stCtagsStringDollar;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (state == stGcc) {
 | 
			
		||||
			return initialColonPart ? SCE_ERR_LUA : SCE_ERR_GCC;
 | 
			
		||||
		} else if ((state == stMsVc) || (state == stMsDotNet)) {
 | 
			
		||||
			return SCE_ERR_MS;
 | 
			
		||||
		} else if ((state == stCtagsStringDollar) || (state == stCtags)) {
 | 
			
		||||
			return SCE_ERR_CTAG;
 | 
			
		||||
		} else if (initialColonPart && strstr(lineBuffer, ": warning C")) {
 | 
			
		||||
			// Microsoft warning without line number
 | 
			
		||||
			// <filename>: warning C9999
 | 
			
		||||
			return SCE_ERR_MS;
 | 
			
		||||
		} else {
 | 
			
		||||
			return SCE_ERR_DEFAULT;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define CSI "\033["
 | 
			
		||||
 | 
			
		||||
constexpr bool SequenceEnd(int ch) noexcept {
 | 
			
		||||
	return (ch == 0) || ((ch >= '@') && (ch <= '~'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int StyleFromSequence(const char *seq) noexcept {
 | 
			
		||||
	int bold = 0;
 | 
			
		||||
	int colour = 0;
 | 
			
		||||
	while (!SequenceEnd(*seq)) {
 | 
			
		||||
		if (Is0To9(*seq)) {
 | 
			
		||||
			int base = *seq - '0';
 | 
			
		||||
			if (Is0To9(seq[1])) {
 | 
			
		||||
				base = base * 10;
 | 
			
		||||
				base += seq[1] - '0';
 | 
			
		||||
				seq++;
 | 
			
		||||
			}
 | 
			
		||||
			if (base == 0) {
 | 
			
		||||
				colour = 0;
 | 
			
		||||
				bold = 0;
 | 
			
		||||
			}
 | 
			
		||||
			else if (base == 1) {
 | 
			
		||||
				bold = 1;
 | 
			
		||||
			}
 | 
			
		||||
			else if (base >= 30 && base <= 37) {
 | 
			
		||||
				colour = base - 30;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		seq++;
 | 
			
		||||
	}
 | 
			
		||||
	return SCE_ERR_ES_BLACK + bold * 8 + colour;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ColouriseErrorListLine(
 | 
			
		||||
    const std::string &lineBuffer,
 | 
			
		||||
    Sci_PositionU endPos,
 | 
			
		||||
    Accessor &styler,
 | 
			
		||||
	bool valueSeparate,
 | 
			
		||||
	bool escapeSequences) {
 | 
			
		||||
	Sci_Position startValue = -1;
 | 
			
		||||
	const Sci_PositionU lengthLine = lineBuffer.length();
 | 
			
		||||
	const int style = RecogniseErrorListLine(lineBuffer.c_str(), lengthLine, startValue);
 | 
			
		||||
	if (escapeSequences && strstr(lineBuffer.c_str(), CSI)) {
 | 
			
		||||
		const Sci_Position startPos = endPos - lengthLine;
 | 
			
		||||
		const char *linePortion = lineBuffer.c_str();
 | 
			
		||||
		Sci_Position startPortion = startPos;
 | 
			
		||||
		int portionStyle = style;
 | 
			
		||||
		while (const char *startSeq = strstr(linePortion, CSI)) {
 | 
			
		||||
			if (startSeq > linePortion) {
 | 
			
		||||
				styler.ColourTo(startPortion + (startSeq - linePortion), portionStyle);
 | 
			
		||||
			}
 | 
			
		||||
			const char *endSeq = startSeq + 2;
 | 
			
		||||
			while (!SequenceEnd(*endSeq))
 | 
			
		||||
				endSeq++;
 | 
			
		||||
			const Sci_Position endSeqPosition = startPortion + (endSeq - linePortion) + 1;
 | 
			
		||||
			switch (*endSeq) {
 | 
			
		||||
			case 0:
 | 
			
		||||
				styler.ColourTo(endPos, SCE_ERR_ESCSEQ_UNKNOWN);
 | 
			
		||||
				return;
 | 
			
		||||
			case 'm':	// Colour command
 | 
			
		||||
				styler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ);
 | 
			
		||||
				portionStyle = StyleFromSequence(startSeq+2);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'K':	// Erase to end of line -> ignore
 | 
			
		||||
				styler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				styler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ_UNKNOWN);
 | 
			
		||||
				portionStyle = style;
 | 
			
		||||
			}
 | 
			
		||||
			startPortion = endSeqPosition;
 | 
			
		||||
			linePortion = endSeq + 1;
 | 
			
		||||
		}
 | 
			
		||||
		styler.ColourTo(endPos, portionStyle);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (valueSeparate && (startValue >= 0)) {
 | 
			
		||||
			styler.ColourTo(endPos - (lengthLine - startValue), style);
 | 
			
		||||
			styler.ColourTo(endPos, SCE_ERR_VALUE);
 | 
			
		||||
		} else {
 | 
			
		||||
			styler.ColourTo(endPos, style);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ColouriseErrorListDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
 | 
			
		||||
	std::string lineBuffer;
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
 | 
			
		||||
	// property lexer.errorlist.value.separate
 | 
			
		||||
	//	For lines in the output pane that are matches from Find in Files or GCC-style
 | 
			
		||||
	//	diagnostics, style the path and line number separately from the rest of the
 | 
			
		||||
	//	line with style 21 used for the rest of the line.
 | 
			
		||||
	//	This allows matched text to be more easily distinguished from its location.
 | 
			
		||||
	const bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 0;
 | 
			
		||||
 | 
			
		||||
	// property lexer.errorlist.escape.sequences
 | 
			
		||||
	//	Set to 1 to interpret escape sequences.
 | 
			
		||||
	const bool escapeSequences = styler.GetPropertyInt("lexer.errorlist.escape.sequences") != 0;
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < startPos + length; i++) {
 | 
			
		||||
		lineBuffer.push_back(styler[i]);
 | 
			
		||||
		if (AtEOL(styler, i)) {
 | 
			
		||||
			// End of line met, colourise it
 | 
			
		||||
			ColouriseErrorListLine(lineBuffer, i, styler, valueSeparate, escapeSequences);
 | 
			
		||||
			lineBuffer.clear();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (!lineBuffer.empty()) {	// Last line does not have ending characters
 | 
			
		||||
		ColouriseErrorListLine(lineBuffer, startPos + length - 1, styler, valueSeparate, escapeSequences);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *const emptyWordListDesc[] = {
 | 
			
		||||
	nullptr
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", nullptr, emptyWordListDesc);
 | 
			
		||||
							
								
								
									
										769
									
								
								3rdparty/lexilla540/lexilla/lexers/LexFSharp.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										769
									
								
								3rdparty/lexilla540/lexilla/lexers/LexFSharp.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,769 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file LexFSharp.cxx
 | 
			
		||||
 * Lexer for F# 5.0
 | 
			
		||||
 * Copyright (c) 2021 Robert Di Pardo <dipardo.r@gmail.com>
 | 
			
		||||
 * Parts of LexerFSharp::Lex were adapted from LexCaml.cxx by Robert Roessler ("RR").
 | 
			
		||||
 * Parts of LexerFSharp::Fold were adapted from LexCPP.cxx by Neil Hodgson and Udo Lechner.
 | 
			
		||||
 * The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 */
 | 
			
		||||
// clang-format off
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "OptionSet.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
// clang-format on
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
static const char *const lexerName = "fsharp";
 | 
			
		||||
static constexpr int WORDLIST_SIZE = 5;
 | 
			
		||||
static const char *const fsharpWordLists[] = {
 | 
			
		||||
	"standard language keywords",
 | 
			
		||||
	"core functions, including those in the FSharp.Collections namespace",
 | 
			
		||||
	"built-in types, core namespaces, modules",
 | 
			
		||||
	"optional",
 | 
			
		||||
	"optional",
 | 
			
		||||
	nullptr,
 | 
			
		||||
};
 | 
			
		||||
static constexpr int keywordClasses[] = {
 | 
			
		||||
	SCE_FSHARP_KEYWORD, SCE_FSHARP_KEYWORD2, SCE_FSHARP_KEYWORD3, SCE_FSHARP_KEYWORD4, SCE_FSHARP_KEYWORD5,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
struct OptionsFSharp {
 | 
			
		||||
	bool fold = true;
 | 
			
		||||
	bool foldCompact = true;
 | 
			
		||||
	bool foldComment = true;
 | 
			
		||||
	bool foldCommentStream = true;
 | 
			
		||||
	bool foldCommentMultiLine = true;
 | 
			
		||||
	bool foldPreprocessor = false;
 | 
			
		||||
	bool foldImports = true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct OptionSetFSharp : public OptionSet<OptionsFSharp> {
 | 
			
		||||
	OptionSetFSharp() {
 | 
			
		||||
		DefineProperty("fold", &OptionsFSharp::fold);
 | 
			
		||||
		DefineProperty("fold.compact", &OptionsFSharp::foldCompact);
 | 
			
		||||
		DefineProperty("fold.comment", &OptionsFSharp::foldComment,
 | 
			
		||||
				   "Setting this option to 0 disables comment folding in F# files.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.fsharp.comment.stream", &OptionsFSharp::foldCommentStream,
 | 
			
		||||
				   "Setting this option to 0 disables folding of ML-style comments in F# files when "
 | 
			
		||||
				   "fold.comment=1.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.fsharp.comment.multiline", &OptionsFSharp::foldCommentMultiLine,
 | 
			
		||||
				   "Setting this option to 0 disables folding of grouped line comments in F# files when "
 | 
			
		||||
				   "fold.comment=1.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.fsharp.preprocessor", &OptionsFSharp::foldPreprocessor,
 | 
			
		||||
				   "Setting this option to 1 enables folding of F# compiler directives.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.fsharp.imports", &OptionsFSharp::foldImports,
 | 
			
		||||
				   "Setting this option to 0 disables folding of F# import declarations.");
 | 
			
		||||
 | 
			
		||||
		DefineWordListSets(fsharpWordLists);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct FSharpString {
 | 
			
		||||
	Sci_Position startPos = INVALID_POSITION;
 | 
			
		||||
	int startChar = '"', nextChar = '\0';
 | 
			
		||||
	constexpr bool HasLength() const {
 | 
			
		||||
		return startPos > INVALID_POSITION;
 | 
			
		||||
	}
 | 
			
		||||
	constexpr bool CanInterpolate() const {
 | 
			
		||||
		return startChar == '$' || (startChar == '@' && nextChar == '$');
 | 
			
		||||
	}
 | 
			
		||||
	constexpr bool IsVerbatim() const {
 | 
			
		||||
		return startChar == '@' || (startChar == '$' && nextChar == '@');
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class UnicodeChar {
 | 
			
		||||
	enum class Notation { none, asciiDec, asciiHex, utf16, utf32 };
 | 
			
		||||
	Notation type = Notation::none;
 | 
			
		||||
	// single-byte Unicode char (000 - 255)
 | 
			
		||||
	int asciiDigits[3] = { 0 };
 | 
			
		||||
	int maxDigit = '9';
 | 
			
		||||
	int toEnd = 0;
 | 
			
		||||
	bool invalid = false;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	UnicodeChar() noexcept = default;
 | 
			
		||||
	explicit UnicodeChar(const int prefix) {
 | 
			
		||||
		if (IsADigit(prefix)) {
 | 
			
		||||
			*asciiDigits = prefix;
 | 
			
		||||
			if (*asciiDigits >= '0' && *asciiDigits <= '2') {
 | 
			
		||||
				type = Notation::asciiDec;
 | 
			
		||||
				// count first digit as "prefix"
 | 
			
		||||
				toEnd = 2;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (prefix == 'x' || prefix == 'u' || prefix == 'U') {
 | 
			
		||||
			switch (prefix) {
 | 
			
		||||
				case 'x':
 | 
			
		||||
					type = Notation::asciiHex;
 | 
			
		||||
					toEnd = 2;
 | 
			
		||||
					break;
 | 
			
		||||
				case 'u':
 | 
			
		||||
					type = Notation::utf16;
 | 
			
		||||
					toEnd = 4;
 | 
			
		||||
					break;
 | 
			
		||||
				case 'U':
 | 
			
		||||
					type = Notation::utf32;
 | 
			
		||||
					toEnd = 8;
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	void Parse(const int ch) {
 | 
			
		||||
		invalid = false;
 | 
			
		||||
		switch (type) {
 | 
			
		||||
			case Notation::asciiDec: {
 | 
			
		||||
				maxDigit = (*asciiDigits < '2') ? '9' : (asciiDigits[1] <= '4') ? '9' : '5';
 | 
			
		||||
				if (IsADigit(ch) && asciiDigits[1] <= maxDigit && ch <= maxDigit) {
 | 
			
		||||
					asciiDigits[1] = ch;
 | 
			
		||||
					toEnd--;
 | 
			
		||||
				} else {
 | 
			
		||||
					invalid = true;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Notation::asciiHex:
 | 
			
		||||
			case Notation::utf16:
 | 
			
		||||
				if (IsADigit(ch, 16)) {
 | 
			
		||||
					toEnd--;
 | 
			
		||||
				} else {
 | 
			
		||||
					invalid = true;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case Notation::utf32:
 | 
			
		||||
				if ((toEnd > 6 && ch == '0') || (toEnd <= 6 && IsADigit(ch, 16))) {
 | 
			
		||||
					toEnd--;
 | 
			
		||||
				} else {
 | 
			
		||||
					invalid = true;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case Notation::none:
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	constexpr bool AtEnd() noexcept {
 | 
			
		||||
		return invalid || type == Notation::none || (type != Notation::none && toEnd < 0);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline bool MatchStreamCommentStart(StyleContext &cxt) {
 | 
			
		||||
	// match (* ... *), but allow point-free usage of the `*` operator,
 | 
			
		||||
	// e.g.  List.fold (*) 1 [ 1; 2; 3 ]
 | 
			
		||||
	return (cxt.Match('(', '*') && cxt.GetRelative(2) != ')');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool MatchStreamCommentEnd(const StyleContext &cxt) {
 | 
			
		||||
	return (cxt.ch == ')' && cxt.chPrev == '*');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool MatchLineComment(const StyleContext &cxt) {
 | 
			
		||||
	// style shebang lines as comments in F# scripts:
 | 
			
		||||
	// https://fsharp.org/specs/language-spec/4.1/FSharpSpec-4.1-latest.pdf#page=30&zoom=auto,-98,537
 | 
			
		||||
	return cxt.Match('/', '/') || cxt.Match('#', '!');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool MatchLineNumberStart(StyleContext &cxt) {
 | 
			
		||||
	return cxt.atLineStart && (cxt.MatchIgnoreCase("#line") ||
 | 
			
		||||
		(cxt.ch == '#' && (IsADigit(cxt.chNext) || IsADigit(cxt.GetRelative(2)))));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool MatchPPDirectiveStart(const StyleContext &cxt) {
 | 
			
		||||
	return (cxt.atLineStart && cxt.ch == '#' && iswordstart(cxt.chNext));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool MatchTypeAttributeStart(const StyleContext &cxt) {
 | 
			
		||||
	return cxt.Match('[', '<');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool MatchTypeAttributeEnd(const StyleContext &cxt) {
 | 
			
		||||
	return (cxt.ch == ']' && cxt.chPrev == '>');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool MatchQuotedExpressionStart(const StyleContext &cxt) {
 | 
			
		||||
	return cxt.Match('<', '@');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool MatchQuotedExpressionEnd(const StyleContext &cxt) {
 | 
			
		||||
	return (cxt.ch == '>' && cxt.chPrev == '@');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool MatchStringStart(StyleContext &cxt) {
 | 
			
		||||
	return (cxt.ch == '"' || cxt.Match("@\"") || cxt.Match("$\"") || cxt.Match("@$\"") || cxt.Match("$@\"") ||
 | 
			
		||||
		cxt.Match("``"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool FollowsEscapedBackslash(StyleContext &cxt) {
 | 
			
		||||
	int count = 0;
 | 
			
		||||
	for (Sci_Position offset = 1; cxt.GetRelative(-offset) == '\\'; offset++)
 | 
			
		||||
		count++;
 | 
			
		||||
	return count % 2 != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool MatchStringEnd(StyleContext &cxt, const FSharpString &fsStr) {
 | 
			
		||||
	return (fsStr.HasLength() &&
 | 
			
		||||
		// end of quoted identifier?
 | 
			
		||||
		((cxt.ch == '`' && cxt.chPrev == '`') ||
 | 
			
		||||
		// end of literal or interpolated triple-quoted string?
 | 
			
		||||
		 ((fsStr.startChar == '"' || (fsStr.CanInterpolate() && !(fsStr.IsVerbatim() || cxt.chPrev == '$'))) &&
 | 
			
		||||
		  cxt.MatchIgnoreCase("\"\"\"")) ||
 | 
			
		||||
		// end of verbatim string?
 | 
			
		||||
		(fsStr.IsVerbatim() &&
 | 
			
		||||
			// embedded quotes must be in pairs
 | 
			
		||||
			cxt.ch == '"' && cxt.chNext != '"' &&
 | 
			
		||||
			(cxt.chPrev != '"' ||
 | 
			
		||||
				// empty verbatim string?
 | 
			
		||||
				((cxt.GetRelative(-2) == '@' || cxt.GetRelative(-2) == '$') ||
 | 
			
		||||
				// pair of quotes at end of string?
 | 
			
		||||
				(cxt.GetRelative(-2) == '"' && !(cxt.GetRelative(-3) == '@' || cxt.GetRelative(-3) == '$'))))))) ||
 | 
			
		||||
		(!fsStr.HasLength() && cxt.ch == '"' &&
 | 
			
		||||
			((cxt.chPrev != '\\' || (cxt.GetRelative(-2) == '\\' && !FollowsEscapedBackslash(cxt))) ||
 | 
			
		||||
			// treat backslashes as char literals in verbatim strings
 | 
			
		||||
			(fsStr.IsVerbatim() && cxt.chPrev == '\\')));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool MatchCharacterStart(StyleContext &cxt) {
 | 
			
		||||
	// don't style generic type parameters: 'a, 'b, 'T, etc.
 | 
			
		||||
	return (cxt.ch == '\'' && !(cxt.chPrev == ':' || cxt.GetRelative(-2) == ':'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool CanEmbedQuotes(StyleContext &cxt) {
 | 
			
		||||
	// allow unescaped double quotes inside literal or interpolated triple-quoted strings, verbatim strings,
 | 
			
		||||
	// and quoted identifiers:
 | 
			
		||||
	// - https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/strings
 | 
			
		||||
	// - https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/interpolated-strings#syntax
 | 
			
		||||
	// - https://fsharp.org/specs/language-spec/4.1/FSharpSpec-4.1-latest.pdf#page=25&zoom=auto,-98,600
 | 
			
		||||
	return cxt.Match("$\"\"\"") || cxt.Match("\"\"\"") || cxt.Match("@$\"\"\"") || cxt.Match("$@\"\"\"") ||
 | 
			
		||||
	       cxt.Match('@', '"') || cxt.Match('`', '`');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool IsLineEnd(StyleContext &cxt, const Sci_Position offset) {
 | 
			
		||||
	const int ch = cxt.GetRelative(offset, '\n');
 | 
			
		||||
	return (ch == '\r' || ch == '\n');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class LexerFSharp : public DefaultLexer {
 | 
			
		||||
	WordList keywords[WORDLIST_SIZE];
 | 
			
		||||
	OptionsFSharp options;
 | 
			
		||||
	OptionSetFSharp optionSet;
 | 
			
		||||
	CharacterSet setOperators;
 | 
			
		||||
	CharacterSet setFormatSpecs;
 | 
			
		||||
	CharacterSet setDotNetFormatSpecs;
 | 
			
		||||
	CharacterSet setFormatFlags;
 | 
			
		||||
	CharacterSet numericMetaChars1;
 | 
			
		||||
	CharacterSet numericMetaChars2;
 | 
			
		||||
	std::map<int, int> numericPrefixes = { { 'b', 2 }, { 'o', 8 }, { 'x', 16 } };
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	explicit LexerFSharp()
 | 
			
		||||
	    : DefaultLexer(lexerName, SCLEX_FSHARP),
 | 
			
		||||
	      setOperators(CharacterSet::setNone, "~^'-+*/%=@|&<>()[]{};,:!?"),
 | 
			
		||||
	      setFormatSpecs(CharacterSet::setNone, ".%aAbBcdeEfFgGiMoOstuxX0123456789"),
 | 
			
		||||
	      setDotNetFormatSpecs(CharacterSet::setNone, "cCdDeEfFgGnNpPxX"),
 | 
			
		||||
	      setFormatFlags(CharacterSet::setNone, ".-+0 "),
 | 
			
		||||
	      numericMetaChars1(CharacterSet::setNone, "_uU"),
 | 
			
		||||
	      numericMetaChars2(CharacterSet::setNone, "fFIlLmMnsy") {
 | 
			
		||||
	}
 | 
			
		||||
	LexerFSharp(const LexerFSharp &) = delete;
 | 
			
		||||
	LexerFSharp(LexerFSharp &&) = delete;
 | 
			
		||||
	LexerFSharp &operator=(const LexerFSharp &) = delete;
 | 
			
		||||
	LexerFSharp &operator=(LexerFSharp &&) = delete;
 | 
			
		||||
	static ILexer5 *LexerFactoryFSharp() {
 | 
			
		||||
		return new LexerFSharp();
 | 
			
		||||
	}
 | 
			
		||||
	virtual ~LexerFSharp() {
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD Release() noexcept override {
 | 
			
		||||
		delete this;
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD Version() const noexcept override {
 | 
			
		||||
		return lvRelease5;
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD GetName() noexcept override {
 | 
			
		||||
		return lexerName;
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD GetIdentifier() noexcept override {
 | 
			
		||||
		return SCLEX_FSHARP;
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD LineEndTypesSupported() noexcept override {
 | 
			
		||||
		return SC_LINE_END_TYPE_DEFAULT;
 | 
			
		||||
	}
 | 
			
		||||
	void *SCI_METHOD PrivateCall(int, void *) noexcept override {
 | 
			
		||||
		return nullptr;
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD DescribeWordListSets() override {
 | 
			
		||||
		return optionSet.DescribeWordListSets();
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD PropertyNames() override {
 | 
			
		||||
		return optionSet.PropertyNames();
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD PropertyType(const char *name) override {
 | 
			
		||||
		return optionSet.PropertyType(name);
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD DescribeProperty(const char *name) override {
 | 
			
		||||
		return optionSet.DescribeProperty(name);
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD PropertyGet(const char *key) override {
 | 
			
		||||
		return optionSet.PropertyGet(key);
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override {
 | 
			
		||||
		if (optionSet.PropertySet(&options, key, val)) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		return INVALID_POSITION;
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
 | 
			
		||||
	void SCI_METHOD Lex(Sci_PositionU start, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
	void SCI_METHOD Fold(Sci_PositionU start, Sci_Position length, int initStyle,IDocument *pAccess) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	inline bool IsNumber(StyleContext &cxt, const int base = 10) {
 | 
			
		||||
		return IsADigit(cxt.ch, base) || (IsADigit(cxt.chPrev, base) && numericMetaChars1.Contains(cxt.ch)) ||
 | 
			
		||||
		       (IsADigit(cxt.GetRelative(-2), base) && numericMetaChars2.Contains(cxt.ch));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline bool IsFloat(StyleContext &cxt) {
 | 
			
		||||
		if (cxt.MatchIgnoreCase("e+") || cxt.MatchIgnoreCase("e-")) {
 | 
			
		||||
			cxt.Forward();
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		return ((cxt.chPrev == '.' && IsADigit(cxt.ch)) ||
 | 
			
		||||
			(IsADigit(cxt.chPrev) && (cxt.ch == '.' || numericMetaChars2.Contains(cxt.ch))));
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerFSharp::WordListSet(int n, const char *wl) {
 | 
			
		||||
	WordList *wordListN = nullptr;
 | 
			
		||||
	Sci_Position firstModification = INVALID_POSITION;
 | 
			
		||||
 | 
			
		||||
	if (n < WORDLIST_SIZE) {
 | 
			
		||||
		wordListN = &keywords[n];
 | 
			
		||||
	}
 | 
			
		||||
	if (wordListN && wordListN->Set(wl)) {
 | 
			
		||||
		firstModification = 0;
 | 
			
		||||
	}
 | 
			
		||||
	return firstModification;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerFSharp::Lex(Sci_PositionU start, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
	StyleContext sc(start, static_cast<Sci_PositionU>(length), initStyle, styler);
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(static_cast<Sci_Position>(start));
 | 
			
		||||
	Sci_PositionU cursor = 0;
 | 
			
		||||
	UnicodeChar uniCh = UnicodeChar();
 | 
			
		||||
	FSharpString fsStr = FSharpString();
 | 
			
		||||
	constexpr Sci_Position MAX_WORD_LEN = 64;
 | 
			
		||||
	constexpr int SPACE = ' ';
 | 
			
		||||
	int currentBase = 10;
 | 
			
		||||
	int levelNesting = (lineCurrent >= 1) ? styler.GetLineState(lineCurrent - 1) : 0;
 | 
			
		||||
	bool isInterpolated = false;
 | 
			
		||||
 | 
			
		||||
	while (sc.More()) {
 | 
			
		||||
		Sci_PositionU colorSpan = sc.currentPos - 1;
 | 
			
		||||
		int state = -1;
 | 
			
		||||
		bool advance = true;
 | 
			
		||||
 | 
			
		||||
		switch (sc.state & 0xff) {
 | 
			
		||||
			case SCE_FSHARP_DEFAULT:
 | 
			
		||||
				cursor = sc.currentPos;
 | 
			
		||||
 | 
			
		||||
				if (MatchLineNumberStart(sc)) {
 | 
			
		||||
					state = SCE_FSHARP_LINENUM;
 | 
			
		||||
				} else if (MatchPPDirectiveStart(sc)) {
 | 
			
		||||
					state = SCE_FSHARP_PREPROCESSOR;
 | 
			
		||||
				} else if (MatchLineComment(sc)) {
 | 
			
		||||
					state = SCE_FSHARP_COMMENTLINE;
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ch = SPACE;
 | 
			
		||||
				} else if (MatchStreamCommentStart(sc)) {
 | 
			
		||||
					state = SCE_FSHARP_COMMENT;
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ch = SPACE;
 | 
			
		||||
				} else if (MatchTypeAttributeStart(sc)) {
 | 
			
		||||
					state = SCE_FSHARP_ATTRIBUTE;
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} else if (MatchQuotedExpressionStart(sc)) {
 | 
			
		||||
					state = SCE_FSHARP_QUOTATION;
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} else if (MatchCharacterStart(sc)) {
 | 
			
		||||
					state = SCE_FSHARP_CHARACTER;
 | 
			
		||||
				} else if (MatchStringStart(sc)) {
 | 
			
		||||
					fsStr.startChar = sc.ch;
 | 
			
		||||
					fsStr.nextChar = sc.chNext;
 | 
			
		||||
					fsStr.startPos = INVALID_POSITION;
 | 
			
		||||
					if (CanEmbedQuotes(sc)) {
 | 
			
		||||
						// double quotes after this position should be non-terminating
 | 
			
		||||
						fsStr.startPos = static_cast<Sci_Position>(sc.currentPos - cursor);
 | 
			
		||||
					}
 | 
			
		||||
					if (sc.ch == '`') {
 | 
			
		||||
						state = SCE_FSHARP_QUOT_IDENTIFIER;
 | 
			
		||||
					} else if (fsStr.IsVerbatim()) {
 | 
			
		||||
						state = SCE_FSHARP_VERBATIM;
 | 
			
		||||
					} else {
 | 
			
		||||
						state = SCE_FSHARP_STRING;
 | 
			
		||||
					}
 | 
			
		||||
				} else if (IsADigit(sc.ch, currentBase) ||
 | 
			
		||||
					   ((sc.ch == '+' || sc.ch == '-') && IsADigit(sc.chNext))) {
 | 
			
		||||
					state = SCE_FSHARP_NUMBER;
 | 
			
		||||
				} else if (setOperators.Contains(sc.ch) &&
 | 
			
		||||
					   // don't use operator style in async keywords (e.g. `return!`)
 | 
			
		||||
					   !(sc.ch == '!' && iswordstart(sc.chPrev)) &&
 | 
			
		||||
					   // don't use operator style in member access, array/string indexing
 | 
			
		||||
					   !(sc.ch == '.' && (sc.chPrev == '\"' || iswordstart(sc.chPrev)) &&
 | 
			
		||||
					     (iswordstart(sc.chNext) || sc.chNext == '['))) {
 | 
			
		||||
					state = SCE_FSHARP_OPERATOR;
 | 
			
		||||
				} else if (iswordstart(sc.ch)) {
 | 
			
		||||
					state = SCE_FSHARP_IDENTIFIER;
 | 
			
		||||
				} else {
 | 
			
		||||
					state = SCE_FSHARP_DEFAULT;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FSHARP_LINENUM:
 | 
			
		||||
			case SCE_FSHARP_PREPROCESSOR:
 | 
			
		||||
			case SCE_FSHARP_COMMENTLINE:
 | 
			
		||||
				if (sc.MatchLineEnd()) {
 | 
			
		||||
					state = SCE_FSHARP_DEFAULT;
 | 
			
		||||
					advance = false;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FSHARP_COMMENT:
 | 
			
		||||
				if (MatchStreamCommentStart(sc)) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ch = SPACE;
 | 
			
		||||
					levelNesting++;
 | 
			
		||||
				} else if (MatchStreamCommentEnd(sc)) {
 | 
			
		||||
					if (levelNesting > 0)
 | 
			
		||||
						levelNesting--;
 | 
			
		||||
					else {
 | 
			
		||||
						state = SCE_FSHARP_DEFAULT;
 | 
			
		||||
						colorSpan++;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FSHARP_ATTRIBUTE:
 | 
			
		||||
			case SCE_FSHARP_QUOTATION:
 | 
			
		||||
				if (MatchTypeAttributeEnd(sc) || MatchQuotedExpressionEnd(sc)) {
 | 
			
		||||
					state = SCE_FSHARP_DEFAULT;
 | 
			
		||||
					colorSpan++;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FSHARP_CHARACTER:
 | 
			
		||||
				if (sc.chPrev == '\\' && sc.GetRelative(-2) != '\\') {
 | 
			
		||||
					uniCh = UnicodeChar(sc.ch);
 | 
			
		||||
				} else if (sc.ch == '\'' &&
 | 
			
		||||
					   ((sc.chPrev == ' ' && sc.GetRelative(-2) == '\'') || sc.chPrev != '\\' ||
 | 
			
		||||
						(sc.chPrev == '\\' && sc.GetRelative(-2) == '\\'))) {
 | 
			
		||||
					// byte literal?
 | 
			
		||||
					if (sc.Match('\'', 'B')) {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
						colorSpan++;
 | 
			
		||||
					}
 | 
			
		||||
					if (!sc.atLineEnd) {
 | 
			
		||||
						colorSpan++;
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.ChangeState(SCE_FSHARP_IDENTIFIER);
 | 
			
		||||
					}
 | 
			
		||||
					state = SCE_FSHARP_DEFAULT;
 | 
			
		||||
				} else {
 | 
			
		||||
					uniCh.Parse(sc.ch);
 | 
			
		||||
					if (uniCh.AtEnd() && (sc.currentPos - cursor) >= 2) {
 | 
			
		||||
						// terminate now, since we left the char behind
 | 
			
		||||
						sc.ChangeState(SCE_FSHARP_IDENTIFIER);
 | 
			
		||||
						advance = false;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FSHARP_STRING:
 | 
			
		||||
			case SCE_FSHARP_VERBATIM:
 | 
			
		||||
			case SCE_FSHARP_QUOT_IDENTIFIER:
 | 
			
		||||
				if (MatchStringEnd(sc, fsStr)) {
 | 
			
		||||
					const Sci_Position strLen = static_cast<Sci_Position>(sc.currentPos - cursor);
 | 
			
		||||
					// backtrack to start of string
 | 
			
		||||
					for (Sci_Position i = -strLen; i < 0; i++) {
 | 
			
		||||
						const int startQuote = sc.GetRelative(i);
 | 
			
		||||
						if (startQuote == '\"' || (startQuote == '`' && sc.GetRelative(i - 1) == '`')) {
 | 
			
		||||
							// byte array?
 | 
			
		||||
							if (sc.Match('\"', 'B')) {
 | 
			
		||||
								sc.Forward();
 | 
			
		||||
								colorSpan++;
 | 
			
		||||
							}
 | 
			
		||||
							if (!sc.atLineEnd) {
 | 
			
		||||
								colorSpan++;
 | 
			
		||||
							} else {
 | 
			
		||||
								sc.ChangeState(SCE_FSHARP_IDENTIFIER);
 | 
			
		||||
							}
 | 
			
		||||
							state = SCE_FSHARP_DEFAULT;
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.ch == '%' &&
 | 
			
		||||
					   !(fsStr.startChar == '`' || sc.MatchIgnoreCase("%  ") || sc.MatchIgnoreCase("% \"")) &&
 | 
			
		||||
					   (setFormatSpecs.Contains(sc.chNext) || setFormatFlags.Contains(sc.chNext))) {
 | 
			
		||||
					if (fsStr.CanInterpolate() && sc.chNext != '%') {
 | 
			
		||||
						for (Sci_Position i = 2; i < length && !IsLineEnd(sc, i); i++) {
 | 
			
		||||
							if (sc.GetRelative(i) == '{') {
 | 
			
		||||
								state = setFormatSpecs.Contains(sc.GetRelative(i - 1))
 | 
			
		||||
									    ? SCE_FSHARP_FORMAT_SPEC
 | 
			
		||||
									    : state;
 | 
			
		||||
								break;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						state = SCE_FSHARP_FORMAT_SPEC;
 | 
			
		||||
					}
 | 
			
		||||
				} else if (isInterpolated) {
 | 
			
		||||
					if (sc.ch == ',') {
 | 
			
		||||
						// .NET alignment specifier?
 | 
			
		||||
						state = (sc.chNext == '+' || sc.chNext == '-' || IsADigit(sc.chNext))
 | 
			
		||||
							    ? SCE_FSHARP_FORMAT_SPEC
 | 
			
		||||
							    : state;
 | 
			
		||||
					} else if (sc.ch == ':') {
 | 
			
		||||
						// .NET format specifier?
 | 
			
		||||
						state = setDotNetFormatSpecs.Contains(sc.chNext)
 | 
			
		||||
							    ? SCE_FSHARP_FORMAT_SPEC
 | 
			
		||||
							    : state;
 | 
			
		||||
					} else if (sc.chNext == '}') {
 | 
			
		||||
						isInterpolated = false;
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
						state = fsStr.IsVerbatim() ? SCE_FSHARP_VERBATIM : SCE_FSHARP_STRING;
 | 
			
		||||
					}
 | 
			
		||||
				} else if (fsStr.CanInterpolate() && sc.ch == '{') {
 | 
			
		||||
					isInterpolated = true;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FSHARP_IDENTIFIER:
 | 
			
		||||
				if (!(iswordstart(sc.ch) || sc.ch == '\'')) {
 | 
			
		||||
					const Sci_Position wordLen = static_cast<Sci_Position>(sc.currentPos - cursor);
 | 
			
		||||
					if (wordLen < MAX_WORD_LEN) {
 | 
			
		||||
						// wordLength is believable as keyword, [re-]construct token - RR
 | 
			
		||||
						char token[MAX_WORD_LEN] = { 0 };
 | 
			
		||||
						for (Sci_Position i = -wordLen; i < 0; i++) {
 | 
			
		||||
							token[wordLen + i] = static_cast<char>(sc.GetRelative(i));
 | 
			
		||||
						}
 | 
			
		||||
						token[wordLen] = '\0';
 | 
			
		||||
						// a snake_case_identifier can never be a keyword
 | 
			
		||||
						if (!(sc.ch == '_' || sc.GetRelative(-wordLen - 1) == '_')) {
 | 
			
		||||
							for (int i = 0; i < WORDLIST_SIZE; i++) {
 | 
			
		||||
								if (keywords[i].InList(token)) {
 | 
			
		||||
									sc.ChangeState(keywordClasses[i]);
 | 
			
		||||
									break;
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					state = SCE_FSHARP_DEFAULT;
 | 
			
		||||
					advance = false;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FSHARP_OPERATOR:
 | 
			
		||||
				// special-case "()" and "[]" tokens as KEYWORDS - RR
 | 
			
		||||
				if ((sc.ch == ')' && sc.chPrev == '(') || (sc.ch == ']' && sc.chPrev == '[')) {
 | 
			
		||||
					sc.ChangeState(SCE_FSHARP_KEYWORD);
 | 
			
		||||
					colorSpan++;
 | 
			
		||||
				} else {
 | 
			
		||||
					advance = false;
 | 
			
		||||
				}
 | 
			
		||||
				state = SCE_FSHARP_DEFAULT;
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FSHARP_NUMBER:
 | 
			
		||||
				if ((setOperators.Contains(sc.chPrev) || IsASpaceOrTab(sc.chPrev)) && sc.ch == '0') {
 | 
			
		||||
					if (numericPrefixes.find(sc.chNext) != numericPrefixes.end()) {
 | 
			
		||||
						currentBase = numericPrefixes[sc.chNext];
 | 
			
		||||
						sc.Forward(2);
 | 
			
		||||
					}
 | 
			
		||||
				} else if ((setOperators.Contains(sc.GetRelative(-2)) || IsASpaceOrTab(sc.GetRelative(-2))) &&
 | 
			
		||||
					   sc.chPrev == '0') {
 | 
			
		||||
					if (numericPrefixes.find(sc.ch) != numericPrefixes.end()) {
 | 
			
		||||
						currentBase = numericPrefixes[sc.ch];
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				state = (IsNumber(sc, currentBase) || IsFloat(sc))
 | 
			
		||||
					? SCE_FSHARP_NUMBER
 | 
			
		||||
					// change style even when operators aren't spaced
 | 
			
		||||
					: setOperators.Contains(sc.ch) ? SCE_FSHARP_OPERATOR : SCE_FSHARP_DEFAULT;
 | 
			
		||||
				currentBase = (state == SCE_FSHARP_NUMBER) ? currentBase : 10;
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FSHARP_FORMAT_SPEC:
 | 
			
		||||
				if (!(isInterpolated && IsADigit(sc.chNext)) &&
 | 
			
		||||
					(!setFormatSpecs.Contains(sc.chNext) ||
 | 
			
		||||
				    !(setFormatFlags.Contains(sc.ch) || IsADigit(sc.ch)) ||
 | 
			
		||||
				    (setFormatFlags.Contains(sc.ch) && sc.ch == sc.chNext))) {
 | 
			
		||||
					colorSpan++;
 | 
			
		||||
					state = fsStr.IsVerbatim() ? SCE_FSHARP_VERBATIM : SCE_FSHARP_STRING;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.MatchLineEnd()) {
 | 
			
		||||
			styler.SetLineState(lineCurrent++, (sc.state == SCE_FSHARP_COMMENT) ? levelNesting : 0);
 | 
			
		||||
			advance = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (state >= SCE_FSHARP_DEFAULT) {
 | 
			
		||||
			styler.ColourTo(colorSpan, sc.state);
 | 
			
		||||
			sc.ChangeState(state);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (advance) {
 | 
			
		||||
			sc.Forward();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool LineContains(LexAccessor &styler, const char *word, const Sci_Position start,
 | 
			
		||||
		  const int chAttr = SCE_FSHARP_DEFAULT);
 | 
			
		||||
 | 
			
		||||
void FoldLexicalGroup(LexAccessor &styler, int &levelNext, const Sci_Position lineCurrent, const char *word,
 | 
			
		||||
		      const int chAttr);
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
	if (!options.fold) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
	const Sci_Position startPos = static_cast<Sci_Position>(start);
 | 
			
		||||
	const Sci_PositionU endPos = start + length;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	Sci_Position lineNext = lineCurrent + 1;
 | 
			
		||||
	Sci_Position lineStartNext = styler.LineStart(lineNext);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int levelNext;
 | 
			
		||||
	int levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
 | 
			
		||||
	if (lineCurrent > 0) {
 | 
			
		||||
		levelCurrent = styler.LevelAt(lineCurrent - 1) >> 0x10;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	levelNext = levelCurrent;
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = start; i < endPos; i++) {
 | 
			
		||||
		const Sci_Position currentPos = static_cast<Sci_Position>(i);
 | 
			
		||||
		const bool atEOL = (currentPos == (lineStartNext - 1) || styler.SafeGetCharAt(currentPos) == '\r');
 | 
			
		||||
		const bool atLineOrDocEnd = (atEOL || (i == (endPos - 1)));
 | 
			
		||||
		const int stylePrev = style;
 | 
			
		||||
		const char ch = chNext;
 | 
			
		||||
		const bool inLineComment = (stylePrev == SCE_FSHARP_COMMENTLINE);
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(currentPos + 1);
 | 
			
		||||
		chNext = styler.SafeGetCharAt(currentPos + 1);
 | 
			
		||||
 | 
			
		||||
		if (options.foldComment) {
 | 
			
		||||
			if (options.foldCommentMultiLine && inLineComment && atEOL) {
 | 
			
		||||
				FoldLexicalGroup(styler, levelNext, lineCurrent, "//", SCE_FSHARP_COMMENTLINE);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (options.foldCommentStream && style == SCE_FSHARP_COMMENT && !inLineComment) {
 | 
			
		||||
				if (stylePrev != SCE_FSHARP_COMMENT ||
 | 
			
		||||
				    (styler.Match(currentPos, "(*") &&
 | 
			
		||||
				     !LineContains(styler, "*)", currentPos + 2, SCE_FSHARP_COMMENT))) {
 | 
			
		||||
					levelNext++;
 | 
			
		||||
				} else if ((styleNext != SCE_FSHARP_COMMENT ||
 | 
			
		||||
					    ((styler.Match(currentPos, "*)") &&
 | 
			
		||||
					      !LineContains(styler, "(*", styler.LineStart(lineCurrent), SCE_FSHARP_COMMENT)) &&
 | 
			
		||||
					     styler.GetLineState(lineCurrent - 1) > 0)) &&
 | 
			
		||||
					   !atEOL) {
 | 
			
		||||
					levelNext--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (options.foldPreprocessor && style == SCE_FSHARP_PREPROCESSOR) {
 | 
			
		||||
			if (styler.Match(currentPos, "#if")) {
 | 
			
		||||
				levelNext++;
 | 
			
		||||
			} else if (styler.Match(currentPos, "#endif")) {
 | 
			
		||||
				levelNext--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (options.foldImports && styler.Match(currentPos, "open ") && styleNext == SCE_FSHARP_KEYWORD) {
 | 
			
		||||
			FoldLexicalGroup(styler, levelNext, lineCurrent, "open ", SCE_FSHARP_KEYWORD);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!IsASpace(ch)) {
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atLineOrDocEnd) {
 | 
			
		||||
			int levelUse = levelCurrent;
 | 
			
		||||
			int lev = levelUse | levelNext << 16;
 | 
			
		||||
 | 
			
		||||
			if (visibleChars == 0 && options.foldCompact) {
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if (levelUse < levelNext) {
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			lineNext = lineCurrent + 1;
 | 
			
		||||
			lineStartNext = styler.LineStart(lineNext);
 | 
			
		||||
			levelCurrent = levelNext;
 | 
			
		||||
 | 
			
		||||
			if (atEOL && (currentPos == (styler.Length() - 1))) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool LineContains(LexAccessor &styler, const char *word, const Sci_Position start, const int chAttr) {
 | 
			
		||||
	bool found = false;
 | 
			
		||||
	bool requireStyle = (chAttr > SCE_FSHARP_DEFAULT);
 | 
			
		||||
	for (Sci_Position i = start; i < styler.LineStart(styler.GetLine(start) + 1) - 1; i++) {
 | 
			
		||||
		if (styler.Match(i, word)) {
 | 
			
		||||
			found = requireStyle ? styler.StyleAt(i) == chAttr : true;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return found;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FoldLexicalGroup(LexAccessor &styler, int &levelNext, const Sci_Position lineCurrent, const char *word,
 | 
			
		||||
		      const int chAttr) {
 | 
			
		||||
	const Sci_Position linePrev = styler.LineStart(lineCurrent - 1);
 | 
			
		||||
	const Sci_Position lineNext = styler.LineStart(lineCurrent + 1);
 | 
			
		||||
	const bool follows = (lineCurrent > 0) && LineContains(styler, word, linePrev, chAttr);
 | 
			
		||||
	const bool isFollowed = LineContains(styler, word, lineNext, chAttr);
 | 
			
		||||
 | 
			
		||||
	if (isFollowed && !follows) {
 | 
			
		||||
		levelNext++;
 | 
			
		||||
	} else if (!isFollowed && follows && levelNext > SC_FOLDLEVELBASE) {
 | 
			
		||||
		levelNext--;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmFSharp(SCLEX_FSHARP, LexerFSharp::LexerFactoryFSharp, "fsharp", fsharpWordLists);
 | 
			
		||||
							
								
								
									
										355
									
								
								3rdparty/lexilla540/lexilla/lexers/LexFlagship.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										355
									
								
								3rdparty/lexilla540/lexilla/lexers/LexFlagship.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,355 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexFlagship.cxx
 | 
			
		||||
 ** Lexer for Harbour and FlagShip.
 | 
			
		||||
 ** (Syntactically compatible to other xBase dialects, like Clipper, dBase, Clip, FoxPro etc.)
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2005 by Randy Butler
 | 
			
		||||
// Copyright 2010 by Xavi <jarabal/at/gmail.com> (Harbour)
 | 
			
		||||
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
// Extended to accept accented characters
 | 
			
		||||
static inline bool IsAWordChar(int ch)
 | 
			
		||||
{
 | 
			
		||||
	return ch >= 0x80 ||
 | 
			
		||||
				(isalnum(ch) || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseFlagShipDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                                 WordList *keywordlists[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
	WordList &keywords2 = *keywordlists[1];
 | 
			
		||||
	WordList &keywords3 = *keywordlists[2];
 | 
			
		||||
	WordList &keywords4 = *keywordlists[3];
 | 
			
		||||
	WordList &keywords5 = *keywordlists[4];
 | 
			
		||||
 | 
			
		||||
	// property lexer.flagship.styling.within.preprocessor
 | 
			
		||||
	//	For Harbour code, determines whether all preprocessor code is styled in the preprocessor style (0) or only from the
 | 
			
		||||
	//	initial # to the end of the command word(1, the default). It also determines how to present text, dump, and disabled code.
 | 
			
		||||
	bool stylingWithinPreprocessor = styler.GetPropertyInt("lexer.flagship.styling.within.preprocessor", 1) != 0;
 | 
			
		||||
 | 
			
		||||
	CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
 | 
			
		||||
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	int closeStringChar = 0;
 | 
			
		||||
	int styleBeforeDCKeyword = SCE_FS_DEFAULT;
 | 
			
		||||
	bool bEnableCode = initStyle < SCE_FS_DISABLEDCODE;
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		switch (sc.state) {
 | 
			
		||||
			case SCE_FS_OPERATOR:
 | 
			
		||||
			case SCE_FS_OPERATOR_C:
 | 
			
		||||
			case SCE_FS_WORDOPERATOR:
 | 
			
		||||
				sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_IDENTIFIER:
 | 
			
		||||
			case SCE_FS_IDENTIFIER_C:
 | 
			
		||||
				if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
					char s[64];
 | 
			
		||||
					sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
					if (keywords.InList(s)) {
 | 
			
		||||
						sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD : SCE_FS_KEYWORD_C);
 | 
			
		||||
					} else if (keywords2.InList(s)) {
 | 
			
		||||
						sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD2 : SCE_FS_KEYWORD2_C);
 | 
			
		||||
					} else if (bEnableCode && keywords3.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_FS_KEYWORD3);
 | 
			
		||||
					} else if (bEnableCode && keywords4.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_FS_KEYWORD4);
 | 
			
		||||
					}// Else, it is really an identifier...
 | 
			
		||||
					sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_NUMBER:
 | 
			
		||||
				if (!IsAWordChar(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
					sc.SetState(SCE_FS_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_NUMBER_C:
 | 
			
		||||
				if (!IsAWordChar(sc.ch) && sc.ch != '.') {
 | 
			
		||||
					sc.SetState(SCE_FS_DEFAULT_C);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_CONSTANT:
 | 
			
		||||
				if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
					sc.SetState(SCE_FS_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_STRING:
 | 
			
		||||
			case SCE_FS_STRING_C:
 | 
			
		||||
				if (sc.ch == closeStringChar) {
 | 
			
		||||
					sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
 | 
			
		||||
				} else if (sc.atLineEnd) {
 | 
			
		||||
					sc.ChangeState(bEnableCode ? SCE_FS_STRINGEOL : SCE_FS_STRINGEOL_C);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_STRINGEOL:
 | 
			
		||||
			case SCE_FS_STRINGEOL_C:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_COMMENTDOC:
 | 
			
		||||
			case SCE_FS_COMMENTDOC_C:
 | 
			
		||||
				if (sc.Match('*', '/')) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
 | 
			
		||||
				} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
 | 
			
		||||
					// Verify that we have the conditions to mark a comment-doc-keyword
 | 
			
		||||
					if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
 | 
			
		||||
						styleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C;
 | 
			
		||||
						sc.SetState(SCE_FS_COMMENTDOCKEYWORD);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_COMMENT:
 | 
			
		||||
			case SCE_FS_COMMENTLINE:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_FS_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_COMMENTLINEDOC:
 | 
			
		||||
			case SCE_FS_COMMENTLINEDOC_C:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
 | 
			
		||||
				} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
 | 
			
		||||
					// Verify that we have the conditions to mark a comment-doc-keyword
 | 
			
		||||
					if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
 | 
			
		||||
						styleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C;
 | 
			
		||||
						sc.SetState(SCE_FS_COMMENTDOCKEYWORD);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_COMMENTDOCKEYWORD:
 | 
			
		||||
				if ((styleBeforeDCKeyword == SCE_FS_COMMENTDOC || styleBeforeDCKeyword == SCE_FS_COMMENTDOC_C) &&
 | 
			
		||||
						sc.Match('*', '/')) {
 | 
			
		||||
					sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
 | 
			
		||||
				} else if (!setDoxygen.Contains(sc.ch)) {
 | 
			
		||||
					char s[64];
 | 
			
		||||
					sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
					if (!IsASpace(sc.ch) || !keywords5.InList(s + 1)) {
 | 
			
		||||
						sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);
 | 
			
		||||
					}
 | 
			
		||||
					sc.SetState(styleBeforeDCKeyword);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_PREPROCESSOR:
 | 
			
		||||
			case SCE_FS_PREPROCESSOR_C:
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					if (!(sc.chPrev == ';' || sc.GetRelative(-2) == ';')) {
 | 
			
		||||
						sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
 | 
			
		||||
					}
 | 
			
		||||
				} else if (stylingWithinPreprocessor) {
 | 
			
		||||
					if (IsASpaceOrTab(sc.ch)) {
 | 
			
		||||
						sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.Match('/', '*') || sc.Match('/', '/') || sc.Match('&', '&')) {
 | 
			
		||||
					sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_DISABLEDCODE:
 | 
			
		||||
				if (sc.ch == '#' && visibleChars == 0) {
 | 
			
		||||
					sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);
 | 
			
		||||
					do {	// Skip whitespace between # and preprocessor word
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					} while (IsASpaceOrTab(sc.ch) && sc.More());
 | 
			
		||||
					if (sc.MatchIgnoreCase("pragma")) {
 | 
			
		||||
						sc.Forward(6);
 | 
			
		||||
						do {	// Skip more whitespace until keyword
 | 
			
		||||
							sc.Forward();
 | 
			
		||||
						} while (IsASpaceOrTab(sc.ch) && sc.More());
 | 
			
		||||
						if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) {
 | 
			
		||||
							bEnableCode = true;
 | 
			
		||||
							sc.SetState(SCE_FS_DISABLEDCODE);
 | 
			
		||||
							sc.Forward(sc.ch == '_' ? 8 : 6);
 | 
			
		||||
							sc.ForwardSetState(SCE_FS_DEFAULT);
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.ChangeState(SCE_FS_DISABLEDCODE);
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.ChangeState(SCE_FS_DISABLEDCODE);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_FS_DATE:
 | 
			
		||||
				if (sc.ch == '}') {
 | 
			
		||||
					sc.ForwardSetState(SCE_FS_DEFAULT);
 | 
			
		||||
				} else if (sc.atLineEnd) {
 | 
			
		||||
					sc.ChangeState(SCE_FS_STRINGEOL);
 | 
			
		||||
				}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_FS_DEFAULT || sc.state == SCE_FS_DEFAULT_C) {
 | 
			
		||||
			if (bEnableCode &&
 | 
			
		||||
					(sc.MatchIgnoreCase(".and.") || sc.MatchIgnoreCase(".not."))) {
 | 
			
		||||
				sc.SetState(SCE_FS_WORDOPERATOR);
 | 
			
		||||
				sc.Forward(4);
 | 
			
		||||
			} else if (bEnableCode && sc.MatchIgnoreCase(".or.")) {
 | 
			
		||||
				sc.SetState(SCE_FS_WORDOPERATOR);
 | 
			
		||||
				sc.Forward(3);
 | 
			
		||||
			} else if (bEnableCode &&
 | 
			
		||||
					(sc.MatchIgnoreCase(".t.") || sc.MatchIgnoreCase(".f.") ||
 | 
			
		||||
					(!IsAWordChar(sc.GetRelative(3)) && sc.MatchIgnoreCase("nil")))) {
 | 
			
		||||
				sc.SetState(SCE_FS_CONSTANT);
 | 
			
		||||
				sc.Forward(2);
 | 
			
		||||
			} else if (sc.Match('/', '*')) {
 | 
			
		||||
				sc.SetState(bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (bEnableCode && sc.Match('&', '&')) {
 | 
			
		||||
				sc.SetState(SCE_FS_COMMENTLINE);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.Match('/', '/')) {
 | 
			
		||||
				sc.SetState(bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (bEnableCode && sc.ch == '*' && visibleChars == 0) {
 | 
			
		||||
				sc.SetState(SCE_FS_COMMENT);
 | 
			
		||||
			} else if (sc.ch == '\"' || sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);
 | 
			
		||||
				closeStringChar = sc.ch;
 | 
			
		||||
			} else if (closeStringChar == '>' && sc.ch == '<') {
 | 
			
		||||
				sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);
 | 
			
		||||
			} else if (sc.ch == '#' && visibleChars == 0) {
 | 
			
		||||
				sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);
 | 
			
		||||
				do {	// Skip whitespace between # and preprocessor word
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} while (IsASpaceOrTab(sc.ch) && sc.More());
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
 | 
			
		||||
				} else if (sc.MatchIgnoreCase("include")) {
 | 
			
		||||
					if (stylingWithinPreprocessor) {
 | 
			
		||||
						closeStringChar = '>';
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.MatchIgnoreCase("pragma")) {
 | 
			
		||||
					sc.Forward(6);
 | 
			
		||||
					do {	// Skip more whitespace until keyword
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					} while (IsASpaceOrTab(sc.ch) && sc.More());
 | 
			
		||||
					if (sc.MatchIgnoreCase("begindump") || sc.MatchIgnoreCase("__cstream")) {
 | 
			
		||||
						bEnableCode = false;
 | 
			
		||||
						if (stylingWithinPreprocessor) {
 | 
			
		||||
							sc.SetState(SCE_FS_DISABLEDCODE);
 | 
			
		||||
							sc.Forward(8);
 | 
			
		||||
							sc.ForwardSetState(SCE_FS_DEFAULT_C);
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.SetState(SCE_FS_DISABLEDCODE);
 | 
			
		||||
						}
 | 
			
		||||
					} else if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) {
 | 
			
		||||
						bEnableCode = true;
 | 
			
		||||
						sc.SetState(SCE_FS_DISABLEDCODE);
 | 
			
		||||
						sc.Forward(sc.ch == '_' ? 8 : 6);
 | 
			
		||||
						sc.ForwardSetState(SCE_FS_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else if (bEnableCode && sc.ch == '{') {
 | 
			
		||||
				Sci_Position p = 0;
 | 
			
		||||
				int chSeek;
 | 
			
		||||
				Sci_PositionU endPos(startPos + length);
 | 
			
		||||
				do {	// Skip whitespace
 | 
			
		||||
					chSeek = sc.GetRelative(++p);
 | 
			
		||||
				} while (IsASpaceOrTab(chSeek) && (sc.currentPos + p < endPos));
 | 
			
		||||
				if (chSeek == '^') {
 | 
			
		||||
					sc.SetState(SCE_FS_DATE);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_FS_OPERATOR);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(bEnableCode ? SCE_FS_NUMBER : SCE_FS_NUMBER_C);
 | 
			
		||||
			} else if (IsAWordChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(bEnableCode ? SCE_FS_IDENTIFIER : SCE_FS_IDENTIFIER_C);
 | 
			
		||||
			} else if (isoperator(static_cast<char>(sc.ch)) || (bEnableCode && sc.ch == '@')) {
 | 
			
		||||
				sc.SetState(bEnableCode ? SCE_FS_OPERATOR : SCE_FS_OPERATOR_C);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.atLineEnd) {
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
			closeStringChar = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!IsASpace(sc.ch)) {
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldFlagShipDoc(Sci_PositionU startPos, Sci_Position length, int,
 | 
			
		||||
									WordList *[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	Sci_Position endPos = startPos + length;
 | 
			
		||||
 | 
			
		||||
	// Backtrack to previous line in case need to fix its fold status
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	if (startPos > 0 && lineCurrent > 0) {
 | 
			
		||||
			lineCurrent--;
 | 
			
		||||
			startPos = styler.LineStart(lineCurrent);
 | 
			
		||||
	}
 | 
			
		||||
	int spaceFlags = 0;
 | 
			
		||||
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	for (Sci_Position i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos-1)) {
 | 
			
		||||
			int lev = indentCurrent;
 | 
			
		||||
			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
 | 
			
		||||
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
 | 
			
		||||
				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
 | 
			
		||||
					lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
 | 
			
		||||
					int spaceFlags2 = 0;
 | 
			
		||||
					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2);
 | 
			
		||||
					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
 | 
			
		||||
						lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			indentCurrent = indentNext;
 | 
			
		||||
			styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const FSWordListDesc[] = {
 | 
			
		||||
	"Keywords Commands",
 | 
			
		||||
	"Std Library Functions",
 | 
			
		||||
	"Procedure, return, exit",
 | 
			
		||||
	"Class (oop)",
 | 
			
		||||
	"Doxygen keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmFlagShip(SCLEX_FLAGSHIP, ColouriseFlagShipDoc, "flagship", FoldFlagShipDoc, FSWordListDesc);
 | 
			
		||||
							
								
								
									
										171
									
								
								3rdparty/lexilla540/lexilla/lexers/LexForth.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								3rdparty/lexilla540/lexilla/lexers/LexForth.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,171 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexForth.cxx
 | 
			
		||||
 ** Lexer for FORTH
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordStart(int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsANumChar(int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsASpaceChar(int ch) {
 | 
			
		||||
	return (ch < 0x80) && isspace(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseForthDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordLists[],
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
    WordList &control = *keywordLists[0];
 | 
			
		||||
    WordList &keyword = *keywordLists[1];
 | 
			
		||||
    WordList &defword = *keywordLists[2];
 | 
			
		||||
    WordList &preword1 = *keywordLists[3];
 | 
			
		||||
    WordList &preword2 = *keywordLists[4];
 | 
			
		||||
    WordList &strings = *keywordLists[5];
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward())
 | 
			
		||||
	{
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		if (sc.state == SCE_FORTH_COMMENT) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_FORTH_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}else if (sc.state == SCE_FORTH_COMMENT_ML) {
 | 
			
		||||
			if (sc.ch == ')') {
 | 
			
		||||
				sc.ForwardSetState(SCE_FORTH_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}else if (sc.state == SCE_FORTH_IDENTIFIER || sc.state == SCE_FORTH_NUMBER) {
 | 
			
		||||
			// handle numbers here too, because what we thought was a number might
 | 
			
		||||
			// turn out to be a keyword e.g. 2DUP
 | 
			
		||||
			if (IsASpaceChar(sc.ch) ) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
				int newState = sc.state == SCE_FORTH_NUMBER ? SCE_FORTH_NUMBER : SCE_FORTH_DEFAULT;
 | 
			
		||||
				if (control.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_FORTH_CONTROL);
 | 
			
		||||
				} else if (keyword.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_FORTH_KEYWORD);
 | 
			
		||||
				} else if (defword.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_FORTH_DEFWORD);
 | 
			
		||||
				}  else if (preword1.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_FORTH_PREWORD1);
 | 
			
		||||
				} else if (preword2.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_FORTH_PREWORD2);
 | 
			
		||||
				} else if (strings.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_FORTH_STRING);
 | 
			
		||||
					newState = SCE_FORTH_STRING;
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(newState);
 | 
			
		||||
			}
 | 
			
		||||
			if (sc.state == SCE_FORTH_NUMBER) {
 | 
			
		||||
				if (IsASpaceChar(sc.ch)) {
 | 
			
		||||
					sc.SetState(SCE_FORTH_DEFAULT);
 | 
			
		||||
				} else if (!IsANumChar(sc.ch)) {
 | 
			
		||||
					sc.ChangeState(SCE_FORTH_IDENTIFIER);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}else if (sc.state == SCE_FORTH_STRING) {
 | 
			
		||||
			if (sc.ch == '\"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_FORTH_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}else if (sc.state == SCE_FORTH_LOCALE) {
 | 
			
		||||
			if (sc.ch == '}') {
 | 
			
		||||
				sc.ForwardSetState(SCE_FORTH_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}else if (sc.state == SCE_FORTH_DEFWORD) {
 | 
			
		||||
			if (IsASpaceChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_FORTH_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_FORTH_DEFAULT) {
 | 
			
		||||
			if (sc.ch == '\\'){
 | 
			
		||||
				sc.SetState(SCE_FORTH_COMMENT);
 | 
			
		||||
			} else if (sc.ch == '(' &&
 | 
			
		||||
					(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
 | 
			
		||||
					(sc.atLineEnd   || IsASpaceChar(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_FORTH_COMMENT_ML);
 | 
			
		||||
			} else if (	(sc.ch == '$' && (IsASCII(sc.chNext) && isxdigit(sc.chNext))) ) {
 | 
			
		||||
				// number starting with $ is a hex number
 | 
			
		||||
				sc.SetState(SCE_FORTH_NUMBER);
 | 
			
		||||
				while(sc.More() && IsASCII(sc.chNext) && isxdigit(sc.chNext))
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
			} else if ( (sc.ch == '%' && (IsASCII(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))) ) {
 | 
			
		||||
				// number starting with % is binary
 | 
			
		||||
				sc.SetState(SCE_FORTH_NUMBER);
 | 
			
		||||
				while(sc.More() && IsASCII(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
			} else if (	IsASCII(sc.ch) &&
 | 
			
		||||
						(isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && IsASCII(sc.chNext) && isxdigit(sc.chNext)) )
 | 
			
		||||
					){
 | 
			
		||||
				sc.SetState(SCE_FORTH_NUMBER);
 | 
			
		||||
			} else if (IsAWordStart(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_FORTH_IDENTIFIER);
 | 
			
		||||
			} else if (sc.ch == '{') {
 | 
			
		||||
				sc.SetState(SCE_FORTH_LOCALE);
 | 
			
		||||
			} else if (sc.ch == ':' && IsASCII(sc.chNext) && isspace(sc.chNext)) {
 | 
			
		||||
				// highlight word definitions e.g.  : GCD ( n n -- n ) ..... ;
 | 
			
		||||
				//                                  ^ ^^^
 | 
			
		||||
				sc.SetState(SCE_FORTH_DEFWORD);
 | 
			
		||||
				while(sc.More() && IsASCII(sc.chNext) && isspace(sc.chNext))
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
			} else if (sc.ch == ';' &&
 | 
			
		||||
					(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
 | 
			
		||||
					(sc.atLineEnd   || IsASpaceChar(sc.chNext))	) {
 | 
			
		||||
				// mark the ';' that ends a word
 | 
			
		||||
				sc.SetState(SCE_FORTH_DEFWORD);
 | 
			
		||||
				sc.ForwardSetState(SCE_FORTH_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldForthDoc(Sci_PositionU, Sci_Position, int, WordList *[],
 | 
			
		||||
						Accessor &) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const forthWordLists[] = {
 | 
			
		||||
			"control keywords",
 | 
			
		||||
			"keywords",
 | 
			
		||||
			"definition words",
 | 
			
		||||
			"prewords with one argument",
 | 
			
		||||
			"prewords with two arguments",
 | 
			
		||||
			"string definition keywords",
 | 
			
		||||
			0,
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										724
									
								
								3rdparty/lexilla540/lexilla/lexers/LexFortran.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										724
									
								
								3rdparty/lexilla540/lexilla/lexers/LexFortran.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,724 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexFortran.cxx
 | 
			
		||||
 ** Lexer for Fortran.
 | 
			
		||||
 ** Written by Chuan-jian Shen, Last changed Sep. 2003
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
/***********************************************/
 | 
			
		||||
static inline bool IsAWordChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');
 | 
			
		||||
}
 | 
			
		||||
/**********************************************/
 | 
			
		||||
static inline bool IsAWordStart(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch));
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static inline bool IsABlank(unsigned int ch) {
 | 
			
		||||
	return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static inline bool IsALineEnd(char ch) {
 | 
			
		||||
	return ((ch == '\n') || (ch == '\r')) ;
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static Sci_PositionU GetContinuedPos(Sci_PositionU pos, Accessor &styler) {
 | 
			
		||||
	while (!IsALineEnd(styler.SafeGetCharAt(pos++))) continue;
 | 
			
		||||
	if (styler.SafeGetCharAt(pos) == '\n') pos++;
 | 
			
		||||
	while (IsABlank(styler.SafeGetCharAt(pos++))) continue;
 | 
			
		||||
	char chCur = styler.SafeGetCharAt(pos);
 | 
			
		||||
	if (chCur == '&') {
 | 
			
		||||
		while (IsABlank(styler.SafeGetCharAt(++pos))) continue;
 | 
			
		||||
		return pos;
 | 
			
		||||
	} else {
 | 
			
		||||
		return pos;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
        WordList *keywordlists[], Accessor &styler, bool isFixFormat) {
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
	WordList &keywords2 = *keywordlists[1];
 | 
			
		||||
	WordList &keywords3 = *keywordlists[2];
 | 
			
		||||
	/***************************************/
 | 
			
		||||
	Sci_Position posLineStart = 0;
 | 
			
		||||
	int numNonBlank = 0, prevState = 0;
 | 
			
		||||
	Sci_Position endPos = startPos + length;
 | 
			
		||||
	/***************************************/
 | 
			
		||||
	// backtrack to the nearest keyword
 | 
			
		||||
	while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) {
 | 
			
		||||
		startPos--;
 | 
			
		||||
	}
 | 
			
		||||
	startPos = styler.LineStart(styler.GetLine(startPos));
 | 
			
		||||
	initStyle = styler.StyleAt(startPos - 1);
 | 
			
		||||
	StyleContext sc(startPos, endPos-startPos, initStyle, styler);
 | 
			
		||||
	/***************************************/
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
		// remember the start position of the line
 | 
			
		||||
		if (sc.atLineStart) {
 | 
			
		||||
			posLineStart = sc.currentPos;
 | 
			
		||||
			numNonBlank = 0;
 | 
			
		||||
			sc.SetState(SCE_F_DEFAULT);
 | 
			
		||||
		}
 | 
			
		||||
		if (!IsASpaceOrTab(sc.ch)) numNonBlank ++;
 | 
			
		||||
		/***********************************************/
 | 
			
		||||
		// Handle the fix format generically
 | 
			
		||||
		Sci_Position toLineStart = sc.currentPos - posLineStart;
 | 
			
		||||
		if (isFixFormat && (toLineStart < 6 || toLineStart >= 72)) {
 | 
			
		||||
			if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') {
 | 
			
		||||
				if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") ||
 | 
			
		||||
				        sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") ||
 | 
			
		||||
				        sc.MatchIgnoreCase("cms$")  || sc.MatchIgnoreCase("*ms$")  || sc.MatchIgnoreCase("!ms$")  ||
 | 
			
		||||
				        sc.chNext == '$') {
 | 
			
		||||
					sc.SetState(SCE_F_PREPROCESSOR);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_F_COMMENT);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
 | 
			
		||||
			} else if (toLineStart >= 72) {
 | 
			
		||||
				sc.SetState(SCE_F_COMMENT);
 | 
			
		||||
				while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
 | 
			
		||||
			} else if (toLineStart < 5) {
 | 
			
		||||
				if (IsADigit(sc.ch))
 | 
			
		||||
					sc.SetState(SCE_F_LABEL);
 | 
			
		||||
				else
 | 
			
		||||
					sc.SetState(SCE_F_DEFAULT);
 | 
			
		||||
			} else if (toLineStart == 5) {
 | 
			
		||||
				//if (!IsASpace(sc.ch) && sc.ch != '0') {
 | 
			
		||||
				if (sc.ch != '\r' && sc.ch != '\n') {
 | 
			
		||||
					sc.SetState(SCE_F_CONTINUATION);
 | 
			
		||||
					if (!IsASpace(sc.ch) && sc.ch != '0')
 | 
			
		||||
						sc.ForwardSetState(prevState);
 | 
			
		||||
				} else
 | 
			
		||||
					sc.SetState(SCE_F_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		/***************************************/
 | 
			
		||||
		// Handle line continuation generically.
 | 
			
		||||
		if (!isFixFormat && sc.ch == '&' && sc.state != SCE_F_COMMENT) {
 | 
			
		||||
			char chTemp = ' ';
 | 
			
		||||
			Sci_Position j = 1;
 | 
			
		||||
			while (IsABlank(chTemp) && j<132) {
 | 
			
		||||
				chTemp = static_cast<char>(sc.GetRelative(j));
 | 
			
		||||
				j++;
 | 
			
		||||
			}
 | 
			
		||||
			if (chTemp == '!') {
 | 
			
		||||
				sc.SetState(SCE_F_CONTINUATION);
 | 
			
		||||
				if (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT);
 | 
			
		||||
			} else if (chTemp == '\r' || chTemp == '\n') {
 | 
			
		||||
				int currentState = sc.state;
 | 
			
		||||
				sc.SetState(SCE_F_CONTINUATION);
 | 
			
		||||
				sc.ForwardSetState(SCE_F_DEFAULT);
 | 
			
		||||
				while (IsASpace(sc.ch) && sc.More()) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					if (sc.atLineStart) numNonBlank = 0;
 | 
			
		||||
					if (!IsASpaceOrTab(sc.ch)) numNonBlank ++;
 | 
			
		||||
				}
 | 
			
		||||
				if (sc.ch == '&') {
 | 
			
		||||
					sc.SetState(SCE_F_CONTINUATION);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(currentState);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		/***************************************/
 | 
			
		||||
		// Hanndle preprocessor directives
 | 
			
		||||
		if (sc.ch == '#' && numNonBlank == 1)
 | 
			
		||||
		{
 | 
			
		||||
			sc.SetState(SCE_F_PREPROCESSOR);
 | 
			
		||||
			while (!sc.atLineEnd && sc.More())
 | 
			
		||||
				sc.Forward(); // Until line end
 | 
			
		||||
		}
 | 
			
		||||
		/***************************************/
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		if (sc.state == SCE_F_OPERATOR) {
 | 
			
		||||
			sc.SetState(SCE_F_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_F_NUMBER) {
 | 
			
		||||
			if (!(IsAWordChar(sc.ch) || sc.ch=='\'' || sc.ch=='\"' || sc.ch=='.')) {
 | 
			
		||||
				sc.SetState(SCE_F_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_F_IDENTIFIER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch) || (sc.ch == '%')) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
				if (keywords.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_F_WORD);
 | 
			
		||||
				} else if (keywords2.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_F_WORD2);
 | 
			
		||||
				} else if (keywords3.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_F_WORD3);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_F_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_F_COMMENT || sc.state == SCE_F_PREPROCESSOR) {
 | 
			
		||||
			if (sc.ch == '\r' || sc.ch == '\n') {
 | 
			
		||||
				sc.SetState(SCE_F_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_F_STRING1) {
 | 
			
		||||
			prevState = sc.state;
 | 
			
		||||
			if (sc.ch == '\'') {
 | 
			
		||||
				if (sc.chNext == '\'') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.ForwardSetState(SCE_F_DEFAULT);
 | 
			
		||||
					prevState = SCE_F_DEFAULT;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.atLineEnd) {
 | 
			
		||||
				sc.ChangeState(SCE_F_STRINGEOL);
 | 
			
		||||
				sc.ForwardSetState(SCE_F_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_F_STRING2) {
 | 
			
		||||
			prevState = sc.state;
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.ChangeState(SCE_F_STRINGEOL);
 | 
			
		||||
				sc.ForwardSetState(SCE_F_DEFAULT);
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				if (sc.chNext == '\"') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.ForwardSetState(SCE_F_DEFAULT);
 | 
			
		||||
					prevState = SCE_F_DEFAULT;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_F_OPERATOR2) {
 | 
			
		||||
			if (sc.ch == '.') {
 | 
			
		||||
				sc.ForwardSetState(SCE_F_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_F_CONTINUATION) {
 | 
			
		||||
			sc.SetState(SCE_F_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_F_LABEL) {
 | 
			
		||||
			if (!IsADigit(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_F_DEFAULT);
 | 
			
		||||
			} else {
 | 
			
		||||
				if (isFixFormat && sc.currentPos-posLineStart > 4)
 | 
			
		||||
					sc.SetState(SCE_F_DEFAULT);
 | 
			
		||||
				else if (numNonBlank > 5)
 | 
			
		||||
					sc.SetState(SCE_F_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		/***************************************/
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_F_DEFAULT) {
 | 
			
		||||
			if (sc.ch == '!') {
 | 
			
		||||
				if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") ||
 | 
			
		||||
					sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
 | 
			
		||||
					sc.SetState(SCE_F_PREPROCESSOR);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_F_COMMENT);
 | 
			
		||||
				}
 | 
			
		||||
			} else if ((!isFixFormat) && IsADigit(sc.ch) && numNonBlank == 1) {
 | 
			
		||||
				sc.SetState(SCE_F_LABEL);
 | 
			
		||||
			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_F_NUMBER);
 | 
			
		||||
			} else if ((tolower(sc.ch) == 'b' || tolower(sc.ch) == 'o' ||
 | 
			
		||||
				tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) {
 | 
			
		||||
				sc.SetState(SCE_F_NUMBER);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.ch == '.' && isalpha(sc.chNext)) {
 | 
			
		||||
				sc.SetState(SCE_F_OPERATOR2);
 | 
			
		||||
			} else if (IsAWordStart(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_F_IDENTIFIER);
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_F_STRING2);
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(SCE_F_STRING1);
 | 
			
		||||
			} else if (isoperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_F_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static void CheckLevelCommentLine(const unsigned int nComL,
 | 
			
		||||
				  Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position &nComCur,
 | 
			
		||||
				  bool comLineB[], bool comLineF[], bool &comLineCur,
 | 
			
		||||
				  int &levelDeltaNext) {
 | 
			
		||||
	levelDeltaNext = 0;
 | 
			
		||||
	if (!comLineCur) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!comLineF[0] || nComColF[0] != nComCur) {
 | 
			
		||||
		unsigned int i=0;
 | 
			
		||||
		for (; i<nComL; i++) {
 | 
			
		||||
			if (!comLineB[i] || nComColB[i] != nComCur) {
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (i == nComL) {
 | 
			
		||||
			levelDeltaNext = -1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else if (!comLineB[0] || nComColB[0] != nComCur) {
 | 
			
		||||
		unsigned int i=0;
 | 
			
		||||
		for (; i<nComL; i++) {
 | 
			
		||||
			if (!comLineF[i] || nComColF[i] != nComCur) {
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (i == nComL) {
 | 
			
		||||
			levelDeltaNext = 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static void GetIfLineComment(Accessor &styler, bool isFixFormat, const Sci_Position line, bool &isComLine, Sci_Position &comCol) {
 | 
			
		||||
	Sci_Position col = 0;
 | 
			
		||||
	isComLine = false;
 | 
			
		||||
	Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
	Sci_Position len = styler.Length();
 | 
			
		||||
	while(pos<len) {
 | 
			
		||||
		char ch = styler.SafeGetCharAt(pos);
 | 
			
		||||
		if (ch == '!' || (isFixFormat && col == 0 && (tolower(ch) == 'c' || ch == '*'))) {
 | 
			
		||||
			isComLine = true;
 | 
			
		||||
			comCol = col;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		else if (!IsABlank(ch) || IsALineEnd(ch)) {
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		pos++;
 | 
			
		||||
		col++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static void StepCommentLine(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,
 | 
			
		||||
				  Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position &nComCur,
 | 
			
		||||
				  bool comLineB[], bool comLineF[], bool &comLineCur) {
 | 
			
		||||
	Sci_Position nLineTotal = styler.GetLine(styler.Length()-1) + 1;
 | 
			
		||||
	if (lineCurrent >= nLineTotal) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (int i=nComL-2; i>=0; i--) {
 | 
			
		||||
		nComColB[i+1] = nComColB[i];
 | 
			
		||||
		comLineB[i+1] = comLineB[i];
 | 
			
		||||
	}
 | 
			
		||||
	nComColB[0] = nComCur;
 | 
			
		||||
	comLineB[0] = comLineCur;
 | 
			
		||||
	nComCur = nComColF[0];
 | 
			
		||||
	comLineCur = comLineF[0];
 | 
			
		||||
	for (unsigned int i=0; i+1<nComL; i++) {
 | 
			
		||||
		nComColF[i] = nComColF[i+1];
 | 
			
		||||
		comLineF[i] = comLineF[i+1];
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position chL = lineCurrent + nComL;
 | 
			
		||||
	if (chL < nLineTotal) {
 | 
			
		||||
		GetIfLineComment(styler, isFixFormat, chL, comLineF[nComL-1], nComColF[nComL-1]);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		comLineF[nComL-1] = false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static void CheckBackComLines(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,
 | 
			
		||||
				  Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position nComCur,
 | 
			
		||||
				  bool comLineB[], bool comLineF[], bool &comLineCur) {
 | 
			
		||||
	unsigned int nLines = nComL + nComL + 1;
 | 
			
		||||
	bool* comL = new bool[nLines];
 | 
			
		||||
	Sci_Position* nComCol = new Sci_Position[nLines];
 | 
			
		||||
	bool comL0;
 | 
			
		||||
	Sci_Position nComCol0;
 | 
			
		||||
	GetIfLineComment(styler, isFixFormat, lineCurrent-nComL-1, comL0, nComCol0);
 | 
			
		||||
	for (unsigned int i=0; i<nComL; i++) {
 | 
			
		||||
		unsigned copyTo = nComL - i - 1;
 | 
			
		||||
		comL[copyTo]    = comLineB[i];
 | 
			
		||||
		nComCol[copyTo] = nComColB[i];
 | 
			
		||||
	}
 | 
			
		||||
	assert(nComL < nLines);
 | 
			
		||||
	comL[nComL] = comLineCur;
 | 
			
		||||
	nComCol[nComL] = nComCur;
 | 
			
		||||
	for (unsigned int i=0; i<nComL; i++) {
 | 
			
		||||
		unsigned copyTo = i + nComL + 1;
 | 
			
		||||
		comL[copyTo]    = comLineF[i];
 | 
			
		||||
		nComCol[copyTo] = nComColF[i];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	Sci_Position lineC = lineCurrent - nComL + 1;
 | 
			
		||||
	Sci_PositionU iStart;
 | 
			
		||||
	if (lineC <= 0) {
 | 
			
		||||
		lineC = 0;
 | 
			
		||||
		iStart = nComL - lineCurrent;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		iStart = 1;
 | 
			
		||||
	}
 | 
			
		||||
	bool levChanged = false;
 | 
			
		||||
	int lev = styler.LevelAt(lineC) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	
 | 
			
		||||
	for (Sci_PositionU i=iStart; i<=nComL; i++) {
 | 
			
		||||
		if (comL[i] && (!comL[i-1] || nComCol[i] != nComCol[i-1])) {
 | 
			
		||||
			bool increase = true;
 | 
			
		||||
			Sci_PositionU until = i + nComL;
 | 
			
		||||
			for (Sci_PositionU j=i+1; j<=until; j++) {
 | 
			
		||||
				if (!comL[j] || nComCol[j] != nComCol[i]) {
 | 
			
		||||
					increase = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			lev = styler.LevelAt(lineC) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
			if (increase) {
 | 
			
		||||
				int levH = lev | SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
				lev += 1;
 | 
			
		||||
				if (levH != styler.LevelAt(lineC)) {
 | 
			
		||||
					styler.SetLevel(lineC, levH);
 | 
			
		||||
				}
 | 
			
		||||
				for (Sci_Position j=lineC+1; j<=lineCurrent; j++) {
 | 
			
		||||
					if (lev != styler.LevelAt(j)) {
 | 
			
		||||
						styler.SetLevel(j, lev);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				if (lev != styler.LevelAt(lineC)) {
 | 
			
		||||
					styler.SetLevel(lineC, lev);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			levChanged = true;
 | 
			
		||||
		}
 | 
			
		||||
		else if (levChanged && comL[i]) {
 | 
			
		||||
			if (lev != styler.LevelAt(lineC)) {
 | 
			
		||||
				styler.SetLevel(lineC, lev);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		lineC++;
 | 
			
		||||
	}
 | 
			
		||||
	delete[] comL;
 | 
			
		||||
	delete[] nComCol;
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
// To determine the folding level depending on keywords
 | 
			
		||||
static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) {
 | 
			
		||||
	int lev = 0;
 | 
			
		||||
 | 
			
		||||
	if ((strcmp(prevWord, "module") == 0 && strcmp(s, "subroutine") == 0)
 | 
			
		||||
		|| (strcmp(prevWord, "module") == 0 && strcmp(s, "function") == 0)) {
 | 
			
		||||
		lev = 0;
 | 
			
		||||
	} else if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0
 | 
			
		||||
	        || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0
 | 
			
		||||
	        || strcmp(s, "selecttype") == 0 || strcmp(s, "selectcase") == 0
 | 
			
		||||
	        || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0
 | 
			
		||||
	        || strcmp(s, "function") == 0 || strcmp(s, "interface") == 0
 | 
			
		||||
	        || strcmp(s, "module") == 0 || strcmp(s, "program") == 0
 | 
			
		||||
	        || strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0
 | 
			
		||||
	        || (strcmp(s, "type") == 0 && chNextNonBlank != '(')
 | 
			
		||||
		|| strcmp(s, "critical") == 0 || strcmp(s, "submodule") == 0){
 | 
			
		||||
		if (strcmp(prevWord, "end") == 0)
 | 
			
		||||
			lev = 0;
 | 
			
		||||
		else
 | 
			
		||||
			lev = 1;
 | 
			
		||||
	} else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=')
 | 
			
		||||
	        || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
 | 
			
		||||
	        || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
 | 
			
		||||
	        || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
 | 
			
		||||
	        || strcmp(s, "endif") == 0 || strcmp(s, "endforall") == 0
 | 
			
		||||
	        || strcmp(s, "endfunction") == 0 || strcmp(s, "endinterface") == 0
 | 
			
		||||
	        || strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0
 | 
			
		||||
	        || strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
 | 
			
		||||
	        || strcmp(s, "endwhere") == 0 || strcmp(s, "endcritical") == 0
 | 
			
		||||
		|| (strcmp(prevWord, "module") == 0 && strcmp(s, "procedure") == 0)  // Take care of the "module procedure" statement
 | 
			
		||||
		|| strcmp(s, "endsubmodule") == 0 || strcmp(s, "endteam") == 0) {
 | 
			
		||||
		lev = -1;
 | 
			
		||||
	} else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
 | 
			
		||||
		lev = 0;
 | 
			
		||||
	} else if (strcmp(prevWord, "type") == 0 && strcmp(s, "is") == 0){ // type is
 | 
			
		||||
		lev = -1;
 | 
			
		||||
	} else if ((strcmp(prevWord, "end") == 0 && strcmp(s, "procedure") == 0)
 | 
			
		||||
			   || strcmp(s, "endprocedure") == 0) {
 | 
			
		||||
			lev = 1; // level back to 0, because no folding support for "module procedure" in submodule
 | 
			
		||||
	} else if (strcmp(prevWord, "change") == 0 && strcmp(s, "team") == 0){ // change team
 | 
			
		||||
		lev = 1;
 | 
			
		||||
	}
 | 
			
		||||
	return lev;
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
// Folding the code
 | 
			
		||||
static void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
        Accessor &styler, bool isFixFormat) {
 | 
			
		||||
 | 
			
		||||
	bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 0;
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	bool isPrevLine;
 | 
			
		||||
	if (lineCurrent > 0) {
 | 
			
		||||
		lineCurrent--;
 | 
			
		||||
		startPos = styler.LineStart(lineCurrent);
 | 
			
		||||
		isPrevLine = true;
 | 
			
		||||
	} else {
 | 
			
		||||
		isPrevLine = false;
 | 
			
		||||
	}
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
	int levelDeltaNext = 0;
 | 
			
		||||
 | 
			
		||||
	const unsigned int nComL = 3; // defines how many comment lines should be before they are folded
 | 
			
		||||
	Sci_Position nComColB[nComL] = {};
 | 
			
		||||
	Sci_Position nComColF[nComL] = {};
 | 
			
		||||
	Sci_Position nComCur = 0;
 | 
			
		||||
	bool comLineB[nComL] = {};
 | 
			
		||||
	bool comLineF[nComL] = {};
 | 
			
		||||
	bool comLineCur;
 | 
			
		||||
	Sci_Position nLineTotal = styler.GetLine(styler.Length()-1) + 1;
 | 
			
		||||
	if (foldComment) {
 | 
			
		||||
		for (unsigned int i=0; i<nComL; i++) {
 | 
			
		||||
			Sci_Position chL = lineCurrent-(i+1);
 | 
			
		||||
			if (chL < 0) {
 | 
			
		||||
				comLineB[i] = false;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			GetIfLineComment(styler, isFixFormat, chL, comLineB[i], nComColB[i]);
 | 
			
		||||
			if (!comLineB[i]) {
 | 
			
		||||
				for (unsigned int j=i+1; j<nComL; j++) {
 | 
			
		||||
					comLineB[j] = false;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		for (unsigned int i=0; i<nComL; i++) {
 | 
			
		||||
			Sci_Position chL = lineCurrent+i+1;
 | 
			
		||||
			if (chL >= nLineTotal) {
 | 
			
		||||
				comLineF[i] = false;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			GetIfLineComment(styler, isFixFormat, chL, comLineF[i], nComColF[i]);
 | 
			
		||||
		}
 | 
			
		||||
		GetIfLineComment(styler, isFixFormat, lineCurrent, comLineCur, nComCur);
 | 
			
		||||
		CheckBackComLines(styler, isFixFormat, lineCurrent, nComL, nComColB, nComColF, nComCur, 
 | 
			
		||||
				comLineB, comLineF, comLineCur);
 | 
			
		||||
	}
 | 
			
		||||
	int levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
 | 
			
		||||
	/***************************************/
 | 
			
		||||
	Sci_Position lastStart = 0;
 | 
			
		||||
	char prevWord[32] = "";
 | 
			
		||||
	/***************************************/
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		char chNextNonBlank = chNext;
 | 
			
		||||
		bool nextEOL = false;
 | 
			
		||||
		if (IsALineEnd(chNextNonBlank)) {
 | 
			
		||||
			nextEOL = true;
 | 
			
		||||
		}
 | 
			
		||||
		Sci_PositionU j=i+1;
 | 
			
		||||
		while(IsABlank(chNextNonBlank) && j<endPos) {
 | 
			
		||||
			j ++ ;
 | 
			
		||||
			chNextNonBlank = styler.SafeGetCharAt(j);
 | 
			
		||||
			if (IsALineEnd(chNextNonBlank)) {
 | 
			
		||||
				nextEOL = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!nextEOL && j == endPos) {
 | 
			
		||||
			nextEOL = true;
 | 
			
		||||
		}
 | 
			
		||||
		int stylePrev = style;
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		//
 | 
			
		||||
		if (((isFixFormat && stylePrev == SCE_F_CONTINUATION) || stylePrev == SCE_F_DEFAULT
 | 
			
		||||
			|| stylePrev == SCE_F_OPERATOR) && (style == SCE_F_WORD || style == SCE_F_LABEL)) {
 | 
			
		||||
			// Store last word and label start point.
 | 
			
		||||
			lastStart = i;
 | 
			
		||||
		}
 | 
			
		||||
		/***************************************/
 | 
			
		||||
		if (style == SCE_F_WORD) {
 | 
			
		||||
			if(iswordchar(ch) && !iswordchar(chNext)) {
 | 
			
		||||
				char s[32];
 | 
			
		||||
				Sci_PositionU k;
 | 
			
		||||
				for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {
 | 
			
		||||
					s[k] = static_cast<char>(tolower(styler[lastStart+k]));
 | 
			
		||||
				}
 | 
			
		||||
				s[k] = '\0';
 | 
			
		||||
				// Handle the forall and where statement and structure.
 | 
			
		||||
				if (strcmp(s, "forall") == 0 || (strcmp(s, "where") == 0 && strcmp(prevWord, "else") != 0)) {
 | 
			
		||||
					if (strcmp(prevWord, "end") != 0) {
 | 
			
		||||
						j = i + 1;
 | 
			
		||||
						char chBrace = '(', chSeek = ')', ch1 = styler.SafeGetCharAt(j);
 | 
			
		||||
						// Find the position of the first (
 | 
			
		||||
						while (ch1 != chBrace && j<endPos) {
 | 
			
		||||
							j++;
 | 
			
		||||
							ch1 = styler.SafeGetCharAt(j);
 | 
			
		||||
						}
 | 
			
		||||
						char styBrace = styler.StyleAt(j);
 | 
			
		||||
						int depth = 1;
 | 
			
		||||
						char chAtPos;
 | 
			
		||||
						char styAtPos;
 | 
			
		||||
						while (j<endPos) {
 | 
			
		||||
							j++;
 | 
			
		||||
							chAtPos = styler.SafeGetCharAt(j);
 | 
			
		||||
							styAtPos = styler.StyleAt(j);
 | 
			
		||||
							if (styAtPos == styBrace) {
 | 
			
		||||
								if (chAtPos == chBrace) depth++;
 | 
			
		||||
								if (chAtPos == chSeek) depth--;
 | 
			
		||||
								if (depth == 0) break;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						Sci_Position tmpLineCurrent = lineCurrent;
 | 
			
		||||
						while (j<endPos) {
 | 
			
		||||
							j++;
 | 
			
		||||
							chAtPos = styler.SafeGetCharAt(j);
 | 
			
		||||
							styAtPos = styler.StyleAt(j);
 | 
			
		||||
							if (!IsALineEnd(chAtPos) && (styAtPos == SCE_F_COMMENT || IsABlank(chAtPos))) continue;
 | 
			
		||||
							if (isFixFormat) {
 | 
			
		||||
								if (!IsALineEnd(chAtPos)) {
 | 
			
		||||
									break;
 | 
			
		||||
								} else {
 | 
			
		||||
									if (tmpLineCurrent < styler.GetLine(styler.Length()-1)) {
 | 
			
		||||
										tmpLineCurrent++;
 | 
			
		||||
										j = styler.LineStart(tmpLineCurrent);
 | 
			
		||||
										if (styler.StyleAt(j+5) == SCE_F_CONTINUATION
 | 
			
		||||
											&& !IsABlank(styler.SafeGetCharAt(j+5)) && styler.SafeGetCharAt(j+5) != '0') {
 | 
			
		||||
											j += 5;
 | 
			
		||||
											continue;
 | 
			
		||||
										} else {
 | 
			
		||||
											levelDeltaNext++;
 | 
			
		||||
											break;
 | 
			
		||||
										}
 | 
			
		||||
									}
 | 
			
		||||
								}
 | 
			
		||||
							} else {
 | 
			
		||||
								if (chAtPos == '&' && styler.StyleAt(j) == SCE_F_CONTINUATION) {
 | 
			
		||||
									j = GetContinuedPos(j+1, styler);
 | 
			
		||||
									continue;
 | 
			
		||||
								} else if (IsALineEnd(chAtPos)) {
 | 
			
		||||
									levelDeltaNext++;
 | 
			
		||||
									break;
 | 
			
		||||
								} else {
 | 
			
		||||
									break;
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					int wordLevelDelta = classifyFoldPointFortran(s, prevWord, chNextNonBlank);
 | 
			
		||||
					levelDeltaNext += wordLevelDelta;
 | 
			
		||||
					if (((strcmp(s, "else") == 0) && (nextEOL || chNextNonBlank == '!')) ||
 | 
			
		||||
						(strcmp(prevWord, "else") == 0 && strcmp(s, "where") == 0) || strcmp(s, "elsewhere") == 0) {
 | 
			
		||||
						if (!isPrevLine) {
 | 
			
		||||
							levelCurrent--;
 | 
			
		||||
						}
 | 
			
		||||
						levelDeltaNext++;
 | 
			
		||||
					} else if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0) {
 | 
			
		||||
						if (!isPrevLine) {
 | 
			
		||||
							levelCurrent--;
 | 
			
		||||
						}
 | 
			
		||||
					} else if ((strcmp(prevWord, "select") == 0 && strcmp(s, "case") == 0) || strcmp(s, "selectcase") == 0 ||
 | 
			
		||||
							   (strcmp(prevWord, "select") == 0 && strcmp(s, "type") == 0) || strcmp(s, "selecttype") == 0) {
 | 
			
		||||
						levelDeltaNext += 2;
 | 
			
		||||
					} else if ((strcmp(s, "case") == 0 && chNextNonBlank == '(') || (strcmp(prevWord, "case") == 0 && strcmp(s, "default") == 0) ||
 | 
			
		||||
							   (strcmp(prevWord, "type") == 0 && strcmp(s, "is") == 0) ||
 | 
			
		||||
							   (strcmp(prevWord, "class") == 0 && strcmp(s, "is") == 0) ||
 | 
			
		||||
							   (strcmp(prevWord, "class") == 0 && strcmp(s, "default") == 0) ) {
 | 
			
		||||
						if (!isPrevLine) {
 | 
			
		||||
							levelCurrent--;
 | 
			
		||||
						}
 | 
			
		||||
						levelDeltaNext++;
 | 
			
		||||
					} else if ((strcmp(prevWord, "end") == 0 && strcmp(s, "select") == 0) || strcmp(s, "endselect") == 0) {
 | 
			
		||||
						levelDeltaNext -= 2;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// There are multiple forms of "do" loop. The older form with a label "do 100 i=1,10" would require matching
 | 
			
		||||
					// labels to ensure the folding level does not decrease too far when labels are used for other purposes.
 | 
			
		||||
					// Since this is difficult, do-label constructs are not folded.
 | 
			
		||||
					if (strcmp(s, "do") == 0 && IsADigit(chNextNonBlank)) {
 | 
			
		||||
						// Remove delta for do-label
 | 
			
		||||
						levelDeltaNext -= wordLevelDelta;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				strcpy(prevWord, s);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			if (foldComment) {
 | 
			
		||||
				int ldNext;
 | 
			
		||||
				CheckLevelCommentLine(nComL, nComColB, nComColF, nComCur, comLineB, comLineF, comLineCur, ldNext);
 | 
			
		||||
				levelDeltaNext += ldNext;
 | 
			
		||||
			}
 | 
			
		||||
			int lev = levelCurrent;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if ((levelDeltaNext > 0) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent))
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelCurrent += levelDeltaNext;
 | 
			
		||||
			levelDeltaNext = 0;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
			strcpy(prevWord, "");
 | 
			
		||||
			isPrevLine = false;
 | 
			
		||||
 | 
			
		||||
			if (foldComment) {
 | 
			
		||||
				StepCommentLine(styler, isFixFormat, lineCurrent, nComL, nComColB, nComColF, nComCur,
 | 
			
		||||
						comLineB, comLineF, comLineCur);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		/***************************************/
 | 
			
		||||
		if (!isspacechar(ch)) visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
	/***************************************/
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static const char * const FortranWordLists[] = {
 | 
			
		||||
	"Primary keywords and identifiers",
 | 
			
		||||
	"Intrinsic functions",
 | 
			
		||||
	"Extended and user defined functions",
 | 
			
		||||
	0,
 | 
			
		||||
};
 | 
			
		||||
/***************************************/
 | 
			
		||||
static void ColouriseFortranDocFreeFormat(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
        Accessor &styler) {
 | 
			
		||||
	ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false);
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static void ColouriseFortranDocFixFormat(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
        Accessor &styler) {
 | 
			
		||||
	ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true);
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static void FoldFortranDocFreeFormat(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
        WordList *[], Accessor &styler) {
 | 
			
		||||
	FoldFortranDoc(startPos, length, initStyle,styler, false);
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
static void FoldFortranDocFixFormat(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
        WordList *[], Accessor &styler) {
 | 
			
		||||
	FoldFortranDoc(startPos, length, initStyle,styler, true);
 | 
			
		||||
}
 | 
			
		||||
/***************************************/
 | 
			
		||||
extern const LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDocFreeFormat, FortranWordLists);
 | 
			
		||||
extern const LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDocFixFormat, FortranWordLists);
 | 
			
		||||
							
								
								
									
										267
									
								
								3rdparty/lexilla540/lexilla/lexers/LexGAP.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										267
									
								
								3rdparty/lexilla540/lexilla/lexers/LexGAP.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,267 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexGAP.cxx
 | 
			
		||||
 ** Lexer for the GAP language. (The GAP System for Computational Discrete Algebra)
 | 
			
		||||
 ** http://www.gap-system.org
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2007 by Istvan Szollosi ( szteven <at> gmail <dot> com )
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static inline bool IsGAPOperator(char ch) {
 | 
			
		||||
	if (IsASCII(ch) && isalnum(ch)) return false;
 | 
			
		||||
	if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
 | 
			
		||||
		ch == '^' || ch == ',' || ch == '!' || ch == '.' ||
 | 
			
		||||
		ch == '=' || ch == '<' || ch == '>' || ch == '(' ||
 | 
			
		||||
		ch == ')' || ch == ';' || ch == '[' || ch == ']' ||
 | 
			
		||||
		ch == '{' || ch == '}' || ch == ':' )
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void GetRange(Sci_PositionU start, Sci_PositionU end, Accessor &styler, char *s, Sci_PositionU len) {
 | 
			
		||||
	Sci_PositionU i = 0;
 | 
			
		||||
	while ((i < end - start + 1) && (i < len-1)) {
 | 
			
		||||
		s[i] = static_cast<char>(styler[start + i]);
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	s[i] = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseGAPDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &keywords1 = *keywordlists[0];
 | 
			
		||||
	WordList &keywords2 = *keywordlists[1];
 | 
			
		||||
	WordList &keywords3 = *keywordlists[2];
 | 
			
		||||
	WordList &keywords4 = *keywordlists[3];
 | 
			
		||||
 | 
			
		||||
	// Do not leak onto next line
 | 
			
		||||
	if (initStyle == SCE_GAP_STRINGEOL) initStyle = SCE_GAP_DEFAULT;
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
		// Prevent SCE_GAP_STRINGEOL from leaking back to previous line
 | 
			
		||||
		if ( sc.atLineStart ) {
 | 
			
		||||
			if (sc.state == SCE_GAP_STRING) sc.SetState(SCE_GAP_STRING);
 | 
			
		||||
			if (sc.state == SCE_GAP_CHAR) sc.SetState(SCE_GAP_CHAR);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Handle line continuation generically
 | 
			
		||||
		if (sc.ch == '\\' ) {
 | 
			
		||||
			if (sc.chNext == '\n' || sc.chNext == '\r') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				if (sc.ch == '\r' && sc.chNext == '\n') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate
 | 
			
		||||
		switch (sc.state) {
 | 
			
		||||
			case SCE_GAP_OPERATOR :
 | 
			
		||||
				sc.SetState(SCE_GAP_DEFAULT);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_GAP_NUMBER :
 | 
			
		||||
				if (!IsADigit(sc.ch)) {
 | 
			
		||||
					if (sc.ch == '\\') {
 | 
			
		||||
						if (!sc.atLineEnd) {
 | 
			
		||||
							if (!IsADigit(sc.chNext)) {
 | 
			
		||||
								sc.Forward();
 | 
			
		||||
								sc.ChangeState(SCE_GAP_IDENTIFIER);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					} else if (isalpha(sc.ch) || sc.ch == '_') {
 | 
			
		||||
						sc.ChangeState(SCE_GAP_IDENTIFIER);
 | 
			
		||||
					}
 | 
			
		||||
					else sc.SetState(SCE_GAP_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_GAP_IDENTIFIER :
 | 
			
		||||
				if (!(iswordstart(static_cast<char>(sc.ch)) || sc.ch == '$')) {
 | 
			
		||||
					if (sc.ch == '\\') sc.Forward();
 | 
			
		||||
					else {
 | 
			
		||||
						char s[1000];
 | 
			
		||||
						sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
						if (keywords1.InList(s)) {
 | 
			
		||||
							sc.ChangeState(SCE_GAP_KEYWORD);
 | 
			
		||||
						} else if (keywords2.InList(s)) {
 | 
			
		||||
							sc.ChangeState(SCE_GAP_KEYWORD2);
 | 
			
		||||
						} else if (keywords3.InList(s)) {
 | 
			
		||||
							sc.ChangeState(SCE_GAP_KEYWORD3);
 | 
			
		||||
						} else if (keywords4.InList(s)) {
 | 
			
		||||
							sc.ChangeState(SCE_GAP_KEYWORD4);
 | 
			
		||||
						}
 | 
			
		||||
						sc.SetState(SCE_GAP_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_GAP_COMMENT :
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.SetState(SCE_GAP_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_GAP_STRING:
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.ChangeState(SCE_GAP_STRINGEOL);
 | 
			
		||||
				} else if (sc.ch == '\\') {
 | 
			
		||||
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.ch == '\"') {
 | 
			
		||||
					sc.ForwardSetState(SCE_GAP_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_GAP_CHAR:
 | 
			
		||||
				if (sc.atLineEnd) {
 | 
			
		||||
					sc.ChangeState(SCE_GAP_STRINGEOL);
 | 
			
		||||
				} else if (sc.ch == '\\') {
 | 
			
		||||
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.ch == '\'') {
 | 
			
		||||
					sc.ForwardSetState(SCE_GAP_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_GAP_STRINGEOL:
 | 
			
		||||
				if (sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_GAP_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered
 | 
			
		||||
		if (sc.state == SCE_GAP_DEFAULT) {
 | 
			
		||||
			if (IsGAPOperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_GAP_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
			else if (IsADigit(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_GAP_NUMBER);
 | 
			
		||||
			} else if (isalpha(sc.ch) || sc.ch == '_' || sc.ch == '\\' || sc.ch == '$' || sc.ch == '~') {
 | 
			
		||||
				sc.SetState(SCE_GAP_IDENTIFIER);
 | 
			
		||||
				if (sc.ch == '\\') sc.Forward();
 | 
			
		||||
			} else if (sc.ch == '#') {
 | 
			
		||||
				sc.SetState(SCE_GAP_COMMENT);
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_GAP_STRING);
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(SCE_GAP_CHAR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int ClassifyFoldPointGAP(const char* s) {
 | 
			
		||||
	int level = 0;
 | 
			
		||||
	if (strcmp(s, "function") == 0 ||
 | 
			
		||||
		strcmp(s, "do") == 0 ||
 | 
			
		||||
		strcmp(s, "if") == 0 ||
 | 
			
		||||
		strcmp(s, "repeat") == 0 ) {
 | 
			
		||||
		level = 1;
 | 
			
		||||
	} else if (strcmp(s, "end") == 0 ||
 | 
			
		||||
			strcmp(s, "od") == 0 ||
 | 
			
		||||
			strcmp(s, "fi") == 0 ||
 | 
			
		||||
			strcmp(s, "until") == 0 ) {
 | 
			
		||||
		level = -1;
 | 
			
		||||
	}
 | 
			
		||||
	return level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldGAPDoc( Sci_PositionU startPos, Sci_Position length, int initStyle,   WordList** , Accessor &styler) {
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
 | 
			
		||||
	Sci_Position lastStart = 0;
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int stylePrev = style;
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
 | 
			
		||||
		if (stylePrev != SCE_GAP_KEYWORD && style == SCE_GAP_KEYWORD) {
 | 
			
		||||
			// Store last word start point.
 | 
			
		||||
			lastStart = i;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (stylePrev == SCE_GAP_KEYWORD) {
 | 
			
		||||
			if(iswordchar(ch) && !iswordchar(chNext)) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				GetRange(lastStart, i, styler, s, sizeof(s));
 | 
			
		||||
				levelCurrent += ClassifyFoldPointGAP(s);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const GAPWordListDesc[] = {
 | 
			
		||||
	"Keywords 1",
 | 
			
		||||
	"Keywords 2",
 | 
			
		||||
	"Keywords 3 (unused)",
 | 
			
		||||
	"Keywords 4 (unused)",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmGAP(
 | 
			
		||||
   SCLEX_GAP,
 | 
			
		||||
   ColouriseGAPDoc,
 | 
			
		||||
   "gap",
 | 
			
		||||
   FoldGAPDoc,
 | 
			
		||||
   GAPWordListDesc);
 | 
			
		||||
							
								
								
									
										772
									
								
								3rdparty/lexilla540/lexilla/lexers/LexGDScript.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										772
									
								
								3rdparty/lexilla540/lexilla/lexers/LexGDScript.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,772 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexGDScript.cxx
 | 
			
		||||
 ** Lexer for GDScript.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// Heavily modified later for GDScript
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "StringCopy.h"
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "Accessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "CharacterCategory.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "OptionSet.h"
 | 
			
		||||
#include "SubStyles.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
enum kwType { kwOther, kwClass, kwDef, kwExtends};
 | 
			
		||||
 | 
			
		||||
constexpr int indicatorWhitespace = 1;
 | 
			
		||||
 | 
			
		||||
bool IsGDStringStart(int ch) {
 | 
			
		||||
    return (ch == '\'' || ch == '"');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool IsGDComment(Accessor &styler, Sci_Position pos, Sci_Position len) {
 | 
			
		||||
	return len > 0 && styler[pos] == '#';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr bool IsGDSingleQuoteStringState(int st) noexcept {
 | 
			
		||||
	return ((st == SCE_GD_CHARACTER) || (st == SCE_GD_STRING));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr bool IsGDTripleQuoteStringState(int st) noexcept {
 | 
			
		||||
	return ((st == SCE_GD_TRIPLE) || (st == SCE_GD_TRIPLEDOUBLE));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char GetGDStringQuoteChar(int st) noexcept {
 | 
			
		||||
	if ((st == SCE_GD_CHARACTER) || (st == SCE_GD_TRIPLE))
 | 
			
		||||
		return '\'';
 | 
			
		||||
	if ((st == SCE_GD_STRING) || (st == SCE_GD_TRIPLEDOUBLE))
 | 
			
		||||
		return '"';
 | 
			
		||||
 | 
			
		||||
	return '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */
 | 
			
		||||
int GetGDStringState(Accessor &styler, Sci_Position i, Sci_PositionU *nextIndex) {
 | 
			
		||||
	char ch = styler.SafeGetCharAt(i);
 | 
			
		||||
	char chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
	if (ch != '"' && ch != '\'') {
 | 
			
		||||
		*nextIndex = i + 1;
 | 
			
		||||
		return SCE_GD_DEFAULT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) {
 | 
			
		||||
		*nextIndex = i + 3;
 | 
			
		||||
 | 
			
		||||
		if (ch == '"')
 | 
			
		||||
			return SCE_GD_TRIPLEDOUBLE;
 | 
			
		||||
		else
 | 
			
		||||
			return SCE_GD_TRIPLE;
 | 
			
		||||
	} else {
 | 
			
		||||
		*nextIndex = i + 1;
 | 
			
		||||
 | 
			
		||||
		if (ch == '"')
 | 
			
		||||
			return SCE_GD_STRING;
 | 
			
		||||
		else
 | 
			
		||||
			return SCE_GD_CHARACTER;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int GetGDStringState(int ch) {
 | 
			
		||||
	if (ch != '"' && ch != '\'')
 | 
			
		||||
		return SCE_GD_DEFAULT;
 | 
			
		||||
 | 
			
		||||
	if (ch == '"')
 | 
			
		||||
		return SCE_GD_STRING;
 | 
			
		||||
	else
 | 
			
		||||
		return SCE_GD_CHARACTER;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool IsAWordChar(int ch, bool unicodeIdentifiers) {
 | 
			
		||||
	if (IsASCII(ch))
 | 
			
		||||
		return (IsAlphaNumeric(ch) || ch == '.' || ch == '_');
 | 
			
		||||
 | 
			
		||||
	if (!unicodeIdentifiers)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	return IsXidContinue(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool IsANodePathChar(int ch, bool unicodeIdentifiers) {
 | 
			
		||||
	if (IsASCII(ch))
 | 
			
		||||
		return (IsAlphaNumeric(ch) || ch == '_' || ch == '/' || ch =='%');
 | 
			
		||||
 | 
			
		||||
	if (!unicodeIdentifiers)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	return IsXidContinue(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool IsAWordStart(int ch, bool unicodeIdentifiers) {
 | 
			
		||||
	if (IsASCII(ch))
 | 
			
		||||
		return (IsUpperOrLowerCase(ch) || ch == '_');
 | 
			
		||||
 | 
			
		||||
	if (!unicodeIdentifiers)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	return IsXidStart(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool IsFirstNonWhitespace(Sci_Position pos, Accessor &styler) {
 | 
			
		||||
	const Sci_Position line = styler.GetLine(pos);
 | 
			
		||||
	const Sci_Position start_pos = styler.LineStart(line);
 | 
			
		||||
	for (Sci_Position i = start_pos; i < pos; i++) {
 | 
			
		||||
		const char ch = styler[i];
 | 
			
		||||
		if (!(ch == ' ' || ch == '\t'))
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Options used for LexerGDScript
 | 
			
		||||
struct OptionsGDScript {
 | 
			
		||||
	int whingeLevel;
 | 
			
		||||
	bool base2or8Literals;
 | 
			
		||||
	bool stringsOverNewline;
 | 
			
		||||
	bool keywords2NoSubIdentifiers;
 | 
			
		||||
	bool fold;
 | 
			
		||||
	bool foldQuotes;
 | 
			
		||||
	bool foldCompact;
 | 
			
		||||
	bool unicodeIdentifiers;
 | 
			
		||||
 | 
			
		||||
	OptionsGDScript() noexcept {
 | 
			
		||||
		whingeLevel = 0;
 | 
			
		||||
		base2or8Literals = true;
 | 
			
		||||
		stringsOverNewline = false;
 | 
			
		||||
		keywords2NoSubIdentifiers = false;
 | 
			
		||||
		fold = false;
 | 
			
		||||
		foldQuotes = false;
 | 
			
		||||
		foldCompact = false;
 | 
			
		||||
		unicodeIdentifiers = true;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char *const gdscriptWordListDesc[] = {
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	"Highlighted identifiers",
 | 
			
		||||
	nullptr
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct OptionSetGDScript : public OptionSet<OptionsGDScript> {
 | 
			
		||||
	OptionSetGDScript() {
 | 
			
		||||
		DefineProperty("lexer.gdscript.whinge.level", &OptionsGDScript::whingeLevel,
 | 
			
		||||
			       "For GDScript code, checks whether indenting is consistent. "
 | 
			
		||||
			       "The default, 0 turns off indentation checking, "
 | 
			
		||||
			       "1 checks whether each line is potentially inconsistent with the previous line, "
 | 
			
		||||
			       "2 checks whether any space characters occur before a tab character in the indentation, "
 | 
			
		||||
			       "3 checks whether any spaces are in the indentation, and "
 | 
			
		||||
			       "4 checks for any tab characters in the indentation. "
 | 
			
		||||
			       "1 is a good level to use.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("lexer.gdscript.literals.binary", &OptionsGDScript::base2or8Literals,
 | 
			
		||||
			       "Set to 0 to not recognise binary and octal literals: 0b1011 0o712.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("lexer.gdscript.strings.over.newline", &OptionsGDScript::stringsOverNewline,
 | 
			
		||||
			       "Set to 1 to allow strings to span newline characters.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("lexer.gdscript.keywords2.no.sub.identifiers", &OptionsGDScript::keywords2NoSubIdentifiers,
 | 
			
		||||
			       "When enabled, it will not style keywords2 items that are used as a sub-identifier. "
 | 
			
		||||
			       "Example: when set, will not highlight \"foo.open\" when \"open\" is a keywords2 item.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold", &OptionsGDScript::fold);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.gdscript.quotes", &OptionsGDScript::foldQuotes,
 | 
			
		||||
			       "This option enables folding multi-line quoted strings when using the GDScript lexer.");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.compact", &OptionsGDScript::foldCompact);
 | 
			
		||||
 | 
			
		||||
		DefineProperty("lexer.gdscript.unicode.identifiers", &OptionsGDScript::unicodeIdentifiers,
 | 
			
		||||
			       "Set to 0 to not recognise Unicode identifiers.");
 | 
			
		||||
 | 
			
		||||
		DefineWordListSets(gdscriptWordListDesc);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char styleSubable[] = { SCE_GD_IDENTIFIER, 0 };
 | 
			
		||||
 | 
			
		||||
LexicalClass lexicalClasses[] = {
 | 
			
		||||
	// Lexer GDScript SCLEX_GDSCRIPT SCE_GD_:
 | 
			
		||||
	0, "SCE_GD_DEFAULT", "default", "White space",
 | 
			
		||||
	1, "SCE_GD_COMMENTLINE", "comment line", "Comment",
 | 
			
		||||
	2, "SCE_GD_NUMBER", "literal numeric", "Number",
 | 
			
		||||
	3, "SCE_GD_STRING", "literal string", "String",
 | 
			
		||||
	4, "SCE_GD_CHARACTER", "literal string", "Single quoted string",
 | 
			
		||||
	5, "SCE_GD_WORD", "keyword", "Keyword",
 | 
			
		||||
	6, "SCE_GD_TRIPLE", "literal string", "Triple quotes",
 | 
			
		||||
	7, "SCE_GD_TRIPLEDOUBLE", "literal string", "Triple double quotes",
 | 
			
		||||
	8, "SCE_GD_CLASSNAME", "identifier", "Class name definition",
 | 
			
		||||
	9, "SCE_GD_FUNCNAME", "identifier", "Function or method name definition",
 | 
			
		||||
	10, "SCE_GD_OPERATOR", "operator", "Operators",
 | 
			
		||||
	11, "SCE_GD_IDENTIFIER", "identifier", "Identifiers",
 | 
			
		||||
	12, "SCE_GD_COMMENTBLOCK", "comment", "Comment-blocks",
 | 
			
		||||
	13, "SCE_GD_STRINGEOL", "error literal string", "End of line where string is not closed",
 | 
			
		||||
	14, "SCE_GD_WORD2", "identifier", "Highlighted identifiers",
 | 
			
		||||
	15, "SCE_GD_ANNOTATION", "annotation", "Annotations",
 | 
			
		||||
	16, "SCE_GD_NODEPATH", "path", "Node path",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class LexerGDScript : public DefaultLexer {
 | 
			
		||||
	WordList keywords;
 | 
			
		||||
	WordList keywords2;
 | 
			
		||||
	OptionsGDScript options;
 | 
			
		||||
	OptionSetGDScript osGDScript;
 | 
			
		||||
	enum { ssIdentifier };
 | 
			
		||||
	SubStyles subStyles{styleSubable};
 | 
			
		||||
public:
 | 
			
		||||
	explicit LexerGDScript() :
 | 
			
		||||
		DefaultLexer("gdscript", SCLEX_GDSCRIPT, lexicalClasses, ELEMENTS(lexicalClasses)) {
 | 
			
		||||
	}
 | 
			
		||||
	~LexerGDScript() override {
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD Release() override {
 | 
			
		||||
		delete this;
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD Version() const override {
 | 
			
		||||
		return lvRelease5;
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD PropertyNames() override {
 | 
			
		||||
		return osGDScript.PropertyNames();
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD PropertyType(const char *name) override {
 | 
			
		||||
		return osGDScript.PropertyType(name);
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD DescribeProperty(const char *name) override {
 | 
			
		||||
		return osGDScript.DescribeProperty(name);
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
 | 
			
		||||
	const char * SCI_METHOD PropertyGet(const char *key) override {
 | 
			
		||||
		return osGDScript.PropertyGet(key);
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD DescribeWordListSets() override {
 | 
			
		||||
		return osGDScript.DescribeWordListSets();
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
 | 
			
		||||
	void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
	void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
 | 
			
		||||
	void *SCI_METHOD PrivateCall(int, void *) override {
 | 
			
		||||
		return nullptr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int SCI_METHOD LineEndTypesSupported() override {
 | 
			
		||||
		return SC_LINE_END_TYPE_UNICODE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {
 | 
			
		||||
		return subStyles.Allocate(styleBase, numberStyles);
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD SubStylesStart(int styleBase) override {
 | 
			
		||||
		return subStyles.Start(styleBase);
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD SubStylesLength(int styleBase) override {
 | 
			
		||||
		return subStyles.Length(styleBase);
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD StyleFromSubStyle(int subStyle) override {
 | 
			
		||||
		const int styleBase = subStyles.BaseStyle(subStyle);
 | 
			
		||||
		return styleBase;
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD PrimaryStyleFromStyle(int style) override {
 | 
			
		||||
		return style;
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD FreeSubStyles() override {
 | 
			
		||||
		subStyles.Free();
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {
 | 
			
		||||
		subStyles.SetIdentifiers(style, identifiers);
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD DistanceToSecondaryStyles() override {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD GetSubStyleBases() override {
 | 
			
		||||
		return styleSubable;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static ILexer5 *LexerFactoryGDScript() {
 | 
			
		||||
		return new LexerGDScript();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void ProcessLineEnd(StyleContext &sc, bool &inContinuedString);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerGDScript::PropertySet(const char *key, const char *val) {
 | 
			
		||||
	if (osGDScript.PropertySet(&options, key, val)) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerGDScript::WordListSet(int n, const char *wl) {
 | 
			
		||||
	WordList *wordListN = nullptr;
 | 
			
		||||
	switch (n) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		wordListN = &keywords;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		wordListN = &keywords2;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position firstModification = -1;
 | 
			
		||||
	if (wordListN) {
 | 
			
		||||
		WordList wlNew;
 | 
			
		||||
		wlNew.Set(wl);
 | 
			
		||||
		if (*wordListN != wlNew) {
 | 
			
		||||
			wordListN->Set(wl);
 | 
			
		||||
			firstModification = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return firstModification;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LexerGDScript::ProcessLineEnd(StyleContext &sc, bool &inContinuedString) {
 | 
			
		||||
	if ((sc.state == SCE_GD_DEFAULT)
 | 
			
		||||
			|| IsGDTripleQuoteStringState(sc.state)) {
 | 
			
		||||
		// Perform colourisation of white space and triple quoted strings at end of each line to allow
 | 
			
		||||
		// tab marking to work inside white space and triple quoted strings
 | 
			
		||||
		sc.SetState(sc.state);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (IsGDSingleQuoteStringState(sc.state)) {
 | 
			
		||||
		if (inContinuedString || options.stringsOverNewline) {
 | 
			
		||||
			inContinuedString = false;
 | 
			
		||||
		} else {
 | 
			
		||||
			sc.ChangeState(SCE_GD_STRINGEOL);
 | 
			
		||||
			sc.ForwardSetState(SCE_GD_DEFAULT);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerGDScript::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
	Accessor styler(pAccess, nullptr);
 | 
			
		||||
 | 
			
		||||
	const Sci_Position endPos = startPos + length;
 | 
			
		||||
 | 
			
		||||
	// Backtrack to previous line in case need to fix its tab whinging
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	if (startPos > 0) {
 | 
			
		||||
		if (lineCurrent > 0) {
 | 
			
		||||
			lineCurrent--;
 | 
			
		||||
			// Look for backslash-continued lines
 | 
			
		||||
			while (lineCurrent > 0) {
 | 
			
		||||
				const Sci_Position eolPos = styler.LineStart(lineCurrent) - 1;
 | 
			
		||||
				const int eolStyle = styler.StyleAt(eolPos);
 | 
			
		||||
				if (eolStyle == SCE_GD_STRING || eolStyle == SCE_GD_CHARACTER
 | 
			
		||||
						|| eolStyle == SCE_GD_STRINGEOL) {
 | 
			
		||||
					lineCurrent -= 1;
 | 
			
		||||
				} else {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			startPos = styler.LineStart(lineCurrent);
 | 
			
		||||
		}
 | 
			
		||||
		initStyle = startPos == 0 ? SCE_GD_DEFAULT : styler.StyleAt(startPos - 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initStyle = initStyle & 31;
 | 
			
		||||
	if (initStyle == SCE_GD_STRINGEOL) {
 | 
			
		||||
		initStyle = SCE_GD_DEFAULT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	kwType kwLast = kwOther;
 | 
			
		||||
	int spaceFlags = 0;
 | 
			
		||||
	styler.IndentAmount(lineCurrent, &spaceFlags, IsGDComment);
 | 
			
		||||
	bool base_n_number = false;
 | 
			
		||||
 | 
			
		||||
	const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_GD_IDENTIFIER);
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, endPos - startPos, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	bool indentGood = true;
 | 
			
		||||
	Sci_Position startIndicator = sc.currentPos;
 | 
			
		||||
	bool inContinuedString = false;
 | 
			
		||||
	bool percentIsNodePath = false;
 | 
			
		||||
	int nodePathStringState = SCE_GD_DEFAULT;
 | 
			
		||||
	
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
		if (sc.atLineStart) {
 | 
			
		||||
			styler.IndentAmount(lineCurrent, &spaceFlags, IsGDComment);
 | 
			
		||||
			indentGood = true;
 | 
			
		||||
			if (options.whingeLevel == 1) {
 | 
			
		||||
				indentGood = (spaceFlags & wsInconsistent) == 0;
 | 
			
		||||
			} else if (options.whingeLevel == 2) {
 | 
			
		||||
				indentGood = (spaceFlags & wsSpaceTab) == 0;
 | 
			
		||||
			} else if (options.whingeLevel == 3) {
 | 
			
		||||
				indentGood = (spaceFlags & wsSpace) == 0;
 | 
			
		||||
			} else if (options.whingeLevel == 4) {
 | 
			
		||||
				indentGood = (spaceFlags & wsTab) == 0;
 | 
			
		||||
			}
 | 
			
		||||
			if (!indentGood) {
 | 
			
		||||
				styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
 | 
			
		||||
				startIndicator = sc.currentPos;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.atLineEnd) {
 | 
			
		||||
			percentIsNodePath = false;
 | 
			
		||||
			ProcessLineEnd(sc, inContinuedString);
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			if (!sc.More())
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool needEOLCheck = false;
 | 
			
		||||
 | 
			
		||||
		if (sc.state == SCE_GD_OPERATOR) {
 | 
			
		||||
			kwLast = kwOther;
 | 
			
		||||
			sc.SetState(SCE_GD_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_GD_NUMBER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch, false) &&
 | 
			
		||||
					!(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
 | 
			
		||||
				sc.SetState(SCE_GD_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_GD_IDENTIFIER) {
 | 
			
		||||
			if ((sc.ch == '.') || (!IsAWordChar(sc.ch, options.unicodeIdentifiers))) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
				int style = SCE_GD_IDENTIFIER;
 | 
			
		||||
				if (keywords.InList(s)) {
 | 
			
		||||
					style = SCE_GD_WORD;
 | 
			
		||||
				} else if (kwLast == kwClass) {
 | 
			
		||||
					style = SCE_GD_CLASSNAME;
 | 
			
		||||
				} else if (kwLast == kwDef) {
 | 
			
		||||
					style = SCE_GD_FUNCNAME;
 | 
			
		||||
				} else if (keywords2.InList(s)) {
 | 
			
		||||
					if (options.keywords2NoSubIdentifiers) {
 | 
			
		||||
						// We don't want to highlight keywords2
 | 
			
		||||
						// that are used as a sub-identifier,
 | 
			
		||||
						// i.e. not open in "foo.open".
 | 
			
		||||
						const Sci_Position pos = styler.GetStartSegment() - 1;
 | 
			
		||||
						if (pos < 0 || (styler.SafeGetCharAt(pos, '\0') != '.'))
 | 
			
		||||
							style = SCE_GD_WORD2;
 | 
			
		||||
					} else {
 | 
			
		||||
						style = SCE_GD_WORD2;
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					const int subStyle = classifierIdentifiers.ValueFor(s);
 | 
			
		||||
					if (subStyle >= 0) {
 | 
			
		||||
						style = subStyle;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				sc.ChangeState(style);
 | 
			
		||||
				sc.SetState(SCE_GD_DEFAULT);
 | 
			
		||||
				if (style == SCE_GD_WORD) {
 | 
			
		||||
					if (0 == strcmp(s, "class"))
 | 
			
		||||
						kwLast = kwClass;
 | 
			
		||||
					else if (0 == strcmp(s, "func"))
 | 
			
		||||
						kwLast = kwDef;
 | 
			
		||||
					else if (0 == strcmp(s, "extends"))
 | 
			
		||||
						kwLast = kwExtends;
 | 
			
		||||
					else
 | 
			
		||||
						kwLast = kwOther;
 | 
			
		||||
				} else {
 | 
			
		||||
					kwLast = kwOther;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if ((sc.state == SCE_GD_COMMENTLINE) || (sc.state == SCE_GD_COMMENTBLOCK)) {
 | 
			
		||||
			if (sc.ch == '\r' || sc.ch == '\n') {
 | 
			
		||||
				sc.SetState(SCE_GD_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_GD_ANNOTATION) {
 | 
			
		||||
			if (!IsAWordStart(sc.ch, options.unicodeIdentifiers)) {
 | 
			
		||||
				sc.SetState(SCE_GD_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_GD_NODEPATH) {
 | 
			
		||||
			if (nodePathStringState != SCE_GD_DEFAULT) {
 | 
			
		||||
				if (sc.ch == GetGDStringQuoteChar(nodePathStringState) ) {
 | 
			
		||||
					nodePathStringState = SCE_GD_DEFAULT;
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if (IsGDStringStart(sc.ch)) {
 | 
			
		||||
					nodePathStringState = GetGDStringState(sc.ch);
 | 
			
		||||
				} else if (!IsANodePathChar(sc.ch, options.unicodeIdentifiers)) {
 | 
			
		||||
					sc.SetState(SCE_GD_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (IsGDSingleQuoteStringState(sc.state)) {
 | 
			
		||||
			if (sc.ch == '\\') {
 | 
			
		||||
				if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				if (sc.chNext == '\n' || sc.chNext == '\r') {
 | 
			
		||||
					inContinuedString = true;
 | 
			
		||||
				} else {
 | 
			
		||||
					// Don't roll over the newline.
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.ch == GetGDStringQuoteChar(sc.state)) {
 | 
			
		||||
				sc.ForwardSetState(SCE_GD_DEFAULT);
 | 
			
		||||
				needEOLCheck = true;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_GD_TRIPLE) {
 | 
			
		||||
			if (sc.ch == '\\') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.Match(R"(''')")) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.ForwardSetState(SCE_GD_DEFAULT);
 | 
			
		||||
				needEOLCheck = true;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_GD_TRIPLEDOUBLE) {
 | 
			
		||||
			if (sc.ch == '\\') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.Match(R"(""")")) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.ForwardSetState(SCE_GD_DEFAULT);
 | 
			
		||||
				needEOLCheck = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!indentGood && !IsASpaceOrTab(sc.ch)) {
 | 
			
		||||
			styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 1);
 | 
			
		||||
			startIndicator = sc.currentPos;
 | 
			
		||||
			indentGood = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// State exit code may have moved on to end of line
 | 
			
		||||
		if (needEOLCheck && sc.atLineEnd) {
 | 
			
		||||
			ProcessLineEnd(sc, inContinuedString);
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			styler.IndentAmount(lineCurrent, &spaceFlags, IsGDComment);
 | 
			
		||||
			if (!sc.More())
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Check for a new state starting character
 | 
			
		||||
		if (sc.state == SCE_GD_DEFAULT) {
 | 
			
		||||
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) {
 | 
			
		||||
					base_n_number = true;
 | 
			
		||||
					sc.SetState(SCE_GD_NUMBER);
 | 
			
		||||
				} else if (sc.ch == '0' &&
 | 
			
		||||
						(sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {
 | 
			
		||||
					if (options.base2or8Literals) {
 | 
			
		||||
						base_n_number = true;
 | 
			
		||||
						sc.SetState(SCE_GD_NUMBER);
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.SetState(SCE_GD_NUMBER);
 | 
			
		||||
						sc.ForwardSetState(SCE_GD_IDENTIFIER);
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					base_n_number = false;
 | 
			
		||||
					sc.SetState(SCE_GD_NUMBER);
 | 
			
		||||
				}
 | 
			
		||||
			} else if ((sc.ch == '$') || (sc.ch == '%' && (percentIsNodePath || IsFirstNonWhitespace(sc.currentPos, styler)))) {
 | 
			
		||||
				percentIsNodePath = false;
 | 
			
		||||
				sc.SetState(SCE_GD_NODEPATH);
 | 
			
		||||
			} else if (isoperator(sc.ch) || sc.ch == '`') {
 | 
			
		||||
				percentIsNodePath = !((sc.ch == ')') || (sc.ch == ']') || (sc.ch == '}'));
 | 
			
		||||
				sc.SetState(SCE_GD_OPERATOR);
 | 
			
		||||
			} else if (sc.ch == '#') {
 | 
			
		||||
				sc.SetState(sc.chNext == '#' ? SCE_GD_COMMENTBLOCK : SCE_GD_COMMENTLINE);
 | 
			
		||||
			} else if (sc.ch == '@') {
 | 
			
		||||
				if (IsFirstNonWhitespace(sc.currentPos, styler))
 | 
			
		||||
					sc.SetState(SCE_GD_ANNOTATION);
 | 
			
		||||
				else
 | 
			
		||||
					sc.SetState(SCE_GD_OPERATOR);
 | 
			
		||||
			} else if (IsGDStringStart(sc.ch)) {
 | 
			
		||||
				Sci_PositionU nextIndex = 0;
 | 
			
		||||
				sc.SetState(GetGDStringState(styler, sc.currentPos, &nextIndex));
 | 
			
		||||
				while (nextIndex > (sc.currentPos + 1) && sc.More()) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
            } else if (IsAWordStart(sc.ch, options.unicodeIdentifiers)) {
 | 
			
		||||
				sc.SetState(SCE_GD_IDENTIFIER);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsCommentLine(Sci_Position line, Accessor &styler) {
 | 
			
		||||
	const Sci_Position pos = styler.LineStart(line);
 | 
			
		||||
	const Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
	for (Sci_Position i = pos; i < eol_pos; i++) {
 | 
			
		||||
		const char ch = styler[i];
 | 
			
		||||
		if (ch == '#')
 | 
			
		||||
			return true;
 | 
			
		||||
		else if (ch != ' ' && ch != '\t')
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsQuoteLine(Sci_Position line, const Accessor &styler) {
 | 
			
		||||
	const int style = styler.StyleAt(styler.LineStart(line)) & 31;
 | 
			
		||||
	return IsGDTripleQuoteStringState(style);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerGDScript::Fold(Sci_PositionU startPos, Sci_Position length, int /*initStyle - unused*/, IDocument *pAccess) {
 | 
			
		||||
	if (!options.fold)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	Accessor styler(pAccess, nullptr);
 | 
			
		||||
 | 
			
		||||
	const Sci_Position maxPos = startPos + length;
 | 
			
		||||
	const Sci_Position maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1);	// Requested last line
 | 
			
		||||
	const Sci_Position docLines = styler.GetLine(styler.Length());	// Available last line
 | 
			
		||||
 | 
			
		||||
	// Backtrack to previous non-blank line so we can determine indent level
 | 
			
		||||
	// for any white space lines (needed esp. within triple quoted strings)
 | 
			
		||||
	// and so we can fix any preceding fold level (which is why we go back
 | 
			
		||||
	// at least one line in all cases)
 | 
			
		||||
	int spaceFlags = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr);
 | 
			
		||||
	while (lineCurrent > 0) {
 | 
			
		||||
		lineCurrent--;
 | 
			
		||||
		indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr);
 | 
			
		||||
		if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&
 | 
			
		||||
				(!IsCommentLine(lineCurrent, styler)) &&
 | 
			
		||||
				(!IsQuoteLine(lineCurrent, styler)))
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
 | 
			
		||||
	// Set up initial loop state
 | 
			
		||||
	startPos = styler.LineStart(lineCurrent);
 | 
			
		||||
	int prev_state = SCE_GD_DEFAULT & 31;
 | 
			
		||||
	if (lineCurrent >= 1)
 | 
			
		||||
		prev_state = styler.StyleAt(startPos - 1) & 31;
 | 
			
		||||
	int prevQuote = options.foldQuotes && IsGDTripleQuoteStringState(prev_state);
 | 
			
		||||
 | 
			
		||||
	// Process all characters to end of requested range or end of any triple quote
 | 
			
		||||
	//that hangs over the end of the range.  Cap processing in all cases
 | 
			
		||||
	// to end of document (in case of unclosed quote at end).
 | 
			
		||||
	while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote)) {
 | 
			
		||||
 | 
			
		||||
		// Gather info
 | 
			
		||||
		int lev = indentCurrent;
 | 
			
		||||
		Sci_Position lineNext = lineCurrent + 1;
 | 
			
		||||
		int indentNext = indentCurrent;
 | 
			
		||||
		int quote = false;
 | 
			
		||||
		if (lineNext <= docLines) {
 | 
			
		||||
			// Information about next line is only available if not at end of document
 | 
			
		||||
			indentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr);
 | 
			
		||||
			const Sci_Position lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext);
 | 
			
		||||
			const int style = styler.StyleAt(lookAtPos) & 31;
 | 
			
		||||
			quote = options.foldQuotes && IsGDTripleQuoteStringState(style);
 | 
			
		||||
		}
 | 
			
		||||
		const bool quote_start = (quote && !prevQuote);
 | 
			
		||||
		const bool quote_continue = (quote && prevQuote);
 | 
			
		||||
		if (!quote || !prevQuote)
 | 
			
		||||
			indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
		if (quote)
 | 
			
		||||
			indentNext = indentCurrentLevel;
 | 
			
		||||
		if (indentNext & SC_FOLDLEVELWHITEFLAG)
 | 
			
		||||
			indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
 | 
			
		||||
 | 
			
		||||
		if (quote_start) {
 | 
			
		||||
			// Place fold point at start of triple quoted string
 | 
			
		||||
			lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		} else if (quote_continue || prevQuote) {
 | 
			
		||||
			// Add level to rest of lines in the string
 | 
			
		||||
			lev = lev + 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Skip past any blank lines for next indent level info; we skip also
 | 
			
		||||
		// comments (all comments, not just those starting in column 0)
 | 
			
		||||
		// which effectively folds them into surrounding code rather
 | 
			
		||||
		// than screwing up folding.  If comments end file, use the min
 | 
			
		||||
		// comment indent as the level after
 | 
			
		||||
 | 
			
		||||
		int minCommentLevel = indentCurrentLevel;
 | 
			
		||||
		while (!quote &&
 | 
			
		||||
				(lineNext < docLines) &&
 | 
			
		||||
				((indentNext & SC_FOLDLEVELWHITEFLAG) || (IsCommentLine(lineNext, styler)))) {
 | 
			
		||||
 | 
			
		||||
			if (IsCommentLine(lineNext, styler) && indentNext < minCommentLevel) {
 | 
			
		||||
				minCommentLevel = indentNext;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			lineNext++;
 | 
			
		||||
			indentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const int levelAfterComments = ((lineNext < docLines) ? indentNext & SC_FOLDLEVELNUMBERMASK : minCommentLevel);
 | 
			
		||||
		const int levelBeforeComments = std::max(indentCurrentLevel, levelAfterComments);
 | 
			
		||||
 | 
			
		||||
		// Now set all the indent levels on the lines we skipped
 | 
			
		||||
		// Do this from end to start.  Once we encounter one line
 | 
			
		||||
		// which is indented more than the line after the end of
 | 
			
		||||
		// the comment-block, use the level of the block before
 | 
			
		||||
 | 
			
		||||
		Sci_Position skipLine = lineNext;
 | 
			
		||||
		int skipLevel = levelAfterComments;
 | 
			
		||||
 | 
			
		||||
		while (--skipLine > lineCurrent) {
 | 
			
		||||
			const int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, nullptr);
 | 
			
		||||
 | 
			
		||||
			if (options.foldCompact) {
 | 
			
		||||
				if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
 | 
			
		||||
					skipLevel = levelBeforeComments;
 | 
			
		||||
 | 
			
		||||
				const int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
 | 
			
		||||
				styler.SetLevel(skipLine, skipLevel | whiteFlag);
 | 
			
		||||
			} else {
 | 
			
		||||
				if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&
 | 
			
		||||
						!(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
 | 
			
		||||
						!IsCommentLine(skipLine, styler))
 | 
			
		||||
					skipLevel = levelBeforeComments;
 | 
			
		||||
 | 
			
		||||
				styler.SetLevel(skipLine, skipLevel);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Set fold header on non-quote line
 | 
			
		||||
		if (!quote && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
 | 
			
		||||
			if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Keep track of triple quote state of previous line
 | 
			
		||||
		prevQuote = quote;
 | 
			
		||||
 | 
			
		||||
		// Set fold level for this line and move to next line
 | 
			
		||||
		styler.SetLevel(lineCurrent, options.foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);
 | 
			
		||||
		indentCurrent = indentNext;
 | 
			
		||||
		lineCurrent = lineNext;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// NOTE: Cannot set level of last line here because indentCurrent doesn't have
 | 
			
		||||
	// header flag set; the loop above is crafted to take care of this case!
 | 
			
		||||
	//styler.SetLevel(lineCurrent, indentCurrent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmGDScript(SCLEX_GDSCRIPT, LexerGDScript::LexerFactoryGDScript, "gdscript",
 | 
			
		||||
		     gdscriptWordListDesc);
 | 
			
		||||
							
								
								
									
										315
									
								
								3rdparty/lexilla540/lexilla/lexers/LexGui4Cli.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								3rdparty/lexilla540/lexilla/lexers/LexGui4Cli.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,315 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// @file LexGui4Cli.cxx
 | 
			
		||||
/*
 | 
			
		||||
This is the Lexer for Gui4Cli, included in SciLexer.dll
 | 
			
		||||
- by d. Keletsekis, 2/10/2003
 | 
			
		||||
 | 
			
		||||
To add to SciLexer.dll:
 | 
			
		||||
1. Add the values below to INCLUDE\Scintilla.iface
 | 
			
		||||
2. Run the scripts/HFacer.py script
 | 
			
		||||
3. Run the scripts/LexGen.py script
 | 
			
		||||
 | 
			
		||||
val SCE_GC_DEFAULT=0
 | 
			
		||||
val SCE_GC_COMMENTLINE=1
 | 
			
		||||
val SCE_GC_COMMENTBLOCK=2
 | 
			
		||||
val SCE_GC_GLOBAL=3
 | 
			
		||||
val SCE_GC_EVENT=4
 | 
			
		||||
val SCE_GC_ATTRIBUTE=5
 | 
			
		||||
val SCE_GC_CONTROL=6
 | 
			
		||||
val SCE_GC_COMMAND=7
 | 
			
		||||
val SCE_GC_STRING=8
 | 
			
		||||
val SCE_GC_OPERATOR=9
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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;
 | 
			
		||||
 | 
			
		||||
#define debug Platform::DebugPrintf
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch =='\\');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool isGCOperator(int ch)
 | 
			
		||||
{	if (isalnum(ch))
 | 
			
		||||
		return false;
 | 
			
		||||
	// '.' left out as it is used to make up numbers
 | 
			
		||||
	if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
 | 
			
		||||
		 ch == '(' || ch == ')' || ch == '=' || ch == '%' ||
 | 
			
		||||
		 ch == '[' || ch == ']' || ch == '<' || ch == '>' ||
 | 
			
		||||
		 ch == ',' || ch == ';' || ch == ':')
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define isSpace(x)		((x)==' ' || (x)=='\t')
 | 
			
		||||
#define isNL(x)			((x)=='\n' || (x)=='\r')
 | 
			
		||||
#define isSpaceOrNL(x)  (isSpace(x) || isNL(x))
 | 
			
		||||
#define BUFFSIZE 500
 | 
			
		||||
#define isFoldPoint(x)  ((styler.LevelAt(x) & SC_FOLDLEVELNUMBERMASK) == 1024)
 | 
			
		||||
 | 
			
		||||
static void colorFirstWord(WordList *keywordlists[], Accessor &styler,
 | 
			
		||||
									StyleContext *sc, char *buff, Sci_Position length, Sci_Position)
 | 
			
		||||
{
 | 
			
		||||
	Sci_Position c = 0;
 | 
			
		||||
	while (sc->More() && isSpaceOrNL(sc->ch))
 | 
			
		||||
	{	sc->Forward();
 | 
			
		||||
	}
 | 
			
		||||
	styler.ColourTo(sc->currentPos - 1, sc->state);
 | 
			
		||||
 | 
			
		||||
	if (!IsAWordChar(sc->ch)) // comment, marker, etc..
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	while (sc->More() && !isSpaceOrNL(sc->ch) && (c < length-1) && !isGCOperator(sc->ch))
 | 
			
		||||
	{	buff[c] = static_cast<char>(sc->ch);
 | 
			
		||||
		++c; sc->Forward();
 | 
			
		||||
	}
 | 
			
		||||
	buff[c] = '\0';
 | 
			
		||||
	char *p = buff;
 | 
			
		||||
	while (*p)	// capitalize..
 | 
			
		||||
	{	if (islower(*p)) *p = static_cast<char>(toupper(*p));
 | 
			
		||||
		++p;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	WordList &kGlobal		= *keywordlists[0];	// keyword lists set by the user
 | 
			
		||||
	WordList &kEvent		= *keywordlists[1];
 | 
			
		||||
	WordList &kAttribute	= *keywordlists[2];
 | 
			
		||||
	WordList &kControl	= *keywordlists[3];
 | 
			
		||||
	WordList &kCommand	= *keywordlists[4];
 | 
			
		||||
 | 
			
		||||
	int state = 0;
 | 
			
		||||
	// int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	// debug ("line = %d, level = %d", line, level);
 | 
			
		||||
 | 
			
		||||
	if	     (kGlobal.InList(buff))		state = SCE_GC_GLOBAL;
 | 
			
		||||
	else if (kAttribute.InList(buff))	state = SCE_GC_ATTRIBUTE;
 | 
			
		||||
	else if (kControl.InList(buff))		state = SCE_GC_CONTROL;
 | 
			
		||||
	else if (kCommand.InList(buff))		state = SCE_GC_COMMAND;
 | 
			
		||||
	else if (kEvent.InList(buff))			state = SCE_GC_EVENT;
 | 
			
		||||
 | 
			
		||||
	if (state)
 | 
			
		||||
	{	sc->ChangeState(state);
 | 
			
		||||
		styler.ColourTo(sc->currentPos - 1, sc->state);
 | 
			
		||||
		sc->ChangeState(SCE_GC_DEFAULT);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{	sc->ChangeState(SCE_GC_DEFAULT);
 | 
			
		||||
		styler.ColourTo(sc->currentPos - 1, sc->state);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Main colorizing function called by Scintilla
 | 
			
		||||
static void
 | 
			
		||||
ColouriseGui4CliDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                    WordList *keywordlists[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
 | 
			
		||||
	Sci_Position currentline = styler.GetLine(startPos);
 | 
			
		||||
	int quotestart = 0, oldstate;
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
	bool noforward;
 | 
			
		||||
	char buff[BUFFSIZE+1];	// buffer for command name
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
	buff[0] = '\0'; // cbuff = 0;
 | 
			
		||||
 | 
			
		||||
	if (sc.state != SCE_GC_COMMENTBLOCK) // colorize 1st word..
 | 
			
		||||
		colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
 | 
			
		||||
 | 
			
		||||
	while (sc.More())
 | 
			
		||||
	{	noforward = 0;
 | 
			
		||||
 | 
			
		||||
		switch (sc.ch)
 | 
			
		||||
		{
 | 
			
		||||
			case '/':
 | 
			
		||||
				if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_STRING)
 | 
			
		||||
					break;
 | 
			
		||||
				if (sc.chNext == '/')	// line comment
 | 
			
		||||
				{	sc.SetState (SCE_GC_COMMENTLINE);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					styler.ColourTo(sc.currentPos, sc.state);
 | 
			
		||||
				}
 | 
			
		||||
				else if (sc.chNext == '*')	// block comment
 | 
			
		||||
				{	sc.SetState(SCE_GC_COMMENTBLOCK);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					styler.ColourTo(sc.currentPos, sc.state);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
					styler.ColourTo(sc.currentPos, sc.state);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case '*':	// end of comment block, or operator..
 | 
			
		||||
				if (sc.state == SCE_GC_STRING)
 | 
			
		||||
					break;
 | 
			
		||||
				if (sc.state == SCE_GC_COMMENTBLOCK && sc.chNext == '/')
 | 
			
		||||
				{	sc.Forward();
 | 
			
		||||
					styler.ColourTo(sc.currentPos, sc.state);
 | 
			
		||||
					sc.ChangeState (SCE_GC_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
					styler.ColourTo(sc.currentPos, sc.state);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case '\'':	case '\"': // strings..
 | 
			
		||||
				if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_COMMENTLINE)
 | 
			
		||||
					break;
 | 
			
		||||
				if (sc.state == SCE_GC_STRING)
 | 
			
		||||
				{	if (sc.ch == quotestart)	// match same quote char..
 | 
			
		||||
					{	styler.ColourTo(sc.currentPos, sc.state);
 | 
			
		||||
						sc.ChangeState(SCE_GC_DEFAULT);
 | 
			
		||||
						quotestart = 0;
 | 
			
		||||
				}	}
 | 
			
		||||
				else
 | 
			
		||||
				{	styler.ColourTo(sc.currentPos - 1, sc.state);
 | 
			
		||||
					sc.ChangeState(SCE_GC_STRING);
 | 
			
		||||
					quotestart = sc.ch;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case ';':	// end of commandline character
 | 
			
		||||
				if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
 | 
			
		||||
					 sc.state != SCE_GC_STRING)
 | 
			
		||||
				{
 | 
			
		||||
					styler.ColourTo(sc.currentPos - 1, sc.state);
 | 
			
		||||
					styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
 | 
			
		||||
					sc.ChangeState(SCE_GC_DEFAULT);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
 | 
			
		||||
					noforward = 1; // don't move forward - already positioned at next char..
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case '+': case '-': case '=':	case '!':	// operators..
 | 
			
		||||
			case '<': case '>': case '&': case '|': case '$':
 | 
			
		||||
				if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
 | 
			
		||||
					 sc.state != SCE_GC_STRING)
 | 
			
		||||
				{
 | 
			
		||||
					styler.ColourTo(sc.currentPos - 1, sc.state);
 | 
			
		||||
					styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
 | 
			
		||||
					sc.ChangeState(SCE_GC_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case '\\':	// escape - same as operator, but also mark in strings..
 | 
			
		||||
				if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE)
 | 
			
		||||
				{
 | 
			
		||||
					oldstate = sc.state;
 | 
			
		||||
					styler.ColourTo(sc.currentPos - 1, sc.state);
 | 
			
		||||
					sc.Forward(); // mark also the next char..
 | 
			
		||||
					styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
 | 
			
		||||
					sc.ChangeState(oldstate);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case '\n': case '\r':
 | 
			
		||||
				++currentline;
 | 
			
		||||
				if (sc.state == SCE_GC_COMMENTLINE)
 | 
			
		||||
				{	styler.ColourTo(sc.currentPos, sc.state);
 | 
			
		||||
					sc.ChangeState (SCE_GC_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				else if (sc.state != SCE_GC_COMMENTBLOCK)
 | 
			
		||||
				{	colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
 | 
			
		||||
					noforward = 1; // don't move forward - already positioned at next char..
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
//			case ' ': case '\t':
 | 
			
		||||
//			default :
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!noforward) sc.Forward();
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Main folding function called by Scintilla - (based on props (.ini) files function)
 | 
			
		||||
static void FoldGui4Cli(Sci_PositionU startPos, Sci_Position length, int,
 | 
			
		||||
								WordList *[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	bool headerPoint = false;
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++)
 | 
			
		||||
	{
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler[i+1];
 | 
			
		||||
 | 
			
		||||
		int style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
 | 
			
		||||
		if (style == SCE_GC_EVENT || style == SCE_GC_GLOBAL)
 | 
			
		||||
		{	headerPoint = true; // fold at events and globals
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atEOL)
 | 
			
		||||
		{	int lev = SC_FOLDLEVELBASE+1;
 | 
			
		||||
 | 
			
		||||
			if (headerPoint)
 | 
			
		||||
				lev = SC_FOLDLEVELBASE;
 | 
			
		||||
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
 | 
			
		||||
			if (headerPoint)
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) // set level, if not already correct
 | 
			
		||||
			{	styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			lineCurrent++;		// re-initialize our flags
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
			headerPoint = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!(isspacechar(ch))) // || (style == SCE_GC_COMMENTLINE) || (style != SCE_GC_COMMENTBLOCK)))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int lev = headerPoint ? SC_FOLDLEVELBASE : SC_FOLDLEVELBASE+1;
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, lev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// I have no idea what these are for.. probably accessible by some message.
 | 
			
		||||
static const char * const gui4cliWordListDesc[] = {
 | 
			
		||||
	"Globals", "Events", "Attributes", "Control", "Commands",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Declare language & pass our function pointers to Scintilla
 | 
			
		||||
extern const LexerModule lmGui4Cli(SCLEX_GUI4CLI, ColouriseGui4CliDoc, "gui4cli", FoldGui4Cli, gui4cliWordListDesc);
 | 
			
		||||
 | 
			
		||||
#undef debug
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2763
									
								
								3rdparty/lexilla540/lexilla/lexers/LexHTML.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2763
									
								
								3rdparty/lexilla540/lexilla/lexers/LexHTML.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1119
									
								
								3rdparty/lexilla540/lexilla/lexers/LexHaskell.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1119
									
								
								3rdparty/lexilla540/lexilla/lexers/LexHaskell.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1048
									
								
								3rdparty/lexilla540/lexilla/lexers/LexHex.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1048
									
								
								3rdparty/lexilla540/lexilla/lexers/LexHex.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										519
									
								
								3rdparty/lexilla540/lexilla/lexers/LexHollywood.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										519
									
								
								3rdparty/lexilla540/lexilla/lexers/LexHollywood.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,519 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexHollywood.cxx
 | 
			
		||||
 ** Lexer for Hollywood
 | 
			
		||||
 ** Written by Andreas Falkenhahn, based on the BlitzBasic/PureBasic/Lua lexers
 | 
			
		||||
 ** Thanks to Nicholai Benalal
 | 
			
		||||
 ** For more information on Hollywood, see http://www.hollywood-mal.com/
 | 
			
		||||
 ** Mail me (andreas <at> airsoftsoftwair <dot> de) for any bugs.
 | 
			
		||||
 ** This code is subject to the same license terms as the rest of the Scintilla project:
 | 
			
		||||
 ** 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 <ctype.h>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "OptionSet.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
/* Bits:
 | 
			
		||||
 * 1  - whitespace
 | 
			
		||||
 * 2  - operator
 | 
			
		||||
 * 4  - identifier
 | 
			
		||||
 * 8  - decimal digit
 | 
			
		||||
 * 16 - hex digit
 | 
			
		||||
 * 32 - bin digit
 | 
			
		||||
 * 64 - letter
 | 
			
		||||
 */
 | 
			
		||||
static int character_classification[128] =
 | 
			
		||||
{
 | 
			
		||||
	0, // NUL ($0)
 | 
			
		||||
	0, // SOH ($1)
 | 
			
		||||
	0, // STX ($2)
 | 
			
		||||
	0, // ETX ($3)
 | 
			
		||||
	0, // EOT ($4)
 | 
			
		||||
	0, // ENQ ($5)
 | 
			
		||||
	0, // ACK ($6)
 | 
			
		||||
	0, // BEL ($7)
 | 
			
		||||
	0, // BS ($8)
 | 
			
		||||
	1, // HT ($9)
 | 
			
		||||
	1, // LF ($A)
 | 
			
		||||
	0, // VT ($B)
 | 
			
		||||
	0, // FF ($C)
 | 
			
		||||
	1, // CR ($D)
 | 
			
		||||
	0, // SO ($E)
 | 
			
		||||
	0, // SI ($F)
 | 
			
		||||
	0, // DLE ($10)
 | 
			
		||||
	0, // DC1 ($11)
 | 
			
		||||
	0, // DC2 ($12)
 | 
			
		||||
	0, // DC3 ($13)
 | 
			
		||||
	0, // DC4 ($14)
 | 
			
		||||
	0, // NAK ($15)
 | 
			
		||||
	0, // SYN ($16)
 | 
			
		||||
	0, // ETB ($17)
 | 
			
		||||
	0, // CAN ($18)
 | 
			
		||||
	0, // EM ($19)
 | 
			
		||||
	0, // SUB ($1A)
 | 
			
		||||
	0, // ESC ($1B)
 | 
			
		||||
	0, // FS ($1C)
 | 
			
		||||
	0, // GS ($1D)
 | 
			
		||||
	0, // RS ($1E)
 | 
			
		||||
	0, // US ($1F)
 | 
			
		||||
	1, // space ($20)
 | 
			
		||||
	4, // ! ($21)
 | 
			
		||||
	0, // " ($22)
 | 
			
		||||
	0, // # ($23)
 | 
			
		||||
	4, // $ ($24)
 | 
			
		||||
	2, // % ($25)
 | 
			
		||||
	2, // & ($26)
 | 
			
		||||
	2, // ' ($27)
 | 
			
		||||
	2, // ( ($28)
 | 
			
		||||
	2, // ) ($29)
 | 
			
		||||
	2, // * ($2A)
 | 
			
		||||
	2, // + ($2B)
 | 
			
		||||
	2, // , ($2C)
 | 
			
		||||
	2, // - ($2D)
 | 
			
		||||
	// NB: we treat "." as an identifier although it is also an operator and a decimal digit
 | 
			
		||||
	// the reason why we treat it as an identifier is to support syntax highlighting for
 | 
			
		||||
	// plugin commands which always use a "." in their names, e.g. pdf.OpenDocument();
 | 
			
		||||
	// we handle the decimal digit case manually below so that 3.1415 and .123 is styled correctly
 | 
			
		||||
	// the collateral damage of treating "." as an identifier is that "." is never styled
 | 
			
		||||
	// SCE_HOLLYWOOD_OPERATOR
 | 
			
		||||
	4, // . ($2E) 
 | 
			
		||||
	2, // / ($2F)
 | 
			
		||||
	28, // 0 ($30)
 | 
			
		||||
	28, // 1 ($31)
 | 
			
		||||
	28, // 2 ($32)
 | 
			
		||||
	28, // 3 ($33)
 | 
			
		||||
	28, // 4 ($34)
 | 
			
		||||
	28, // 5 ($35)
 | 
			
		||||
	28, // 6 ($36)
 | 
			
		||||
	28, // 7 ($37)
 | 
			
		||||
	28, // 8 ($38)
 | 
			
		||||
	28, // 9 ($39)
 | 
			
		||||
	2, // : ($3A)
 | 
			
		||||
	2, // ; ($3B)
 | 
			
		||||
	2, // < ($3C)
 | 
			
		||||
	2, // = ($3D)
 | 
			
		||||
	2, // > ($3E)
 | 
			
		||||
	2, // ? ($3F)
 | 
			
		||||
	0, // @ ($40)
 | 
			
		||||
	84, // A ($41)
 | 
			
		||||
	84, // B ($42)
 | 
			
		||||
	84, // C ($43)
 | 
			
		||||
	84, // D ($44)
 | 
			
		||||
	84, // E ($45)
 | 
			
		||||
	84, // F ($46)
 | 
			
		||||
	68, // G ($47)
 | 
			
		||||
	68, // H ($48)
 | 
			
		||||
	68, // I ($49)
 | 
			
		||||
	68, // J ($4A)
 | 
			
		||||
	68, // K ($4B)
 | 
			
		||||
	68, // L ($4C)
 | 
			
		||||
	68, // M ($4D)
 | 
			
		||||
	68, // N ($4E)
 | 
			
		||||
	68, // O ($4F)
 | 
			
		||||
	68, // P ($50)
 | 
			
		||||
	68, // Q ($51)
 | 
			
		||||
	68, // R ($52)
 | 
			
		||||
	68, // S ($53)
 | 
			
		||||
	68, // T ($54)
 | 
			
		||||
	68, // U ($55)
 | 
			
		||||
	68, // V ($56)
 | 
			
		||||
	68, // W ($57)
 | 
			
		||||
	68, // X ($58)
 | 
			
		||||
	68, // Y ($59)
 | 
			
		||||
	68, // Z ($5A)
 | 
			
		||||
	2, // [ ($5B)
 | 
			
		||||
	2, // \ ($5C)
 | 
			
		||||
	2, // ] ($5D)
 | 
			
		||||
	2, // ^ ($5E)
 | 
			
		||||
	68, // _ ($5F)
 | 
			
		||||
	2, // ` ($60)
 | 
			
		||||
	84, // a ($61)
 | 
			
		||||
	84, // b ($62)
 | 
			
		||||
	84, // c ($63)
 | 
			
		||||
	84, // d ($64)
 | 
			
		||||
	84, // e ($65)
 | 
			
		||||
	84, // f ($66)
 | 
			
		||||
	68, // g ($67)
 | 
			
		||||
	68, // h ($68)
 | 
			
		||||
	68, // i ($69)
 | 
			
		||||
	68, // j ($6A)
 | 
			
		||||
	68, // k ($6B)
 | 
			
		||||
	68, // l ($6C)
 | 
			
		||||
	68, // m ($6D)
 | 
			
		||||
	68, // n ($6E)
 | 
			
		||||
	68, // o ($6F)
 | 
			
		||||
	68, // p ($70)
 | 
			
		||||
	68, // q ($71)
 | 
			
		||||
	68, // r ($72)
 | 
			
		||||
	68, // s ($73)
 | 
			
		||||
	68, // t ($74)
 | 
			
		||||
	68, // u ($75)
 | 
			
		||||
	68, // v ($76)
 | 
			
		||||
	68, // w ($77)
 | 
			
		||||
	68, // x ($78)
 | 
			
		||||
	68, // y ($79)
 | 
			
		||||
	68, // z ($7A)
 | 
			
		||||
	2, // { ($7B)
 | 
			
		||||
	2, // | ($7C)
 | 
			
		||||
	2, // } ($7D)
 | 
			
		||||
	2, // ~ ($7E)
 | 
			
		||||
	0, //  ($7F)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool IsSpace(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsOperator(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsIdentifier(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsDigit(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsHexDigit(int c) {
 | 
			
		||||
	return c < 128 && (character_classification[c] & 16);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int LowerCase(int c)
 | 
			
		||||
{
 | 
			
		||||
	if (c >= 'A' && c <= 'Z')
 | 
			
		||||
		return 'a' + c - 'A';
 | 
			
		||||
	return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CheckHollywoodFoldPoint(char const *token) {
 | 
			
		||||
	if (!strcmp(token, "function")) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	if (!strcmp(token, "endfunction")) {
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// An individual named option for use in an OptionSet
 | 
			
		||||
 | 
			
		||||
// Options used for LexerHollywood
 | 
			
		||||
struct OptionsHollywood {
 | 
			
		||||
	bool fold;
 | 
			
		||||
	bool foldCompact;
 | 
			
		||||
	OptionsHollywood() {
 | 
			
		||||
		fold = false;
 | 
			
		||||
		foldCompact = false;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char * const hollywoodWordListDesc[] = {
 | 
			
		||||
	"Hollywood keywords",
 | 
			
		||||
	"Hollywood standard API functions",
 | 
			
		||||
	"Hollywood plugin API functions",
 | 
			
		||||
	"Hollywood plugin methods",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct OptionSetHollywood : public OptionSet<OptionsHollywood> {
 | 
			
		||||
	OptionSetHollywood(const char * const wordListDescriptions[]) {
 | 
			
		||||
		DefineProperty("fold", &OptionsHollywood::fold);
 | 
			
		||||
		DefineProperty("fold.compact", &OptionsHollywood::foldCompact);
 | 
			
		||||
		DefineWordListSets(wordListDescriptions);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LexerHollywood : public DefaultLexer {
 | 
			
		||||
	int (*CheckFoldPoint)(char const *);
 | 
			
		||||
	WordList keywordlists[4];	
 | 
			
		||||
	OptionsHollywood options;
 | 
			
		||||
	OptionSetHollywood osHollywood;
 | 
			
		||||
public:
 | 
			
		||||
	LexerHollywood(int (*CheckFoldPoint_)(char const *), const char * const wordListDescriptions[]) :
 | 
			
		||||
						 DefaultLexer("hollywood", SCLEX_HOLLYWOOD),
 | 
			
		||||
						 CheckFoldPoint(CheckFoldPoint_),
 | 
			
		||||
						 osHollywood(wordListDescriptions) {
 | 
			
		||||
	}
 | 
			
		||||
	virtual ~LexerHollywood() {
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD Release() override {
 | 
			
		||||
		delete this;
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD Version() const override {
 | 
			
		||||
		return lvRelease5;
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD PropertyNames() override {
 | 
			
		||||
		return osHollywood.PropertyNames();
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD PropertyType(const char *name) override {
 | 
			
		||||
		return osHollywood.PropertyType(name);
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD DescribeProperty(const char *name) override {
 | 
			
		||||
		return osHollywood.DescribeProperty(name);
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
 | 
			
		||||
	const char * SCI_METHOD PropertyGet(const char* key) override {
 | 
			
		||||
		return osHollywood.PropertyGet(key);
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD DescribeWordListSets() override {
 | 
			
		||||
		return osHollywood.DescribeWordListSets();
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
 | 
			
		||||
	void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
	void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
 | 
			
		||||
	void * SCI_METHOD PrivateCall(int, void *) override {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	static ILexer5 *LexerFactoryHollywood() {
 | 
			
		||||
		return new LexerHollywood(CheckHollywoodFoldPoint, hollywoodWordListDesc);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerHollywood::PropertySet(const char *key, const char *val) {
 | 
			
		||||
	if (osHollywood.PropertySet(&options, key, val)) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerHollywood::WordListSet(int n, const char *wl) {
 | 
			
		||||
	WordList *wordListN = 0;
 | 
			
		||||
	switch (n) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		wordListN = &keywordlists[0];
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		wordListN = &keywordlists[1];
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		wordListN = &keywordlists[2];
 | 
			
		||||
		break;
 | 
			
		||||
	case 3:
 | 
			
		||||
		wordListN = &keywordlists[3];
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position firstModification = -1;
 | 
			
		||||
	if (wordListN) {
 | 
			
		||||
		WordList wlNew;
 | 
			
		||||
		wlNew.Set(wl);
 | 
			
		||||
		if (*wordListN != wlNew) {
 | 
			
		||||
			wordListN->Set(wl);
 | 
			
		||||
			firstModification = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return firstModification;	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerHollywood::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
	bool inString = false;
 | 
			
		||||
	
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	// Can't use sc.More() here else we miss the last character
 | 
			
		||||
	for (; ; sc.Forward())
 | 
			
		||||
	 {
 | 
			
		||||
	 	if (sc.atLineStart) inString = false;
 | 
			
		||||
	 		
 | 
			
		||||
	 	if (sc.ch == '\"' && sc.chPrev != '\\') inString = !inString;
 | 
			
		||||
	 		
 | 
			
		||||
		if (sc.state == SCE_HOLLYWOOD_IDENTIFIER) {
 | 
			
		||||
			if (!IsIdentifier(sc.ch)) {				
 | 
			
		||||
				char s[100];
 | 
			
		||||
				int kstates[4] = {
 | 
			
		||||
					SCE_HOLLYWOOD_KEYWORD,
 | 
			
		||||
					SCE_HOLLYWOOD_STDAPI,
 | 
			
		||||
					SCE_HOLLYWOOD_PLUGINAPI,
 | 
			
		||||
					SCE_HOLLYWOOD_PLUGINMETHOD,
 | 
			
		||||
				};
 | 
			
		||||
				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
				for (int i = 0; i < 4; i++) {
 | 
			
		||||
					if (keywordlists[i].InList(s)) {
 | 
			
		||||
						sc.ChangeState(kstates[i]);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_DEFAULT);				
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_HOLLYWOOD_OPERATOR) {
 | 
			
		||||
			
 | 
			
		||||
			// always reset to default on operators because otherwise
 | 
			
		||||
			// comments won't be recognized in sequences like "+/* Hello*/"
 | 
			
		||||
			// --> "+/*" would be recognized as a sequence of operators
 | 
			
		||||
			
 | 
			
		||||
			// if (!IsOperator(sc.ch)) sc.SetState(SCE_HOLLYWOOD_DEFAULT);
 | 
			
		||||
			sc.SetState(SCE_HOLLYWOOD_DEFAULT);
 | 
			
		||||
			
 | 
			
		||||
		} else if (sc.state == SCE_HOLLYWOOD_PREPROCESSOR) {
 | 
			
		||||
			if (!IsIdentifier(sc.ch))
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_HOLLYWOOD_CONSTANT) {
 | 
			
		||||
			if (!IsIdentifier(sc.ch))
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_HOLLYWOOD_NUMBER) {
 | 
			
		||||
			if (!IsDigit(sc.ch) && sc.ch != '.')
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_HOLLYWOOD_HEXNUMBER) {
 | 
			
		||||
			if (!IsHexDigit(sc.ch))
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_HOLLYWOOD_STRING) {
 | 
			
		||||
			if (sc.ch == '"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_HOLLYWOOD_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_HOLLYWOOD_COMMENT) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_HOLLYWOOD_COMMENTBLOCK) {
 | 
			
		||||
			if (sc.Match("*/") && !inString) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.ForwardSetState(SCE_HOLLYWOOD_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_HOLLYWOOD_STRINGBLOCK) {
 | 
			
		||||
			if (sc.Match("]]") && !inString) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.ForwardSetState(SCE_HOLLYWOOD_DEFAULT);
 | 
			
		||||
			}			
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.state == SCE_HOLLYWOOD_DEFAULT) {
 | 
			
		||||
			if (sc.Match(';')) {
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_COMMENT);
 | 
			
		||||
			} else if (sc.Match("/*")) {
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_COMMENTBLOCK);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.Match("[[")) {
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_STRINGBLOCK);
 | 
			
		||||
				sc.Forward();				
 | 
			
		||||
			} else if (sc.Match('"')) {
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_STRING);
 | 
			
		||||
			} else if (sc.Match('$')) { 
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_HEXNUMBER);
 | 
			
		||||
			} else if (sc.Match("0x") || sc.Match("0X")) {  // must be before IsDigit() because of 0x
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_HEXNUMBER);
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else if (sc.ch == '.' && (sc.chNext >= '0' && sc.chNext <= '9')) {  // ".1234" style numbers
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_NUMBER);
 | 
			
		||||
				sc.Forward();	
 | 
			
		||||
			} else if (IsDigit(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_NUMBER);
 | 
			
		||||
			} else if (sc.Match('#')) {
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_CONSTANT);
 | 
			
		||||
			} else if (sc.Match('@')) {
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_PREPROCESSOR);	
 | 
			
		||||
			} else if (IsOperator(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_OPERATOR);
 | 
			
		||||
			} else if (IsIdentifier(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_HOLLYWOOD_IDENTIFIER);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!sc.More())
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerHollywood::Fold(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, IDocument *pAccess) {
 | 
			
		||||
 | 
			
		||||
	if (!options.fold)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
	
 | 
			
		||||
	Sci_PositionU lengthDoc = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int done = 0;
 | 
			
		||||
	char word[256];
 | 
			
		||||
	int wordlen = 0;
 | 
			
		||||
		
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if (!done) {
 | 
			
		||||
			if (wordlen) { // are we scanning a token already?
 | 
			
		||||
				word[wordlen] = static_cast<char>(LowerCase(ch));
 | 
			
		||||
				if (!IsIdentifier(ch)) { // done with token
 | 
			
		||||
					word[wordlen] = '\0';
 | 
			
		||||
					levelCurrent += CheckFoldPoint(word);
 | 
			
		||||
					done = 1;
 | 
			
		||||
				} else if (wordlen < 255) {
 | 
			
		||||
					wordlen++;
 | 
			
		||||
				}
 | 
			
		||||
			} else { // start scanning at first non-whitespace character
 | 
			
		||||
				if (!IsSpace(ch)) {
 | 
			
		||||
					if (style != SCE_HOLLYWOOD_COMMENTBLOCK && IsIdentifier(ch)) {
 | 
			
		||||
						word[0] = static_cast<char>(LowerCase(ch));
 | 
			
		||||
						wordlen = 1;
 | 
			
		||||
					} else // done with this line
 | 
			
		||||
						done = 1;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}		
 | 
			
		||||
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0 && options.foldCompact) {
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
			done = 0;
 | 
			
		||||
			wordlen = 0;			
 | 
			
		||||
		}
 | 
			
		||||
		if (!IsSpace(ch)) {
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmHollywood(SCLEX_HOLLYWOOD, LexerHollywood::LexerFactoryHollywood, "hollywood", hollywoodWordListDesc);
 | 
			
		||||
							
								
								
									
										74
									
								
								3rdparty/lexilla540/lexilla/lexers/LexIndent.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								3rdparty/lexilla540/lexilla/lexers/LexIndent.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,74 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexIndent.cxx
 | 
			
		||||
 ** Lexer for no language. Used for indentation-based folding of files.
 | 
			
		||||
 **/
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static void ColouriseIndentDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
	// Indent language means all style bytes are 0 so just mark the end - no need to fill in.
 | 
			
		||||
	if (length > 0) {
 | 
			
		||||
		styler.StartAt(startPos + length - 1);
 | 
			
		||||
		styler.StartSegment(startPos + length - 1);
 | 
			
		||||
		styler.ColourTo(startPos + length - 1, 0);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldIndentDoc(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[], Accessor &styler) {
 | 
			
		||||
	int visibleCharsCurrent, visibleCharsNext;
 | 
			
		||||
	int levelCurrent, levelNext;
 | 
			
		||||
	Sci_PositionU i, lineEnd;
 | 
			
		||||
	Sci_PositionU lengthDoc   = startPos + length;
 | 
			
		||||
	Sci_Position  lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
 | 
			
		||||
	i       = styler.LineStart(lineCurrent  );
 | 
			
		||||
	lineEnd = styler.LineStart(lineCurrent+1)-1;
 | 
			
		||||
	if(lineEnd>=lengthDoc) lineEnd = lengthDoc-1;
 | 
			
		||||
	while(styler[lineEnd]=='\n' || styler[lineEnd]=='\r') lineEnd--;
 | 
			
		||||
	for(visibleCharsCurrent=0, levelCurrent=SC_FOLDLEVELBASE; !visibleCharsCurrent && i<=lineEnd; i++){
 | 
			
		||||
		if(isspacechar(styler[i])) levelCurrent++;
 | 
			
		||||
		else                       visibleCharsCurrent=1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for(; i<lengthDoc; lineCurrent++) {
 | 
			
		||||
		i       = styler.LineStart(lineCurrent+1);
 | 
			
		||||
		lineEnd = styler.LineStart(lineCurrent+2)-1;
 | 
			
		||||
		if(lineEnd>=lengthDoc) lineEnd = lengthDoc-1;
 | 
			
		||||
		while(styler[lineEnd]=='\n' || styler[lineEnd]=='\r') lineEnd--;
 | 
			
		||||
		for(visibleCharsNext=0, levelNext=SC_FOLDLEVELBASE; !visibleCharsNext && i<=lineEnd; i++){
 | 
			
		||||
			if(isspacechar(styler[i])) levelNext++;
 | 
			
		||||
			else                       visibleCharsNext=1;
 | 
			
		||||
		}
 | 
			
		||||
		int lev = levelCurrent;
 | 
			
		||||
		if(!visibleCharsCurrent) lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
		else if(levelNext > levelCurrent) lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
		levelCurrent = levelNext;
 | 
			
		||||
		visibleCharsCurrent = visibleCharsNext;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmIndent(SCLEX_INDENT, ColouriseIndentDoc, "indent", FoldIndentDoc);
 | 
			
		||||
							
								
								
									
										378
									
								
								3rdparty/lexilla540/lexilla/lexers/LexInno.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										378
									
								
								3rdparty/lexilla540/lexilla/lexers/LexInno.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,378 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexInno.cxx
 | 
			
		||||
 ** Lexer for Inno Setup scripts.
 | 
			
		||||
 **/
 | 
			
		||||
// Written by Friedrich Vedder <fvedd@t-online.de>, using code from LexOthers.cxx.
 | 
			
		||||
// Modified by Michael Heath.
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static bool innoIsBlank(int ch) {
 | 
			
		||||
	return (ch == ' ') || (ch == '\t');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool innoNextNotBlankIs(Sci_Position i, Accessor &styler, char needle) {
 | 
			
		||||
	char ch;
 | 
			
		||||
 | 
			
		||||
	while (i < styler.Length()) {
 | 
			
		||||
		ch = styler.SafeGetCharAt(i);
 | 
			
		||||
 | 
			
		||||
		if (ch == needle)
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
		if (!innoIsBlank(ch))
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseInnoDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordLists[], Accessor &styler) {
 | 
			
		||||
	int state = SCE_INNO_DEFAULT;
 | 
			
		||||
	char chPrev;
 | 
			
		||||
	char ch = 0;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	Sci_Position lengthDoc = startPos + length;
 | 
			
		||||
	char *buffer = new char[length + 1];
 | 
			
		||||
	Sci_Position bufferCount = 0;
 | 
			
		||||
	bool isBOL, isEOL, isWS, isBOLWS = 0;
 | 
			
		||||
 | 
			
		||||
	// Save line state later with bitState and bitand with bit... to get line state
 | 
			
		||||
	int bitState = 0;
 | 
			
		||||
	int const bitCode = 1, bitMessages = 2, bitCommentCurly = 4, bitCommentRound = 8;
 | 
			
		||||
 | 
			
		||||
	// Get keyword lists
 | 
			
		||||
	WordList §ionKeywords = *keywordLists[0];
 | 
			
		||||
	WordList &standardKeywords = *keywordLists[1];
 | 
			
		||||
	WordList ¶meterKeywords = *keywordLists[2];
 | 
			
		||||
	WordList &preprocessorKeywords = *keywordLists[3];
 | 
			
		||||
	WordList &pascalKeywords = *keywordLists[4];
 | 
			
		||||
	WordList &userKeywords = *keywordLists[5];
 | 
			
		||||
 | 
			
		||||
	// Get line state
 | 
			
		||||
	Sci_Position curLine = styler.GetLine(startPos);
 | 
			
		||||
	int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
 | 
			
		||||
	bool isCode = (curLineState & bitCode);
 | 
			
		||||
	bool isMessages = (curLineState & bitMessages);
 | 
			
		||||
	bool isCommentCurly = (curLineState & bitCommentCurly);
 | 
			
		||||
	bool isCommentRound = (curLineState & bitCommentRound);
 | 
			
		||||
	bool isCommentSlash = false;
 | 
			
		||||
 | 
			
		||||
	// Continue Pascal multline comment state
 | 
			
		||||
	if (isCommentCurly || isCommentRound)
 | 
			
		||||
		state = SCE_INNO_COMMENT_PASCAL;
 | 
			
		||||
 | 
			
		||||
	// Go through all provided text segment
 | 
			
		||||
	// using the hand-written state machine shown below
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
 | 
			
		||||
	for (Sci_Position i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		chPrev = ch;
 | 
			
		||||
		ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
		if (styler.IsLeadByte(ch)) {
 | 
			
		||||
			chNext = styler.SafeGetCharAt(i + 2);
 | 
			
		||||
			i++;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		isBOL = (chPrev == 0) || (chPrev == '\n') || (chPrev == '\r' && ch != '\n');
 | 
			
		||||
		isBOLWS = (isBOL) ? 1 : (isBOLWS && (chPrev == ' ' || chPrev == '\t'));
 | 
			
		||||
		isEOL = (ch == '\n' || ch == '\r');
 | 
			
		||||
		isWS = (ch == ' ' || ch == '\t');
 | 
			
		||||
 | 
			
		||||
		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
 | 
			
		||||
			// Remember the line state for future incremental lexing
 | 
			
		||||
			curLine = styler.GetLine(i);
 | 
			
		||||
			bitState = 0;
 | 
			
		||||
 | 
			
		||||
			if (isCode)
 | 
			
		||||
				bitState |= bitCode;
 | 
			
		||||
 | 
			
		||||
			if (isMessages)
 | 
			
		||||
				bitState |= bitMessages;
 | 
			
		||||
 | 
			
		||||
			if (isCommentCurly)
 | 
			
		||||
				bitState |= bitCommentCurly;
 | 
			
		||||
 | 
			
		||||
			if (isCommentRound)
 | 
			
		||||
				bitState |= bitCommentRound;
 | 
			
		||||
 | 
			
		||||
			styler.SetLineState(curLine, bitState);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch(state) {
 | 
			
		||||
			case SCE_INNO_DEFAULT:
 | 
			
		||||
				if (!isCode && ch == ';' && isBOLWS) {
 | 
			
		||||
					// Start of a comment
 | 
			
		||||
					state = SCE_INNO_COMMENT;
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_COMMENT);
 | 
			
		||||
				} else if (ch == '[' && isBOLWS) {
 | 
			
		||||
					// Start of a section name
 | 
			
		||||
					state = SCE_INNO_SECTION;
 | 
			
		||||
					bufferCount = 0;
 | 
			
		||||
				} else if (ch == '#' && isBOLWS) {
 | 
			
		||||
					// Start of a preprocessor directive
 | 
			
		||||
					state = SCE_INNO_PREPROC;
 | 
			
		||||
				} else if (!isCode && ch == '{' && chNext != '{' && chPrev != '{') {
 | 
			
		||||
					// Start of an inline expansion
 | 
			
		||||
					state = SCE_INNO_INLINE_EXPANSION;
 | 
			
		||||
				} else if (isCode && ch == '{') {
 | 
			
		||||
					// Start of a Pascal comment
 | 
			
		||||
					state = SCE_INNO_COMMENT_PASCAL;
 | 
			
		||||
					isCommentCurly = true;
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_COMMENT_PASCAL);
 | 
			
		||||
				} else if (isCode && (ch == '(' && chNext == '*')) {
 | 
			
		||||
					// Start of a Pascal comment
 | 
			
		||||
					state = SCE_INNO_COMMENT_PASCAL;
 | 
			
		||||
					isCommentRound = true;
 | 
			
		||||
					styler.ColourTo(i + 1, SCE_INNO_COMMENT_PASCAL);
 | 
			
		||||
				} else if (isCode && ch == '/' && chNext == '/') {
 | 
			
		||||
					// Start of C-style comment
 | 
			
		||||
					state = SCE_INNO_COMMENT_PASCAL;
 | 
			
		||||
					isCommentSlash = true;
 | 
			
		||||
					styler.ColourTo(i + 1, SCE_INNO_COMMENT_PASCAL);
 | 
			
		||||
				} else if (!isMessages && ch == '"') {
 | 
			
		||||
					// Start of a double-quote string
 | 
			
		||||
					state = SCE_INNO_STRING_DOUBLE;
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_STRING_DOUBLE);
 | 
			
		||||
				} else if (!isMessages && ch == '\'') {
 | 
			
		||||
					// Start of a single-quote string
 | 
			
		||||
					state = SCE_INNO_STRING_SINGLE;
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_STRING_SINGLE);
 | 
			
		||||
				} else if (!isMessages && IsASCII(ch) && (isalpha(ch) || (ch == '_'))) {
 | 
			
		||||
					// Start of an identifier
 | 
			
		||||
					state = SCE_INNO_IDENTIFIER;
 | 
			
		||||
					bufferCount = 0;
 | 
			
		||||
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
 | 
			
		||||
				} else {
 | 
			
		||||
					// Style it the default style
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_INNO_COMMENT:
 | 
			
		||||
				if (isEOL) {
 | 
			
		||||
					state = SCE_INNO_DEFAULT;
 | 
			
		||||
					styler.ColourTo(i - 1, SCE_INNO_COMMENT);
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_DEFAULT);
 | 
			
		||||
				} else {
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_COMMENT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_INNO_IDENTIFIER:
 | 
			
		||||
				if (IsASCII(ch) && (isalnum(ch) || (ch == '_'))) {
 | 
			
		||||
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
 | 
			
		||||
				} else {
 | 
			
		||||
					state = SCE_INNO_DEFAULT;
 | 
			
		||||
					buffer[bufferCount] = '\0';
 | 
			
		||||
 | 
			
		||||
					// Check if the buffer contains a keyword
 | 
			
		||||
					if (!isCode && standardKeywords.InList(buffer) && innoNextNotBlankIs(i, styler, '=')) {
 | 
			
		||||
						styler.ColourTo(i - 1, SCE_INNO_KEYWORD);
 | 
			
		||||
					} else if (!isCode && parameterKeywords.InList(buffer) && innoNextNotBlankIs(i, styler, ':')) {
 | 
			
		||||
						styler.ColourTo(i - 1, SCE_INNO_PARAMETER);
 | 
			
		||||
					} else if (isCode && pascalKeywords.InList(buffer)) {
 | 
			
		||||
						styler.ColourTo(i - 1, SCE_INNO_KEYWORD_PASCAL);
 | 
			
		||||
					} else if (!isCode && userKeywords.InList(buffer)) {
 | 
			
		||||
						styler.ColourTo(i - 1, SCE_INNO_KEYWORD_USER);
 | 
			
		||||
					} else {
 | 
			
		||||
						styler.ColourTo(i - 1, SCE_INNO_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// Push back the faulty character
 | 
			
		||||
					chNext = styler[i--];
 | 
			
		||||
					ch = chPrev;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_INNO_SECTION:
 | 
			
		||||
				if (ch == ']') {
 | 
			
		||||
					state = SCE_INNO_DEFAULT;
 | 
			
		||||
					buffer[bufferCount] = '\0';
 | 
			
		||||
 | 
			
		||||
					// Check if the buffer contains a section name
 | 
			
		||||
					if (sectionKeywords.InList(buffer)) {
 | 
			
		||||
						styler.ColourTo(i, SCE_INNO_SECTION);
 | 
			
		||||
						isCode = !CompareCaseInsensitive(buffer, "code");
 | 
			
		||||
 | 
			
		||||
						isMessages = isCode ? false : (
 | 
			
		||||
									!CompareCaseInsensitive(buffer, "custommessages")
 | 
			
		||||
									|| !CompareCaseInsensitive(buffer, "messages"));
 | 
			
		||||
					} else {
 | 
			
		||||
						styler.ColourTo(i, SCE_INNO_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				} else if (IsASCII(ch) && (isalnum(ch) || (ch == '_'))) {
 | 
			
		||||
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
 | 
			
		||||
				} else {
 | 
			
		||||
					state = SCE_INNO_DEFAULT;
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_INNO_PREPROC:
 | 
			
		||||
				if (isWS || isEOL) {
 | 
			
		||||
					if (IsASCII(chPrev) && isalpha(chPrev)) {
 | 
			
		||||
						state = SCE_INNO_DEFAULT;
 | 
			
		||||
						buffer[bufferCount] = '\0';
 | 
			
		||||
 | 
			
		||||
						// Check if the buffer contains a preprocessor directive
 | 
			
		||||
						if (preprocessorKeywords.InList(buffer)) {
 | 
			
		||||
							styler.ColourTo(i - 1, SCE_INNO_PREPROC);
 | 
			
		||||
						} else {
 | 
			
		||||
							styler.ColourTo(i - 1, SCE_INNO_DEFAULT);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						// Push back the faulty character
 | 
			
		||||
						chNext = styler[i--];
 | 
			
		||||
						ch = chPrev;
 | 
			
		||||
					}
 | 
			
		||||
				} else if (IsASCII(ch) && isalpha(ch)) {
 | 
			
		||||
					if (chPrev == '#' || chPrev == ' ' || chPrev == '\t')
 | 
			
		||||
						bufferCount = 0;
 | 
			
		||||
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_INNO_STRING_DOUBLE:
 | 
			
		||||
				if (ch == '"') {
 | 
			
		||||
					state = SCE_INNO_DEFAULT;
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_STRING_DOUBLE);
 | 
			
		||||
				} else if (isEOL) {
 | 
			
		||||
					state = SCE_INNO_DEFAULT;
 | 
			
		||||
					styler.ColourTo(i - 1, SCE_INNO_STRING_DOUBLE);
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_DEFAULT);
 | 
			
		||||
				} else {
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_STRING_DOUBLE);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_INNO_STRING_SINGLE:
 | 
			
		||||
				if (ch == '\'') {
 | 
			
		||||
					state = SCE_INNO_DEFAULT;
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_STRING_SINGLE);
 | 
			
		||||
				} else if (isEOL) {
 | 
			
		||||
					state = SCE_INNO_DEFAULT;
 | 
			
		||||
					styler.ColourTo(i - 1, SCE_INNO_STRING_SINGLE);
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_DEFAULT);
 | 
			
		||||
				} else {
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_STRING_SINGLE);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_INNO_INLINE_EXPANSION:
 | 
			
		||||
				if (ch == '}') {
 | 
			
		||||
					state = SCE_INNO_DEFAULT;
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_INLINE_EXPANSION);
 | 
			
		||||
				} else if (isEOL) {
 | 
			
		||||
					state = SCE_INNO_DEFAULT;
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SCE_INNO_COMMENT_PASCAL:
 | 
			
		||||
				if (isCommentSlash) {
 | 
			
		||||
					if (isEOL) {
 | 
			
		||||
						state = SCE_INNO_DEFAULT;
 | 
			
		||||
						isCommentSlash = false;
 | 
			
		||||
						styler.ColourTo(i - 1, SCE_INNO_COMMENT_PASCAL);
 | 
			
		||||
						styler.ColourTo(i, SCE_INNO_DEFAULT);
 | 
			
		||||
					} else {
 | 
			
		||||
						styler.ColourTo(i, SCE_INNO_COMMENT_PASCAL);
 | 
			
		||||
					}
 | 
			
		||||
				} else if (isCommentCurly) {
 | 
			
		||||
					if (ch == '}') {
 | 
			
		||||
						state = SCE_INNO_DEFAULT;
 | 
			
		||||
						isCommentCurly = false;
 | 
			
		||||
					}
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_COMMENT_PASCAL);
 | 
			
		||||
				} else if (isCommentRound) {
 | 
			
		||||
					if (ch == ')' && chPrev == '*') {
 | 
			
		||||
						state = SCE_INNO_DEFAULT;
 | 
			
		||||
						isCommentRound = false;
 | 
			
		||||
					}
 | 
			
		||||
					styler.ColourTo(i, SCE_INNO_COMMENT_PASCAL);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	delete []buffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const innoWordListDesc[] = {
 | 
			
		||||
	"Sections",
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	"Parameters",
 | 
			
		||||
	"Preprocessor directives",
 | 
			
		||||
	"Pascal keywords",
 | 
			
		||||
	"User defined keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void FoldInnoDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
 | 
			
		||||
	bool sectionFlag = false;
 | 
			
		||||
	int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;
 | 
			
		||||
	int level;
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler[i + 1];
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		int style = styler.StyleAt(i);
 | 
			
		||||
 | 
			
		||||
		if (style == SCE_INNO_SECTION)
 | 
			
		||||
			sectionFlag = true;
 | 
			
		||||
 | 
			
		||||
		if (atEOL || i == endPos - 1) {
 | 
			
		||||
			if (sectionFlag) {
 | 
			
		||||
				level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
				if (level == levelPrev)
 | 
			
		||||
					styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
 | 
			
		||||
			} else {
 | 
			
		||||
				level = levelPrev & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
				if (levelPrev & SC_FOLDLEVELHEADERFLAG)
 | 
			
		||||
					level++;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			styler.SetLevel(lineCurrent, level);
 | 
			
		||||
 | 
			
		||||
			levelPrev = level;
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			sectionFlag = false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc);
 | 
			
		||||
							
								
								
									
										507
									
								
								3rdparty/lexilla540/lexilla/lexers/LexJSON.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										507
									
								
								3rdparty/lexilla540/lexilla/lexers/LexJSON.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,507 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/**
 | 
			
		||||
 * @file LexJSON.cxx
 | 
			
		||||
 * @date February 19, 2016
 | 
			
		||||
 * @brief Lexer for JSON and JSON-LD formats
 | 
			
		||||
 * @author nkmathew
 | 
			
		||||
 *
 | 
			
		||||
 * The License.txt file describes the conditions under which this software may
 | 
			
		||||
 * be distributed.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cctype>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "OptionSet.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
const char *const JSONWordListDesc[] = {
 | 
			
		||||
	"JSON Keywords",
 | 
			
		||||
	"JSON-LD Keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Used to detect compact IRI/URLs in JSON-LD without first looking ahead for the
 | 
			
		||||
 * colon separating the prefix and suffix
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.w3.org/TR/json-ld/#dfn-compact-iri
 | 
			
		||||
 */
 | 
			
		||||
struct CompactIRI {
 | 
			
		||||
	int colonCount;
 | 
			
		||||
	bool foundInvalidChar;
 | 
			
		||||
	CharacterSet setCompactIRI;
 | 
			
		||||
	CompactIRI() {
 | 
			
		||||
		colonCount = 0;
 | 
			
		||||
		foundInvalidChar = false;
 | 
			
		||||
		setCompactIRI = CharacterSet(CharacterSet::setAlpha, "$_-");
 | 
			
		||||
	}
 | 
			
		||||
	void resetState() {
 | 
			
		||||
		colonCount = 0;
 | 
			
		||||
		foundInvalidChar = false;
 | 
			
		||||
	}
 | 
			
		||||
	void checkChar(int ch) {
 | 
			
		||||
		if (ch == ':') {
 | 
			
		||||
			colonCount++;
 | 
			
		||||
		} else {
 | 
			
		||||
			foundInvalidChar |= !setCompactIRI.Contains(ch);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	bool shouldHighlight() const {
 | 
			
		||||
		return !foundInvalidChar && colonCount == 1;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Keeps track of escaped characters in strings as per:
 | 
			
		||||
 *
 | 
			
		||||
 * https://tools.ietf.org/html/rfc7159#section-7
 | 
			
		||||
 */
 | 
			
		||||
struct EscapeSequence {
 | 
			
		||||
	int digitsLeft;
 | 
			
		||||
	CharacterSet setHexDigits;
 | 
			
		||||
	CharacterSet setEscapeChars;
 | 
			
		||||
	EscapeSequence() {
 | 
			
		||||
		digitsLeft = 0;
 | 
			
		||||
		setHexDigits = CharacterSet(CharacterSet::setDigits, "ABCDEFabcdef");
 | 
			
		||||
		setEscapeChars = CharacterSet(CharacterSet::setNone, "\\\"tnbfru/");
 | 
			
		||||
	}
 | 
			
		||||
	// Returns true if the following character is a valid escaped character
 | 
			
		||||
	bool newSequence(int nextChar) {
 | 
			
		||||
		digitsLeft = 0;
 | 
			
		||||
		if (nextChar == 'u') {
 | 
			
		||||
			digitsLeft = 5;
 | 
			
		||||
		} else if (!setEscapeChars.Contains(nextChar)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	bool atEscapeEnd() const {
 | 
			
		||||
		return digitsLeft <= 0;
 | 
			
		||||
	}
 | 
			
		||||
	bool isInvalidChar(int currChar) const {
 | 
			
		||||
		return !setHexDigits.Contains(currChar);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct OptionsJSON {
 | 
			
		||||
	bool foldCompact;
 | 
			
		||||
	bool fold;
 | 
			
		||||
	bool allowComments;
 | 
			
		||||
	bool escapeSequence;
 | 
			
		||||
	OptionsJSON() {
 | 
			
		||||
		foldCompact = false;
 | 
			
		||||
		fold = false;
 | 
			
		||||
		allowComments = false;
 | 
			
		||||
		escapeSequence = false;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct OptionSetJSON : public OptionSet<OptionsJSON> {
 | 
			
		||||
	OptionSetJSON() {
 | 
			
		||||
		DefineProperty("lexer.json.escape.sequence", &OptionsJSON::escapeSequence,
 | 
			
		||||
					   "Set to 1 to enable highlighting of escape sequences in strings");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("lexer.json.allow.comments", &OptionsJSON::allowComments,
 | 
			
		||||
					   "Set to 1 to enable highlighting of line/block comments in JSON");
 | 
			
		||||
 | 
			
		||||
		DefineProperty("fold.compact", &OptionsJSON::foldCompact);
 | 
			
		||||
		DefineProperty("fold", &OptionsJSON::fold);
 | 
			
		||||
		DefineWordListSets(JSONWordListDesc);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LexerJSON : public DefaultLexer {
 | 
			
		||||
	OptionsJSON options;
 | 
			
		||||
	OptionSetJSON optSetJSON;
 | 
			
		||||
	EscapeSequence escapeSeq;
 | 
			
		||||
	WordList keywordsJSON;
 | 
			
		||||
	WordList keywordsJSONLD;
 | 
			
		||||
	CharacterSet setOperators;
 | 
			
		||||
	CharacterSet setURL;
 | 
			
		||||
	CharacterSet setKeywordJSONLD;
 | 
			
		||||
	CharacterSet setKeywordJSON;
 | 
			
		||||
	CompactIRI compactIRI;
 | 
			
		||||
 | 
			
		||||
	static bool IsNextNonWhitespace(LexAccessor &styler, Sci_Position start, char ch) {
 | 
			
		||||
		Sci_Position i = 0;
 | 
			
		||||
		while (i < 50) {
 | 
			
		||||
			i++;
 | 
			
		||||
			char curr = styler.SafeGetCharAt(start+i, '\0');
 | 
			
		||||
			char next = styler.SafeGetCharAt(start+i+1, '\0');
 | 
			
		||||
			bool atEOL = (curr == '\r' && next != '\n') || (curr == '\n');
 | 
			
		||||
			if (curr == ch) {
 | 
			
		||||
				return true;
 | 
			
		||||
			} else if (!isspacechar(curr) || atEOL) {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Looks for the colon following the end quote
 | 
			
		||||
	 *
 | 
			
		||||
	 * Assumes property names of lengths no longer than a 100 characters.
 | 
			
		||||
	 * The colon is also expected to be less than 50 spaces after the end
 | 
			
		||||
	 * quote for the string to be considered a property name
 | 
			
		||||
	 */
 | 
			
		||||
	static bool AtPropertyName(LexAccessor &styler, Sci_Position start) {
 | 
			
		||||
		Sci_Position i = 0;
 | 
			
		||||
		bool escaped = false;
 | 
			
		||||
		while (i < 100) {
 | 
			
		||||
			i++;
 | 
			
		||||
			char curr = styler.SafeGetCharAt(start+i, '\0');
 | 
			
		||||
			if (escaped) {
 | 
			
		||||
				escaped = false;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			escaped = curr == '\\';
 | 
			
		||||
			if (curr == '"') {
 | 
			
		||||
				return IsNextNonWhitespace(styler, start+i, ':');
 | 
			
		||||
			} else if (!curr) {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static bool IsNextWordInList(WordList &keywordList, CharacterSet wordSet,
 | 
			
		||||
								 StyleContext &context, LexAccessor &styler) {
 | 
			
		||||
		char word[51];
 | 
			
		||||
		Sci_Position currPos = (Sci_Position) context.currentPos;
 | 
			
		||||
		int i = 0;
 | 
			
		||||
		while (i < 50) {
 | 
			
		||||
			char ch = styler.SafeGetCharAt(currPos + i);
 | 
			
		||||
			if (!wordSet.Contains(ch)) {
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			word[i] = ch;
 | 
			
		||||
			i++;
 | 
			
		||||
		}
 | 
			
		||||
		word[i] = '\0';
 | 
			
		||||
		return keywordList.InList(word);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
	LexerJSON() :
 | 
			
		||||
		DefaultLexer("json", SCLEX_JSON),
 | 
			
		||||
		setOperators(CharacterSet::setNone, "[{}]:,"),
 | 
			
		||||
		setURL(CharacterSet::setAlphaNum, "-._~:/?#[]@!$&'()*+,),="),
 | 
			
		||||
		setKeywordJSONLD(CharacterSet::setAlpha, ":@"),
 | 
			
		||||
		setKeywordJSON(CharacterSet::setAlpha, "$_") {
 | 
			
		||||
	}
 | 
			
		||||
	virtual ~LexerJSON() {}
 | 
			
		||||
	int SCI_METHOD Version() const override {
 | 
			
		||||
		return lvRelease5;
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD Release() override {
 | 
			
		||||
		delete this;
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD PropertyNames() override {
 | 
			
		||||
		return optSetJSON.PropertyNames();
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD PropertyType(const char *name) override {
 | 
			
		||||
		return optSetJSON.PropertyType(name);
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD DescribeProperty(const char *name) override {
 | 
			
		||||
		return optSetJSON.DescribeProperty(name);
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override {
 | 
			
		||||
		if (optSetJSON.PropertySet(&options, key, val)) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	const char * SCI_METHOD PropertyGet(const char *key) override {
 | 
			
		||||
		return optSetJSON.PropertyGet(key);
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override {
 | 
			
		||||
		WordList *wordListN = 0;
 | 
			
		||||
		switch (n) {
 | 
			
		||||
			case 0:
 | 
			
		||||
				wordListN = &keywordsJSON;
 | 
			
		||||
				break;
 | 
			
		||||
			case 1:
 | 
			
		||||
				wordListN = &keywordsJSONLD;
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		Sci_Position firstModification = -1;
 | 
			
		||||
		if (wordListN) {
 | 
			
		||||
			if (wordListN->Set(wl)) {
 | 
			
		||||
				firstModification = 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return firstModification;
 | 
			
		||||
	}
 | 
			
		||||
	void *SCI_METHOD PrivateCall(int, void *) override {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	static ILexer5 *LexerFactoryJSON() {
 | 
			
		||||
		return new LexerJSON;
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD DescribeWordListSets() override {
 | 
			
		||||
		return optSetJSON.DescribeWordListSets();
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD Lex(Sci_PositionU startPos,
 | 
			
		||||
								Sci_Position length,
 | 
			
		||||
								int initStyle,
 | 
			
		||||
								IDocument *pAccess) override;
 | 
			
		||||
	void SCI_METHOD Fold(Sci_PositionU startPos,
 | 
			
		||||
								 Sci_Position length,
 | 
			
		||||
								 int initStyle,
 | 
			
		||||
								 IDocument *pAccess) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerJSON::Lex(Sci_PositionU startPos,
 | 
			
		||||
							   Sci_Position length,
 | 
			
		||||
							   int initStyle,
 | 
			
		||||
							   IDocument *pAccess) {
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
	StyleContext context(startPos, length, initStyle, styler);
 | 
			
		||||
	int stringStyleBefore = SCE_JSON_STRING;
 | 
			
		||||
	while (context.More()) {
 | 
			
		||||
		switch (context.state) {
 | 
			
		||||
			case SCE_JSON_BLOCKCOMMENT:
 | 
			
		||||
				if (context.Match("*/")) {
 | 
			
		||||
					context.Forward();
 | 
			
		||||
					context.ForwardSetState(SCE_JSON_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_JSON_LINECOMMENT:
 | 
			
		||||
				if (context.MatchLineEnd()) {
 | 
			
		||||
					context.SetState(SCE_JSON_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_JSON_STRINGEOL:
 | 
			
		||||
				if (context.atLineStart) {
 | 
			
		||||
					context.SetState(SCE_JSON_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_JSON_ESCAPESEQUENCE:
 | 
			
		||||
				escapeSeq.digitsLeft--;
 | 
			
		||||
				if (!escapeSeq.atEscapeEnd()) {
 | 
			
		||||
					if (escapeSeq.isInvalidChar(context.ch)) {
 | 
			
		||||
						context.SetState(SCE_JSON_ERROR);
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				if (context.ch == '"') {
 | 
			
		||||
					context.SetState(stringStyleBefore);
 | 
			
		||||
					context.ForwardSetState(SCE_JSON_DEFAULT);
 | 
			
		||||
				} else if (context.ch == '\\') {
 | 
			
		||||
					if (!escapeSeq.newSequence(context.chNext)) {
 | 
			
		||||
						context.SetState(SCE_JSON_ERROR);
 | 
			
		||||
					}
 | 
			
		||||
					context.Forward();
 | 
			
		||||
				} else {
 | 
			
		||||
					context.SetState(stringStyleBefore);
 | 
			
		||||
					if (context.atLineEnd) {
 | 
			
		||||
						context.ChangeState(SCE_JSON_STRINGEOL);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_JSON_PROPERTYNAME:
 | 
			
		||||
			case SCE_JSON_STRING:
 | 
			
		||||
				if (context.ch == '"') {
 | 
			
		||||
					if (compactIRI.shouldHighlight()) {
 | 
			
		||||
						context.ChangeState(SCE_JSON_COMPACTIRI);
 | 
			
		||||
						context.ForwardSetState(SCE_JSON_DEFAULT);
 | 
			
		||||
						compactIRI.resetState();
 | 
			
		||||
					} else {
 | 
			
		||||
						context.ForwardSetState(SCE_JSON_DEFAULT);
 | 
			
		||||
					}
 | 
			
		||||
				} else if (context.atLineEnd) {
 | 
			
		||||
					context.ChangeState(SCE_JSON_STRINGEOL);
 | 
			
		||||
				} else if (context.ch == '\\') {
 | 
			
		||||
					stringStyleBefore = context.state;
 | 
			
		||||
					if (options.escapeSequence) {
 | 
			
		||||
						context.SetState(SCE_JSON_ESCAPESEQUENCE);
 | 
			
		||||
						if (!escapeSeq.newSequence(context.chNext)) {
 | 
			
		||||
							context.SetState(SCE_JSON_ERROR);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					context.Forward();
 | 
			
		||||
				} else if (context.Match("https://") ||
 | 
			
		||||
						   context.Match("http://") ||
 | 
			
		||||
						   context.Match("ssh://") ||
 | 
			
		||||
						   context.Match("git://") ||
 | 
			
		||||
						   context.Match("svn://") ||
 | 
			
		||||
						   context.Match("ftp://") ||
 | 
			
		||||
						   context.Match("mailto:")) {
 | 
			
		||||
					// Handle most common URI schemes only
 | 
			
		||||
					stringStyleBefore = context.state;
 | 
			
		||||
					context.SetState(SCE_JSON_URI);
 | 
			
		||||
				} else if (context.ch == '@') {
 | 
			
		||||
					// https://www.w3.org/TR/json-ld/#dfn-keyword
 | 
			
		||||
					if (IsNextWordInList(keywordsJSONLD, setKeywordJSONLD, context, styler)) {
 | 
			
		||||
						stringStyleBefore = context.state;
 | 
			
		||||
						context.SetState(SCE_JSON_LDKEYWORD);
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					compactIRI.checkChar(context.ch);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_JSON_LDKEYWORD:
 | 
			
		||||
			case SCE_JSON_URI:
 | 
			
		||||
				if ((!setKeywordJSONLD.Contains(context.ch) &&
 | 
			
		||||
					 (context.state == SCE_JSON_LDKEYWORD)) ||
 | 
			
		||||
					(!setURL.Contains(context.ch))) {
 | 
			
		||||
					context.SetState(stringStyleBefore);
 | 
			
		||||
				}
 | 
			
		||||
				if (context.ch == '"') {
 | 
			
		||||
					context.ForwardSetState(SCE_JSON_DEFAULT);
 | 
			
		||||
				} else if (context.atLineEnd) {
 | 
			
		||||
					context.ChangeState(SCE_JSON_STRINGEOL);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_JSON_OPERATOR:
 | 
			
		||||
			case SCE_JSON_NUMBER:
 | 
			
		||||
				context.SetState(SCE_JSON_DEFAULT);
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_JSON_ERROR:
 | 
			
		||||
				if (context.MatchLineEnd()) {
 | 
			
		||||
					context.SetState(SCE_JSON_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case SCE_JSON_KEYWORD:
 | 
			
		||||
				if (!setKeywordJSON.Contains(context.ch)) {
 | 
			
		||||
					context.SetState(SCE_JSON_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		if (context.state == SCE_JSON_DEFAULT) {
 | 
			
		||||
			if (context.ch == '"') {
 | 
			
		||||
				compactIRI.resetState();
 | 
			
		||||
				context.SetState(SCE_JSON_STRING);
 | 
			
		||||
				Sci_Position currPos = static_cast<Sci_Position>(context.currentPos);
 | 
			
		||||
				if (AtPropertyName(styler, currPos)) {
 | 
			
		||||
					context.SetState(SCE_JSON_PROPERTYNAME);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (setOperators.Contains(context.ch)) {
 | 
			
		||||
				context.SetState(SCE_JSON_OPERATOR);
 | 
			
		||||
			} else if (options.allowComments && context.Match("/*")) {
 | 
			
		||||
				context.SetState(SCE_JSON_BLOCKCOMMENT);
 | 
			
		||||
				context.Forward();
 | 
			
		||||
			} else if (options.allowComments && context.Match("//")) {
 | 
			
		||||
				context.SetState(SCE_JSON_LINECOMMENT);
 | 
			
		||||
			} else if (setKeywordJSON.Contains(context.ch)) {
 | 
			
		||||
				if (IsNextWordInList(keywordsJSON, setKeywordJSON, context, styler)) {
 | 
			
		||||
					context.SetState(SCE_JSON_KEYWORD);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			bool numberStart =
 | 
			
		||||
				IsADigit(context.ch) && (context.chPrev == '+'||
 | 
			
		||||
										 context.chPrev == '-' ||
 | 
			
		||||
										 context.atLineStart ||
 | 
			
		||||
										 IsASpace(context.chPrev) ||
 | 
			
		||||
										 setOperators.Contains(context.chPrev));
 | 
			
		||||
			bool exponentPart =
 | 
			
		||||
				tolower(context.ch) == 'e' &&
 | 
			
		||||
				IsADigit(context.chPrev) &&
 | 
			
		||||
				(IsADigit(context.chNext) ||
 | 
			
		||||
				 context.chNext == '+' ||
 | 
			
		||||
				 context.chNext == '-');
 | 
			
		||||
			bool signPart =
 | 
			
		||||
				(context.ch == '-' || context.ch == '+') &&
 | 
			
		||||
				((tolower(context.chPrev) == 'e' && IsADigit(context.chNext)) ||
 | 
			
		||||
				 ((IsASpace(context.chPrev) || setOperators.Contains(context.chPrev))
 | 
			
		||||
				  && IsADigit(context.chNext)));
 | 
			
		||||
			bool adjacentDigit =
 | 
			
		||||
				IsADigit(context.ch) && IsADigit(context.chPrev);
 | 
			
		||||
			bool afterExponent = IsADigit(context.ch) && tolower(context.chPrev) == 'e';
 | 
			
		||||
			bool dotPart = context.ch == '.' &&
 | 
			
		||||
				IsADigit(context.chPrev) &&
 | 
			
		||||
				IsADigit(context.chNext);
 | 
			
		||||
			bool afterDot = IsADigit(context.ch) && context.chPrev == '.';
 | 
			
		||||
			if (numberStart ||
 | 
			
		||||
				exponentPart ||
 | 
			
		||||
				signPart ||
 | 
			
		||||
				adjacentDigit ||
 | 
			
		||||
				dotPart ||
 | 
			
		||||
				afterExponent ||
 | 
			
		||||
				afterDot) {
 | 
			
		||||
				context.SetState(SCE_JSON_NUMBER);
 | 
			
		||||
			} else if (context.state == SCE_JSON_DEFAULT && !IsASpace(context.ch)) {
 | 
			
		||||
				context.SetState(SCE_JSON_ERROR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		context.Forward();
 | 
			
		||||
	}
 | 
			
		||||
	context.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SCI_METHOD LexerJSON::Fold(Sci_PositionU startPos,
 | 
			
		||||
								Sci_Position length,
 | 
			
		||||
								int,
 | 
			
		||||
								IDocument *pAccess) {
 | 
			
		||||
	if (!options.fold) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
	Sci_PositionU currLine = styler.GetLine(startPos);
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int currLevel = SC_FOLDLEVELBASE;
 | 
			
		||||
	if (currLine > 0)
 | 
			
		||||
		currLevel = styler.LevelAt(currLine - 1) >> 16;
 | 
			
		||||
	int nextLevel = currLevel;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char curr = styler.SafeGetCharAt(i);
 | 
			
		||||
		char next = styler.SafeGetCharAt(i+1);
 | 
			
		||||
		bool atEOL = (curr == '\r' && next != '\n') || (curr == '\n');
 | 
			
		||||
		if (styler.StyleAt(i) == SCE_JSON_OPERATOR) {
 | 
			
		||||
			if (curr == '{' || curr == '[') {
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			} else if (curr == '}' || curr == ']') {
 | 
			
		||||
				nextLevel--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (atEOL || i == (endPos-1)) {
 | 
			
		||||
			int level = currLevel | nextLevel << 16;
 | 
			
		||||
			if (!visibleChars && options.foldCompact) {
 | 
			
		||||
				level |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			} else if (nextLevel > currLevel) {
 | 
			
		||||
				level |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if (level != styler.LevelAt(currLine)) {
 | 
			
		||||
				styler.SetLevel(currLine, level);
 | 
			
		||||
			}
 | 
			
		||||
			currLine++;
 | 
			
		||||
			currLevel = nextLevel;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!isspacechar(curr)) {
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmJSON(SCLEX_JSON,
 | 
			
		||||
				   LexerJSON::LexerFactoryJSON,
 | 
			
		||||
				   "json",
 | 
			
		||||
				   JSONWordListDesc);
 | 
			
		||||
							
								
								
									
										1262
									
								
								3rdparty/lexilla540/lexilla/lexers/LexJulia.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1262
									
								
								3rdparty/lexilla540/lexilla/lexers/LexJulia.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										474
									
								
								3rdparty/lexilla540/lexilla/lexers/LexKVIrc.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										474
									
								
								3rdparty/lexilla540/lexilla/lexers/LexKVIrc.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,474 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexKVIrc.cxx
 | 
			
		||||
 ** Lexer for KVIrc script.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2013 by OmegaPhil <OmegaPhil+scintilla@gmail.com>, based in
 | 
			
		||||
// part from LexPython Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// and LexCmake Copyright 2007 by Cristian Adam <cristian [dot] adam [at] gmx [dot] net>
 | 
			
		||||
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* KVIrc Script syntactic rules: http://www.kvirc.net/doc/doc_syntactic_rules.html */
 | 
			
		||||
 | 
			
		||||
/* Utility functions */
 | 
			
		||||
static inline bool IsAWordChar(int ch) {
 | 
			
		||||
 | 
			
		||||
    /* Keyword list includes modules, i.e. words including '.', and
 | 
			
		||||
     * alias namespaces include ':' */
 | 
			
		||||
    return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.'
 | 
			
		||||
            || ch == ':');
 | 
			
		||||
}
 | 
			
		||||
static inline bool IsAWordStart(int ch) {
 | 
			
		||||
 | 
			
		||||
    /* Functions (start with '$') are treated separately to keywords */
 | 
			
		||||
    return (ch < 0x80) && (isalnum(ch) || ch == '_' );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Interface function called by Scintilla to request some text to be
 | 
			
		||||
 syntax highlighted */
 | 
			
		||||
static void ColouriseKVIrcDoc(Sci_PositionU startPos, Sci_Position length,
 | 
			
		||||
                              int initStyle, WordList *keywordlists[],
 | 
			
		||||
                              Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
    /* Fetching style context */
 | 
			
		||||
    StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
    /* Accessing keywords and function-marking keywords */
 | 
			
		||||
    WordList &keywords = *keywordlists[0];
 | 
			
		||||
    WordList &functionKeywords = *keywordlists[1];
 | 
			
		||||
 | 
			
		||||
    /* Looping for all characters - only automatically moving forward
 | 
			
		||||
     * when asked for (transitions leaving strings and keywords do this
 | 
			
		||||
     * already) */
 | 
			
		||||
    bool next = true;
 | 
			
		||||
    for( ; sc.More(); next ? sc.Forward() : (void)0 )
 | 
			
		||||
    {
 | 
			
		||||
        /* Resetting next */
 | 
			
		||||
        next = true;
 | 
			
		||||
 | 
			
		||||
        /* Dealing with different states */
 | 
			
		||||
        switch (sc.state)
 | 
			
		||||
        {
 | 
			
		||||
            case SCE_KVIRC_DEFAULT:
 | 
			
		||||
 | 
			
		||||
                /* Detecting single-line comments
 | 
			
		||||
                 * Unfortunately KVIrc script allows raw '#<channel
 | 
			
		||||
                 * name>' to be used, and appending # to an array returns
 | 
			
		||||
                 * its length...
 | 
			
		||||
                 * Going for a compromise where single line comments not
 | 
			
		||||
                 * starting on a newline are allowed in all cases except
 | 
			
		||||
                 * when they are preceeded with an opening bracket or comma
 | 
			
		||||
                 * (this will probably be the most common style a valid
 | 
			
		||||
                 * string-less channel name will be used with), with the
 | 
			
		||||
                 * array length case included
 | 
			
		||||
                 */
 | 
			
		||||
                if (
 | 
			
		||||
                    (sc.ch == '#' && sc.atLineStart) ||
 | 
			
		||||
                    (sc.ch == '#' && (
 | 
			
		||||
                        sc.chPrev != '(' && sc.chPrev != ',' &&
 | 
			
		||||
                        sc.chPrev != ']')
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_COMMENT);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Detecting multi-line comments */
 | 
			
		||||
                if (sc.Match('/', '*'))
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_COMMENTBLOCK);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Detecting strings */
 | 
			
		||||
                if (sc.ch == '"')
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_STRING);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Detecting functions */
 | 
			
		||||
                if (sc.ch == '$')
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_FUNCTION);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Detecting variables */
 | 
			
		||||
                if (sc.ch == '%')
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_VARIABLE);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Detecting numbers - isdigit is unsafe as it does not
 | 
			
		||||
                 * validate, use CharacterSet.h functions */
 | 
			
		||||
                if (IsADigit(sc.ch))
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_NUMBER);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Detecting words */
 | 
			
		||||
                if (IsAWordStart(sc.ch) && IsAWordChar(sc.chNext))
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_WORD);
 | 
			
		||||
                    sc.Forward();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Detecting operators */
 | 
			
		||||
                if (isoperator(sc.ch))
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_OPERATOR);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case SCE_KVIRC_COMMENT:
 | 
			
		||||
 | 
			
		||||
                /* Breaking out of single line comment when a newline
 | 
			
		||||
                 * is introduced */
 | 
			
		||||
                if (sc.ch == '\r' || sc.ch == '\n')
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_DEFAULT);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case SCE_KVIRC_COMMENTBLOCK:
 | 
			
		||||
 | 
			
		||||
                /* Detecting end of multi-line comment */
 | 
			
		||||
                if (sc.Match('*', '/'))
 | 
			
		||||
                {
 | 
			
		||||
                    // Moving the current position forward two characters
 | 
			
		||||
                    // so that '*/' is included in the comment
 | 
			
		||||
                    sc.Forward(2);
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_DEFAULT);
 | 
			
		||||
 | 
			
		||||
                    /* Comment has been exited and the current position
 | 
			
		||||
                     * moved forward, yet the new current character
 | 
			
		||||
                     * has yet to be defined - loop without moving
 | 
			
		||||
                     * forward again */
 | 
			
		||||
                    next = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case SCE_KVIRC_STRING:
 | 
			
		||||
 | 
			
		||||
                /* Detecting end of string - closing speechmarks */
 | 
			
		||||
                if (sc.ch == '"')
 | 
			
		||||
                {
 | 
			
		||||
                    /* Allowing escaped speechmarks to pass */
 | 
			
		||||
                    if (sc.chPrev == '\\')
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    /* Moving the current position forward to capture the
 | 
			
		||||
                     * terminating speechmarks, and ending string */
 | 
			
		||||
                    sc.ForwardSetState(SCE_KVIRC_DEFAULT);
 | 
			
		||||
 | 
			
		||||
                    /* String has been exited and the current position
 | 
			
		||||
                     * moved forward, yet the new current character
 | 
			
		||||
                     * has yet to be defined - loop without moving
 | 
			
		||||
                     * forward again */
 | 
			
		||||
                    next = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Functions and variables are now highlighted in strings
 | 
			
		||||
                 * Detecting functions */
 | 
			
		||||
                if (sc.ch == '$')
 | 
			
		||||
                {
 | 
			
		||||
                    /* Allowing escaped functions to pass */
 | 
			
		||||
                    if (sc.chPrev == '\\')
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_STRING_FUNCTION);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Detecting variables */
 | 
			
		||||
                if (sc.ch == '%')
 | 
			
		||||
                {
 | 
			
		||||
                    /* Allowing escaped variables to pass */
 | 
			
		||||
                    if (sc.chPrev == '\\')
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_STRING_VARIABLE);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Breaking out of a string when a newline is introduced */
 | 
			
		||||
                if (sc.ch == '\r' || sc.ch == '\n')
 | 
			
		||||
                {
 | 
			
		||||
                    /* Allowing escaped newlines */
 | 
			
		||||
                    if (sc.chPrev == '\\')
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_DEFAULT);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case SCE_KVIRC_FUNCTION:
 | 
			
		||||
            case SCE_KVIRC_VARIABLE:
 | 
			
		||||
 | 
			
		||||
                /* Detecting the end of a function/variable (word) */
 | 
			
		||||
                if (!IsAWordChar(sc.ch))
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_DEFAULT);
 | 
			
		||||
 | 
			
		||||
                    /* Word has been exited yet the current character
 | 
			
		||||
                     * has yet to be defined - loop without moving
 | 
			
		||||
                     * forward again */
 | 
			
		||||
                    next = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case SCE_KVIRC_STRING_FUNCTION:
 | 
			
		||||
            case SCE_KVIRC_STRING_VARIABLE:
 | 
			
		||||
 | 
			
		||||
                /* A function or variable in a string
 | 
			
		||||
                 * Detecting the end of a function/variable (word) */
 | 
			
		||||
                if (!IsAWordChar(sc.ch))
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_STRING);
 | 
			
		||||
 | 
			
		||||
                    /* Word has been exited yet the current character
 | 
			
		||||
                     * has yet to be defined - loop without moving
 | 
			
		||||
                     * forward again */
 | 
			
		||||
                    next = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case SCE_KVIRC_NUMBER:
 | 
			
		||||
 | 
			
		||||
                /* Detecting the end of a number */
 | 
			
		||||
                if (!IsADigit(sc.ch))
 | 
			
		||||
                {
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_DEFAULT);
 | 
			
		||||
 | 
			
		||||
                    /* Number has been exited yet the current character
 | 
			
		||||
                     * has yet to be defined - loop without moving
 | 
			
		||||
                     * forward */
 | 
			
		||||
                    next = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case SCE_KVIRC_OPERATOR:
 | 
			
		||||
 | 
			
		||||
                /* Because '%' is an operator but is also the marker for
 | 
			
		||||
                 * a variable, I need to always treat operators as single
 | 
			
		||||
                 * character strings and therefore redo their detection
 | 
			
		||||
                 * after every character */
 | 
			
		||||
                sc.SetState(SCE_KVIRC_DEFAULT);
 | 
			
		||||
 | 
			
		||||
                /* Operator has been exited yet the current character
 | 
			
		||||
                 * has yet to be defined - loop without moving
 | 
			
		||||
                 * forward */
 | 
			
		||||
                next = false;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case SCE_KVIRC_WORD:
 | 
			
		||||
 | 
			
		||||
                /* Detecting the end of a word */
 | 
			
		||||
                if (!IsAWordChar(sc.ch))
 | 
			
		||||
                {
 | 
			
		||||
                    /* Checking if the word was actually a keyword -
 | 
			
		||||
                     * fetching the current word, NULL-terminated like
 | 
			
		||||
                     * the keyword list */
 | 
			
		||||
                    char s[100];
 | 
			
		||||
                    Sci_Position wordLen = sc.currentPos - styler.GetStartSegment();
 | 
			
		||||
                    if (wordLen > 99)
 | 
			
		||||
                        wordLen = 99;  /* Include '\0' in buffer */
 | 
			
		||||
                    Sci_Position i;
 | 
			
		||||
                    for( i = 0; i < wordLen; ++i )
 | 
			
		||||
                    {
 | 
			
		||||
                        s[i] = styler.SafeGetCharAt( styler.GetStartSegment() + i );
 | 
			
		||||
                    }
 | 
			
		||||
                    s[wordLen] = '\0';
 | 
			
		||||
 | 
			
		||||
                    /* Actually detecting keywords and fixing the state */
 | 
			
		||||
                    if (keywords.InList(s))
 | 
			
		||||
                    {
 | 
			
		||||
                        /* The SetState call actually commits the
 | 
			
		||||
                         * previous keyword state */
 | 
			
		||||
                        sc.ChangeState(SCE_KVIRC_KEYWORD);
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (functionKeywords.InList(s))
 | 
			
		||||
                    {
 | 
			
		||||
                        // Detecting function keywords and fixing the state
 | 
			
		||||
                        sc.ChangeState(SCE_KVIRC_FUNCTION_KEYWORD);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    /* Transitioning to default and committing the previous
 | 
			
		||||
                     * word state */
 | 
			
		||||
                    sc.SetState(SCE_KVIRC_DEFAULT);
 | 
			
		||||
 | 
			
		||||
                    /* Word has been exited yet the current character
 | 
			
		||||
                     * has yet to be defined - loop without moving
 | 
			
		||||
                     * forward again */
 | 
			
		||||
                    next = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Indicating processing is complete */
 | 
			
		||||
    sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldKVIrcDoc(Sci_PositionU startPos, Sci_Position length, int /*initStyle - unused*/,
 | 
			
		||||
                      WordList *[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
    /* Based on CMake's folder */
 | 
			
		||||
 | 
			
		||||
    /* Exiting if folding isnt enabled */
 | 
			
		||||
    if ( styler.GetPropertyInt("fold") == 0 )
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    /* Obtaining current line number*/
 | 
			
		||||
    Sci_Position currentLine = styler.GetLine(startPos);
 | 
			
		||||
 | 
			
		||||
    /* Obtaining starting character - indentation is done on a line basis,
 | 
			
		||||
     * not character */
 | 
			
		||||
    Sci_PositionU safeStartPos = styler.LineStart( currentLine );
 | 
			
		||||
 | 
			
		||||
    /* Initialising current level - this is defined as indentation level
 | 
			
		||||
     * in the low 12 bits, with flag bits in the upper four bits.
 | 
			
		||||
     * It looks like two indentation states are maintained in the returned
 | 
			
		||||
     * 32bit value - 'nextLevel' in the most-significant bits, 'currentLevel'
 | 
			
		||||
     * in the least-significant bits. Since the next level is the most
 | 
			
		||||
     * up to date, this must refer to the current state of indentation.
 | 
			
		||||
     * So the code bitshifts the old current level out of existence to
 | 
			
		||||
     * get at the actual current state of indentation
 | 
			
		||||
     * Based on the LexerCPP.cxx line 958 comment */
 | 
			
		||||
    int currentLevel = SC_FOLDLEVELBASE;
 | 
			
		||||
    if (currentLine > 0)
 | 
			
		||||
        currentLevel = styler.LevelAt(currentLine - 1) >> 16;
 | 
			
		||||
    int nextLevel = currentLevel;
 | 
			
		||||
 | 
			
		||||
    // Looping for characters in range
 | 
			
		||||
    for (Sci_PositionU i = safeStartPos; i < startPos + length; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        /* Folding occurs after syntax highlighting, meaning Scintilla
 | 
			
		||||
         * already knows where the comments are
 | 
			
		||||
         * Fetching the current state */
 | 
			
		||||
        int state = styler.StyleAt(i) & 31;
 | 
			
		||||
 | 
			
		||||
        switch( styler.SafeGetCharAt(i) )
 | 
			
		||||
        {
 | 
			
		||||
            case '{':
 | 
			
		||||
 | 
			
		||||
                /* Indenting only when the braces are not contained in
 | 
			
		||||
                 * a comment */
 | 
			
		||||
                if (state != SCE_KVIRC_COMMENT &&
 | 
			
		||||
                    state != SCE_KVIRC_COMMENTBLOCK)
 | 
			
		||||
                    ++nextLevel;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case '}':
 | 
			
		||||
 | 
			
		||||
                /* Outdenting only when the braces are not contained in
 | 
			
		||||
                 * a comment */
 | 
			
		||||
                if (state != SCE_KVIRC_COMMENT &&
 | 
			
		||||
                    state != SCE_KVIRC_COMMENTBLOCK)
 | 
			
		||||
                    --nextLevel;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case '\n':
 | 
			
		||||
            case '\r':
 | 
			
		||||
 | 
			
		||||
                /* Preparing indentation information to return - combining
 | 
			
		||||
                 * current and next level data */
 | 
			
		||||
                int lev = currentLevel | nextLevel << 16;
 | 
			
		||||
 | 
			
		||||
                /* If the next level increases the indent level, mark the
 | 
			
		||||
                 * current line as a fold point - current level data is
 | 
			
		||||
                 * in the least significant bits */
 | 
			
		||||
                if (nextLevel > currentLevel )
 | 
			
		||||
                    lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
 | 
			
		||||
                /* Updating indentation level if needed */
 | 
			
		||||
                if (lev != styler.LevelAt(currentLine))
 | 
			
		||||
                    styler.SetLevel(currentLine, lev);
 | 
			
		||||
 | 
			
		||||
                /* Updating variables */
 | 
			
		||||
                ++currentLine;
 | 
			
		||||
                currentLevel = nextLevel;
 | 
			
		||||
 | 
			
		||||
                /* Dealing with problematic Windows newlines -
 | 
			
		||||
                 * incrementing to avoid the extra newline breaking the
 | 
			
		||||
                 * fold point */
 | 
			
		||||
                if (styler.SafeGetCharAt(i) == '\r' &&
 | 
			
		||||
                    styler.SafeGetCharAt(i + 1) == '\n')
 | 
			
		||||
                    ++i;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* At this point the data has ended, so presumably the end of the line?
 | 
			
		||||
     * Preparing indentation information to return - combining current
 | 
			
		||||
     * and next level data */
 | 
			
		||||
    int lev = currentLevel | nextLevel << 16;
 | 
			
		||||
 | 
			
		||||
    /* If the next level increases the indent level, mark the current
 | 
			
		||||
     * line as a fold point - current level data is in the least
 | 
			
		||||
     * significant bits */
 | 
			
		||||
    if (nextLevel > currentLevel )
 | 
			
		||||
        lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
 | 
			
		||||
    /* Updating indentation level if needed */
 | 
			
		||||
    if (lev != styler.LevelAt(currentLine))
 | 
			
		||||
        styler.SetLevel(currentLine, lev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Registering wordlists */
 | 
			
		||||
static const char *const kvircWordListDesc[] = {
 | 
			
		||||
	"primary",
 | 
			
		||||
	"function_keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Registering functions and wordlists */
 | 
			
		||||
extern const LexerModule lmKVIrc(SCLEX_KVIRC, ColouriseKVIrcDoc, "kvirc", FoldKVIrcDoc,
 | 
			
		||||
                    kvircWordListDesc);
 | 
			
		||||
							
								
								
									
										137
									
								
								3rdparty/lexilla540/lexilla/lexers/LexKix.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								3rdparty/lexilla540/lexilla/lexers/LexKix.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,137 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexKix.cxx
 | 
			
		||||
 ** Lexer for KIX-Scripts.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2004 by Manfred Becker <manfred@becker-trdf.de>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
// Edited by Lee Wilmott (24-Jun-2014) added support for block comments
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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;
 | 
			
		||||
 | 
			
		||||
// Extended to accept accented characters
 | 
			
		||||
static inline bool IsAWordChar(int ch) {
 | 
			
		||||
	return ch >= 0x80 || isalnum(ch) || ch == '_';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsOperator(const int ch) {
 | 
			
		||||
	return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '&' || ch == '|' || ch == '<' || ch == '>' || ch == '=');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseKixDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                           WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
	WordList &keywords2 = *keywordlists[1];
 | 
			
		||||
	WordList &keywords3 = *keywordlists[2];
 | 
			
		||||
//	WordList &keywords4 = *keywordlists[3];
 | 
			
		||||
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
		if (sc.state == SCE_KIX_COMMENT) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_KIX_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_KIX_COMMENTSTREAM) {
 | 
			
		||||
			if (sc.ch == '/' && sc.chPrev == '*') {
 | 
			
		||||
				sc.ForwardSetState(SCE_KIX_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_KIX_STRING1) {
 | 
			
		||||
			// This is a doubles quotes string
 | 
			
		||||
			if (sc.ch == '\"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_KIX_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_KIX_STRING2) {
 | 
			
		||||
			// This is a single quote string
 | 
			
		||||
			if (sc.ch == '\'') {
 | 
			
		||||
				sc.ForwardSetState(SCE_KIX_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_KIX_NUMBER) {
 | 
			
		||||
			if (!IsADigit(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_KIX_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_KIX_VAR) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_KIX_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_KIX_MACRO) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch) && !IsADigit(sc.ch)) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
 | 
			
		||||
				if (!keywords3.InList(&s[1])) {
 | 
			
		||||
					sc.ChangeState(SCE_KIX_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_KIX_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_KIX_OPERATOR) {
 | 
			
		||||
			if (!IsOperator(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_KIX_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_KIX_IDENTIFIER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrentLowered(s, sizeof(s));
 | 
			
		||||
 | 
			
		||||
				if (keywords.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_KIX_KEYWORD);
 | 
			
		||||
				} else if (keywords2.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_KIX_FUNCTIONS);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_KIX_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_KIX_DEFAULT) {
 | 
			
		||||
			if (sc.ch == ';') {
 | 
			
		||||
				sc.SetState(SCE_KIX_COMMENT);
 | 
			
		||||
			} else if (sc.ch == '/' && sc.chNext == '*') {
 | 
			
		||||
				sc.SetState(SCE_KIX_COMMENTSTREAM);
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_KIX_STRING1);
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(SCE_KIX_STRING2);
 | 
			
		||||
			} else if (sc.ch == '$') {
 | 
			
		||||
				sc.SetState(SCE_KIX_VAR);
 | 
			
		||||
			} else if (sc.ch == '@') {
 | 
			
		||||
				sc.SetState(SCE_KIX_MACRO);
 | 
			
		||||
			} else if (IsADigit(sc.ch) || ((sc.ch == '.' || sc.ch == '&') && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_KIX_NUMBER);
 | 
			
		||||
			} else if (IsOperator(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_KIX_OPERATOR);
 | 
			
		||||
			} else if (IsAWordChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_KIX_IDENTIFIER);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmKix(SCLEX_KIX, ColouriseKixDoc, "kix");
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										563
									
								
								3rdparty/lexilla540/lexilla/lexers/LexLaTeX.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										563
									
								
								3rdparty/lexilla540/lexilla/lexers/LexLaTeX.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,563 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexLaTeX.cxx
 | 
			
		||||
 ** Lexer for LaTeX2e.
 | 
			
		||||
  **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
// Modified by G. HU in 2013. Added folding, syntax highting inside math environments, and changed some minor behaviors.
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "PropSetSimple.h"
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "Accessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
#include "LexerBase.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
struct latexFoldSave {
 | 
			
		||||
	latexFoldSave() : structLev(0) {
 | 
			
		||||
		for (int i = 0; i < 8; ++i) openBegins[i] = 0;
 | 
			
		||||
	}
 | 
			
		||||
	latexFoldSave(const latexFoldSave &save) : structLev(save.structLev) {
 | 
			
		||||
		for (int i = 0; i < 8; ++i) openBegins[i] = save.openBegins[i];
 | 
			
		||||
	}
 | 
			
		||||
	latexFoldSave &operator=(const latexFoldSave &save) {
 | 
			
		||||
		if (this != &save) {
 | 
			
		||||
			structLev = save.structLev;
 | 
			
		||||
			for (int i = 0; i < 8; ++i) openBegins[i] = save.openBegins[i];
 | 
			
		||||
		}
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	int openBegins[8];
 | 
			
		||||
	Sci_Position structLev;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LexerLaTeX : public LexerBase {
 | 
			
		||||
private:
 | 
			
		||||
	vector<int> modes;
 | 
			
		||||
	void setMode(Sci_Position line, int mode) {
 | 
			
		||||
		if (line >= static_cast<Sci_Position>(modes.size())) modes.resize(line + 1, 0);
 | 
			
		||||
		modes[line] = mode;
 | 
			
		||||
	}
 | 
			
		||||
	int getMode(Sci_Position line) {
 | 
			
		||||
		if (line >= 0 && line < static_cast<Sci_Position>(modes.size())) return modes[line];
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	void truncModes(Sci_Position numLines) {
 | 
			
		||||
		if (static_cast<Sci_Position>(modes.size()) > numLines * 2 + 256)
 | 
			
		||||
			modes.resize(numLines + 128);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vector<latexFoldSave> saves;
 | 
			
		||||
	void setSave(Sci_Position line, const latexFoldSave &save) {
 | 
			
		||||
		if (line >= static_cast<Sci_Position>(saves.size())) saves.resize(line + 1);
 | 
			
		||||
		saves[line] = save;
 | 
			
		||||
	}
 | 
			
		||||
	void getSave(Sci_Position line, latexFoldSave &save) {
 | 
			
		||||
		if (line >= 0 && line < static_cast<Sci_Position>(saves.size())) save = saves[line];
 | 
			
		||||
		else {
 | 
			
		||||
			save.structLev = 0;
 | 
			
		||||
			for (int i = 0; i < 8; ++i) save.openBegins[i] = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	void truncSaves(Sci_Position numLines) {
 | 
			
		||||
		if (static_cast<Sci_Position>(saves.size()) > numLines * 2 + 256)
 | 
			
		||||
			saves.resize(numLines + 128);
 | 
			
		||||
	}
 | 
			
		||||
public:
 | 
			
		||||
	static ILexer5 *LexerFactoryLaTeX() {
 | 
			
		||||
		return new LexerLaTeX();
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
	void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
 | 
			
		||||
	// ILexer5 methods
 | 
			
		||||
	const char * SCI_METHOD GetName() override {
 | 
			
		||||
		return "latex";
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD  GetIdentifier() override {
 | 
			
		||||
		return SCLEX_LATEX;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool latexIsSpecial(int ch) {
 | 
			
		||||
	return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||
 | 
			
		||||
		   (ch == '{') || (ch == '}') || (ch == ' ');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool latexIsBlank(int ch) {
 | 
			
		||||
	return (ch == ' ') || (ch == '\t');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool latexIsBlankAndNL(int ch) {
 | 
			
		||||
	return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool latexIsLetter(int ch) {
 | 
			
		||||
	return IsASCII(ch) && isalpha(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool latexIsTagValid(Sci_Position &i, Sci_Position l, Accessor &styler) {
 | 
			
		||||
	while (i < l) {
 | 
			
		||||
		if (styler.SafeGetCharAt(i) == '{') {
 | 
			
		||||
			while (i < l) {
 | 
			
		||||
				i++;
 | 
			
		||||
				if (styler.SafeGetCharAt(i) == '}') {
 | 
			
		||||
					return true;
 | 
			
		||||
				}	else if (!latexIsLetter(styler.SafeGetCharAt(i)) &&
 | 
			
		||||
                   styler.SafeGetCharAt(i)!='*') {
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (!latexIsBlank(styler.SafeGetCharAt(i))) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool latexNextNotBlankIs(Sci_Position i, Accessor &styler, char needle) {
 | 
			
		||||
  char ch;
 | 
			
		||||
	while (i < styler.Length()) {
 | 
			
		||||
    ch = styler.SafeGetCharAt(i);
 | 
			
		||||
		if (!latexIsBlankAndNL(ch) && ch != '*') {
 | 
			
		||||
      if (ch == needle)
 | 
			
		||||
        return true;
 | 
			
		||||
      else
 | 
			
		||||
        return false;
 | 
			
		||||
		}
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool latexLastWordIs(Sci_Position start, Accessor &styler, const char *needle) {
 | 
			
		||||
	Sci_PositionU i = 0;
 | 
			
		||||
	Sci_PositionU l = static_cast<Sci_PositionU>(strlen(needle));
 | 
			
		||||
	Sci_Position ini = start-l+1;
 | 
			
		||||
	char s[32];
 | 
			
		||||
 | 
			
		||||
	while (i < l && i < 31) {
 | 
			
		||||
		s[i] = styler.SafeGetCharAt(ini + i);
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	s[i] = '\0';
 | 
			
		||||
 | 
			
		||||
	return (strcmp(s, needle) == 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool latexLastWordIsMathEnv(Sci_Position pos, Accessor &styler) {
 | 
			
		||||
	Sci_Position i, j;
 | 
			
		||||
	char s[32];
 | 
			
		||||
	const char *mathEnvs[] = { "align", "alignat", "flalign", "gather",
 | 
			
		||||
		"multiline", "displaymath", "eqnarray", "equation" };
 | 
			
		||||
	if (styler.SafeGetCharAt(pos) != '}') return false;
 | 
			
		||||
	for (i = pos - 1; i >= 0; --i) {
 | 
			
		||||
		if (styler.SafeGetCharAt(i) == '{') break;
 | 
			
		||||
		if (pos - i >= 20) return false;
 | 
			
		||||
	}
 | 
			
		||||
	if (i < 0 || i == pos - 1) return false;
 | 
			
		||||
	++i;
 | 
			
		||||
	for (j = 0; i + j < pos; ++j)
 | 
			
		||||
		s[j] = styler.SafeGetCharAt(i + j);
 | 
			
		||||
	s[j] = '\0';
 | 
			
		||||
	if (j == 0) return false;
 | 
			
		||||
	if (s[j - 1] == '*') s[--j] = '\0';
 | 
			
		||||
	for (i = 0; i < static_cast<int>(sizeof(mathEnvs) / sizeof(const char *)); ++i)
 | 
			
		||||
		if (strcmp(s, mathEnvs[i]) == 0) return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void latexStateReset(int &mode, int &state) {
 | 
			
		||||
	switch (mode) {
 | 
			
		||||
	case 1:     state = SCE_L_MATH; break;
 | 
			
		||||
	case 2:     state = SCE_L_MATH2; break;
 | 
			
		||||
	default:    state = SCE_L_DEFAULT; break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// There are cases not handled correctly, like $abcd\textrm{what is $x+y$}z+w$.
 | 
			
		||||
// But I think it's already good enough.
 | 
			
		||||
void SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
	// startPos is assumed to be the first character of a line
 | 
			
		||||
	Accessor styler(pAccess, &props);
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
	int mode = getMode(styler.GetLine(startPos) - 1);
 | 
			
		||||
	int state = initStyle;
 | 
			
		||||
	if (state == SCE_L_ERROR || state == SCE_L_SHORTCMD || state == SCE_L_SPECIAL)   // should not happen
 | 
			
		||||
		latexStateReset(mode, state);
 | 
			
		||||
 | 
			
		||||
	char chNext = styler.SafeGetCharAt(startPos);
 | 
			
		||||
	char chVerbatimDelim = '\0';
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
	Sci_Position lengthDoc = startPos + length;
 | 
			
		||||
 | 
			
		||||
	for (Sci_Position i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
		if (styler.IsLeadByte(ch)) {
 | 
			
		||||
			i++;
 | 
			
		||||
			chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (ch == '\r' || ch == '\n')
 | 
			
		||||
			setMode(styler.GetLine(i), mode);
 | 
			
		||||
 | 
			
		||||
		switch (state) {
 | 
			
		||||
		case SCE_L_DEFAULT :
 | 
			
		||||
			switch (ch) {
 | 
			
		||||
			case '\\' :
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				if (latexIsLetter(chNext)) {
 | 
			
		||||
					state = SCE_L_COMMAND;
 | 
			
		||||
				} else if (latexIsSpecial(chNext)) {
 | 
			
		||||
					styler.ColourTo(i + 1, SCE_L_SPECIAL);
 | 
			
		||||
					i++;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				} else if (chNext == '\r' || chNext == '\n') {
 | 
			
		||||
					styler.ColourTo(i, SCE_L_ERROR);
 | 
			
		||||
				} else if (IsASCII(chNext)) {
 | 
			
		||||
					styler.ColourTo(i + 1, SCE_L_SHORTCMD);
 | 
			
		||||
					if (chNext == '(') {
 | 
			
		||||
						mode = 1;
 | 
			
		||||
						state = SCE_L_MATH;
 | 
			
		||||
					} else if (chNext == '[') {
 | 
			
		||||
						mode = 2;
 | 
			
		||||
						state = SCE_L_MATH2;
 | 
			
		||||
					}
 | 
			
		||||
					i++;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '$' :
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				if (chNext == '$') {
 | 
			
		||||
					styler.ColourTo(i + 1, SCE_L_SHORTCMD);
 | 
			
		||||
					mode = 2;
 | 
			
		||||
					state = SCE_L_MATH2;
 | 
			
		||||
					i++;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				} else {
 | 
			
		||||
					styler.ColourTo(i, SCE_L_SHORTCMD);
 | 
			
		||||
					mode = 1;
 | 
			
		||||
					state = SCE_L_MATH;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '%' :
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				state = SCE_L_COMMENT;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		// These 3 will never be reached.
 | 
			
		||||
		case SCE_L_ERROR:
 | 
			
		||||
		case SCE_L_SPECIAL:
 | 
			
		||||
		case SCE_L_SHORTCMD:
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_L_COMMAND :
 | 
			
		||||
			if (!latexIsLetter(chNext)) {
 | 
			
		||||
				styler.ColourTo(i, state);
 | 
			
		||||
				if (latexNextNotBlankIs(i + 1, styler, '[' )) {
 | 
			
		||||
					state = SCE_L_CMDOPT;
 | 
			
		||||
				} else if (latexLastWordIs(i, styler, "\\begin")) {
 | 
			
		||||
					state = SCE_L_TAG;
 | 
			
		||||
				} else if (latexLastWordIs(i, styler, "\\end")) {
 | 
			
		||||
					state = SCE_L_TAG2;
 | 
			
		||||
				} else if (latexLastWordIs(i, styler, "\\verb") && chNext != '*' && chNext != ' ') {
 | 
			
		||||
					chVerbatimDelim = chNext;
 | 
			
		||||
					state = SCE_L_VERBATIM;
 | 
			
		||||
				} else {
 | 
			
		||||
					latexStateReset(mode, state);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_L_CMDOPT :
 | 
			
		||||
			if (ch == ']') {
 | 
			
		||||
				styler.ColourTo(i, state);
 | 
			
		||||
				latexStateReset(mode, state);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_L_TAG :
 | 
			
		||||
			if (latexIsTagValid(i, lengthDoc, styler)) {
 | 
			
		||||
				styler.ColourTo(i, state);
 | 
			
		||||
				latexStateReset(mode, state);
 | 
			
		||||
				if (latexLastWordIs(i, styler, "{verbatim}")) {
 | 
			
		||||
					state = SCE_L_VERBATIM;
 | 
			
		||||
				} else if (latexLastWordIs(i, styler, "{lstlisting}")) {
 | 
			
		||||
					state = SCE_L_VERBATIM;
 | 
			
		||||
				} else if (latexLastWordIs(i, styler, "{comment}")) {
 | 
			
		||||
					state = SCE_L_COMMENT2;
 | 
			
		||||
				} else if (latexLastWordIs(i, styler, "{math}") && mode == 0) {
 | 
			
		||||
					mode = 1;
 | 
			
		||||
					state = SCE_L_MATH;
 | 
			
		||||
				} else if (latexLastWordIsMathEnv(i, styler) && mode == 0) {
 | 
			
		||||
					mode = 2;
 | 
			
		||||
					state = SCE_L_MATH2;
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				styler.ColourTo(i, SCE_L_ERROR);
 | 
			
		||||
				latexStateReset(mode, state);
 | 
			
		||||
				ch = styler.SafeGetCharAt(i);
 | 
			
		||||
				if (ch == '\r' || ch == '\n') setMode(styler.GetLine(i), mode);
 | 
			
		||||
			}
 | 
			
		||||
			chNext = styler.SafeGetCharAt(i+1);
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_L_TAG2 :
 | 
			
		||||
			if (latexIsTagValid(i, lengthDoc, styler)) {
 | 
			
		||||
				styler.ColourTo(i, state);
 | 
			
		||||
				latexStateReset(mode, state);
 | 
			
		||||
			} else {
 | 
			
		||||
				styler.ColourTo(i, SCE_L_ERROR);
 | 
			
		||||
				latexStateReset(mode, state);
 | 
			
		||||
				ch = styler.SafeGetCharAt(i);
 | 
			
		||||
				if (ch == '\r' || ch == '\n') setMode(styler.GetLine(i), mode);
 | 
			
		||||
			}
 | 
			
		||||
			chNext = styler.SafeGetCharAt(i+1);
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_L_MATH :
 | 
			
		||||
			switch (ch) {
 | 
			
		||||
			case '\\' :
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				if (latexIsLetter(chNext)) {
 | 
			
		||||
					Sci_Position match = i + 3;
 | 
			
		||||
					if (latexLastWordIs(match, styler, "\\end")) {
 | 
			
		||||
						match++;
 | 
			
		||||
						if (latexIsTagValid(match, lengthDoc, styler)) {
 | 
			
		||||
							if (latexLastWordIs(match, styler, "{math}"))
 | 
			
		||||
								mode = 0;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					state = SCE_L_COMMAND;
 | 
			
		||||
				} else if (latexIsSpecial(chNext)) {
 | 
			
		||||
					styler.ColourTo(i + 1, SCE_L_SPECIAL);
 | 
			
		||||
					i++;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				} else if (chNext == '\r' || chNext == '\n') {
 | 
			
		||||
					styler.ColourTo(i, SCE_L_ERROR);
 | 
			
		||||
				} else if (IsASCII(chNext)) {
 | 
			
		||||
					if (chNext == ')') {
 | 
			
		||||
						mode = 0;
 | 
			
		||||
						state = SCE_L_DEFAULT;
 | 
			
		||||
					}
 | 
			
		||||
					styler.ColourTo(i + 1, SCE_L_SHORTCMD);
 | 
			
		||||
					i++;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '$' :
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				styler.ColourTo(i, SCE_L_SHORTCMD);
 | 
			
		||||
				mode = 0;
 | 
			
		||||
				state = SCE_L_DEFAULT;
 | 
			
		||||
				break;
 | 
			
		||||
			case '%' :
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				state = SCE_L_COMMENT;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_L_MATH2 :
 | 
			
		||||
			switch (ch) {
 | 
			
		||||
			case '\\' :
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				if (latexIsLetter(chNext)) {
 | 
			
		||||
					Sci_Position match = i + 3;
 | 
			
		||||
					if (latexLastWordIs(match, styler, "\\end")) {
 | 
			
		||||
						match++;
 | 
			
		||||
						if (latexIsTagValid(match, lengthDoc, styler)) {
 | 
			
		||||
							if (latexLastWordIsMathEnv(match, styler))
 | 
			
		||||
								mode = 0;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					state = SCE_L_COMMAND;
 | 
			
		||||
				} else if (latexIsSpecial(chNext)) {
 | 
			
		||||
					styler.ColourTo(i + 1, SCE_L_SPECIAL);
 | 
			
		||||
					i++;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				} else if (chNext == '\r' || chNext == '\n') {
 | 
			
		||||
					styler.ColourTo(i, SCE_L_ERROR);
 | 
			
		||||
				} else if (IsASCII(chNext)) {
 | 
			
		||||
					if (chNext == ']') {
 | 
			
		||||
						mode = 0;
 | 
			
		||||
						state = SCE_L_DEFAULT;
 | 
			
		||||
					}
 | 
			
		||||
					styler.ColourTo(i + 1, SCE_L_SHORTCMD);
 | 
			
		||||
					i++;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '$' :
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				if (chNext == '$') {
 | 
			
		||||
					styler.ColourTo(i + 1, SCE_L_SHORTCMD);
 | 
			
		||||
					i++;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
					mode = 0;
 | 
			
		||||
					state = SCE_L_DEFAULT;
 | 
			
		||||
				} else { // This may not be an error, e.g. \begin{equation}\text{$a$}\end{equation}
 | 
			
		||||
					styler.ColourTo(i, SCE_L_SHORTCMD);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '%' :
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				state = SCE_L_COMMENT;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_L_COMMENT :
 | 
			
		||||
			if (ch == '\r' || ch == '\n') {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				latexStateReset(mode, state);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_L_COMMENT2 :
 | 
			
		||||
			if (ch == '\\') {
 | 
			
		||||
				Sci_Position match = i + 3;
 | 
			
		||||
				if (latexLastWordIs(match, styler, "\\end")) {
 | 
			
		||||
					match++;
 | 
			
		||||
					if (latexIsTagValid(match, lengthDoc, styler)) {
 | 
			
		||||
						if (latexLastWordIs(match, styler, "{comment}")) {
 | 
			
		||||
							styler.ColourTo(i - 1, state);
 | 
			
		||||
							state = SCE_L_COMMAND;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case SCE_L_VERBATIM :
 | 
			
		||||
			if (ch == '\\') {
 | 
			
		||||
				Sci_Position match = i + 3;
 | 
			
		||||
				if (latexLastWordIs(match, styler, "\\end")) {
 | 
			
		||||
					match++;
 | 
			
		||||
					if (latexIsTagValid(match, lengthDoc, styler)) {
 | 
			
		||||
						if (latexLastWordIs(match, styler, "{verbatim}")) {
 | 
			
		||||
							styler.ColourTo(i - 1, state);
 | 
			
		||||
							state = SCE_L_COMMAND;
 | 
			
		||||
						} else if (latexLastWordIs(match, styler, "{lstlisting}")) {
 | 
			
		||||
							styler.ColourTo(i - 1, state);
 | 
			
		||||
							state = SCE_L_COMMAND;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else if (chNext == chVerbatimDelim) {
 | 
			
		||||
				styler.ColourTo(i + 1, state);
 | 
			
		||||
				latexStateReset(mode, state);
 | 
			
		||||
				chVerbatimDelim = '\0';
 | 
			
		||||
				i++;
 | 
			
		||||
				chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
			} else if (chVerbatimDelim != '\0' && (ch == '\n' || ch == '\r')) {
 | 
			
		||||
				styler.ColourTo(i, SCE_L_ERROR);
 | 
			
		||||
				latexStateReset(mode, state);
 | 
			
		||||
				chVerbatimDelim = '\0';
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (lengthDoc == styler.Length()) truncModes(styler.GetLine(lengthDoc - 1));
 | 
			
		||||
	styler.ColourTo(lengthDoc - 1, state);
 | 
			
		||||
	styler.Flush();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int latexFoldSaveToInt(const latexFoldSave &save) {
 | 
			
		||||
	int sum = 0;
 | 
			
		||||
	for (int i = 0; i <= save.structLev; ++i)
 | 
			
		||||
		sum += save.openBegins[i];
 | 
			
		||||
	return ((sum + save.structLev + SC_FOLDLEVELBASE) & SC_FOLDLEVELNUMBERMASK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Change folding state while processing a line
 | 
			
		||||
// Return the level before the first relevant command
 | 
			
		||||
void SCI_METHOD LexerLaTeX::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess) {
 | 
			
		||||
	const char *structWords[7] = {"part", "chapter", "section", "subsection",
 | 
			
		||||
		"subsubsection", "paragraph", "subparagraph"};
 | 
			
		||||
	Accessor styler(pAccess, &props);
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	Sci_Position curLine = styler.GetLine(startPos);
 | 
			
		||||
	latexFoldSave save;
 | 
			
		||||
	getSave(curLine - 1, save);
 | 
			
		||||
	do {
 | 
			
		||||
		char ch, buf[16];
 | 
			
		||||
		Sci_Position i, j;
 | 
			
		||||
		int lev = -1;
 | 
			
		||||
		bool needFold = false;
 | 
			
		||||
		for (i = static_cast<Sci_Position>(startPos); i < static_cast<Sci_Position>(endPos); ++i) {
 | 
			
		||||
			ch = styler.SafeGetCharAt(i);
 | 
			
		||||
			if (ch == '\r' || ch == '\n') break;
 | 
			
		||||
			if (ch != '\\' || styler.StyleAt(i) != SCE_L_COMMAND) continue;
 | 
			
		||||
			for (j = 0; j < 15 && i + 1 < static_cast<Sci_Position>(endPos); ++j, ++i) {
 | 
			
		||||
				buf[j] = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				if (!latexIsLetter(buf[j])) break;
 | 
			
		||||
			}
 | 
			
		||||
			buf[j] = '\0';
 | 
			
		||||
			if (strcmp(buf, "begin") == 0) {
 | 
			
		||||
				if (lev < 0) lev = latexFoldSaveToInt(save);
 | 
			
		||||
				++save.openBegins[save.structLev];
 | 
			
		||||
				needFold = true;
 | 
			
		||||
			}
 | 
			
		||||
			else if (strcmp(buf, "end") == 0) {
 | 
			
		||||
				while (save.structLev > 0 && save.openBegins[save.structLev] == 0)
 | 
			
		||||
					--save.structLev;
 | 
			
		||||
				if (lev < 0) lev = latexFoldSaveToInt(save);
 | 
			
		||||
				if (save.openBegins[save.structLev] > 0) --save.openBegins[save.structLev];
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				for (j = 0; j < 7; ++j)
 | 
			
		||||
					if (strcmp(buf, structWords[j]) == 0) break;
 | 
			
		||||
				if (j >= 7) continue;
 | 
			
		||||
				save.structLev = j;   // level before the command
 | 
			
		||||
				for (j = save.structLev + 1; j < 8; ++j) {
 | 
			
		||||
					save.openBegins[save.structLev] += save.openBegins[j];
 | 
			
		||||
					save.openBegins[j] = 0;
 | 
			
		||||
				}
 | 
			
		||||
				if (lev < 0) lev = latexFoldSaveToInt(save);
 | 
			
		||||
				++save.structLev;   // level after the command
 | 
			
		||||
				needFold = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (lev < 0) lev = latexFoldSaveToInt(save);
 | 
			
		||||
		if (needFold) lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
		styler.SetLevel(curLine, lev);
 | 
			
		||||
		setSave(curLine, save);
 | 
			
		||||
		++curLine;
 | 
			
		||||
		startPos = styler.LineStart(curLine);
 | 
			
		||||
		if (static_cast<Sci_Position>(startPos) == styler.Length()) {
 | 
			
		||||
			lev = latexFoldSaveToInt(save);
 | 
			
		||||
			styler.SetLevel(curLine, lev);
 | 
			
		||||
			setSave(curLine, save);
 | 
			
		||||
			truncSaves(curLine);
 | 
			
		||||
		}
 | 
			
		||||
	} while (startPos < endPos);
 | 
			
		||||
	styler.Flush();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *const emptyWordListDesc[] = {
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmLatex(SCLEX_LATEX, LexerLaTeX::LexerFactoryLaTeX, "latex", emptyWordListDesc);
 | 
			
		||||
							
								
								
									
										286
									
								
								3rdparty/lexilla540/lexilla/lexers/LexLisp.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								3rdparty/lexilla540/lexilla/lexers/LexLisp.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,286 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexLisp.cxx
 | 
			
		||||
 ** Lexer for Lisp.
 | 
			
		||||
 ** Written by Alexey Yutkin.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
#define SCE_LISP_CHARACTER 29
 | 
			
		||||
#define SCE_LISP_MACRO 30
 | 
			
		||||
#define SCE_LISP_MACRO_DISPATCH 31
 | 
			
		||||
 | 
			
		||||
static inline bool isLispoperator(char ch) {
 | 
			
		||||
	if (IsASCII(ch) && isalnum(ch))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '{' || ch == '}')
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool isLispwordstart(char ch) {
 | 
			
		||||
	return IsASCII(ch) && ch != ';'  && !isspacechar(ch) && !isLispoperator(ch) &&
 | 
			
		||||
		ch != '\n' && ch != '\r' &&  ch != '\"';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void classifyWordLisp(Sci_PositionU start, Sci_PositionU end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
 | 
			
		||||
	assert(end >= start);
 | 
			
		||||
	char s[100];
 | 
			
		||||
	Sci_PositionU i;
 | 
			
		||||
	bool digit_flag = true;
 | 
			
		||||
	for (i = 0; (i < end - start + 1) && (i < 99); i++) {
 | 
			
		||||
		s[i] = styler[start + i];
 | 
			
		||||
		s[i + 1] = '\0';
 | 
			
		||||
		if (!isdigit(s[i]) && (s[i] != '.')) digit_flag = false;
 | 
			
		||||
	}
 | 
			
		||||
	char chAttr = SCE_LISP_IDENTIFIER;
 | 
			
		||||
 | 
			
		||||
	if(digit_flag) chAttr = SCE_LISP_NUMBER;
 | 
			
		||||
	else {
 | 
			
		||||
		if (keywords.InList(s)) {
 | 
			
		||||
			chAttr = SCE_LISP_KEYWORD;
 | 
			
		||||
		} else if (keywords_kw.InList(s)) {
 | 
			
		||||
			chAttr = SCE_LISP_KEYWORD_KW;
 | 
			
		||||
		} else if ((s[0] == '*' && s[i-1] == '*') ||
 | 
			
		||||
			   (s[0] == '+' && s[i-1] == '+')) {
 | 
			
		||||
			chAttr = SCE_LISP_SPECIAL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	styler.ColourTo(end, chAttr);
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void ColouriseLispDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
	WordList &keywords_kw = *keywordlists[1];
 | 
			
		||||
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
 | 
			
		||||
	int state = initStyle, radix = -1;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	Sci_PositionU lengthDoc = startPos + length;
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
 | 
			
		||||
		if (styler.IsLeadByte(ch)) {
 | 
			
		||||
			chNext = styler.SafeGetCharAt(i + 2);
 | 
			
		||||
			i += 1;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (state == SCE_LISP_DEFAULT) {
 | 
			
		||||
			if (ch == '#') {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				radix = -1;
 | 
			
		||||
				state = SCE_LISP_MACRO_DISPATCH;
 | 
			
		||||
			} else if (ch == ':' && isLispwordstart(chNext)) {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				state = SCE_LISP_SYMBOL;
 | 
			
		||||
			} else if (isLispwordstart(ch)) {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				state = SCE_LISP_IDENTIFIER;
 | 
			
		||||
			}
 | 
			
		||||
			else if (ch == ';') {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				state = SCE_LISP_COMMENT;
 | 
			
		||||
			}
 | 
			
		||||
			else if (isLispoperator(ch) || ch=='\'') {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				styler.ColourTo(i, SCE_LISP_OPERATOR);
 | 
			
		||||
				if (ch=='\'' && isLispwordstart(chNext)) {
 | 
			
		||||
					state = SCE_LISP_SYMBOL;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (ch == '\"') {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				state = SCE_LISP_STRING;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_LISP_IDENTIFIER || state == SCE_LISP_SYMBOL) {
 | 
			
		||||
			if (!isLispwordstart(ch)) {
 | 
			
		||||
				if (state == SCE_LISP_IDENTIFIER) {
 | 
			
		||||
					classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, keywords_kw, styler);
 | 
			
		||||
				} else {
 | 
			
		||||
					styler.ColourTo(i - 1, state);
 | 
			
		||||
				}
 | 
			
		||||
				state = SCE_LISP_DEFAULT;
 | 
			
		||||
			} /*else*/
 | 
			
		||||
			if (isLispoperator(ch) || ch=='\'') {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				styler.ColourTo(i, SCE_LISP_OPERATOR);
 | 
			
		||||
				if (ch=='\'' && isLispwordstart(chNext)) {
 | 
			
		||||
					state = SCE_LISP_SYMBOL;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_LISP_MACRO_DISPATCH) {
 | 
			
		||||
			if (!(IsASCII(ch) && isdigit(ch))) {
 | 
			
		||||
				if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
 | 
			
		||||
					state = SCE_LISP_DEFAULT;
 | 
			
		||||
				} else {
 | 
			
		||||
					switch (ch) {
 | 
			
		||||
						case '|': state = SCE_LISP_MULTI_COMMENT; break;
 | 
			
		||||
						case 'o':
 | 
			
		||||
						case 'O': radix = 8; state = SCE_LISP_MACRO; break;
 | 
			
		||||
						case 'x':
 | 
			
		||||
						case 'X': radix = 16; state = SCE_LISP_MACRO; break;
 | 
			
		||||
						case 'b':
 | 
			
		||||
						case 'B': radix = 2; state = SCE_LISP_MACRO; break;
 | 
			
		||||
						case '\\': state = SCE_LISP_CHARACTER; break;
 | 
			
		||||
						case ':':
 | 
			
		||||
						case '-':
 | 
			
		||||
						case '+': state = SCE_LISP_MACRO; break;
 | 
			
		||||
						case '\'': if (isLispwordstart(chNext)) {
 | 
			
		||||
								   state = SCE_LISP_SPECIAL;
 | 
			
		||||
							   } else {
 | 
			
		||||
								   styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
 | 
			
		||||
								   styler.ColourTo(i, SCE_LISP_OPERATOR);
 | 
			
		||||
								   state = SCE_LISP_DEFAULT;
 | 
			
		||||
							   }
 | 
			
		||||
							   break;
 | 
			
		||||
						default: if (isLispoperator(ch)) {
 | 
			
		||||
								 styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
 | 
			
		||||
								 styler.ColourTo(i, SCE_LISP_OPERATOR);
 | 
			
		||||
							 }
 | 
			
		||||
							 state = SCE_LISP_DEFAULT;
 | 
			
		||||
							 break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_LISP_MACRO) {
 | 
			
		||||
			if (isLispwordstart(ch) && (radix == -1 || IsADigit(ch, radix))) {
 | 
			
		||||
				state = SCE_LISP_SPECIAL;
 | 
			
		||||
			} else {
 | 
			
		||||
				state = SCE_LISP_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_LISP_CHARACTER) {
 | 
			
		||||
			if (isLispoperator(ch)) {
 | 
			
		||||
				styler.ColourTo(i, SCE_LISP_SPECIAL);
 | 
			
		||||
				state = SCE_LISP_DEFAULT;
 | 
			
		||||
			} else if (isLispwordstart(ch)) {
 | 
			
		||||
				styler.ColourTo(i, SCE_LISP_SPECIAL);
 | 
			
		||||
				state = SCE_LISP_SPECIAL;
 | 
			
		||||
			} else {
 | 
			
		||||
				state = SCE_LISP_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_LISP_SPECIAL) {
 | 
			
		||||
			if (!isLispwordstart(ch) || (radix != -1 && !IsADigit(ch, radix))) {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				state = SCE_LISP_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
			if (isLispoperator(ch) || ch=='\'') {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				styler.ColourTo(i, SCE_LISP_OPERATOR);
 | 
			
		||||
				if (ch=='\'' && isLispwordstart(chNext)) {
 | 
			
		||||
					state = SCE_LISP_SYMBOL;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			if (state == SCE_LISP_COMMENT) {
 | 
			
		||||
				if (atEOL) {
 | 
			
		||||
					styler.ColourTo(i - 1, state);
 | 
			
		||||
					state = SCE_LISP_DEFAULT;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (state == SCE_LISP_MULTI_COMMENT) {
 | 
			
		||||
				if (ch == '|' && chNext == '#') {
 | 
			
		||||
					i++;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
					styler.ColourTo(i, state);
 | 
			
		||||
					state = SCE_LISP_DEFAULT;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (state == SCE_LISP_STRING) {
 | 
			
		||||
				if (ch == '\\') {
 | 
			
		||||
					if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
 | 
			
		||||
						i++;
 | 
			
		||||
						chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
					}
 | 
			
		||||
				} else if (ch == '\"') {
 | 
			
		||||
					styler.ColourTo(i, state);
 | 
			
		||||
					state = SCE_LISP_DEFAULT;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	styler.ColourTo(lengthDoc - 1, state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldLispDoc(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[],
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
	Sci_PositionU lengthDoc = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if (style == SCE_LISP_OPERATOR) {
 | 
			
		||||
			if (ch == '(' || ch == '[' || ch == '{') {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			} else if (ch == ')' || ch == ']' || ch == '}') {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const lispWordListDesc[] = {
 | 
			
		||||
	"Functions and special operators",
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc);
 | 
			
		||||
							
								
								
									
										216
									
								
								3rdparty/lexilla540/lexilla/lexers/LexLout.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								3rdparty/lexilla540/lexilla/lexers/LexLout.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,216 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexLout.cxx
 | 
			
		||||
 ** Lexer for the Basser Lout (>= version 3) typesetting language
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2003 by Kein-Hong Man <mkh@pl.jaring.my>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalpha(ch) || ch == '@' || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsAnOther(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (ch == '{' || ch == '}' ||
 | 
			
		||||
	ch == '!' || ch == '$' || ch == '%' || ch == '&' || ch == '\'' ||
 | 
			
		||||
	ch == '(' || ch == ')' || ch == '*' || ch == '+' || ch == ',' ||
 | 
			
		||||
	ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == ';' ||
 | 
			
		||||
	ch == '<' || ch == '=' || ch == '>' || ch == '?' || ch == '[' ||
 | 
			
		||||
	ch == ']' || ch == '^' || ch == '`' || ch == '|' || ch == '~');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseLoutDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
			     WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
	WordList &keywords2 = *keywordlists[1];
 | 
			
		||||
	WordList &keywords3 = *keywordlists[2];
 | 
			
		||||
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	int firstWordInLine = 0;
 | 
			
		||||
	int leadingAtSign = 0;
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
		if (sc.atLineStart && (sc.state == SCE_LOUT_STRING)) {
 | 
			
		||||
			// Prevent SCE_LOUT_STRINGEOL from leaking back to previous line
 | 
			
		||||
			sc.SetState(SCE_LOUT_STRING);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		if (sc.state == SCE_LOUT_COMMENT) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_LOUT_DEFAULT);
 | 
			
		||||
				visibleChars = 0;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_LOUT_NUMBER) {
 | 
			
		||||
			if (!IsADigit(sc.ch) && sc.ch != '.') {
 | 
			
		||||
				sc.SetState(SCE_LOUT_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_LOUT_STRING) {
 | 
			
		||||
			if (sc.ch == '\\') {
 | 
			
		||||
				if (sc.chNext == '\"' || sc.chNext == '\\') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_LOUT_DEFAULT);
 | 
			
		||||
			} else if (sc.atLineEnd) {
 | 
			
		||||
				sc.ChangeState(SCE_LOUT_STRINGEOL);
 | 
			
		||||
				sc.ForwardSetState(SCE_LOUT_DEFAULT);
 | 
			
		||||
				visibleChars = 0;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_LOUT_IDENTIFIER) {
 | 
			
		||||
			if (!IsAWordChar(sc.ch)) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
 | 
			
		||||
				if (leadingAtSign) {
 | 
			
		||||
					if (keywords.InList(s)) {
 | 
			
		||||
						sc.ChangeState(SCE_LOUT_WORD);
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.ChangeState(SCE_LOUT_WORD4);
 | 
			
		||||
					}
 | 
			
		||||
				} else if (firstWordInLine && keywords3.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_LOUT_WORD3);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_LOUT_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_LOUT_OPERATOR) {
 | 
			
		||||
			if (!IsAnOther(sc.ch)) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
 | 
			
		||||
				if (keywords2.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_LOUT_WORD2);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_LOUT_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_LOUT_DEFAULT) {
 | 
			
		||||
			if (sc.ch == '#') {
 | 
			
		||||
				sc.SetState(SCE_LOUT_COMMENT);
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_LOUT_STRING);
 | 
			
		||||
			} else if (IsADigit(sc.ch) ||
 | 
			
		||||
				  (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_LOUT_NUMBER);
 | 
			
		||||
			} else if (IsAWordChar(sc.ch)) {
 | 
			
		||||
				firstWordInLine = (visibleChars == 0);
 | 
			
		||||
				leadingAtSign = (sc.ch == '@');
 | 
			
		||||
				sc.SetState(SCE_LOUT_IDENTIFIER);
 | 
			
		||||
			} else if (IsAnOther(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_LOUT_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sc.atLineEnd) {
 | 
			
		||||
			// Reset states to begining of colourise so no surprises
 | 
			
		||||
			// if different sets of lines lexed.
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!IsASpace(sc.ch)) {
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldLoutDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
 | 
			
		||||
                        Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	char s[10] = "";
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
 | 
			
		||||
		if (style == SCE_LOUT_WORD) {
 | 
			
		||||
			if (ch == '@') {
 | 
			
		||||
				for (Sci_PositionU j = 0; j < 8; j++) {
 | 
			
		||||
					if (!IsAWordChar(styler[i + j])) {
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					s[j] = styler[i + j];
 | 
			
		||||
					s[j + 1] = '\0';
 | 
			
		||||
				}
 | 
			
		||||
				if (strcmp(s, "@Begin") == 0) {
 | 
			
		||||
					levelCurrent++;
 | 
			
		||||
				} else if (strcmp(s, "@End") == 0) {
 | 
			
		||||
					levelCurrent--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (style == SCE_LOUT_OPERATOR) {
 | 
			
		||||
			if (ch == '{') {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			} else if (ch == '}') {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact) {
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const loutWordLists[] = {
 | 
			
		||||
            "Predefined identifiers",
 | 
			
		||||
            "Predefined delimiters",
 | 
			
		||||
            "Predefined keywords",
 | 
			
		||||
            0,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmLout(SCLEX_LOUT, ColouriseLoutDoc, "lout", FoldLoutDoc, loutWordLists);
 | 
			
		||||
							
								
								
									
										646
									
								
								3rdparty/lexilla540/lexilla/lexers/LexLua.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										646
									
								
								3rdparty/lexilla540/lexilla/lexers/LexLua.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,646 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexLua.cxx
 | 
			
		||||
 ** Lexer for Lua language.
 | 
			
		||||
 **
 | 
			
		||||
 ** Written by Paul Winwood.
 | 
			
		||||
 ** Folder by Alexey Yutkin.
 | 
			
		||||
 ** Modified by Marcos E. Wurzius & Philippe Lhoste
 | 
			
		||||
 **/
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#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"
 | 
			
		||||
#include "OptionSet.h"
 | 
			
		||||
#include "SubStyles.h"
 | 
			
		||||
#include "DefaultLexer.h"
 | 
			
		||||
 | 
			
		||||
using namespace Scintilla;
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
// Test for [=[ ... ]=] delimiters, returns 0 if it's only a [ or ],
 | 
			
		||||
// return 1 for [[ or ]], returns >=2 for [=[ or ]=] and so on.
 | 
			
		||||
// The maximum number of '=' characters allowed is 254.
 | 
			
		||||
int LongDelimCheck(StyleContext &sc) {
 | 
			
		||||
	constexpr int maximumEqualCharacters = 254;
 | 
			
		||||
	int sep = 1;
 | 
			
		||||
	while (sc.GetRelative(sep) == '=' && sep <= maximumEqualCharacters)
 | 
			
		||||
		sep++;
 | 
			
		||||
	if (sc.GetRelative(sep) == sc.ch)
 | 
			
		||||
		return sep;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *const luaWordListDesc[] = {
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	"Basic functions",
 | 
			
		||||
	"String, (table) & math functions",
 | 
			
		||||
	"(coroutines), I/O & system facilities",
 | 
			
		||||
	"user1",
 | 
			
		||||
	"user2",
 | 
			
		||||
	"user3",
 | 
			
		||||
	"user4",
 | 
			
		||||
	nullptr
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char styleSubable[] = { SCE_LUA_IDENTIFIER, 0 };
 | 
			
		||||
 | 
			
		||||
const LexicalClass lexicalClasses[] = {
 | 
			
		||||
	// Lexer Lua SCLEX_LUA SCE_LUA_:
 | 
			
		||||
	0, "SCE_LUA_DEFAULT", "default", "White space: Visible only in View Whitespace mode (or if it has a back colour)",
 | 
			
		||||
	1, "SCE_LUA_COMMENT", "comment", "Block comment (Lua 5.0)",
 | 
			
		||||
	2, "SCE_LUA_COMMENTLINE", "comment line", "Line comment",
 | 
			
		||||
	3, "SCE_LUA_COMMENTDOC", "comment documentation", "Doc comment",
 | 
			
		||||
	4, "SCE_LUA_NUMBER", "literal numeric", "Number",
 | 
			
		||||
	5, "SCE_LUA_WORD", "keyword", "Keyword",
 | 
			
		||||
	6, "SCE_LUA_STRING", "literal string", "(Double quoted) String",
 | 
			
		||||
	7, "SCE_LUA_CHARACTER", "literal string character", "Character (Single quoted string)",
 | 
			
		||||
	8, "SCE_LUA_LITERALSTRING", "literal string", "Literal string",
 | 
			
		||||
	9, "SCE_LUA_PREPROCESSOR", "preprocessor", "Preprocessor (obsolete in Lua 4.0 and up)",
 | 
			
		||||
	10, "SCE_LUA_OPERATOR", "operator", "Operators",
 | 
			
		||||
	11, "SCE_LUA_IDENTIFIER", "identifier", "Identifier (everything else...)",
 | 
			
		||||
	12, "SCE_LUA_STRINGEOL", "error literal string", "End of line where string is not closed",
 | 
			
		||||
	13, "SCE_LUA_WORD2", "identifier", "Other keywords",
 | 
			
		||||
	14, "SCE_LUA_WORD3", "identifier", "Other keywords",
 | 
			
		||||
	15, "SCE_LUA_WORD4", "identifier", "Other keywords",
 | 
			
		||||
	16, "SCE_LUA_WORD5", "identifier", "Other keywords",
 | 
			
		||||
	17, "SCE_LUA_WORD6", "identifier", "Other keywords",
 | 
			
		||||
	18, "SCE_LUA_WORD7", "identifier", "Other keywords",
 | 
			
		||||
	19, "SCE_LUA_WORD8", "identifier", "Other keywords",
 | 
			
		||||
	20, "SCE_LUA_LABEL", "label", "Labels",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Options used for LexerLua
 | 
			
		||||
struct OptionsLua {
 | 
			
		||||
	bool foldCompact = true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct OptionSetLua : public OptionSet<OptionsLua> {
 | 
			
		||||
	OptionSetLua() {
 | 
			
		||||
		DefineProperty("fold.compact", &OptionsLua::foldCompact);
 | 
			
		||||
 | 
			
		||||
		DefineWordListSets(luaWordListDesc);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LexerLua : public DefaultLexer {
 | 
			
		||||
	WordList keywords;
 | 
			
		||||
	WordList keywords2;
 | 
			
		||||
	WordList keywords3;
 | 
			
		||||
	WordList keywords4;
 | 
			
		||||
	WordList keywords5;
 | 
			
		||||
	WordList keywords6;
 | 
			
		||||
	WordList keywords7;
 | 
			
		||||
	WordList keywords8;
 | 
			
		||||
	OptionsLua options;
 | 
			
		||||
	OptionSetLua osLua;
 | 
			
		||||
	SubStyles subStyles{styleSubable};
 | 
			
		||||
public:
 | 
			
		||||
	explicit LexerLua() :
 | 
			
		||||
		DefaultLexer("lua", SCLEX_LUA, lexicalClasses, std::size(lexicalClasses)) {
 | 
			
		||||
	}
 | 
			
		||||
	LexerLua(const LexerLua &) = delete;
 | 
			
		||||
	LexerLua(LexerLua &&) = delete;
 | 
			
		||||
	LexerLua &operator=(const LexerLua &) = delete;
 | 
			
		||||
	LexerLua &operator=(LexerLua &&) = delete;
 | 
			
		||||
	~LexerLua() override = default;
 | 
			
		||||
	void SCI_METHOD Release() noexcept override {
 | 
			
		||||
		delete this;
 | 
			
		||||
	}
 | 
			
		||||
	[[nodiscard]] int SCI_METHOD Version() const noexcept override {
 | 
			
		||||
		return lvRelease5;
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD PropertyNames() noexcept override {
 | 
			
		||||
		return osLua.PropertyNames();
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD PropertyType(const char *name) override {
 | 
			
		||||
		return osLua.PropertyType(name);
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD DescribeProperty(const char *name) override {
 | 
			
		||||
		return osLua.DescribeProperty(name);
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
 | 
			
		||||
	const char *SCI_METHOD PropertyGet(const char *key) override {
 | 
			
		||||
		return osLua.PropertyGet(key);
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD DescribeWordListSets() noexcept override {
 | 
			
		||||
		return osLua.DescribeWordListSets();
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
 | 
			
		||||
	void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
	void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
 | 
			
		||||
 | 
			
		||||
	int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {
 | 
			
		||||
		return subStyles.Allocate(styleBase, numberStyles);
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD SubStylesStart(int styleBase) override {
 | 
			
		||||
		return subStyles.Start(styleBase);
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD SubStylesLength(int styleBase) override {
 | 
			
		||||
		return subStyles.Length(styleBase);
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD StyleFromSubStyle(int subStyle) override {
 | 
			
		||||
		const int styleBase = subStyles.BaseStyle(subStyle);
 | 
			
		||||
		return styleBase;
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD PrimaryStyleFromStyle(int style) override {
 | 
			
		||||
		return style;
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD FreeSubStyles() override {
 | 
			
		||||
		subStyles.Free();
 | 
			
		||||
	}
 | 
			
		||||
	void SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {
 | 
			
		||||
		subStyles.SetIdentifiers(style, identifiers);
 | 
			
		||||
	}
 | 
			
		||||
	int SCI_METHOD DistanceToSecondaryStyles() override {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	const char *SCI_METHOD GetSubStyleBases() override {
 | 
			
		||||
		return styleSubable;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static ILexer5 *LexerFactoryLua() {
 | 
			
		||||
		return new LexerLua();
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerLua::PropertySet(const char *key, const char *val) {
 | 
			
		||||
	if (osLua.PropertySet(&options, key, val)) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sci_Position SCI_METHOD LexerLua::WordListSet(int n, const char *wl) {
 | 
			
		||||
	WordList *wordListN = nullptr;
 | 
			
		||||
	switch (n) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		wordListN = &keywords;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		wordListN = &keywords2;
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		wordListN = &keywords3;
 | 
			
		||||
		break;
 | 
			
		||||
	case 3:
 | 
			
		||||
		wordListN = &keywords4;
 | 
			
		||||
		break;
 | 
			
		||||
	case 4:
 | 
			
		||||
		wordListN = &keywords5;
 | 
			
		||||
		break;
 | 
			
		||||
	case 5:
 | 
			
		||||
		wordListN = &keywords6;
 | 
			
		||||
		break;
 | 
			
		||||
	case 6:
 | 
			
		||||
		wordListN = &keywords7;
 | 
			
		||||
		break;
 | 
			
		||||
	case 7:
 | 
			
		||||
		wordListN = &keywords8;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	Sci_Position firstModification = -1;
 | 
			
		||||
	if (wordListN) {
 | 
			
		||||
		if (wordListN->Set(wl)) {
 | 
			
		||||
			firstModification = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return firstModification;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr int maskSeparator = 0xFF;
 | 
			
		||||
constexpr int maskStringWs = 0x100;
 | 
			
		||||
constexpr int maskDocComment = 0x200;
 | 
			
		||||
 | 
			
		||||
void LexerLua::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
 | 
			
		||||
	// Accepts accented characters
 | 
			
		||||
	const CharacterSet setWordStart(CharacterSet::setAlpha, "_", true);
 | 
			
		||||
	const CharacterSet setWord(CharacterSet::setAlphaNum, "_", true);
 | 
			
		||||
	// Not exactly following number definition (several dots are seen as OK, etc.)
 | 
			
		||||
	// but probably enough in most cases. [pP] is for hex floats.
 | 
			
		||||
	const CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP");
 | 
			
		||||
	const CharacterSet setExponent("eEpP");
 | 
			
		||||
	const CharacterSet setLuaOperator("*/-+()={}~[];<>,.^%:#&|");
 | 
			
		||||
	const CharacterSet setEscapeSkip("\"'\\");
 | 
			
		||||
 | 
			
		||||
	const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_LUA_IDENTIFIER);
 | 
			
		||||
 | 
			
		||||
	Sci_Position currentLine = styler.GetLine(startPos);
 | 
			
		||||
	// Initialize long string [[ ... ]] or block comment --[[ ... ]],
 | 
			
		||||
	// if we are inside such a string. Block comment was introduced in Lua 5.0,
 | 
			
		||||
	// blocks with separators [=[ ... ]=] in Lua 5.1.
 | 
			
		||||
	// Continuation of a string (\z whitespace escaping) is controlled by stringWs.
 | 
			
		||||
	int sepCount = 0;
 | 
			
		||||
	int stringWs = 0;
 | 
			
		||||
	int lastLineDocComment = 0;
 | 
			
		||||
	if ((currentLine > 0) &&
 | 
			
		||||
		AnyOf(initStyle, SCE_LUA_DEFAULT, SCE_LUA_LITERALSTRING, SCE_LUA_COMMENT, SCE_LUA_COMMENTDOC, SCE_LUA_STRING, SCE_LUA_CHARACTER)) {
 | 
			
		||||
		const int lineState = styler.GetLineState(currentLine - 1);
 | 
			
		||||
		sepCount = lineState & maskSeparator;
 | 
			
		||||
		stringWs = lineState & maskStringWs;
 | 
			
		||||
		lastLineDocComment = lineState & maskDocComment;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// results of identifier/keyword matching
 | 
			
		||||
	Sci_Position idenPos = 0;
 | 
			
		||||
	Sci_Position idenStartCharWidth = 0;
 | 
			
		||||
	Sci_Position idenWordPos = 0;
 | 
			
		||||
	int idenStyle = SCE_LUA_IDENTIFIER;
 | 
			
		||||
	bool foundGoto = false;
 | 
			
		||||
 | 
			
		||||
	// Do not leak onto next line
 | 
			
		||||
	if (AnyOf(initStyle, SCE_LUA_STRINGEOL, SCE_LUA_COMMENTLINE, SCE_LUA_COMMENTDOC, SCE_LUA_PREPROCESSOR)) {
 | 
			
		||||
		initStyle = SCE_LUA_DEFAULT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
	if (startPos == 0 && sc.ch == '#' && sc.chNext == '!') {
 | 
			
		||||
		// shbang line: "#!" is a comment only if located at the start of the script
 | 
			
		||||
		sc.SetState(SCE_LUA_COMMENTLINE);
 | 
			
		||||
	}
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
		if (sc.atLineEnd) {
 | 
			
		||||
			// Update the line state, so it can be seen by next line
 | 
			
		||||
			currentLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
			switch (sc.state) {
 | 
			
		||||
			case SCE_LUA_DEFAULT:
 | 
			
		||||
			case SCE_LUA_LITERALSTRING:
 | 
			
		||||
			case SCE_LUA_COMMENT:
 | 
			
		||||
			case SCE_LUA_COMMENTDOC:
 | 
			
		||||
			case SCE_LUA_STRING:
 | 
			
		||||
			case SCE_LUA_CHARACTER:
 | 
			
		||||
				// Inside a literal string, block comment or string, we set the line state
 | 
			
		||||
				styler.SetLineState(currentLine, lastLineDocComment | stringWs | sepCount);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				// Reset the line state
 | 
			
		||||
				styler.SetLineState(currentLine, 0);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (sc.atLineStart && (sc.state == SCE_LUA_STRING)) {
 | 
			
		||||
			// Prevent SCE_LUA_STRINGEOL from leaking back to previous line
 | 
			
		||||
			sc.SetState(SCE_LUA_STRING);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Handle string line continuation
 | 
			
		||||
		if ((sc.state == SCE_LUA_STRING || sc.state == SCE_LUA_CHARACTER) &&
 | 
			
		||||
				sc.ch == '\\') {
 | 
			
		||||
			if (sc.chNext == '\n' || sc.chNext == '\r') {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				if (sc.ch == '\r' && sc.chNext == '\n') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		if (sc.state == SCE_LUA_OPERATOR) {
 | 
			
		||||
			if (sc.ch == ':' && sc.chPrev == ':') {	// :: <label> :: forward scan
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				Sci_Position ln = 0;
 | 
			
		||||
				while (IsASpaceOrTab(sc.GetRelativeChar(ln)))	// skip over spaces/tabs
 | 
			
		||||
					ln++;
 | 
			
		||||
				const Sci_Position ws1 = ln;
 | 
			
		||||
				if (setWordStart.Contains(sc.GetRelativeChar(ln))) {
 | 
			
		||||
					char cLabel = 0;
 | 
			
		||||
					std::string s;
 | 
			
		||||
					while (setWord.Contains(cLabel = sc.GetRelativeChar(ln))) {	// get potential label
 | 
			
		||||
						s.push_back(cLabel);
 | 
			
		||||
						ln++;
 | 
			
		||||
					}
 | 
			
		||||
					const Sci_Position lbl = ln;
 | 
			
		||||
					if (!keywords.InList(s)) {
 | 
			
		||||
						while (IsASpaceOrTab(sc.GetRelativeChar(ln)))	// skip over spaces/tabs
 | 
			
		||||
							ln++;
 | 
			
		||||
						const Sci_Position ws2 = ln - lbl;
 | 
			
		||||
						if (sc.GetRelativeChar(ln) == ':' && sc.GetRelativeChar(ln + 1) == ':') {
 | 
			
		||||
							// final :: found, complete valid label construct
 | 
			
		||||
							sc.ChangeState(SCE_LUA_LABEL);
 | 
			
		||||
							if (ws1) {
 | 
			
		||||
								sc.SetState(SCE_LUA_DEFAULT);
 | 
			
		||||
								sc.ForwardBytes(ws1);
 | 
			
		||||
							}
 | 
			
		||||
							sc.SetState(SCE_LUA_LABEL);
 | 
			
		||||
							sc.ForwardBytes(lbl - ws1);
 | 
			
		||||
							if (ws2) {
 | 
			
		||||
								sc.SetState(SCE_LUA_DEFAULT);
 | 
			
		||||
								sc.ForwardBytes(ws2);
 | 
			
		||||
							}
 | 
			
		||||
							sc.SetState(SCE_LUA_LABEL);
 | 
			
		||||
							sc.ForwardBytes(2);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			sc.SetState(SCE_LUA_DEFAULT);
 | 
			
		||||
		} else if (sc.state == SCE_LUA_NUMBER) {
 | 
			
		||||
			// We stop the number definition on non-numerical non-dot non-eEpP non-sign non-hexdigit char
 | 
			
		||||
			if (!setNumber.Contains(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_LUA_DEFAULT);
 | 
			
		||||
			} else if (sc.ch == '-' || sc.ch == '+') {
 | 
			
		||||
				if (!setExponent.Contains(sc.chPrev))
 | 
			
		||||
					sc.SetState(SCE_LUA_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_LUA_IDENTIFIER) {
 | 
			
		||||
			idenPos -= idenStartCharWidth;			// commit already-scanned identifier/word parts
 | 
			
		||||
			if (idenWordPos > 0) {
 | 
			
		||||
				idenWordPos--;
 | 
			
		||||
				sc.ChangeState(idenStyle);
 | 
			
		||||
				sc.ForwardBytes(idenWordPos);
 | 
			
		||||
				idenPos -= idenWordPos;
 | 
			
		||||
				if (idenPos > 0) {
 | 
			
		||||
					sc.SetState(SCE_LUA_IDENTIFIER);
 | 
			
		||||
					sc.ForwardBytes(idenPos);
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				sc.ForwardBytes(idenPos);
 | 
			
		||||
			}
 | 
			
		||||
			sc.SetState(SCE_LUA_DEFAULT);
 | 
			
		||||
			if (foundGoto) {					// goto <label> forward scan
 | 
			
		||||
				while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				if (setWordStart.Contains(sc.ch)) {
 | 
			
		||||
					sc.SetState(SCE_LUA_LABEL);
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					while (setWord.Contains(sc.ch))
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					std::string s;
 | 
			
		||||
					sc.GetCurrentString(s, StyleContext::Transform::none);
 | 
			
		||||
					if (keywords.InList(s))		// labels cannot be keywords
 | 
			
		||||
						sc.ChangeState(SCE_LUA_WORD);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_LUA_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (AnyOf(sc.state, SCE_LUA_COMMENTLINE, SCE_LUA_COMMENTDOC, SCE_LUA_PREPROCESSOR)) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.ForwardSetState(SCE_LUA_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_LUA_STRING) {
 | 
			
		||||
			if (stringWs) {
 | 
			
		||||
				if (!IsASpace(sc.ch))
 | 
			
		||||
					stringWs = 0;
 | 
			
		||||
			}
 | 
			
		||||
			if (sc.ch == '\\') {
 | 
			
		||||
				if (setEscapeSkip.Contains(sc.chNext)) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} else if (sc.chNext == 'z') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					stringWs = maskStringWs;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_LUA_DEFAULT);
 | 
			
		||||
			} else if (stringWs == 0 && sc.atLineEnd) {
 | 
			
		||||
				sc.ChangeState(SCE_LUA_STRINGEOL);
 | 
			
		||||
				sc.ForwardSetState(SCE_LUA_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_LUA_CHARACTER) {
 | 
			
		||||
			if (stringWs) {
 | 
			
		||||
				if (!IsASpace(sc.ch))
 | 
			
		||||
					stringWs = 0;
 | 
			
		||||
			}
 | 
			
		||||
			if (sc.ch == '\\') {
 | 
			
		||||
				if (setEscapeSkip.Contains(sc.chNext)) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} else if (sc.chNext == 'z') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
					stringWs = maskStringWs;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.ForwardSetState(SCE_LUA_DEFAULT);
 | 
			
		||||
			} else if (stringWs == 0 && sc.atLineEnd) {
 | 
			
		||||
				sc.ChangeState(SCE_LUA_STRINGEOL);
 | 
			
		||||
				sc.ForwardSetState(SCE_LUA_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.ch == ']' && (sc.state == SCE_LUA_LITERALSTRING || sc.state == SCE_LUA_COMMENT)) {
 | 
			
		||||
			const int sep = LongDelimCheck(sc);
 | 
			
		||||
			if (sep == sepCount) {   // ]=]-style delim
 | 
			
		||||
				sc.Forward(sep);
 | 
			
		||||
				sc.ForwardSetState(SCE_LUA_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_LUA_DEFAULT) {
 | 
			
		||||
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_LUA_NUMBER);
 | 
			
		||||
				if (sc.ch == '0' && AnyOf(sc.chNext, 'x', 'X')) {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
			} else if (setWordStart.Contains(sc.ch)) {
 | 
			
		||||
				// For matching various identifiers with dots and colons, multiple
 | 
			
		||||
				// matches are done as identifier segments are added. Longest match is
 | 
			
		||||
				// set to a word style. The non-matched part is in identifier style.
 | 
			
		||||
				std::string ident;
 | 
			
		||||
				idenPos = 0;
 | 
			
		||||
				idenStartCharWidth = sc.width;
 | 
			
		||||
				idenWordPos = 0;
 | 
			
		||||
				idenStyle = SCE_LUA_IDENTIFIER;
 | 
			
		||||
				foundGoto = false;
 | 
			
		||||
				char cNext = 0;
 | 
			
		||||
				do {
 | 
			
		||||
					char cIdent = 0;
 | 
			
		||||
					const Sci_Position idenPosOld = idenPos;
 | 
			
		||||
					std::string identSeg;
 | 
			
		||||
					identSeg += sc.GetRelativeChar(idenPos++);
 | 
			
		||||
					while (setWord.Contains(cIdent = sc.GetRelativeChar(idenPos))) {
 | 
			
		||||
						identSeg += cIdent;
 | 
			
		||||
						idenPos++;
 | 
			
		||||
					}
 | 
			
		||||
					if (keywords.InList(identSeg) && (idenPosOld > 0)) {
 | 
			
		||||
						idenPos = idenPosOld - 1;	// keywords cannot mix
 | 
			
		||||
						ident.pop_back();
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					ident += identSeg;
 | 
			
		||||
					int newStyle = SCE_LUA_IDENTIFIER;
 | 
			
		||||
					if (keywords.InList(ident)) {
 | 
			
		||||
						newStyle = SCE_LUA_WORD;
 | 
			
		||||
					} else if (keywords2.InList(ident)) {
 | 
			
		||||
						newStyle = SCE_LUA_WORD2;
 | 
			
		||||
					} else if (keywords3.InList(ident)) {
 | 
			
		||||
						newStyle = SCE_LUA_WORD3;
 | 
			
		||||
					} else if (keywords4.InList(ident)) {
 | 
			
		||||
						newStyle = SCE_LUA_WORD4;
 | 
			
		||||
					} else if (keywords5.InList(ident)) {
 | 
			
		||||
						newStyle = SCE_LUA_WORD5;
 | 
			
		||||
					} else if (keywords6.InList(ident)) {
 | 
			
		||||
						newStyle = SCE_LUA_WORD6;
 | 
			
		||||
					} else if (keywords7.InList(ident)) {
 | 
			
		||||
						newStyle = SCE_LUA_WORD7;
 | 
			
		||||
					} else if (keywords8.InList(ident)) {
 | 
			
		||||
						newStyle = SCE_LUA_WORD8;
 | 
			
		||||
					} else {
 | 
			
		||||
						const int subStyle = classifierIdentifiers.ValueFor(ident);
 | 
			
		||||
						if (subStyle >= 0) {
 | 
			
		||||
							newStyle = subStyle;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					if (newStyle != SCE_LUA_IDENTIFIER) {
 | 
			
		||||
						idenStyle = newStyle;
 | 
			
		||||
						idenWordPos = idenPos;
 | 
			
		||||
					}
 | 
			
		||||
					if (idenStyle == SCE_LUA_WORD)	// keywords cannot mix
 | 
			
		||||
						break;
 | 
			
		||||
					cNext = sc.GetRelativeChar(idenPos + 1);
 | 
			
		||||
					if ((cIdent == '.' || cIdent == ':') && setWordStart.Contains(cNext)) {
 | 
			
		||||
						ident += cIdent;
 | 
			
		||||
						idenPos++;
 | 
			
		||||
					} else {
 | 
			
		||||
						cNext = 0;
 | 
			
		||||
					}
 | 
			
		||||
				} while (cNext);
 | 
			
		||||
				if ((idenStyle == SCE_LUA_WORD) && (ident == "goto")) {
 | 
			
		||||
					foundGoto = true;
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_LUA_IDENTIFIER);
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.SetState(SCE_LUA_STRING);
 | 
			
		||||
				stringWs = 0;
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				sc.SetState(SCE_LUA_CHARACTER);
 | 
			
		||||
				stringWs = 0;
 | 
			
		||||
			} else if (sc.ch == '[') {
 | 
			
		||||
				sepCount = LongDelimCheck(sc);
 | 
			
		||||
				if (sepCount == 0) {
 | 
			
		||||
					sc.SetState(SCE_LUA_OPERATOR);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_LUA_LITERALSTRING);
 | 
			
		||||
					sc.Forward(sepCount);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.Match('-', '-')) {
 | 
			
		||||
				sc.SetState(lastLineDocComment ? SCE_LUA_COMMENTDOC : SCE_LUA_COMMENTLINE);
 | 
			
		||||
				if (sc.Match("--[")) {
 | 
			
		||||
					sc.Forward(2);
 | 
			
		||||
					sepCount = LongDelimCheck(sc);
 | 
			
		||||
					if (sepCount > 0) {
 | 
			
		||||
						sc.ChangeState(SCE_LUA_COMMENT);
 | 
			
		||||
						sc.Forward(sepCount);
 | 
			
		||||
					}
 | 
			
		||||
				} else if (sc.Match("---")) {
 | 
			
		||||
					sc.SetState(SCE_LUA_COMMENTDOC);
 | 
			
		||||
					lastLineDocComment = maskDocComment;
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.atLineStart && sc.Match('$')) {
 | 
			
		||||
				sc.SetState(SCE_LUA_PREPROCESSOR);	// Obsolete since Lua 4.0, but still in old code
 | 
			
		||||
			} else if (setLuaOperator.Contains(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_LUA_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
			if (!AnyOf(sc.state, SCE_LUA_DEFAULT, SCE_LUA_COMMENTDOC)) {
 | 
			
		||||
				lastLineDocComment = 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LexerLua::Fold(Sci_PositionU startPos_, Sci_Position length, int initStyle, IDocument *pAccess) {
 | 
			
		||||
	LexAccessor styler(pAccess);
 | 
			
		||||
	const Sci_Position startPos = startPos_;
 | 
			
		||||
	const Sci_Position lengthDoc = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	const bool foldCompact = options.foldCompact;
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
	int styleNext = styler.StyleIndexAt(startPos);
 | 
			
		||||
 | 
			
		||||
	for (Sci_Position i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		const char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		const int stylePrev = style;
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		if ((i + 1) < lengthDoc) {
 | 
			
		||||
			// Only read styles that have been set, otherwise treat style as continuing
 | 
			
		||||
			styleNext = styler.StyleIndexAt(i + 1);
 | 
			
		||||
		}
 | 
			
		||||
		const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
		if (style == SCE_LUA_WORD) {
 | 
			
		||||
			// Fixed list of folding words: if, do, function, repeat, end, until
 | 
			
		||||
			// Must fix up next line with initial characters if any new words added.
 | 
			
		||||
			if ((style != stylePrev) && AnyOf(ch, 'i', 'd', 'f', 'e', 'r', 'u')) {
 | 
			
		||||
				constexpr Sci_Position maxFoldWord = 9; // "function"sv.length() + 1
 | 
			
		||||
				std::string s;
 | 
			
		||||
				for (Sci_Position j = 0; j < maxFoldWord; j++) {
 | 
			
		||||
					if (!iswordchar(styler[i + j])) {
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					s.push_back(styler[i + j]);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (s == "if" || s == "do" || s == "function" || s == "repeat") {
 | 
			
		||||
					levelCurrent++;
 | 
			
		||||
				}
 | 
			
		||||
				if (s == "end" || s == "until") {
 | 
			
		||||
					levelCurrent--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (style == SCE_LUA_OPERATOR) {
 | 
			
		||||
			if (ch == '{' || ch == '(') {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			} else if (ch == '}' || ch == ')') {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (style == SCE_LUA_LITERALSTRING || style == SCE_LUA_COMMENT) {
 | 
			
		||||
			if (stylePrev != style) {
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			} else if (styleNext != style) {
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact) {
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			}
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!isspacechar(ch)) {
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
 | 
			
		||||
	const int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmLua(SCLEX_LUA, LexerLua::LexerFactoryLua, "lua", luaWordListDesc);
 | 
			
		||||
							
								
								
									
										186
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMMIXAL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMMIXAL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,186 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
// Encoding: UTF-8
 | 
			
		||||
/** @file LexMMIXAL.cxx
 | 
			
		||||
 ** Lexer for MMIX Assembler Language.
 | 
			
		||||
 ** Written by Christoph Hösler <christoph.hoesler@student.uni-tuebingen.de>
 | 
			
		||||
 ** For information about MMIX visit http://www-cs-faculty.stanford.edu/~knuth/mmix.html
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline bool IsAWordChar(const int ch) {
 | 
			
		||||
	return (ch < 0x80) && (isalnum(ch) || ch == ':' || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool isMMIXALOperator(char ch) {
 | 
			
		||||
	if (IsASCII(ch) && isalnum(ch))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (ch == '+' || ch == '-' || ch == '|' || ch == '^' ||
 | 
			
		||||
		ch == '*' || ch == '/' ||
 | 
			
		||||
		ch == '%' || ch == '<' || ch == '>' || ch == '&' ||
 | 
			
		||||
		ch == '~' || ch == '$' ||
 | 
			
		||||
		ch == ',' || ch == '(' || ch == ')' ||
 | 
			
		||||
		ch == '[' || ch == ']')
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseMMIXALDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
 | 
			
		||||
                            Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	WordList &opcodes = *keywordlists[0];
 | 
			
		||||
	WordList &special_register = *keywordlists[1];
 | 
			
		||||
	WordList &predef_symbols = *keywordlists[2];
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward())
 | 
			
		||||
	{
 | 
			
		||||
		// No EOL continuation
 | 
			
		||||
		if (sc.atLineStart) {
 | 
			
		||||
			if (sc.ch ==  '@' && sc.chNext == 'i') {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_INCLUDE);
 | 
			
		||||
			} else {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_LEADWS);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Check if first non whitespace character in line is alphanumeric
 | 
			
		||||
		if (sc.state == SCE_MMIXAL_LEADWS && !isspace(sc.ch)) {	// LEADWS
 | 
			
		||||
			if(!IsAWordChar(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_COMMENT);
 | 
			
		||||
			} else {
 | 
			
		||||
				if(sc.atLineStart) {
 | 
			
		||||
					sc.SetState(SCE_MMIXAL_LABEL);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_MMIXAL_OPCODE_PRE);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if the current state should terminate.
 | 
			
		||||
		if (sc.state == SCE_MMIXAL_OPERATOR) {			// OPERATOR
 | 
			
		||||
			sc.SetState(SCE_MMIXAL_OPERANDS);
 | 
			
		||||
		} else if (sc.state == SCE_MMIXAL_NUMBER) {		// NUMBER
 | 
			
		||||
			if (!isdigit(sc.ch)) {
 | 
			
		||||
				if (IsAWordChar(sc.ch)) {
 | 
			
		||||
					sc.ChangeState(SCE_MMIXAL_REF);
 | 
			
		||||
					sc.SetState(SCE_MMIXAL_REF);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_MMIXAL_OPERANDS);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MMIXAL_LABEL) {			// LABEL
 | 
			
		||||
			if (!IsAWordChar(sc.ch) ) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_OPCODE_PRE);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MMIXAL_REF) {			// REF
 | 
			
		||||
			if (!IsAWordChar(sc.ch) ) {
 | 
			
		||||
				char s0[100];
 | 
			
		||||
				sc.GetCurrent(s0, sizeof(s0));
 | 
			
		||||
				const char *s = s0;
 | 
			
		||||
				if (*s == ':') {	// ignore base prefix for match
 | 
			
		||||
					++s;
 | 
			
		||||
				}
 | 
			
		||||
				if (special_register.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_MMIXAL_REGISTER);
 | 
			
		||||
				} else if (predef_symbols.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_MMIXAL_SYMBOL);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_OPERANDS);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MMIXAL_OPCODE_PRE) {	// OPCODE_PRE
 | 
			
		||||
				if (!isspace(sc.ch)) {
 | 
			
		||||
					sc.SetState(SCE_MMIXAL_OPCODE);
 | 
			
		||||
				}
 | 
			
		||||
		} else if (sc.state == SCE_MMIXAL_OPCODE) {		// OPCODE
 | 
			
		||||
			if (!IsAWordChar(sc.ch) ) {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
				if (opcodes.InList(s)) {
 | 
			
		||||
					sc.ChangeState(SCE_MMIXAL_OPCODE_VALID);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN);
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_OPCODE_POST);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MMIXAL_STRING) {		// STRING
 | 
			
		||||
			if (sc.ch == '\"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
 | 
			
		||||
			} else if (sc.atLineEnd) {
 | 
			
		||||
				sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MMIXAL_CHAR) {			// CHAR
 | 
			
		||||
			if (sc.ch == '\'') {
 | 
			
		||||
				sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
 | 
			
		||||
			} else if (sc.atLineEnd) {
 | 
			
		||||
				sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MMIXAL_REGISTER) {		// REGISTER
 | 
			
		||||
			if (!isdigit(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_OPERANDS);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MMIXAL_HEX) {			// HEX
 | 
			
		||||
			if (!isxdigit(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_OPERANDS);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Determine if a new state should be entered.
 | 
			
		||||
		if (sc.state == SCE_MMIXAL_OPCODE_POST ||		// OPCODE_POST
 | 
			
		||||
			sc.state == SCE_MMIXAL_OPERANDS) {			// OPERANDS
 | 
			
		||||
			if (sc.state == SCE_MMIXAL_OPERANDS && isspace(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_COMMENT);
 | 
			
		||||
			} else if (isdigit(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_NUMBER);
 | 
			
		||||
			} else if (IsAWordChar(sc.ch) || sc.Match('@')) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_REF);
 | 
			
		||||
			} else if (sc.Match('\"')) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_STRING);
 | 
			
		||||
			} else if (sc.Match('\'')) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_CHAR);
 | 
			
		||||
			} else if (sc.Match('$')) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_REGISTER);
 | 
			
		||||
			} else if (sc.Match('#')) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_HEX);
 | 
			
		||||
			} else if (isMMIXALOperator(static_cast<char>(sc.ch))) {
 | 
			
		||||
				sc.SetState(SCE_MMIXAL_OPERATOR);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const MMIXALWordListDesc[] = {
 | 
			
		||||
	"Operation Codes",
 | 
			
		||||
	"Special Register",
 | 
			
		||||
	"Predefined Symbols",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmMMIXAL(SCLEX_MMIXAL, ColouriseMMIXALDoc, "mmixal", 0, MMIXALWordListDesc);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										192
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMPT.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMPT.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,192 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexMPT.cxx
 | 
			
		||||
 ** Lexer for MPT specific files. Based on LexOthers.cxx
 | 
			
		||||
 ** LOT = the text log file created by the MPT application while running a test program
 | 
			
		||||
 ** Other MPT specific files to be added later.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2003 by Marius Gheorghe <mgheorghe@cabletest.com>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static int GetLotLineState(std::string &line) {
 | 
			
		||||
	if (line.length()) {
 | 
			
		||||
		// Most of the time the first non-blank character in line determines that line's type
 | 
			
		||||
		// Now finds the first non-blank character
 | 
			
		||||
		unsigned i; // Declares counter here to make it persistent after the for loop
 | 
			
		||||
		for (i = 0; i < line.length(); ++i) {
 | 
			
		||||
			if (!(IsASCII(line[i]) && isspace(line[i])))
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Checks if it was a blank line
 | 
			
		||||
		if (i == line.length())
 | 
			
		||||
			return SCE_LOT_DEFAULT;
 | 
			
		||||
 | 
			
		||||
		switch (line[i]) {
 | 
			
		||||
		case '*': // Fail measurement
 | 
			
		||||
			return SCE_LOT_FAIL;
 | 
			
		||||
 | 
			
		||||
		case '+': // Header
 | 
			
		||||
		case '|': // Header
 | 
			
		||||
			return SCE_LOT_HEADER;
 | 
			
		||||
 | 
			
		||||
		case ':': // Set test limits
 | 
			
		||||
			return SCE_LOT_SET;
 | 
			
		||||
 | 
			
		||||
		case '-': // Section break
 | 
			
		||||
			return SCE_LOT_BREAK;
 | 
			
		||||
 | 
			
		||||
		default:  // Any other line
 | 
			
		||||
			// Checks for message at the end of lot file
 | 
			
		||||
			if (line.find("PASSED") != std::string::npos) {
 | 
			
		||||
				return SCE_LOT_PASS;
 | 
			
		||||
			}
 | 
			
		||||
			else if (line.find("FAILED") != std::string::npos) {
 | 
			
		||||
				return SCE_LOT_FAIL;
 | 
			
		||||
			}
 | 
			
		||||
			else if (line.find("ABORTED") != std::string::npos) {
 | 
			
		||||
				return SCE_LOT_ABORT;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				return i ? SCE_LOT_PASS : SCE_LOT_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		return SCE_LOT_DEFAULT;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColourizeLotDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
	bool atLineStart = true;// Arms the 'at line start' flag
 | 
			
		||||
	char chNext = styler.SafeGetCharAt(startPos);
 | 
			
		||||
	std::string line("");
 | 
			
		||||
	line.reserve(256);	// Lot lines are less than 256 chars long most of the time. This should avoid reallocations
 | 
			
		||||
 | 
			
		||||
	// Styles LOT document
 | 
			
		||||
	Sci_PositionU i;			// Declared here because it's used after the for loop
 | 
			
		||||
	for (i = startPos; i < startPos + length; ++i) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		line += ch;
 | 
			
		||||
		atLineStart = false;
 | 
			
		||||
 | 
			
		||||
		// LOT files are only used on the Win32 platform, thus EOL == CR+LF
 | 
			
		||||
		// Searches for the end of line
 | 
			
		||||
		if (ch == '\r' && chNext == '\n') {
 | 
			
		||||
			line += chNext; // Gets the '\n'
 | 
			
		||||
			++i; // Advances past the '\n'
 | 
			
		||||
			chNext = styler.SafeGetCharAt(i + 1); // Gets character of next line
 | 
			
		||||
			styler.ColourTo(i, GetLotLineState(line));
 | 
			
		||||
			line = "";
 | 
			
		||||
			atLineStart = true; // Arms flag for next line
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Last line may not have a line ending
 | 
			
		||||
	if (!atLineStart) {
 | 
			
		||||
		styler.ColourTo(i - 1, GetLotLineState(line));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Folds an MPT LOT file: the blocks that can be folded are:
 | 
			
		||||
// sections (headed by a set line)
 | 
			
		||||
// passes (contiguous pass results within a section)
 | 
			
		||||
// fails (contiguous fail results within a section)
 | 
			
		||||
static void FoldLotDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 0) != 0;
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
 | 
			
		||||
	char chNext = styler.SafeGetCharAt(startPos);
 | 
			
		||||
	int style = SCE_LOT_DEFAULT;
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int lev = SC_FOLDLEVELBASE;
 | 
			
		||||
 | 
			
		||||
	// Gets style of previous line if not at the beginning of the document
 | 
			
		||||
	if (startPos > 1)
 | 
			
		||||
		style = styler.StyleAt(startPos - 2);
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
		if (ch == '\r' && chNext == '\n') {
 | 
			
		||||
			// TO DO:
 | 
			
		||||
			// Should really get the state of the previous line from the styler
 | 
			
		||||
			int stylePrev = style;
 | 
			
		||||
			style = styleNext;
 | 
			
		||||
			styleNext = styler.StyleAt(i + 2);
 | 
			
		||||
 | 
			
		||||
			switch (style) {
 | 
			
		||||
/*
 | 
			
		||||
			case SCE_LOT_SET:
 | 
			
		||||
				lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
				break;
 | 
			
		||||
*/
 | 
			
		||||
			case SCE_LOT_FAIL:
 | 
			
		||||
/*
 | 
			
		||||
				if (stylePrev != SCE_LOT_FAIL)
 | 
			
		||||
					lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
				else
 | 
			
		||||
					lev = SC_FOLDLEVELBASE + 1;
 | 
			
		||||
*/
 | 
			
		||||
				lev = SC_FOLDLEVELBASE;
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			default:
 | 
			
		||||
				if (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL)
 | 
			
		||||
					lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
				else
 | 
			
		||||
					lev = SC_FOLDLEVELBASE + 1;
 | 
			
		||||
 | 
			
		||||
				if (visibleChars == 0 && foldCompact)
 | 
			
		||||
					lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent))
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, lev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const emptyWordListDesc[] = {
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmLot(SCLEX_LOT, ColourizeLotDoc, "lot", FoldLotDoc, emptyWordListDesc);
 | 
			
		||||
							
								
								
									
										370
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMSSQL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										370
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMSSQL.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,370 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexMSSQL.cxx
 | 
			
		||||
 ** Lexer for MSSQL.
 | 
			
		||||
 **/
 | 
			
		||||
// By Filip Yaghob <fyaghob@gmail.com>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
#define KW_MSSQL_STATEMENTS         0
 | 
			
		||||
#define KW_MSSQL_DATA_TYPES         1
 | 
			
		||||
#define KW_MSSQL_SYSTEM_TABLES      2
 | 
			
		||||
#define KW_MSSQL_GLOBAL_VARIABLES   3
 | 
			
		||||
#define KW_MSSQL_FUNCTIONS          4
 | 
			
		||||
#define KW_MSSQL_STORED_PROCEDURES  5
 | 
			
		||||
#define KW_MSSQL_OPERATORS          6
 | 
			
		||||
 | 
			
		||||
static char classifyWordSQL(Sci_PositionU start,
 | 
			
		||||
                            Sci_PositionU end,
 | 
			
		||||
                            WordList *keywordlists[],
 | 
			
		||||
                            Accessor &styler,
 | 
			
		||||
                            unsigned int actualState,
 | 
			
		||||
							unsigned int prevState) {
 | 
			
		||||
	char s[256];
 | 
			
		||||
	bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
 | 
			
		||||
 | 
			
		||||
	WordList &kwStatements          = *keywordlists[KW_MSSQL_STATEMENTS];
 | 
			
		||||
    WordList &kwDataTypes           = *keywordlists[KW_MSSQL_DATA_TYPES];
 | 
			
		||||
    WordList &kwSystemTables        = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
 | 
			
		||||
    WordList &kwGlobalVariables     = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
 | 
			
		||||
    WordList &kwFunctions           = *keywordlists[KW_MSSQL_FUNCTIONS];
 | 
			
		||||
    WordList &kwStoredProcedures    = *keywordlists[KW_MSSQL_STORED_PROCEDURES];
 | 
			
		||||
    WordList &kwOperators           = *keywordlists[KW_MSSQL_OPERATORS];
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i = 0; i < end - start + 1 && i < 128; i++) {
 | 
			
		||||
		s[i] = static_cast<char>(tolower(styler[start + i]));
 | 
			
		||||
		s[i + 1] = '\0';
 | 
			
		||||
	}
 | 
			
		||||
	char chAttr = SCE_MSSQL_IDENTIFIER;
 | 
			
		||||
 | 
			
		||||
	if (actualState == SCE_MSSQL_GLOBAL_VARIABLE) {
 | 
			
		||||
 | 
			
		||||
        if (kwGlobalVariables.InList(&s[2]))
 | 
			
		||||
            chAttr = SCE_MSSQL_GLOBAL_VARIABLE;
 | 
			
		||||
 | 
			
		||||
	} else if (wordIsNumber) {
 | 
			
		||||
		chAttr = SCE_MSSQL_NUMBER;
 | 
			
		||||
 | 
			
		||||
	} else if (prevState == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
 | 
			
		||||
		// Look first in datatypes
 | 
			
		||||
        if (kwDataTypes.InList(s))
 | 
			
		||||
            chAttr = SCE_MSSQL_DATATYPE;
 | 
			
		||||
		else if (kwOperators.InList(s))
 | 
			
		||||
			chAttr = SCE_MSSQL_OPERATOR;
 | 
			
		||||
		else if (kwStatements.InList(s))
 | 
			
		||||
			chAttr = SCE_MSSQL_STATEMENT;
 | 
			
		||||
		else if (kwSystemTables.InList(s))
 | 
			
		||||
			chAttr = SCE_MSSQL_SYSTABLE;
 | 
			
		||||
		else if (kwFunctions.InList(s))
 | 
			
		||||
            chAttr = SCE_MSSQL_FUNCTION;
 | 
			
		||||
		else if (kwStoredProcedures.InList(s))
 | 
			
		||||
			chAttr = SCE_MSSQL_STORED_PROCEDURE;
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
		if (kwOperators.InList(s))
 | 
			
		||||
			chAttr = SCE_MSSQL_OPERATOR;
 | 
			
		||||
		else if (kwStatements.InList(s))
 | 
			
		||||
			chAttr = SCE_MSSQL_STATEMENT;
 | 
			
		||||
		else if (kwSystemTables.InList(s))
 | 
			
		||||
			chAttr = SCE_MSSQL_SYSTABLE;
 | 
			
		||||
		else if (kwFunctions.InList(s))
 | 
			
		||||
			chAttr = SCE_MSSQL_FUNCTION;
 | 
			
		||||
		else if (kwStoredProcedures.InList(s))
 | 
			
		||||
			chAttr = SCE_MSSQL_STORED_PROCEDURE;
 | 
			
		||||
		else if (kwDataTypes.InList(s))
 | 
			
		||||
			chAttr = SCE_MSSQL_DATATYPE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	styler.ColourTo(end, chAttr);
 | 
			
		||||
 | 
			
		||||
	return chAttr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseMSSQLDoc(Sci_PositionU startPos, Sci_Position length,
 | 
			
		||||
                              int initStyle, WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
 | 
			
		||||
	bool fold = styler.GetPropertyInt("fold") != 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int spaceFlags = 0;
 | 
			
		||||
 | 
			
		||||
	int state = initStyle;
 | 
			
		||||
	int prevState = initStyle;
 | 
			
		||||
	char chPrev = ' ';
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int nesting = 0;
 | 
			
		||||
 | 
			
		||||
	if (lineCurrent >= 1) {
 | 
			
		||||
		nesting = styler.GetLineState(lineCurrent - 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
	Sci_PositionU lengthDoc = startPos + length;
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
 | 
			
		||||
		const Sci_Position lineStartNext = styler.LineStart(lineCurrent + 1);
 | 
			
		||||
		const bool atEOL = (static_cast<Sci_Position>(i) == (lineStartNext - 1));
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
 | 
			
		||||
			int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
 | 
			
		||||
			int lev = indentCurrent;
 | 
			
		||||
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
 | 
			
		||||
				// Only non whitespace lines can be headers
 | 
			
		||||
				int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
 | 
			
		||||
				if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
 | 
			
		||||
					lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (fold) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (styler.IsLeadByte(ch)) {
 | 
			
		||||
			chNext = styler.SafeGetCharAt(i + 2);
 | 
			
		||||
			chPrev = ' ';
 | 
			
		||||
			i += 1;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// When the last char isn't part of the state (have to deal with it too)...
 | 
			
		||||
		if ( (state == SCE_MSSQL_IDENTIFIER) ||
 | 
			
		||||
                    (state == SCE_MSSQL_STORED_PROCEDURE) ||
 | 
			
		||||
                    (state == SCE_MSSQL_DATATYPE) ||
 | 
			
		||||
                    //~ (state == SCE_MSSQL_COLUMN_NAME) ||
 | 
			
		||||
                    (state == SCE_MSSQL_FUNCTION) ||
 | 
			
		||||
                    //~ (state == SCE_MSSQL_GLOBAL_VARIABLE) ||
 | 
			
		||||
                    (state == SCE_MSSQL_VARIABLE)) {
 | 
			
		||||
			if (!iswordchar(ch)) {
 | 
			
		||||
				int stateTmp;
 | 
			
		||||
 | 
			
		||||
                if ((state == SCE_MSSQL_VARIABLE) || (state == SCE_MSSQL_COLUMN_NAME)) {
 | 
			
		||||
                    styler.ColourTo(i - 1, state);
 | 
			
		||||
					stateTmp = state;
 | 
			
		||||
                } else
 | 
			
		||||
                    stateTmp = classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
 | 
			
		||||
 | 
			
		||||
				prevState = state;
 | 
			
		||||
 | 
			
		||||
				if (stateTmp == SCE_MSSQL_IDENTIFIER || stateTmp == SCE_MSSQL_VARIABLE)
 | 
			
		||||
					state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
 | 
			
		||||
				else
 | 
			
		||||
					state = SCE_MSSQL_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_MSSQL_LINE_COMMENT) {
 | 
			
		||||
			if (ch == '\r' || ch == '\n') {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				prevState = state;
 | 
			
		||||
				state = SCE_MSSQL_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (state == SCE_MSSQL_GLOBAL_VARIABLE) {
 | 
			
		||||
			if ((ch != '@') && !iswordchar(ch)) {
 | 
			
		||||
				classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
 | 
			
		||||
				prevState = state;
 | 
			
		||||
				state = SCE_MSSQL_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If is the default or one of the above succeeded
 | 
			
		||||
		if (state == SCE_MSSQL_DEFAULT || state == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
 | 
			
		||||
			if (iswordstart(ch)) {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				prevState = state;
 | 
			
		||||
				state = SCE_MSSQL_IDENTIFIER;
 | 
			
		||||
			} else if (ch == '/' && chNext == '*') {
 | 
			
		||||
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
 | 
			
		||||
				prevState = state;
 | 
			
		||||
				state = SCE_MSSQL_COMMENT;
 | 
			
		||||
			} else if (ch == '-' && chNext == '-') {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				prevState = state;
 | 
			
		||||
				state = SCE_MSSQL_LINE_COMMENT;
 | 
			
		||||
			} else if (ch == '\'') {
 | 
			
		||||
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
 | 
			
		||||
				prevState = state;
 | 
			
		||||
				state = SCE_MSSQL_STRING;
 | 
			
		||||
			} else if (ch == '"') {
 | 
			
		||||
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
 | 
			
		||||
				prevState = state;
 | 
			
		||||
				state = SCE_MSSQL_COLUMN_NAME;
 | 
			
		||||
			} else if (ch == '[') {
 | 
			
		||||
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
 | 
			
		||||
				prevState = state;
 | 
			
		||||
				state = SCE_MSSQL_COLUMN_NAME_2;
 | 
			
		||||
			} else if (isoperator(ch)) {
 | 
			
		||||
				styler.ColourTo(i - 1, state);
 | 
			
		||||
				styler.ColourTo(i, SCE_MSSQL_OPERATOR);
 | 
			
		||||
                //~ style = SCE_MSSQL_DEFAULT;
 | 
			
		||||
				prevState = state;
 | 
			
		||||
				state = SCE_MSSQL_DEFAULT;
 | 
			
		||||
			} else if (ch == '@') {
 | 
			
		||||
                styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
 | 
			
		||||
				prevState = state;
 | 
			
		||||
                if (chNext == '@') {
 | 
			
		||||
                    state = SCE_MSSQL_GLOBAL_VARIABLE;
 | 
			
		||||
//                    i += 2;
 | 
			
		||||
                } else
 | 
			
		||||
                    state = SCE_MSSQL_VARIABLE;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		// When the last char is part of the state...
 | 
			
		||||
		} else if (state == SCE_MSSQL_COMMENT) {
 | 
			
		||||
				if (ch == '/' && chNext == '*')
 | 
			
		||||
					nesting++;
 | 
			
		||||
				else if (ch == '/' && chPrev == '*') {
 | 
			
		||||
					if (nesting > 0)
 | 
			
		||||
						nesting--;
 | 
			
		||||
					else if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_MSSQL_COMMENT) &&
 | 
			
		||||
					    (styler.GetStartSegment() == startPos)))) {
 | 
			
		||||
						styler.ColourTo(i, state);
 | 
			
		||||
						//~ state = SCE_MSSQL_COMMENT;
 | 
			
		||||
					prevState = state;
 | 
			
		||||
                        state = SCE_MSSQL_DEFAULT;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else if (state == SCE_MSSQL_STRING) {
 | 
			
		||||
				if (ch == '\'') {
 | 
			
		||||
					if ( chNext == '\'' ) {
 | 
			
		||||
						i++;
 | 
			
		||||
					ch = chNext;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
					} else {
 | 
			
		||||
						styler.ColourTo(i, state);
 | 
			
		||||
					prevState = state;
 | 
			
		||||
						state = SCE_MSSQL_DEFAULT;
 | 
			
		||||
					//i++;
 | 
			
		||||
					}
 | 
			
		||||
				//ch = chNext;
 | 
			
		||||
				//chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (state == SCE_MSSQL_COLUMN_NAME) {
 | 
			
		||||
				if (ch == '"') {
 | 
			
		||||
					if (chNext == '"') {
 | 
			
		||||
						i++;
 | 
			
		||||
					ch = chNext;
 | 
			
		||||
					chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
				} else {
 | 
			
		||||
                    styler.ColourTo(i, state);
 | 
			
		||||
					prevState = state;
 | 
			
		||||
					state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
 | 
			
		||||
					//i++;
 | 
			
		||||
                }
 | 
			
		||||
                }
 | 
			
		||||
		} else if (state == SCE_MSSQL_COLUMN_NAME_2) {
 | 
			
		||||
			if (ch == ']') {
 | 
			
		||||
                styler.ColourTo(i, state);
 | 
			
		||||
				prevState = state;
 | 
			
		||||
                state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
 | 
			
		||||
                //i++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atEOL)
 | 
			
		||||
			styler.SetLineState(lineCurrent++, (state == SCE_MSSQL_COMMENT) ? nesting : 0);
 | 
			
		||||
 | 
			
		||||
		chPrev = ch;
 | 
			
		||||
	}
 | 
			
		||||
	styler.ColourTo(lengthDoc - 1, state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldMSSQLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
 | 
			
		||||
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent = levelPrev;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);
 | 
			
		||||
    char s[10] = "";
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		int style = styler.StyleAt(i);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
        // Comment folding
 | 
			
		||||
		if (foldComment) {
 | 
			
		||||
			if (!inComment && (style == SCE_MSSQL_COMMENT))
 | 
			
		||||
				levelCurrent++;
 | 
			
		||||
			else if (inComment && (style != SCE_MSSQL_COMMENT))
 | 
			
		||||
				levelCurrent--;
 | 
			
		||||
			inComment = (style == SCE_MSSQL_COMMENT);
 | 
			
		||||
		}
 | 
			
		||||
        if (style == SCE_MSSQL_STATEMENT) {
 | 
			
		||||
            // Folding between begin or case and end
 | 
			
		||||
            if (ch == 'b' || ch == 'B' || ch == 'c' || ch == 'C' || ch == 'e' || ch == 'E') {
 | 
			
		||||
                for (Sci_PositionU j = 0; j < 5; j++) {
 | 
			
		||||
					if (!iswordchar(styler[i + j])) {
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					s[j] = static_cast<char>(tolower(styler[i + j]));
 | 
			
		||||
					s[j + 1] = '\0';
 | 
			
		||||
                }
 | 
			
		||||
				if ((strcmp(s, "begin") == 0) || (strcmp(s, "case") == 0)) {
 | 
			
		||||
					levelCurrent++;
 | 
			
		||||
				}
 | 
			
		||||
				if (strcmp(s, "end") == 0) {
 | 
			
		||||
					levelCurrent--;
 | 
			
		||||
				}
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const sqlWordListDesc[] = {
 | 
			
		||||
	"Statements",
 | 
			
		||||
    "Data Types",
 | 
			
		||||
    "System tables",
 | 
			
		||||
    "Global variables",
 | 
			
		||||
    "Functions",
 | 
			
		||||
    "System Stored Procedures",
 | 
			
		||||
    "Operators",
 | 
			
		||||
	0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", FoldMSSQLDoc, sqlWordListDesc);
 | 
			
		||||
							
								
								
									
										449
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMagik.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										449
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMagik.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,449 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/**
 | 
			
		||||
 * @file LexMagik.cxx
 | 
			
		||||
 * Lexer for GE(r) Smallworld(tm) MagikSF
 | 
			
		||||
 */
 | 
			
		||||
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Is it a core character (C isalpha(), exclamation and question mark)
 | 
			
		||||
 *
 | 
			
		||||
 * \param  ch The character
 | 
			
		||||
 * \return True if ch is a character, False otherwise
 | 
			
		||||
 */
 | 
			
		||||
static inline bool IsAlphaCore(int ch) {
 | 
			
		||||
    return (isalpha(ch) || ch == '!' || ch == '?');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Is it a character (IsAlphaCore() and underscore)
 | 
			
		||||
 *
 | 
			
		||||
 * \param  ch The character
 | 
			
		||||
 * \return True if ch is a character, False otherwise
 | 
			
		||||
 */
 | 
			
		||||
static inline bool IsAlpha(int ch) {
 | 
			
		||||
    return (IsAlphaCore(ch) || ch == '_');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Is it a symbolic character (IsAlpha() and colon)
 | 
			
		||||
 *
 | 
			
		||||
 * \param  ch The character
 | 
			
		||||
 * \return True if ch is a character, False otherwise
 | 
			
		||||
 */
 | 
			
		||||
static inline bool IsAlphaSym(int ch) {
 | 
			
		||||
    return (IsAlpha(ch) || ch == ':');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Is it a numerical character (IsAlpha() and 0 - 9)
 | 
			
		||||
 *
 | 
			
		||||
 * \param  ch The character
 | 
			
		||||
 * \return True if ch is a character, False otherwise
 | 
			
		||||
 */
 | 
			
		||||
static inline bool IsAlNum(int ch) {
 | 
			
		||||
    return ((ch >= '0' && ch <= '9') || IsAlpha(ch));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Is it a symbolic numerical character (IsAlNum() and colon)
 | 
			
		||||
 *
 | 
			
		||||
 * \param  ch The character
 | 
			
		||||
 * \return True if ch is a character, False otherwise
 | 
			
		||||
 */
 | 
			
		||||
static inline bool IsAlNumSym(int ch) {
 | 
			
		||||
    return (IsAlNum(ch) || ch == ':');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The lexer function
 | 
			
		||||
 *
 | 
			
		||||
 * \param  startPos Where to start scanning
 | 
			
		||||
 * \param  length Where to scan to
 | 
			
		||||
 * \param  initStyle The style at the initial point, not used in this folder
 | 
			
		||||
 * \param  keywordlists The keywordslists, currently, number 5 is used
 | 
			
		||||
 * \param  styler The styler
 | 
			
		||||
 */
 | 
			
		||||
static void ColouriseMagikDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                           WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
    styler.StartAt(startPos);
 | 
			
		||||
 | 
			
		||||
    WordList &keywords = *keywordlists[0];
 | 
			
		||||
    WordList &pragmatics = *keywordlists[1];
 | 
			
		||||
    WordList &containers = *keywordlists[2];
 | 
			
		||||
    WordList &flow = *keywordlists[3];
 | 
			
		||||
    WordList &characters = *keywordlists[4];
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
    repeat:
 | 
			
		||||
 | 
			
		||||
        if(sc.ch == '#') {
 | 
			
		||||
            if (sc.chNext == '#') sc.SetState(SCE_MAGIK_HYPER_COMMENT);
 | 
			
		||||
            else sc.SetState(SCE_MAGIK_COMMENT);
 | 
			
		||||
            for(; sc.More() && !(sc.atLineEnd); sc.Forward());
 | 
			
		||||
            sc.SetState(SCE_MAGIK_DEFAULT);
 | 
			
		||||
            goto repeat;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(sc.ch == '"') {
 | 
			
		||||
            sc.SetState(SCE_MAGIK_STRING);
 | 
			
		||||
 | 
			
		||||
            if(sc.More())
 | 
			
		||||
            {
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
                for(; sc.More() && sc.ch != '"'; sc.Forward());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            sc.ForwardSetState(SCE_MAGIK_DEFAULT);
 | 
			
		||||
            goto repeat;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
	    // The default state
 | 
			
		||||
	    if(sc.state == SCE_MAGIK_DEFAULT) {
 | 
			
		||||
 | 
			
		||||
	        // A certain keyword has been detected
 | 
			
		||||
	        if (sc.ch == '_' && (
 | 
			
		||||
                    sc.currentPos == 0 || !IsAlNum(sc.chPrev))) {
 | 
			
		||||
	            char keyword[50];
 | 
			
		||||
	            memset(keyword, '\0', 50);
 | 
			
		||||
 | 
			
		||||
	            for(
 | 
			
		||||
                    int scanPosition = 0;
 | 
			
		||||
                    scanPosition < 50;
 | 
			
		||||
                    scanPosition++) {
 | 
			
		||||
	                char keywordChar = static_cast<char>(
 | 
			
		||||
                        tolower(styler.SafeGetCharAt(
 | 
			
		||||
                            scanPosition +
 | 
			
		||||
                                static_cast<Sci_Position>(sc.currentPos+1), ' ')));
 | 
			
		||||
                    if(IsAlpha(keywordChar)) {
 | 
			
		||||
                        keyword[scanPosition] = keywordChar;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
	            }
 | 
			
		||||
 | 
			
		||||
                // It is a pragma
 | 
			
		||||
	            if(pragmatics.InList(keyword)) {
 | 
			
		||||
	                sc.SetState(SCE_MAGIK_PRAGMA);
 | 
			
		||||
	            }
 | 
			
		||||
 | 
			
		||||
	            // it is a normal keyword like _local, _self, etc.
 | 
			
		||||
	            else if(keywords.InList(keyword)) {
 | 
			
		||||
	                sc.SetState(SCE_MAGIK_KEYWORD);
 | 
			
		||||
	            }
 | 
			
		||||
 | 
			
		||||
                // It is a container keyword, such as _method, _proc, etc.
 | 
			
		||||
	            else if(containers.InList(keyword)) {
 | 
			
		||||
	                sc.SetState(SCE_MAGIK_CONTAINER);
 | 
			
		||||
	            }
 | 
			
		||||
 | 
			
		||||
	            // It is a flow keyword, such as _for, _if, _try, etc.
 | 
			
		||||
	            else if(flow.InList(keyword)) {
 | 
			
		||||
	                sc.SetState(SCE_MAGIK_FLOW);
 | 
			
		||||
	            }
 | 
			
		||||
 | 
			
		||||
	            // Interpret as unknown keyword
 | 
			
		||||
	            else {
 | 
			
		||||
	                sc.SetState(SCE_MAGIK_UNKNOWN_KEYWORD);
 | 
			
		||||
	            }
 | 
			
		||||
	        }
 | 
			
		||||
 | 
			
		||||
            // Symbolic expression
 | 
			
		||||
	        else if(sc.ch == ':' && !IsAlNum(sc.chPrev)) {
 | 
			
		||||
	            sc.SetState(SCE_MAGIK_SYMBOL);
 | 
			
		||||
	            bool firstTrip = true;
 | 
			
		||||
	            for(sc.Forward(); sc.More(); sc.Forward()) {
 | 
			
		||||
	                if(firstTrip && IsAlphaSym(sc.ch));
 | 
			
		||||
	                else if(!firstTrip && IsAlNumSym(sc.ch));
 | 
			
		||||
	                else if(sc.ch == '|') {
 | 
			
		||||
	                    for(sc.Forward();
 | 
			
		||||
                            sc.More() && sc.ch != '|';
 | 
			
		||||
                            sc.Forward());
 | 
			
		||||
	                }
 | 
			
		||||
	                else break;
 | 
			
		||||
 | 
			
		||||
	                firstTrip = false;
 | 
			
		||||
	            }
 | 
			
		||||
	            sc.SetState(SCE_MAGIK_DEFAULT);
 | 
			
		||||
	            goto repeat;
 | 
			
		||||
	        }
 | 
			
		||||
 | 
			
		||||
            // Identifier (label) expression
 | 
			
		||||
	        else if(sc.ch == '@') {
 | 
			
		||||
	            sc.SetState(SCE_MAGIK_IDENTIFIER);
 | 
			
		||||
	            bool firstTrip = true;
 | 
			
		||||
	            for(sc.Forward(); sc.More(); sc.Forward()) {
 | 
			
		||||
	                if(firstTrip && IsAlphaCore(sc.ch)) {
 | 
			
		||||
	                    firstTrip = false;
 | 
			
		||||
	                }
 | 
			
		||||
	                else if(!firstTrip && IsAlpha(sc.ch));
 | 
			
		||||
	                else break;
 | 
			
		||||
	            }
 | 
			
		||||
	            sc.SetState(SCE_MAGIK_DEFAULT);
 | 
			
		||||
	            goto repeat;
 | 
			
		||||
	        }
 | 
			
		||||
 | 
			
		||||
	        // Start of a character
 | 
			
		||||
            else if(sc.ch == '%') {
 | 
			
		||||
                sc.SetState(SCE_MAGIK_CHARACTER);
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
                char keyword[50];
 | 
			
		||||
	            memset(keyword, '\0', 50);
 | 
			
		||||
 | 
			
		||||
	            for(
 | 
			
		||||
                    int scanPosition = 0;
 | 
			
		||||
                    scanPosition < 50;
 | 
			
		||||
                    scanPosition++) {
 | 
			
		||||
	                char keywordChar = static_cast<char>(
 | 
			
		||||
                        tolower(styler.SafeGetCharAt(
 | 
			
		||||
                            scanPosition +
 | 
			
		||||
                                static_cast<int>(sc.currentPos), ' ')));
 | 
			
		||||
                    if(IsAlpha(keywordChar)) {
 | 
			
		||||
                        keyword[scanPosition] = keywordChar;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
	            }
 | 
			
		||||
 | 
			
		||||
	            if(characters.InList(keyword)) {
 | 
			
		||||
	                sc.Forward(static_cast<int>(strlen(keyword)));
 | 
			
		||||
	            } else {
 | 
			
		||||
	                sc.Forward();
 | 
			
		||||
	            }
 | 
			
		||||
 | 
			
		||||
                sc.SetState(SCE_MAGIK_DEFAULT);
 | 
			
		||||
                goto repeat;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Operators
 | 
			
		||||
	        else if(
 | 
			
		||||
                sc.ch == '>' ||
 | 
			
		||||
                sc.ch == '<' ||
 | 
			
		||||
                sc.ch == '.' ||
 | 
			
		||||
                sc.ch == ',' ||
 | 
			
		||||
                sc.ch == '+' ||
 | 
			
		||||
                sc.ch == '-' ||
 | 
			
		||||
                sc.ch == '/' ||
 | 
			
		||||
                sc.ch == '*' ||
 | 
			
		||||
                sc.ch == '~' ||
 | 
			
		||||
                sc.ch == '$' ||
 | 
			
		||||
                sc.ch == '=') {
 | 
			
		||||
                sc.SetState(SCE_MAGIK_OPERATOR);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Braces
 | 
			
		||||
            else if(sc.ch == '(' || sc.ch == ')') {
 | 
			
		||||
                sc.SetState(SCE_MAGIK_BRACE_BLOCK);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Brackets
 | 
			
		||||
            else if(sc.ch == '{' || sc.ch == '}') {
 | 
			
		||||
                sc.SetState(SCE_MAGIK_BRACKET_BLOCK);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Square Brackets
 | 
			
		||||
            else if(sc.ch == '[' || sc.ch == ']') {
 | 
			
		||||
                sc.SetState(SCE_MAGIK_SQBRACKET_BLOCK);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
	    // It is an operator
 | 
			
		||||
	    else if(
 | 
			
		||||
            sc.state == SCE_MAGIK_OPERATOR ||
 | 
			
		||||
            sc.state == SCE_MAGIK_BRACE_BLOCK ||
 | 
			
		||||
            sc.state == SCE_MAGIK_BRACKET_BLOCK ||
 | 
			
		||||
            sc.state == SCE_MAGIK_SQBRACKET_BLOCK) {
 | 
			
		||||
	        sc.SetState(SCE_MAGIK_DEFAULT);
 | 
			
		||||
	        goto repeat;
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
	    // It is the pragma state
 | 
			
		||||
	    else if(sc.state == SCE_MAGIK_PRAGMA) {
 | 
			
		||||
	        if(!IsAlpha(sc.ch)) {
 | 
			
		||||
	            sc.SetState(SCE_MAGIK_DEFAULT);
 | 
			
		||||
                goto repeat;
 | 
			
		||||
	        }
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
	    // It is the keyword state
 | 
			
		||||
	    else if(
 | 
			
		||||
            sc.state == SCE_MAGIK_KEYWORD ||
 | 
			
		||||
            sc.state == SCE_MAGIK_CONTAINER ||
 | 
			
		||||
            sc.state == SCE_MAGIK_FLOW ||
 | 
			
		||||
            sc.state == SCE_MAGIK_UNKNOWN_KEYWORD) {
 | 
			
		||||
	        if(!IsAlpha(sc.ch)) {
 | 
			
		||||
	            sc.SetState(SCE_MAGIK_DEFAULT);
 | 
			
		||||
	            goto repeat;
 | 
			
		||||
	        }
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The word list description
 | 
			
		||||
 */
 | 
			
		||||
static const char * const magikWordListDesc[] = {
 | 
			
		||||
    "Accessors (local, global, self, super, thisthread)",
 | 
			
		||||
    "Pragmatic (pragma, private)",
 | 
			
		||||
    "Containers (method, block, proc)",
 | 
			
		||||
    "Flow (if, then, elif, else)",
 | 
			
		||||
    "Characters (space, tab, newline, return)",
 | 
			
		||||
    "Fold Containers (method, proc, block, if, loop)",
 | 
			
		||||
    0};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This function detects keywords which are able to have a body. Note that it
 | 
			
		||||
 * uses the Fold Containers word description, not the containers description. It
 | 
			
		||||
 * only works when the style at that particular position is set on Containers
 | 
			
		||||
 * or Flow (number 3 or 4).
 | 
			
		||||
 *
 | 
			
		||||
 * \param  keywordslist The list of keywords that are scanned, they should only
 | 
			
		||||
 *         contain the start keywords, not the end keywords
 | 
			
		||||
 * \param  keyword The actual keyword
 | 
			
		||||
 * \return 1 if it is a folding start-keyword, -1 if it is a folding end-keyword
 | 
			
		||||
 *         0 otherwise
 | 
			
		||||
 */
 | 
			
		||||
static inline int IsFoldingContainer(WordList &keywordslist, char * keyword) {
 | 
			
		||||
    if(
 | 
			
		||||
        strlen(keyword) > 3 &&
 | 
			
		||||
        keyword[0] == 'e' && keyword[1] == 'n' && keyword[2] == 'd') {
 | 
			
		||||
        if (keywordslist.InList(keyword + 3)) {
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        if(keywordslist.InList(keyword)) {
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The folding function
 | 
			
		||||
 *
 | 
			
		||||
 * \param  startPos Where to start scanning
 | 
			
		||||
 * \param  length Where to scan to
 | 
			
		||||
 * \param  keywordslists The keywordslists, currently, number 5 is used
 | 
			
		||||
 * \param  styler The styler
 | 
			
		||||
 */
 | 
			
		||||
static void FoldMagikDoc(Sci_PositionU startPos, Sci_Position length, int,
 | 
			
		||||
    WordList *keywordslists[], Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
    bool compact = styler.GetPropertyInt("fold.compact") != 0;
 | 
			
		||||
 | 
			
		||||
    WordList &foldingElements = *keywordslists[5];
 | 
			
		||||
    Sci_Position endPos = startPos + length;
 | 
			
		||||
    Sci_Position line = styler.GetLine(startPos);
 | 
			
		||||
    int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
    int flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
 | 
			
		||||
    for(
 | 
			
		||||
        Sci_Position currentPos = startPos;
 | 
			
		||||
        currentPos < endPos;
 | 
			
		||||
        currentPos++) {
 | 
			
		||||
            char currentState = styler.StyleAt(currentPos);
 | 
			
		||||
            char c = styler.SafeGetCharAt(currentPos, ' ');
 | 
			
		||||
            Sci_Position prevLine = styler.GetLine(currentPos - 1);
 | 
			
		||||
            line = styler.GetLine(currentPos);
 | 
			
		||||
 | 
			
		||||
            // Default situation
 | 
			
		||||
            if(prevLine < line) {
 | 
			
		||||
                styler.SetLevel(line, (level|flags) & ~SC_FOLDLEVELHEADERFLAG);
 | 
			
		||||
                flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(
 | 
			
		||||
                (
 | 
			
		||||
                    currentState == SCE_MAGIK_CONTAINER ||
 | 
			
		||||
                    currentState == SCE_MAGIK_FLOW
 | 
			
		||||
                ) &&
 | 
			
		||||
                c == '_') {
 | 
			
		||||
 | 
			
		||||
                char keyword[50];
 | 
			
		||||
                memset(keyword, '\0', 50);
 | 
			
		||||
 | 
			
		||||
                for(
 | 
			
		||||
                    int scanPosition = 0;
 | 
			
		||||
                    scanPosition < 50;
 | 
			
		||||
                    scanPosition++) {
 | 
			
		||||
                    char keywordChar = static_cast<char>(
 | 
			
		||||
                        tolower(styler.SafeGetCharAt(
 | 
			
		||||
                            scanPosition +
 | 
			
		||||
                                currentPos + 1, ' ')));
 | 
			
		||||
                    if(IsAlpha(keywordChar)) {
 | 
			
		||||
                        keyword[scanPosition] = keywordChar;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if(IsFoldingContainer(foldingElements, keyword) > 0) {
 | 
			
		||||
                    styler.SetLevel(
 | 
			
		||||
                        line,
 | 
			
		||||
                        styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
 | 
			
		||||
                    level++;
 | 
			
		||||
                } else if(IsFoldingContainer(foldingElements, keyword) < 0) {
 | 
			
		||||
                    styler.SetLevel(line, styler.LevelAt(line));
 | 
			
		||||
                    level--;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(
 | 
			
		||||
                compact && (
 | 
			
		||||
                    currentState == SCE_MAGIK_BRACE_BLOCK ||
 | 
			
		||||
                    currentState == SCE_MAGIK_BRACKET_BLOCK ||
 | 
			
		||||
                    currentState == SCE_MAGIK_SQBRACKET_BLOCK)) {
 | 
			
		||||
                if(c == '{' || c == '[' || c == '(') {
 | 
			
		||||
                    styler.SetLevel(
 | 
			
		||||
                        line,
 | 
			
		||||
                        styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
 | 
			
		||||
                    level++;
 | 
			
		||||
                } else if(c == '}' || c == ']' || c == ')') {
 | 
			
		||||
                    styler.SetLevel(line, styler.LevelAt(line));
 | 
			
		||||
                    level--;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Injecting the module
 | 
			
		||||
 */
 | 
			
		||||
extern const LexerModule lmMagikSF(
 | 
			
		||||
    SCLEX_MAGIK, ColouriseMagikDoc, "magiksf", FoldMagikDoc, magikWordListDesc);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										143
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMake.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMake.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,143 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexMake.cxx
 | 
			
		||||
 ** Lexer for make files.
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cctype>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cstdarg>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
static inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
 | 
			
		||||
	return (styler[i] == '\n') ||
 | 
			
		||||
	       ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseMakeLine(
 | 
			
		||||
	const std::string &lineBuffer,
 | 
			
		||||
    Sci_PositionU startLine,
 | 
			
		||||
    Sci_PositionU endPos,
 | 
			
		||||
    Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	const Sci_PositionU lengthLine = lineBuffer.length();
 | 
			
		||||
	Sci_PositionU i = 0;
 | 
			
		||||
	Sci_Position lastNonSpace = -1;
 | 
			
		||||
	unsigned int state = SCE_MAKE_DEFAULT;
 | 
			
		||||
	bool bSpecial = false;
 | 
			
		||||
 | 
			
		||||
	// check for a tab character in column 0 indicating a command
 | 
			
		||||
	bool bCommand = false;
 | 
			
		||||
	if ((lengthLine > 0) && (lineBuffer[0] == '\t'))
 | 
			
		||||
		bCommand = true;
 | 
			
		||||
 | 
			
		||||
	// Skip initial spaces
 | 
			
		||||
	while ((i < lengthLine) && isspacechar(lineBuffer[i])) {
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	if (i < lengthLine) {
 | 
			
		||||
		if (lineBuffer[i] == '#') {	// Comment
 | 
			
		||||
			styler.ColourTo(endPos, SCE_MAKE_COMMENT);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		if (lineBuffer[i] == '!') {	// Special directive
 | 
			
		||||
			styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	int varCount = 0;
 | 
			
		||||
	while (i < lengthLine) {
 | 
			
		||||
		if (((i + 1) < lengthLine) && (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(')) {
 | 
			
		||||
			styler.ColourTo(startLine + i - 1, state);
 | 
			
		||||
			state = SCE_MAKE_IDENTIFIER;
 | 
			
		||||
			varCount++;
 | 
			
		||||
		} else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
 | 
			
		||||
			if (--varCount == 0) {
 | 
			
		||||
				styler.ColourTo(startLine + i, state);
 | 
			
		||||
				state = SCE_MAKE_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// skip identifier and target styling if this is a command line
 | 
			
		||||
		if (!bSpecial && !bCommand) {
 | 
			
		||||
			if (lineBuffer[i] == ':') {
 | 
			
		||||
				if (((i + 1) < lengthLine) && (lineBuffer[i + 1] == '=')) {
 | 
			
		||||
					// it's a ':=', so style as an identifier
 | 
			
		||||
					if (lastNonSpace >= 0)
 | 
			
		||||
						styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
 | 
			
		||||
					styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
 | 
			
		||||
					styler.ColourTo(startLine + i + 1, SCE_MAKE_OPERATOR);
 | 
			
		||||
				} else {
 | 
			
		||||
					// We should check that no colouring was made since the beginning of the line,
 | 
			
		||||
					// to avoid colouring stuff like /OUT:file
 | 
			
		||||
					if (lastNonSpace >= 0)
 | 
			
		||||
						styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
 | 
			
		||||
					styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
 | 
			
		||||
					styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
 | 
			
		||||
				}
 | 
			
		||||
				bSpecial = true;	// Only react to the first ':' of the line
 | 
			
		||||
				state = SCE_MAKE_DEFAULT;
 | 
			
		||||
			} else if (lineBuffer[i] == '=') {
 | 
			
		||||
				if (lastNonSpace >= 0)
 | 
			
		||||
					styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
 | 
			
		||||
				styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
 | 
			
		||||
				styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
 | 
			
		||||
				bSpecial = true;	// Only react to the first '=' of the line
 | 
			
		||||
				state = SCE_MAKE_DEFAULT;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!isspacechar(lineBuffer[i])) {
 | 
			
		||||
			lastNonSpace = i;
 | 
			
		||||
		}
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	if (state == SCE_MAKE_IDENTIFIER) {
 | 
			
		||||
		styler.ColourTo(endPos, SCE_MAKE_IDEOL);	// Error, variable reference not ended
 | 
			
		||||
	} else {
 | 
			
		||||
		styler.ColourTo(endPos, SCE_MAKE_DEFAULT);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseMakeDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
 | 
			
		||||
	std::string lineBuffer;
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
	styler.StartSegment(startPos);
 | 
			
		||||
	Sci_PositionU startLine = startPos;
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < startPos + length; i++) {
 | 
			
		||||
		lineBuffer.push_back(styler[i]);
 | 
			
		||||
		if (AtEOL(styler, i)) {
 | 
			
		||||
			// End of line (or of line buffer) met, colourise it
 | 
			
		||||
			ColouriseMakeLine(lineBuffer, startLine, i, styler);
 | 
			
		||||
			lineBuffer.clear();
 | 
			
		||||
			startLine = i + 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (!lineBuffer.empty()) {	// Last line does not have ending characters
 | 
			
		||||
		ColouriseMakeLine(lineBuffer, startLine, startPos + length - 1, styler);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *const emptyWordListDesc[] = {
 | 
			
		||||
	nullptr
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", nullptr, emptyWordListDesc);
 | 
			
		||||
							
								
								
									
										486
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMarkdown.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										486
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMarkdown.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,486 @@
 | 
			
		||||
/******************************************************************
 | 
			
		||||
 *  LexMarkdown.cxx
 | 
			
		||||
 *
 | 
			
		||||
 *  A simple Markdown lexer for scintilla.
 | 
			
		||||
 *
 | 
			
		||||
 *  Includes highlighting for some extra features from the
 | 
			
		||||
 *  Pandoc implementation; strikeout, using '#.' as a default
 | 
			
		||||
 *  ordered list item marker, and delimited code blocks.
 | 
			
		||||
 *
 | 
			
		||||
 *  Limitations:
 | 
			
		||||
 *
 | 
			
		||||
 *  Standard indented code blocks are not highlighted at all,
 | 
			
		||||
 *  as it would conflict with other indentation schemes. Use
 | 
			
		||||
 *  delimited code blocks for blanket highlighting of an
 | 
			
		||||
 *  entire code block.  Embedded HTML is not highlighted either.
 | 
			
		||||
 *  Blanket HTML highlighting has issues, because some Markdown
 | 
			
		||||
 *  implementations allow Markdown markup inside of the HTML. Also,
 | 
			
		||||
 *  there is a following blank line issue that can't be ignored,
 | 
			
		||||
 *  explained in the next paragraph. Embedded HTML and code
 | 
			
		||||
 *  blocks would be better supported with language specific
 | 
			
		||||
 *  highlighting.
 | 
			
		||||
 *
 | 
			
		||||
 *  The highlighting aims to accurately reflect correct syntax,
 | 
			
		||||
 *  but a few restrictions are relaxed. Delimited code blocks are
 | 
			
		||||
 *  highlighted, even if the line following the code block is not blank.
 | 
			
		||||
 *  Requiring a blank line after a block, breaks the highlighting
 | 
			
		||||
 *  in certain cases, because of the way Scintilla ends up calling
 | 
			
		||||
 *  the lexer.
 | 
			
		||||
 *
 | 
			
		||||
 *  Written by Jon Strait - jstrait@moonloop.net
 | 
			
		||||
 *
 | 
			
		||||
 *  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;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
constexpr bool IsNewline(const int ch) {
 | 
			
		||||
    // sc.GetRelative(i) returns '\0' if out of range
 | 
			
		||||
    return (ch == '\n' || ch == '\r' || ch == '\0');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// True if can follow ch down to the end with possibly trailing whitespace
 | 
			
		||||
// Does not set the state SCE_MARKDOWN_LINE_BEGIN as to allow further processing
 | 
			
		||||
static bool FollowToLineEnd(const int ch, const int state, const Sci_PositionU endPos, StyleContext &sc) {
 | 
			
		||||
    Sci_Position i = 0;
 | 
			
		||||
    while (sc.GetRelative(++i) == ch)
 | 
			
		||||
        ;
 | 
			
		||||
    // Skip over whitespace
 | 
			
		||||
    while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)
 | 
			
		||||
        ++i;
 | 
			
		||||
    if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {
 | 
			
		||||
        sc.SetState(state);
 | 
			
		||||
        sc.Forward(i);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set the state on text section from current to length characters,
 | 
			
		||||
// then set the rest until the newline to default, except for any characters matching token
 | 
			
		||||
static void SetStateAndZoom(const int state, const Sci_Position length, const int token, StyleContext &sc) {
 | 
			
		||||
    sc.SetState(state);
 | 
			
		||||
    sc.Forward(length);
 | 
			
		||||
    sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
    sc.Forward();
 | 
			
		||||
    bool started = false;
 | 
			
		||||
    while (sc.More() && !IsNewline(sc.ch)) {
 | 
			
		||||
        if (sc.ch == token && !started) {
 | 
			
		||||
            sc.SetState(state);
 | 
			
		||||
            started = true;
 | 
			
		||||
        }
 | 
			
		||||
        else if (sc.ch != token) {
 | 
			
		||||
            sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            started = false;
 | 
			
		||||
        }
 | 
			
		||||
        sc.Forward();
 | 
			
		||||
    }
 | 
			
		||||
    sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Does the previous line have more than spaces and tabs?
 | 
			
		||||
static bool HasPrevLineContent(StyleContext &sc) {
 | 
			
		||||
    Sci_Position i = 0;
 | 
			
		||||
    // Go back to the previous newline
 | 
			
		||||
    while ((--i + (Sci_Position)sc.currentPos) >= 0 && !IsNewline(sc.GetRelative(i)))
 | 
			
		||||
        ;
 | 
			
		||||
    while ((--i + (Sci_Position)sc.currentPos) >= 0) {
 | 
			
		||||
        const int ch = sc.GetRelative(i);
 | 
			
		||||
        if (ch == '\n')
 | 
			
		||||
            break;
 | 
			
		||||
        if (!((ch == '\r' || IsASpaceOrTab(ch))))
 | 
			
		||||
            return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool AtTermStart(StyleContext &sc) {
 | 
			
		||||
    return sc.currentPos == 0 || sc.chPrev == 0 || isspacechar(sc.chPrev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsCompleteStyleRegion(StyleContext &sc, const char *token) {
 | 
			
		||||
    bool found = false;
 | 
			
		||||
    const size_t start = strlen(token);
 | 
			
		||||
    Sci_Position i = static_cast<Sci_Position>(start);
 | 
			
		||||
    while (!IsNewline(sc.GetRelative(i))) {
 | 
			
		||||
        // make sure an empty pair of single-char tokens doesn't match
 | 
			
		||||
        // with a longer token: {*}{*} != {**}
 | 
			
		||||
        if (sc.GetRelative(i) == *token && sc.GetRelative(i - 1) != *token) {
 | 
			
		||||
            found = start > 1U ? sc.GetRelative(i + 1) == token[1] : true;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        i++;
 | 
			
		||||
    }
 | 
			
		||||
    return AtTermStart(sc) && found;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsValidHrule(const Sci_PositionU endPos, StyleContext &sc) {
 | 
			
		||||
    int count = 1;
 | 
			
		||||
    Sci_Position i = 0;
 | 
			
		||||
    for (;;) {
 | 
			
		||||
        ++i;
 | 
			
		||||
        int c = sc.GetRelative(i);
 | 
			
		||||
        if (c == sc.ch)
 | 
			
		||||
            ++count;
 | 
			
		||||
        // hit a terminating character
 | 
			
		||||
        else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
 | 
			
		||||
            // Are we a valid HRULE
 | 
			
		||||
            if ((IsNewline(c) || sc.currentPos + i == endPos) &&
 | 
			
		||||
                    count >= 3 && !HasPrevLineContent(sc)) {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_HRULE);
 | 
			
		||||
                sc.Forward(i);
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColorizeMarkdownDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                                WordList **, Accessor &styler) {
 | 
			
		||||
    Sci_PositionU endPos = startPos + length;
 | 
			
		||||
    int precharCount = 0;
 | 
			
		||||
    bool isLinkNameDetecting = false;
 | 
			
		||||
    // Don't advance on a new loop iteration and retry at the same position.
 | 
			
		||||
    // Useful in the corner case of having to start at the beginning file position
 | 
			
		||||
    // in the default state.
 | 
			
		||||
    bool freezeCursor = false;
 | 
			
		||||
 | 
			
		||||
    // property lexer.markdown.header.eolfill
 | 
			
		||||
    //  Set to 1 to highlight all ATX header text.
 | 
			
		||||
    bool headerEOLFill = styler.GetPropertyInt("lexer.markdown.header.eolfill", 0) == 1;
 | 
			
		||||
 | 
			
		||||
    StyleContext sc(startPos, static_cast<Sci_PositionU>(length), initStyle, styler);
 | 
			
		||||
 | 
			
		||||
    while (sc.More()) {
 | 
			
		||||
        // Skip past escaped characters
 | 
			
		||||
        if (sc.ch == '\\') {
 | 
			
		||||
            sc.Forward();
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // A blockquotes resets the line semantics
 | 
			
		||||
        if (sc.state == SCE_MARKDOWN_BLOCKQUOTE)
 | 
			
		||||
            sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
 | 
			
		||||
 | 
			
		||||
        // Conditional state-based actions
 | 
			
		||||
        if (sc.state == SCE_MARKDOWN_CODE2) {
 | 
			
		||||
            if (sc.Match("``")) {
 | 
			
		||||
                const int closingSpan = (sc.GetRelative(2) == '`') ? 3 : 2;
 | 
			
		||||
                sc.Forward(closingSpan);
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (sc.state == SCE_MARKDOWN_CODE) {
 | 
			
		||||
            if (sc.ch == '`' && sc.chPrev != ' ')
 | 
			
		||||
                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
        }
 | 
			
		||||
        /* De-activated because it gets in the way of other valid indentation
 | 
			
		||||
         * schemes, for example multiple paragraphs inside a list item.
 | 
			
		||||
        // Code block
 | 
			
		||||
        else if (sc.state == SCE_MARKDOWN_CODEBK) {
 | 
			
		||||
            bool d = true;
 | 
			
		||||
            if (IsNewline(sc.ch)) {
 | 
			
		||||
                if (sc.chNext != '\t') {
 | 
			
		||||
                    for (int c = 1; c < 5; ++c) {
 | 
			
		||||
                        if (sc.GetRelative(c) != ' ')
 | 
			
		||||
                            d = false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.atLineStart) {
 | 
			
		||||
                if (sc.ch != '\t' ) {
 | 
			
		||||
                    for (int i = 0; i < 4; ++i) {
 | 
			
		||||
                        if (sc.GetRelative(i) != ' ')
 | 
			
		||||
                            d = false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (!d)
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
 | 
			
		||||
        }
 | 
			
		||||
        */
 | 
			
		||||
        // Strong
 | 
			
		||||
        else if (sc.state == SCE_MARKDOWN_STRONG1) {
 | 
			
		||||
            if ((sc.Match("**") && sc.chPrev != ' ') || IsNewline(sc.GetRelative(2))) {
 | 
			
		||||
                sc.Forward(2);
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (sc.state == SCE_MARKDOWN_STRONG2) {
 | 
			
		||||
            if ((sc.Match("__") && sc.chPrev != ' ') || IsNewline(sc.GetRelative(2))) {
 | 
			
		||||
                sc.Forward(2);
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Emphasis
 | 
			
		||||
        else if (sc.state == SCE_MARKDOWN_EM1) {
 | 
			
		||||
            if ((sc.ch == '*' && sc.chPrev != ' ') || IsNewline(sc.chNext))
 | 
			
		||||
                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
        }
 | 
			
		||||
        else if (sc.state == SCE_MARKDOWN_EM2) {
 | 
			
		||||
            if ((sc.ch == '_' && sc.chPrev != ' ') || IsNewline(sc.chNext))
 | 
			
		||||
                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
        }
 | 
			
		||||
        else if (sc.state == SCE_MARKDOWN_CODEBK) {
 | 
			
		||||
            if (sc.atLineStart && sc.Match("~~~")) {
 | 
			
		||||
                Sci_Position i = 1;
 | 
			
		||||
                while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos)
 | 
			
		||||
                    i++;
 | 
			
		||||
                sc.Forward(i);
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (sc.state == SCE_MARKDOWN_STRIKEOUT) {
 | 
			
		||||
            if ((sc.Match("~~") && sc.chPrev != ' ') || IsNewline(sc.GetRelative(2))) {
 | 
			
		||||
                sc.Forward(2);
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (sc.state == SCE_MARKDOWN_LINE_BEGIN) {
 | 
			
		||||
            // Header
 | 
			
		||||
            if (sc.Match("######")) {
 | 
			
		||||
                if (headerEOLFill)
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_HEADER6);
 | 
			
		||||
                else
 | 
			
		||||
                    SetStateAndZoom(SCE_MARKDOWN_HEADER6, 6, '#', sc);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.Match("#####")) {
 | 
			
		||||
                if (headerEOLFill)
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_HEADER5);
 | 
			
		||||
                else
 | 
			
		||||
                    SetStateAndZoom(SCE_MARKDOWN_HEADER5, 5, '#', sc);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.Match("####")) {
 | 
			
		||||
                if (headerEOLFill)
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_HEADER4);
 | 
			
		||||
                else
 | 
			
		||||
                    SetStateAndZoom(SCE_MARKDOWN_HEADER4, 4, '#', sc);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.Match("###")) {
 | 
			
		||||
                if (headerEOLFill)
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_HEADER3);
 | 
			
		||||
                else
 | 
			
		||||
                    SetStateAndZoom(SCE_MARKDOWN_HEADER3, 3, '#', sc);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.Match("##")) {
 | 
			
		||||
                if (headerEOLFill)
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_HEADER2);
 | 
			
		||||
                else
 | 
			
		||||
                    SetStateAndZoom(SCE_MARKDOWN_HEADER2, 2, '#', sc);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.Match("#")) {
 | 
			
		||||
                // Catch the special case of an unordered list
 | 
			
		||||
                if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
 | 
			
		||||
                    precharCount = 0;
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_PRECHAR);
 | 
			
		||||
                }
 | 
			
		||||
                else if (headerEOLFill) {
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_HEADER1);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    SetStateAndZoom(SCE_MARKDOWN_HEADER1, 1, '#', sc);
 | 
			
		||||
            }
 | 
			
		||||
            // Code block
 | 
			
		||||
            else if (sc.Match("~~~")) {
 | 
			
		||||
                if (!HasPrevLineContent(sc))
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_CODEBK);
 | 
			
		||||
                else
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.ch == '=') {
 | 
			
		||||
                if (HasPrevLineContent(sc) && FollowToLineEnd('=', SCE_MARKDOWN_HEADER1, endPos, sc)) {
 | 
			
		||||
                    if (!headerEOLFill)
 | 
			
		||||
                        sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.ch == '-') {
 | 
			
		||||
                if (HasPrevLineContent(sc) && FollowToLineEnd('-', SCE_MARKDOWN_HEADER2, endPos, sc)) {
 | 
			
		||||
                    if (!headerEOLFill)
 | 
			
		||||
                        sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    precharCount = 0;
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_PRECHAR);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (IsNewline(sc.ch))
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
 | 
			
		||||
            else {
 | 
			
		||||
                precharCount = 0;
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_PRECHAR);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // The header lasts until the newline
 | 
			
		||||
        else if (sc.state == SCE_MARKDOWN_HEADER1 || sc.state == SCE_MARKDOWN_HEADER2 ||
 | 
			
		||||
                 sc.state == SCE_MARKDOWN_HEADER3 || sc.state == SCE_MARKDOWN_HEADER4 ||
 | 
			
		||||
                 sc.state == SCE_MARKDOWN_HEADER5 || sc.state == SCE_MARKDOWN_HEADER6) {
 | 
			
		||||
            if (headerEOLFill) {
 | 
			
		||||
                if (sc.atLineStart) {
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
 | 
			
		||||
                    freezeCursor = true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (IsNewline(sc.ch))
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // New state only within the initial whitespace
 | 
			
		||||
        if (sc.state == SCE_MARKDOWN_PRECHAR) {
 | 
			
		||||
            // Blockquote
 | 
			
		||||
            if (sc.ch == '>' && precharCount < 5)
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_BLOCKQUOTE);
 | 
			
		||||
            /*
 | 
			
		||||
            // Begin of code block
 | 
			
		||||
            else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4))
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_CODEBK);
 | 
			
		||||
            */
 | 
			
		||||
            // HRule - Total of three or more hyphens, asterisks, or underscores
 | 
			
		||||
            // on a line by themselves
 | 
			
		||||
            else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '_') && IsValidHrule(endPos, sc))
 | 
			
		||||
                ;
 | 
			
		||||
            // Unordered list
 | 
			
		||||
            else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '+') && IsASpaceOrTab(sc.chNext)) {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_ULIST_ITEM);
 | 
			
		||||
                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            // Ordered list
 | 
			
		||||
            else if (IsADigit(sc.ch)) {
 | 
			
		||||
                int digitCount = 0;
 | 
			
		||||
                while (IsADigit(sc.GetRelative(++digitCount)))
 | 
			
		||||
                    ;
 | 
			
		||||
                if (sc.GetRelative(digitCount) == '.' &&
 | 
			
		||||
                        IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
 | 
			
		||||
                    sc.Forward(digitCount + 1);
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
                } else {
 | 
			
		||||
                    // a textual number at the margin should be plain text
 | 
			
		||||
                    sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // Alternate Ordered list
 | 
			
		||||
            else if (sc.ch == '#' && sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
 | 
			
		||||
                sc.Forward(2);
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.ch != ' ' || precharCount > 2)
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            else
 | 
			
		||||
                ++precharCount;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Any link
 | 
			
		||||
        if (sc.state == SCE_MARKDOWN_LINK) {
 | 
			
		||||
            if (sc.Match("](") && sc.GetRelative(-1) != '\\') {
 | 
			
		||||
                sc.Forward(2);
 | 
			
		||||
                isLinkNameDetecting = true;
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.Match("]:") && sc.GetRelative(-1) != '\\') {
 | 
			
		||||
                sc.Forward(2);
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (!isLinkNameDetecting && sc.ch == ']' && sc.GetRelative(-1) != '\\') {
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
            else if (isLinkNameDetecting && sc.ch == ')' && sc.GetRelative(-1) != '\\') {
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_DEFAULT);
 | 
			
		||||
                isLinkNameDetecting = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // New state anywhere in doc
 | 
			
		||||
        if (sc.state == SCE_MARKDOWN_DEFAULT) {
 | 
			
		||||
            if (sc.atLineStart && sc.ch == '#') {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
 | 
			
		||||
                freezeCursor = true;
 | 
			
		||||
            }
 | 
			
		||||
            // Links and Images
 | 
			
		||||
            if (sc.Match("![")) {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_LINK);
 | 
			
		||||
                sc.Forward(1);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.ch == '[' && sc.GetRelative(-1) != '\\') {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_LINK);
 | 
			
		||||
            }
 | 
			
		||||
            // Code - also a special case for alternate inside spacing
 | 
			
		||||
            else if (sc.Match("``") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) {
 | 
			
		||||
                const int openingSpan = (sc.GetRelative(2) == '`') ? 2 : 1;
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_CODE2);
 | 
			
		||||
                sc.Forward(openingSpan);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.ch == '`' && sc.chNext != ' ' && IsCompleteStyleRegion(sc, "`")) {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_CODE);
 | 
			
		||||
            }
 | 
			
		||||
            // Strong
 | 
			
		||||
            else if (sc.Match("**") && sc.GetRelative(2) != ' ' && IsCompleteStyleRegion(sc, "**")) {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_STRONG1);
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.Match("__") && sc.GetRelative(2) != ' ' && IsCompleteStyleRegion(sc, "__")) {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_STRONG2);
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
            }
 | 
			
		||||
            // Emphasis
 | 
			
		||||
            else if (sc.ch == '*' && sc.chNext != ' ' && IsCompleteStyleRegion(sc, "*")) {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_EM1);
 | 
			
		||||
            }
 | 
			
		||||
            else if (sc.ch == '_' && sc.chNext != ' ' && IsCompleteStyleRegion(sc, "_")) {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_EM2);
 | 
			
		||||
            }
 | 
			
		||||
            // Strikeout
 | 
			
		||||
            else if (sc.Match("~~") && !(sc.GetRelative(2) == '~' || sc.GetRelative(2) == ' ') &&
 | 
			
		||||
                     IsCompleteStyleRegion(sc, "~~")) {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_STRIKEOUT);
 | 
			
		||||
                sc.Forward();
 | 
			
		||||
            }
 | 
			
		||||
            // Beginning of line
 | 
			
		||||
            else if (IsNewline(sc.ch)) {
 | 
			
		||||
                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Advance if not holding back the cursor for this iteration.
 | 
			
		||||
        if (!freezeCursor)
 | 
			
		||||
            sc.Forward();
 | 
			
		||||
        freezeCursor = false;
 | 
			
		||||
    }
 | 
			
		||||
    sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmMarkdown(SCLEX_MARKDOWN, ColorizeMarkdownDoc, "markdown");
 | 
			
		||||
							
								
								
									
										528
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMatlab.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										528
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMatlab.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,528 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
// Encoding: UTF-8
 | 
			
		||||
/** @file LexMatlab.cxx
 | 
			
		||||
 ** Lexer for Matlab.
 | 
			
		||||
 ** Written by José Fonseca
 | 
			
		||||
 **
 | 
			
		||||
 ** Changes by Christoph Dalitz 2003/12/04:
 | 
			
		||||
 **   - added support for Octave
 | 
			
		||||
 **   - Strings can now be included both in single or double quotes
 | 
			
		||||
 **
 | 
			
		||||
 ** Changes by John Donoghue 2012/04/02
 | 
			
		||||
 **   - added block comment (and nested block comments)
 | 
			
		||||
 **   - added ... displayed as a comment
 | 
			
		||||
 **   - removed unused IsAWord functions
 | 
			
		||||
 **   - added some comments
 | 
			
		||||
 **
 | 
			
		||||
 ** Changes by John Donoghue 2014/08/01
 | 
			
		||||
 **   - fix allowed transpose ' after {} operator
 | 
			
		||||
 **
 | 
			
		||||
 ** Changes by John Donoghue 2016/11/15
 | 
			
		||||
 **   - update matlab code folding
 | 
			
		||||
 **
 | 
			
		||||
 ** Changes by John Donoghue 2017/01/18
 | 
			
		||||
 **   - update matlab block comment detection
 | 
			
		||||
 **
 | 
			
		||||
 ** Changes by Andrey Smolyakov 2022/04/15
 | 
			
		||||
 **   - add support for "arguments" block and class definition syntax
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static bool IsMatlabCommentChar(int c) {
 | 
			
		||||
	return (c == '%') ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsOctaveCommentChar(int c) {
 | 
			
		||||
	return (c == '%' || c == '#') ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int LowerCase(int c) {
 | 
			
		||||
	if (c >= 'A' && c <= 'Z')
 | 
			
		||||
		return 'a' + c - 'A';
 | 
			
		||||
	return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CheckKeywordFoldPoint(char *str) {
 | 
			
		||||
	if (strcmp ("if", str) == 0 ||
 | 
			
		||||
		strcmp ("for", str) == 0 ||
 | 
			
		||||
		strcmp ("switch", str) == 0 ||
 | 
			
		||||
		strcmp ("while", str) == 0 ||
 | 
			
		||||
		strcmp ("try", str) == 0 ||
 | 
			
		||||
		strcmp ("do", str) == 0 ||
 | 
			
		||||
		strcmp ("parfor", str) == 0 ||
 | 
			
		||||
		strcmp ("classdef", str) == 0 ||
 | 
			
		||||
		strcmp ("spmd", str) == 0 ||
 | 
			
		||||
		strcmp ("arguments", str) == 0 ||
 | 
			
		||||
		strcmp ("methods", str) == 0 ||
 | 
			
		||||
		strcmp ("properties", str) == 0 ||
 | 
			
		||||
		strcmp ("events", str) == 0 ||
 | 
			
		||||
		strcmp ("function", str) == 0)
 | 
			
		||||
		return 1;
 | 
			
		||||
	if (strncmp("end", str, 3) == 0 ||
 | 
			
		||||
		strcmp("until", str) == 0)
 | 
			
		||||
		return -1;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool IsSpaceToEOL(Sci_Position startPos, Accessor &styler) {
 | 
			
		||||
	Sci_Position line = styler.GetLine(startPos);
 | 
			
		||||
	Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
 | 
			
		||||
	for (Sci_Position i = startPos; i < eol_pos; i++) {
 | 
			
		||||
		char ch = styler[i];
 | 
			
		||||
		if(!IsASpace(ch)) return false;
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define MATLAB_STATE_FOLD_LVL_OFFSET     8
 | 
			
		||||
#define MATLAB_STATE_FOLD_LVL_MASK       (0xFF00)
 | 
			
		||||
#define MATLAB_STATE_FLAGS_OFFSET        16
 | 
			
		||||
#define MATLAB_STATE_COMM_DEPTH_OFFSET   0
 | 
			
		||||
#define MATLAB_STATE_COMM_DEPTH_MASK     (0xFF)
 | 
			
		||||
#define MATLAB_STATE_EXPECTING_ARG_BLOCK (1 << MATLAB_STATE_FLAGS_OFFSET)
 | 
			
		||||
#define MATLAB_STATE_IN_CLASS_SCOPE      (1 <<(MATLAB_STATE_FLAGS_OFFSET+1))
 | 
			
		||||
#define MATLAB_STATE_IN_ARGUMENTS_SCOPE  (1 <<(MATLAB_STATE_FLAGS_OFFSET+2))
 | 
			
		||||
 | 
			
		||||
static int ComposeLineState(int commentDepth,
 | 
			
		||||
							int foldingLevel,
 | 
			
		||||
							int expectingArgumentsBlock,
 | 
			
		||||
							int inClassScope,
 | 
			
		||||
							int inArgumentsScope) {
 | 
			
		||||
 | 
			
		||||
	return  ((commentDepth << MATLAB_STATE_COMM_DEPTH_OFFSET)
 | 
			
		||||
				& MATLAB_STATE_COMM_DEPTH_MASK)					|
 | 
			
		||||
			((foldingLevel << MATLAB_STATE_FOLD_LVL_OFFSET)
 | 
			
		||||
				& MATLAB_STATE_FOLD_LVL_MASK)					|
 | 
			
		||||
			(expectingArgumentsBlock
 | 
			
		||||
				& MATLAB_STATE_EXPECTING_ARG_BLOCK)				|
 | 
			
		||||
			(inClassScope
 | 
			
		||||
				& MATLAB_STATE_IN_CLASS_SCOPE)					|
 | 
			
		||||
			(inArgumentsScope
 | 
			
		||||
				& MATLAB_STATE_IN_ARGUMENTS_SCOPE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseMatlabOctaveDoc(
 | 
			
		||||
            Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
            WordList *keywordlists[], Accessor &styler,
 | 
			
		||||
            bool (*IsCommentChar)(int),
 | 
			
		||||
            bool ismatlab) {
 | 
			
		||||
 | 
			
		||||
	WordList &keywords = *keywordlists[0];
 | 
			
		||||
 | 
			
		||||
	styler.StartAt(startPos);
 | 
			
		||||
 | 
			
		||||
	// boolean for when the ' is allowed to be transpose vs the start/end
 | 
			
		||||
	// of a string
 | 
			
		||||
	bool transpose = false;
 | 
			
		||||
 | 
			
		||||
	// count of brackets as boolean for when end could be an operator not a keyword
 | 
			
		||||
	int allow_end_op = 0;
 | 
			
		||||
 | 
			
		||||
	// approximate position of first non space character in a line
 | 
			
		||||
	int nonSpaceColumn = -1;
 | 
			
		||||
	// approximate column position of the current character in a line
 | 
			
		||||
	int column = 0;
 | 
			
		||||
 | 
			
		||||
	// This line contains a function declaration
 | 
			
		||||
	bool funcDeclarationLine = false;
 | 
			
		||||
	// We've just seen "function" keyword, so now we may expect the "arguments"
 | 
			
		||||
	// keyword opening the corresponding code block
 | 
			
		||||
	int expectingArgumentsBlock = 0;
 | 
			
		||||
    // We saw "arguments" keyword, but not the closing "end"
 | 
			
		||||
    int inArgumentsScope = 0;
 | 
			
		||||
	// Current line's folding level
 | 
			
		||||
	int foldingLevel = 0;
 | 
			
		||||
	// Current line in in class scope
 | 
			
		||||
	int inClassScope = 0;
 | 
			
		||||
 | 
			
		||||
	// use the line state of each line to store the block comment depth
 | 
			
		||||
	Sci_Position curLine = styler.GetLine(startPos);
 | 
			
		||||
	int commentDepth = 0;
 | 
			
		||||
	// Restore the previous line's state, if there was such a line
 | 
			
		||||
	if (curLine > 0) {
 | 
			
		||||
		int prevState = styler.GetLineState(curLine-1);
 | 
			
		||||
		commentDepth = (prevState & MATLAB_STATE_COMM_DEPTH_MASK)
 | 
			
		||||
							>> MATLAB_STATE_COMM_DEPTH_OFFSET;
 | 
			
		||||
		foldingLevel = (prevState & MATLAB_STATE_FOLD_LVL_MASK)
 | 
			
		||||
							>> MATLAB_STATE_FOLD_LVL_OFFSET;
 | 
			
		||||
		expectingArgumentsBlock = prevState & MATLAB_STATE_EXPECTING_ARG_BLOCK;
 | 
			
		||||
		inClassScope = prevState & MATLAB_STATE_IN_CLASS_SCOPE;
 | 
			
		||||
		inArgumentsScope = prevState & MATLAB_STATE_IN_ARGUMENTS_SCOPE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, initStyle, styler);
 | 
			
		||||
 | 
			
		||||
	for (; sc.More(); sc.Forward(), column++) {
 | 
			
		||||
 | 
			
		||||
		if(sc.atLineStart) {
 | 
			
		||||
			// set the line state to the current commentDepth
 | 
			
		||||
			curLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
			styler.SetLineState(curLine, ComposeLineState(
 | 
			
		||||
				commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
 | 
			
		||||
 | 
			
		||||
			// reset the column to 0, nonSpace to -1 (not set)
 | 
			
		||||
			column = 0;
 | 
			
		||||
			nonSpaceColumn = -1;
 | 
			
		||||
 | 
			
		||||
			// Reset the flag
 | 
			
		||||
			funcDeclarationLine = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Semicolon ends function declaration
 | 
			
		||||
		// This condition is for one line functions support
 | 
			
		||||
		if (sc.chPrev == ';') {
 | 
			
		||||
			funcDeclarationLine = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Only comments allowed between the function declaration and the
 | 
			
		||||
		// arguments code block
 | 
			
		||||
		if (expectingArgumentsBlock && !(funcDeclarationLine || inArgumentsScope)) {
 | 
			
		||||
			if ((sc.state != SCE_MATLAB_KEYWORD) &&
 | 
			
		||||
					(sc.state != SCE_MATLAB_COMMENT) &&
 | 
			
		||||
					(sc.state != SCE_MATLAB_DEFAULT) &&
 | 
			
		||||
					!(sc.state == SCE_MATLAB_OPERATOR && sc.chPrev == ';')) {
 | 
			
		||||
				expectingArgumentsBlock = 0;
 | 
			
		||||
				styler.SetLineState(curLine, ComposeLineState(
 | 
			
		||||
					commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// We've just left the class scope
 | 
			
		||||
		if ((foldingLevel ==0) && inClassScope) {
 | 
			
		||||
			inClassScope = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// save the column position of first non space character in a line
 | 
			
		||||
		if((nonSpaceColumn == -1) && (! IsASpace(sc.ch))) {
 | 
			
		||||
			nonSpaceColumn = column;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// check for end of states
 | 
			
		||||
		if (sc.state == SCE_MATLAB_OPERATOR) {
 | 
			
		||||
			if (sc.chPrev == '.') {
 | 
			
		||||
				if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
 | 
			
		||||
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
					transpose = false;
 | 
			
		||||
				} else if (sc.ch == '\'') {
 | 
			
		||||
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
					transpose = true;
 | 
			
		||||
				} else if(sc.ch == '.' && sc.chNext == '.') {
 | 
			
		||||
					// we werent an operator, but a '...'
 | 
			
		||||
					sc.ChangeState(SCE_MATLAB_COMMENT);
 | 
			
		||||
					transpose = false;
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				sc.SetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MATLAB_KEYWORD) {
 | 
			
		||||
			if (!isalnum(sc.ch) && sc.ch != '_') {
 | 
			
		||||
				char s[100];
 | 
			
		||||
				sc.GetCurrent(s, sizeof(s));
 | 
			
		||||
				bool notKeyword = false;
 | 
			
		||||
				transpose = false;
 | 
			
		||||
 | 
			
		||||
				if (keywords.InList(s)) {
 | 
			
		||||
 | 
			
		||||
					expectingArgumentsBlock = (funcDeclarationLine || inArgumentsScope) ? expectingArgumentsBlock : 0;
 | 
			
		||||
 | 
			
		||||
					if (strcmp ("end", s) == 0 && allow_end_op) {
 | 
			
		||||
						sc.ChangeState(SCE_MATLAB_NUMBER);
 | 
			
		||||
						notKeyword = true;
 | 
			
		||||
					} else if (strcmp("end", s) == 0 && !allow_end_op) {
 | 
			
		||||
						inArgumentsScope = 0;
 | 
			
		||||
					} else if (strcmp("function", s) == 0) {
 | 
			
		||||
						// Need this flag to handle "arguments" block correctly
 | 
			
		||||
						funcDeclarationLine = true;
 | 
			
		||||
						expectingArgumentsBlock = ismatlab ? MATLAB_STATE_EXPECTING_ARG_BLOCK : 0;
 | 
			
		||||
					} else if (strcmp("classdef", s) == 0) {
 | 
			
		||||
						// Need this flag to process "events", "methods" and "properties" blocks
 | 
			
		||||
						inClassScope = MATLAB_STATE_IN_CLASS_SCOPE;
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					// "arguments" is a keyword here, despite not being in the keywords list
 | 
			
		||||
					if (expectingArgumentsBlock && !(funcDeclarationLine || inArgumentsScope) && (strcmp("arguments", s) == 0)) {
 | 
			
		||||
						// We've entered an "arguments" block
 | 
			
		||||
						inArgumentsScope = MATLAB_STATE_IN_ARGUMENTS_SCOPE;
 | 
			
		||||
					} else {
 | 
			
		||||
						// Found an identifier or a keyword after the function declaration
 | 
			
		||||
						// No need to wait for the arguments block anymore
 | 
			
		||||
						expectingArgumentsBlock = (funcDeclarationLine || inArgumentsScope) ? expectingArgumentsBlock : 0;
 | 
			
		||||
 | 
			
		||||
						// "properties", "methods" and "events" are not keywords if they're declared
 | 
			
		||||
						// inside some function in methods block
 | 
			
		||||
						// To avoid tracking possible nested functions scopes, lexer considers everything
 | 
			
		||||
						// beyond level 2 of folding to be in a scope of some function declared in the
 | 
			
		||||
						// methods block. It is ok for the valid syntax: classes can only be declared in
 | 
			
		||||
						// a separate file, function - only in methods block. However, in case of the invalid
 | 
			
		||||
						// syntax lexer may erroneously ignore a keyword.
 | 
			
		||||
						if (!((inClassScope) && (foldingLevel <= 2) && (
 | 
			
		||||
								strcmp("properties", s) == 0 ||
 | 
			
		||||
								strcmp("methods",    s) == 0 ||
 | 
			
		||||
								strcmp("events",     s) == 0 ))) {
 | 
			
		||||
							sc.ChangeState(SCE_MATLAB_IDENTIFIER);
 | 
			
		||||
							transpose = true;
 | 
			
		||||
							notKeyword = true;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				sc.SetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
				if (!notKeyword) {
 | 
			
		||||
					foldingLevel += CheckKeywordFoldPoint(s);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			styler.SetLineState(curLine, ComposeLineState(
 | 
			
		||||
				commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
 | 
			
		||||
		} else if (sc.state == SCE_MATLAB_NUMBER) {
 | 
			
		||||
			if (!isdigit(sc.ch) && sc.ch != '.'
 | 
			
		||||
			        && !(sc.ch == 'e' || sc.ch == 'E')
 | 
			
		||||
			        && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))
 | 
			
		||||
			        && !(((sc.ch == 'x' || sc.ch == 'X') && sc.chPrev == '0') || (sc.ch >= 'a' && sc.ch <= 'f') || (sc.ch >= 'A' && sc.ch <= 'F'))
 | 
			
		||||
			        && !(sc.ch == 's' || sc.ch == 'S' || sc.ch == 'u' || sc.ch == 'U')
 | 
			
		||||
			        && !(sc.ch == 'i' || sc.ch == 'I' || sc.ch == 'j' || sc.ch == 'J')
 | 
			
		||||
			        && !(sc.ch == '_')) {
 | 
			
		||||
				sc.SetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
				transpose = true;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MATLAB_STRING) {
 | 
			
		||||
			if (sc.ch == '\'') {
 | 
			
		||||
				if (sc.chNext == '\'') {
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.MatchLineEnd()) {
 | 
			
		||||
				sc.SetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
 | 
			
		||||
			if (sc.ch == '\\' && !ismatlab) {
 | 
			
		||||
				sc.Forward(); // skip escape sequence, new line and others after backlash
 | 
			
		||||
			} else if (sc.ch == '\"') {
 | 
			
		||||
				sc.ForwardSetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
			} else if (sc.MatchLineEnd()) {
 | 
			
		||||
				sc.SetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MATLAB_COMMAND) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
				transpose = false;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (sc.state == SCE_MATLAB_COMMENT) {
 | 
			
		||||
			// end or start of a nested a block comment?
 | 
			
		||||
			if( IsCommentChar(sc.ch) && sc.chNext == '}' && nonSpaceColumn == column && IsSpaceToEOL(sc.currentPos+2, styler)) {
 | 
			
		||||
				if(commentDepth > 0) commentDepth --;
 | 
			
		||||
 | 
			
		||||
				curLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
				styler.SetLineState(curLine, ComposeLineState(
 | 
			
		||||
					commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
 | 
			
		||||
				if (commentDepth == 0) {
 | 
			
		||||
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
					transpose = false;
 | 
			
		||||
				}
 | 
			
		||||
			} else if( IsCommentChar(sc.ch) && sc.chNext == '{' && nonSpaceColumn == column && IsSpaceToEOL(sc.currentPos+2, styler)) {
 | 
			
		||||
				commentDepth ++;
 | 
			
		||||
 | 
			
		||||
				curLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
				styler.SetLineState(curLine, ComposeLineState(
 | 
			
		||||
					commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				transpose = false;
 | 
			
		||||
 | 
			
		||||
			} else if(commentDepth == 0) {
 | 
			
		||||
				// single line comment
 | 
			
		||||
				if (sc.atLineEnd || sc.ch == '\r' || sc.ch == '\n') {
 | 
			
		||||
					sc.SetState(SCE_MATLAB_DEFAULT);
 | 
			
		||||
					transpose = false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// check start of a new state
 | 
			
		||||
		if (sc.state == SCE_MATLAB_DEFAULT) {
 | 
			
		||||
			if (IsCommentChar(sc.ch)) {
 | 
			
		||||
				// ncrement depth if we are a block comment
 | 
			
		||||
				if(sc.chNext == '{' && nonSpaceColumn == column) {
 | 
			
		||||
					if(IsSpaceToEOL(sc.currentPos+2, styler)) {
 | 
			
		||||
						commentDepth ++;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				curLine = styler.GetLine(sc.currentPos);
 | 
			
		||||
				styler.SetLineState(curLine, ComposeLineState(
 | 
			
		||||
					commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
 | 
			
		||||
				sc.SetState(SCE_MATLAB_COMMENT);
 | 
			
		||||
			} else if (sc.ch == '!' && sc.chNext != '=' ) {
 | 
			
		||||
				if(ismatlab) {
 | 
			
		||||
					sc.SetState(SCE_MATLAB_COMMAND);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_MATLAB_OPERATOR);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.ch == '\'') {
 | 
			
		||||
				if (transpose) {
 | 
			
		||||
					sc.SetState(SCE_MATLAB_OPERATOR);
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_MATLAB_STRING);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (sc.ch == '"') {
 | 
			
		||||
				sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);
 | 
			
		||||
			} else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
 | 
			
		||||
				sc.SetState(SCE_MATLAB_NUMBER);
 | 
			
		||||
			} else if (isalpha(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_MATLAB_KEYWORD);
 | 
			
		||||
			} else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
 | 
			
		||||
				if (sc.ch == '(' || sc.ch == '[' || sc.ch == '{') {
 | 
			
		||||
					allow_end_op ++;
 | 
			
		||||
				} else if ((sc.ch == ')' || sc.ch == ']' || sc.ch == '}') && (allow_end_op > 0)) {
 | 
			
		||||
					allow_end_op --;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (sc.ch == ')' || sc.ch == ']' || sc.ch == '}') {
 | 
			
		||||
					transpose = true;
 | 
			
		||||
				} else {
 | 
			
		||||
					transpose = false;
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState(SCE_MATLAB_OPERATOR);
 | 
			
		||||
			} else {
 | 
			
		||||
				transpose = false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseMatlabDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                               WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
	ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                               WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
	ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                                WordList *[], Accessor &styler,
 | 
			
		||||
                                bool (*IsComment)(int ch)) {
 | 
			
		||||
 | 
			
		||||
	if (styler.GetPropertyInt("fold") == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	const bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 | 
			
		||||
	const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
 | 
			
		||||
	Sci_PositionU endPos = startPos + length;
 | 
			
		||||
	int visibleChars = 0;
 | 
			
		||||
	Sci_Position lineCurrent = styler.GetLine(startPos);
 | 
			
		||||
	int levelCurrent = SC_FOLDLEVELBASE;
 | 
			
		||||
	if (lineCurrent > 0)
 | 
			
		||||
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 | 
			
		||||
	int levelNext = levelCurrent;
 | 
			
		||||
	char chNext = styler[startPos];
 | 
			
		||||
	int styleNext = styler.StyleAt(startPos);
 | 
			
		||||
	int style = initStyle;
 | 
			
		||||
	char word[100];
 | 
			
		||||
	int wordlen = 0;
 | 
			
		||||
	for (Sci_PositionU i = startPos; i < endPos; i++) {
 | 
			
		||||
		char ch = chNext;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		style = styleNext;
 | 
			
		||||
		styleNext = styler.StyleAt(i + 1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
 | 
			
		||||
		// a line that starts with a comment
 | 
			
		||||
		if (foldComment && style == SCE_MATLAB_COMMENT && IsComment(ch) && visibleChars == 0) {
 | 
			
		||||
			// start/end of block comment
 | 
			
		||||
			if (chNext == '{' && IsSpaceToEOL(i+2, styler))
 | 
			
		||||
				levelNext ++;
 | 
			
		||||
			if (chNext == '}' && IsSpaceToEOL(i+2, styler))
 | 
			
		||||
				levelNext --;
 | 
			
		||||
		}
 | 
			
		||||
		// keyword
 | 
			
		||||
		if(style == SCE_MATLAB_KEYWORD) {
 | 
			
		||||
			word[wordlen++] = static_cast<char>(LowerCase(ch));
 | 
			
		||||
			if (wordlen == 100) {  // prevent overflow
 | 
			
		||||
				word[0] = '\0';
 | 
			
		||||
				wordlen = 1;
 | 
			
		||||
			}
 | 
			
		||||
			if (styleNext !=  SCE_MATLAB_KEYWORD) {
 | 
			
		||||
				word[wordlen] = '\0';
 | 
			
		||||
				wordlen = 0;
 | 
			
		||||
 | 
			
		||||
				levelNext += CheckKeywordFoldPoint(word);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!IsASpace(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
		if (atEOL || (i == endPos-1)) {
 | 
			
		||||
			int levelUse = levelCurrent;
 | 
			
		||||
			int lev = levelUse | levelNext << 16;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if (levelUse < levelNext)
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelCurrent = levelNext;
 | 
			
		||||
			if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length() - 1))) {
 | 
			
		||||
				// There is an empty line at end of file so give it same level and empty
 | 
			
		||||
				styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
 | 
			
		||||
			}
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldMatlabDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                          WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
	FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | 
			
		||||
                          WordList *keywordlists[], Accessor &styler) {
 | 
			
		||||
	FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char * const matlabWordListDesc[] = {
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char * const octaveWordListDesc[] = {
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc);
 | 
			
		||||
							
								
								
									
										225
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMaxima.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMaxima.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,225 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
/** @file LexMaxima.cxx
 | 
			
		||||
 ** Lexer for Maxima (http://maxima.sourceforge.net).
 | 
			
		||||
 ** Written by Gunter Königsmann based on the lisp lexer by Alexey Yutkin and Neil Hodgson .
 | 
			
		||||
 **/
 | 
			
		||||
// Copyright 2018 by Gunter Königsmann <wxMaxima@physikbuch.de>
 | 
			
		||||
// 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 <ctype.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;
 | 
			
		||||
 | 
			
		||||
static inline bool isMaximaoperator(char ch) {
 | 
			
		||||
  return (ch == '\'' || ch == '`' || ch == '(' ||
 | 
			
		||||
	  ch == ')'  || ch == '[' || ch == ']' ||
 | 
			
		||||
	  ch == '{'  || ch == '}' || ch == '!' ||
 | 
			
		||||
	  ch == '*'  || ch == '/' || ch == '^' ||
 | 
			
		||||
	  ch == ','  || ch == ':' || ch == '+' ||
 | 
			
		||||
	  ch == '-');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseMaximaDoc(Sci_PositionU startPos, Sci_Position length, int lastStyle,
 | 
			
		||||
			       WordList *[],
 | 
			
		||||
			       Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
  styler.StartAt(startPos);
 | 
			
		||||
 | 
			
		||||
  Sci_PositionU lengthDoc = startPos + length;
 | 
			
		||||
  styler.StartSegment(startPos);
 | 
			
		||||
 | 
			
		||||
  Sci_PositionU i = startPos;
 | 
			
		||||
 | 
			
		||||
  // If we are in the middle of a comment we go back to its start before highlighting
 | 
			
		||||
  if(lastStyle == SCE_MAXIMA_COMMENT)
 | 
			
		||||
    {
 | 
			
		||||
      while((i>0) &&
 | 
			
		||||
	    !((styler.SafeGetCharAt(i+1) == '*') && (styler.SafeGetCharAt(i) == '/')))
 | 
			
		||||
	i--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  for (; i < lengthDoc; i++) {
 | 
			
		||||
    char ch = styler.SafeGetCharAt(i);
 | 
			
		||||
    char chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
    if (styler.IsLeadByte(ch))
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    // Handle comments.
 | 
			
		||||
    // Comments start with /* and end with */
 | 
			
		||||
    if((ch == '/') && (chNext == '*'))
 | 
			
		||||
      {
 | 
			
		||||
	i++;i++;
 | 
			
		||||
 | 
			
		||||
	chNext = styler.SafeGetCharAt(i);
 | 
			
		||||
	for (; i < lengthDoc; i++)
 | 
			
		||||
	  {
 | 
			
		||||
	    ch = chNext;
 | 
			
		||||
	    chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
	    if((ch == '*') && (chNext == '/'))
 | 
			
		||||
	      {
 | 
			
		||||
		i++;
 | 
			
		||||
		i++;
 | 
			
		||||
		break;
 | 
			
		||||
	      }
 | 
			
		||||
	  }
 | 
			
		||||
	if(i > lengthDoc)
 | 
			
		||||
	  i = lengthDoc;
 | 
			
		||||
	i--;
 | 
			
		||||
	styler.ColourTo(i, SCE_MAXIMA_COMMENT);
 | 
			
		||||
	continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    // Handle Operators
 | 
			
		||||
    if(isMaximaoperator(ch))
 | 
			
		||||
      {
 | 
			
		||||
	styler.ColourTo(i, SCE_MAXIMA_OPERATOR);
 | 
			
		||||
	continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    // Handle command endings.
 | 
			
		||||
    if((ch == '$') || (ch == ';'))
 | 
			
		||||
      {
 | 
			
		||||
	styler.ColourTo(i, SCE_MAXIMA_COMMANDENDING);
 | 
			
		||||
	continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    // Handle numbers. Numbers always begin with a digit.
 | 
			
		||||
    if(IsASCII(ch) && isdigit(ch))
 | 
			
		||||
      {
 | 
			
		||||
	i++;
 | 
			
		||||
	for (; i < lengthDoc; i++)
 | 
			
		||||
	  {
 | 
			
		||||
	    ch = chNext;
 | 
			
		||||
	    chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
 | 
			
		||||
	    if(ch == '.')
 | 
			
		||||
	      continue;
 | 
			
		||||
 | 
			
		||||
	    // A "e" or similar can be followed by a "+" or a "-"
 | 
			
		||||
	    if(((ch == 'e') || (ch == 'b') || (ch == 'g') || (ch == 'f')) &&
 | 
			
		||||
	       ((chNext == '+') || (chNext == '-')))
 | 
			
		||||
	      {
 | 
			
		||||
		i++;
 | 
			
		||||
		chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
		continue;
 | 
			
		||||
	      }
 | 
			
		||||
 | 
			
		||||
	    if(!IsASCII(ch) || !(isdigit(ch) || islower(ch) || isupper(ch)))
 | 
			
		||||
	      {
 | 
			
		||||
		i--;
 | 
			
		||||
		break;
 | 
			
		||||
	      }
 | 
			
		||||
	  }
 | 
			
		||||
	styler.ColourTo(i, SCE_MAXIMA_NUMBER);
 | 
			
		||||
	continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    // Handle strings
 | 
			
		||||
    if(ch == '\"')
 | 
			
		||||
      {
 | 
			
		||||
	i++;
 | 
			
		||||
	for (; i < lengthDoc; i++)
 | 
			
		||||
	  {
 | 
			
		||||
	    ch = chNext;
 | 
			
		||||
	    chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
	    if(ch == '\\')
 | 
			
		||||
	      i++;
 | 
			
		||||
	    else
 | 
			
		||||
	      {
 | 
			
		||||
		if(ch == '\"')
 | 
			
		||||
		  break;
 | 
			
		||||
	      }
 | 
			
		||||
	  }
 | 
			
		||||
	styler.ColourTo(i, SCE_MAXIMA_STRING);
 | 
			
		||||
	continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    // Handle keywords. Maxima treats Non-ASCII chars as ordinary letters.
 | 
			
		||||
    if(((!IsASCII(ch))) || isalpha(ch) || (ch == '_'))
 | 
			
		||||
      {
 | 
			
		||||
	char cmd[100];
 | 
			
		||||
	int cmdidx = 0;
 | 
			
		||||
	memset(cmd,0,100);
 | 
			
		||||
	cmd[cmdidx++] = ch;
 | 
			
		||||
	i++;
 | 
			
		||||
	for (; i < lengthDoc; i++)
 | 
			
		||||
	  {
 | 
			
		||||
	    ch = chNext;
 | 
			
		||||
	    chNext = styler.SafeGetCharAt(i + 1);
 | 
			
		||||
	    if(ch == '\\')
 | 
			
		||||
	      {
 | 
			
		||||
		if(cmdidx < 99)
 | 
			
		||||
		  cmd[cmdidx++] = ch;
 | 
			
		||||
		i++;
 | 
			
		||||
		if(cmdidx < 99)
 | 
			
		||||
		  cmd[cmdidx++] = ch;
 | 
			
		||||
		continue;
 | 
			
		||||
	      }
 | 
			
		||||
	    if(isMaximaoperator(ch) || ((IsASCII(ch) && !isalpha(ch) && !isdigit(ch) && (ch != '_'))))
 | 
			
		||||
	      {
 | 
			
		||||
		i--;
 | 
			
		||||
		break;
 | 
			
		||||
	      }
 | 
			
		||||
	    if(cmdidx < 99)
 | 
			
		||||
	      cmd[cmdidx++] = ch;
 | 
			
		||||
	  }
 | 
			
		||||
 | 
			
		||||
	// A few known keywords
 | 
			
		||||
	if(
 | 
			
		||||
	   (strncmp(cmd,"if",99) == 0) ||
 | 
			
		||||
	   (strncmp(cmd,"then",99) == 0) ||
 | 
			
		||||
	   (strncmp(cmd,"else",99) == 0) ||
 | 
			
		||||
	   (strncmp(cmd,"thru",99) == 0) ||
 | 
			
		||||
	   (strncmp(cmd,"for",99) == 0) ||
 | 
			
		||||
	   (strncmp(cmd,"while",99) == 0) ||
 | 
			
		||||
	   (strncmp(cmd,"do",99) == 0)
 | 
			
		||||
	   )
 | 
			
		||||
	  {
 | 
			
		||||
	    styler.ColourTo(i, SCE_MAXIMA_COMMAND);
 | 
			
		||||
	    continue;
 | 
			
		||||
	  }
 | 
			
		||||
 | 
			
		||||
	// All other keywords are functions if they are followed
 | 
			
		||||
	// by an opening parenthesis
 | 
			
		||||
	char nextNonwhitespace = ' ';
 | 
			
		||||
	for (Sci_PositionU o = i + 1; o < lengthDoc; o++)
 | 
			
		||||
	  {
 | 
			
		||||
	    nextNonwhitespace = styler.SafeGetCharAt(o);
 | 
			
		||||
	    if(!IsASCII(nextNonwhitespace) || !isspacechar(nextNonwhitespace))
 | 
			
		||||
	      break;
 | 
			
		||||
	  }
 | 
			
		||||
	if(nextNonwhitespace == '(')
 | 
			
		||||
	  {
 | 
			
		||||
	    styler.ColourTo(i, SCE_MAXIMA_COMMAND);
 | 
			
		||||
	  }
 | 
			
		||||
	else
 | 
			
		||||
	  {
 | 
			
		||||
	    styler.ColourTo(i, SCE_MAXIMA_VARIABLE);
 | 
			
		||||
	  }
 | 
			
		||||
	continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    styler.ColourTo(i-1, SCE_MAXIMA_UNKNOWN);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmMaxima(SCLEX_MAXIMA, ColouriseMaximaDoc, "maxima", 0, 0);
 | 
			
		||||
							
								
								
									
										404
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMetapost.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										404
									
								
								3rdparty/lexilla540/lexilla/lexers/LexMetapost.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,404 @@
 | 
			
		||||
// Scintilla source code edit control
 | 
			
		||||
 | 
			
		||||
// @file LexMetapost.cxx - general context conformant metapost coloring scheme
 | 
			
		||||
// Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com
 | 
			
		||||
// Version: September 28, 2003
 | 
			
		||||
// Modified by instanton: July 10, 2007
 | 
			
		||||
// Folding based on keywordlists[]
 | 
			
		||||
 | 
			
		||||
// Copyright: 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 | 
			
		||||
// The License.txt file describes the conditions under which this software may be distributed.
 | 
			
		||||
 | 
			
		||||
// This lexer is derived from the one written for the texwork environment (1999++) which in
 | 
			
		||||
// turn is inspired on texedit (1991++) which finds its roots in wdt (1986).
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.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;
 | 
			
		||||
 | 
			
		||||
// val SCE_METAPOST_DEFAULT = 0
 | 
			
		||||
// val SCE_METAPOST_SPECIAL = 1
 | 
			
		||||
// val SCE_METAPOST_GROUP = 2
 | 
			
		||||
// val SCE_METAPOST_SYMBOL = 3
 | 
			
		||||
// val SCE_METAPOST_COMMAND = 4
 | 
			
		||||
// val SCE_METAPOST_TEXT = 5
 | 
			
		||||
 | 
			
		||||
// Definitions in SciTEGlobal.properties:
 | 
			
		||||
//
 | 
			
		||||
// Metapost Highlighting
 | 
			
		||||
//
 | 
			
		||||
// # Default
 | 
			
		||||
// style.metapost.0=fore:#7F7F00
 | 
			
		||||
// # Special
 | 
			
		||||
// style.metapost.1=fore:#007F7F
 | 
			
		||||
// # Group
 | 
			
		||||
// style.metapost.2=fore:#880000
 | 
			
		||||
// # Symbol
 | 
			
		||||
// style.metapost.3=fore:#7F7F00
 | 
			
		||||
// # Command
 | 
			
		||||
// style.metapost.4=fore:#008800
 | 
			
		||||
// # Text
 | 
			
		||||
// style.metapost.5=fore:#000000
 | 
			
		||||
 | 
			
		||||
// lexer.tex.comment.process=0
 | 
			
		||||
 | 
			
		||||
// Auxiliary functions:
 | 
			
		||||
 | 
			
		||||
static inline bool endOfLine(Accessor &styler, Sci_PositionU i) {
 | 
			
		||||
	return
 | 
			
		||||
      (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')) ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool isMETAPOSTcomment(int ch) {
 | 
			
		||||
	return
 | 
			
		||||
      (ch == '%') ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool isMETAPOSTone(int ch) {
 | 
			
		||||
	return
 | 
			
		||||
      (ch == '[') || (ch == ']') || (ch == '(') || (ch == ')') ||
 | 
			
		||||
      (ch == ':') || (ch == '=') || (ch == '<') || (ch == '>') ||
 | 
			
		||||
      (ch == '{') || (ch == '}') || (ch == '\'') || (ch == '\"') ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool isMETAPOSTtwo(int ch) {
 | 
			
		||||
	return
 | 
			
		||||
      (ch == ';') || (ch == '$') || (ch == '@') || (ch == '#');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool isMETAPOSTthree(int ch) {
 | 
			
		||||
	return
 | 
			
		||||
      (ch == '.') || (ch == '-') || (ch == '+') || (ch == '/') ||
 | 
			
		||||
      (ch == '*') || (ch == ',') || (ch == '|') || (ch == '`') ||
 | 
			
		||||
      (ch == '!') || (ch == '?') || (ch == '^') || (ch == '&') ||
 | 
			
		||||
      (ch == '%') ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool isMETAPOSTidentifier(int ch) {
 | 
			
		||||
	return
 | 
			
		||||
      ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ||
 | 
			
		||||
      (ch == '_') ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool isMETAPOSTnumber(int ch) {
 | 
			
		||||
	return
 | 
			
		||||
      (ch >= '0') && (ch <= '9') ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool isMETAPOSTstring(int ch) {
 | 
			
		||||
	return
 | 
			
		||||
      (ch == '\"') ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool isMETAPOSTcolon(int ch) {
 | 
			
		||||
	return
 | 
			
		||||
		(ch == ':') ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool isMETAPOSTequal(int ch) {
 | 
			
		||||
	return
 | 
			
		||||
		(ch == '=') ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CheckMETAPOSTInterface(
 | 
			
		||||
    Sci_PositionU startPos,
 | 
			
		||||
    Sci_Position length,
 | 
			
		||||
    Accessor &styler,
 | 
			
		||||
	int defaultInterface) {
 | 
			
		||||
 | 
			
		||||
    char lineBuffer[1024] ;
 | 
			
		||||
	Sci_PositionU linePos = 0 ;
 | 
			
		||||
 | 
			
		||||
	// some day we can make something lexer.metapost.mapping=(none,0)(metapost,1)(mp,1)(metafun,2)...
 | 
			
		||||
 | 
			
		||||
    if (styler.SafeGetCharAt(0) == '%') {
 | 
			
		||||
        for (Sci_PositionU i = 0; i < startPos + length; i++) {
 | 
			
		||||
            lineBuffer[linePos++] = styler.SafeGetCharAt(i) ;
 | 
			
		||||
            if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
 | 
			
		||||
                lineBuffer[linePos] = '\0';
 | 
			
		||||
				if (strstr(lineBuffer, "interface=none")) {
 | 
			
		||||
                    return 0 ;
 | 
			
		||||
				} else if (strstr(lineBuffer, "interface=metapost") || strstr(lineBuffer, "interface=mp")) {
 | 
			
		||||
                    return 1 ;
 | 
			
		||||
				} else if (strstr(lineBuffer, "interface=metafun")) {
 | 
			
		||||
                    return 2 ;
 | 
			
		||||
				} else if (styler.SafeGetCharAt(1) == 'D' && strstr(lineBuffer, "%D \\module")) {
 | 
			
		||||
					// better would be to limit the search to just one line
 | 
			
		||||
					return 2 ;
 | 
			
		||||
                } else {
 | 
			
		||||
                    return defaultInterface ;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
		}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return defaultInterface ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseMETAPOSTDoc(
 | 
			
		||||
    Sci_PositionU startPos,
 | 
			
		||||
    Sci_Position length,
 | 
			
		||||
    int,
 | 
			
		||||
    WordList *keywordlists[],
 | 
			
		||||
    Accessor &styler) {
 | 
			
		||||
 | 
			
		||||
	styler.StartAt(startPos) ;
 | 
			
		||||
	styler.StartSegment(startPos) ;
 | 
			
		||||
 | 
			
		||||
	bool processComment   = styler.GetPropertyInt("lexer.metapost.comment.process",   0) == 1 ;
 | 
			
		||||
    int  defaultInterface = styler.GetPropertyInt("lexer.metapost.interface.default", 1) ;
 | 
			
		||||
 | 
			
		||||
	int currentInterface = CheckMETAPOSTInterface(startPos,length,styler,defaultInterface) ;
 | 
			
		||||
 | 
			
		||||
	// 0  no keyword highlighting
 | 
			
		||||
	// 1  metapost keyword hightlighting
 | 
			
		||||
	// 2+ metafun keyword hightlighting
 | 
			
		||||
 | 
			
		||||
	int extraInterface = 0 ;
 | 
			
		||||
 | 
			
		||||
	if (currentInterface != 0) {
 | 
			
		||||
		extraInterface = currentInterface ;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	WordList &keywords  = *keywordlists[0] ;
 | 
			
		||||
	WordList kwEmpty;
 | 
			
		||||
	WordList &keywords2 = (extraInterface > 0) ? *keywordlists[extraInterface - 1] : kwEmpty;
 | 
			
		||||
 | 
			
		||||
	StyleContext sc(startPos, length, SCE_METAPOST_TEXT, styler) ;
 | 
			
		||||
 | 
			
		||||
	char key[100] ;
 | 
			
		||||
 | 
			
		||||
    bool inTeX     = false ;
 | 
			
		||||
	bool inComment = false ;
 | 
			
		||||
	bool inString  = false ;
 | 
			
		||||
	bool inClause  = false ;
 | 
			
		||||
 | 
			
		||||
	bool going = sc.More() ; // needed because of a fuzzy end of file state
 | 
			
		||||
 | 
			
		||||
	for (; going; sc.Forward()) {
 | 
			
		||||
 | 
			
		||||
		if (! sc.More()) { going = false ; } // we need to go one behind the end of text
 | 
			
		||||
 | 
			
		||||
		if (inClause) {
 | 
			
		||||
			sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
			inClause = false ;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (inComment) {
 | 
			
		||||
			if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
				inTeX = false ;
 | 
			
		||||
				inComment = false ;
 | 
			
		||||
				inClause = false ;
 | 
			
		||||
				inString = false ; // not correct but we want to stimulate one-lines
 | 
			
		||||
			}
 | 
			
		||||
		} else if (inString) {
 | 
			
		||||
			if (isMETAPOSTstring(sc.ch)) {
 | 
			
		||||
				sc.SetState(SCE_METAPOST_SPECIAL) ;
 | 
			
		||||
				sc.ForwardSetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
				inString = false ;
 | 
			
		||||
			} else if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
				inTeX = false ;
 | 
			
		||||
				inComment = false ;
 | 
			
		||||
				inClause = false ;
 | 
			
		||||
				inString = false ; // not correct but we want to stimulate one-lines
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			if ((! isMETAPOSTidentifier(sc.ch)) && (sc.LengthCurrent() > 0)) {
 | 
			
		||||
				if (sc.state == SCE_METAPOST_COMMAND) {
 | 
			
		||||
					sc.GetCurrent(key, sizeof(key)) ;
 | 
			
		||||
					if ((strcmp(key,"btex") == 0) || (strcmp(key,"verbatimtex") == 0)) {
 | 
			
		||||
    					sc.ChangeState(SCE_METAPOST_GROUP) ;
 | 
			
		||||
						inTeX = true ;
 | 
			
		||||
					} else if (inTeX) {
 | 
			
		||||
						if (strcmp(key,"etex") == 0) {
 | 
			
		||||
	    					sc.ChangeState(SCE_METAPOST_GROUP) ;
 | 
			
		||||
							inTeX = false ;
 | 
			
		||||
						} else {
 | 
			
		||||
	    					sc.ChangeState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						if (keywords && keywords.InList(key)) {
 | 
			
		||||
    						sc.ChangeState(SCE_METAPOST_COMMAND) ;
 | 
			
		||||
						} else if (keywords2 && keywords2.InList(key)) {
 | 
			
		||||
							sc.ChangeState(SCE_METAPOST_EXTRA) ;
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.ChangeState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (isMETAPOSTcomment(sc.ch)) {
 | 
			
		||||
				if (! inTeX) {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_SYMBOL) ;
 | 
			
		||||
					sc.ForwardSetState(SCE_METAPOST_DEFAULT) ;
 | 
			
		||||
					inComment = ! processComment ;
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (isMETAPOSTstring(sc.ch)) {
 | 
			
		||||
				if (! inTeX) {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_SPECIAL) ;
 | 
			
		||||
					if (! isMETAPOSTstring(sc.chNext)) {
 | 
			
		||||
						sc.ForwardSetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
					}
 | 
			
		||||
					inString = true ;
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (isMETAPOSTcolon(sc.ch)) {
 | 
			
		||||
				if (! inTeX) {
 | 
			
		||||
					if (! isMETAPOSTequal(sc.chNext)) {
 | 
			
		||||
						sc.SetState(SCE_METAPOST_COMMAND) ;
 | 
			
		||||
						inClause = true ;
 | 
			
		||||
					} else {
 | 
			
		||||
						sc.SetState(SCE_METAPOST_SPECIAL) ;
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (isMETAPOSTone(sc.ch)) {
 | 
			
		||||
				if (! inTeX) {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_SPECIAL) ;
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (isMETAPOSTtwo(sc.ch)) {
 | 
			
		||||
				if (! inTeX) {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_GROUP) ;
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (isMETAPOSTthree(sc.ch)) {
 | 
			
		||||
				if (! inTeX) {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_SYMBOL) ;
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (isMETAPOSTidentifier(sc.ch)) {
 | 
			
		||||
				if (sc.state != SCE_METAPOST_COMMAND) {
 | 
			
		||||
					sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
					sc.ChangeState(SCE_METAPOST_COMMAND) ;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (isMETAPOSTnumber(sc.ch)) {
 | 
			
		||||
				// rather redundant since for the moment we don't handle numbers
 | 
			
		||||
				sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
			} else if (sc.atLineEnd) {
 | 
			
		||||
				sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
				inTeX = false ;
 | 
			
		||||
				inComment = false ;
 | 
			
		||||
				inClause = false ;
 | 
			
		||||
				inString = false ;
 | 
			
		||||
			} else {
 | 
			
		||||
				sc.SetState(SCE_METAPOST_TEXT) ;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Hooks info the system:
 | 
			
		||||
 | 
			
		||||
static const char * const metapostWordListDesc[] = {
 | 
			
		||||
	"MetaPost",
 | 
			
		||||
	"MetaFun",
 | 
			
		||||
	0
 | 
			
		||||
} ;
 | 
			
		||||
 | 
			
		||||
static int classifyFoldPointMetapost(const char* s,WordList *keywordlists[]) {
 | 
			
		||||
	WordList& keywordsStart=*keywordlists[3];
 | 
			
		||||
	WordList& keywordsStop1=*keywordlists[4];
 | 
			
		||||
 | 
			
		||||
	if (keywordsStart.InList(s)) {return 1;}
 | 
			
		||||
	else if (keywordsStop1.InList(s)) {return -1;}
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int ParseMetapostWord(Sci_PositionU pos, Accessor &styler, char *word)
 | 
			
		||||
{
 | 
			
		||||
  int length=0;
 | 
			
		||||
  char ch=styler.SafeGetCharAt(pos);
 | 
			
		||||
  *word=0;
 | 
			
		||||
 | 
			
		||||
  while(isMETAPOSTidentifier(ch) && isalpha(ch) && length<100){
 | 
			
		||||
          word[length]=ch;
 | 
			
		||||
          length++;
 | 
			
		||||
          ch=styler.SafeGetCharAt(pos+length);
 | 
			
		||||
  }
 | 
			
		||||
  word[length]=0;
 | 
			
		||||
  return length;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldMetapostDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordlists[], Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 | 
			
		||||
	Sci_PositionU endPos = startPos+length;
 | 
			
		||||
	int visibleChars=0;
 | 
			
		||||
	Sci_Position lineCurrent=styler.GetLine(startPos);
 | 
			
		||||
	int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	int levelCurrent=levelPrev;
 | 
			
		||||
	char chNext=styler[startPos];
 | 
			
		||||
 | 
			
		||||
	char buffer[100]="";
 | 
			
		||||
 | 
			
		||||
	for (Sci_PositionU i=startPos; i < endPos; i++) {
 | 
			
		||||
		char ch=chNext;
 | 
			
		||||
		chNext=styler.SafeGetCharAt(i+1);
 | 
			
		||||
		char chPrev=styler.SafeGetCharAt(i-1);
 | 
			
		||||
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 | 
			
		||||
 | 
			
		||||
		if(i==0 || chPrev == '\r' || chPrev=='\n'|| chPrev==' '|| chPrev=='(' || chPrev=='$')
 | 
			
		||||
		{
 | 
			
		||||
            ParseMetapostWord(i, styler, buffer);
 | 
			
		||||
			levelCurrent += classifyFoldPointMetapost(buffer,keywordlists);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (atEOL) {
 | 
			
		||||
			int lev = levelPrev;
 | 
			
		||||
			if (visibleChars == 0 && foldCompact)
 | 
			
		||||
				lev |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | 
			
		||||
				lev |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if (lev != styler.LevelAt(lineCurrent)) {
 | 
			
		||||
				styler.SetLevel(lineCurrent, lev);
 | 
			
		||||
			}
 | 
			
		||||
			lineCurrent++;
 | 
			
		||||
			levelPrev = levelCurrent;
 | 
			
		||||
			visibleChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!isspacechar(ch))
 | 
			
		||||
			visibleChars++;
 | 
			
		||||
	}
 | 
			
		||||
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | 
			
		||||
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | 
			
		||||
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmMETAPOST(SCLEX_METAPOST, ColouriseMETAPOSTDoc, "metapost", FoldMetapostDoc, metapostWordListDesc);
 | 
			
		||||
							
								
								
									
										746
									
								
								3rdparty/lexilla540/lexilla/lexers/LexModula.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										746
									
								
								3rdparty/lexilla540/lexilla/lexers/LexModula.cxx
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,746 @@
 | 
			
		||||
//	-*- coding: utf-8 -*-
 | 
			
		||||
//	Scintilla source code edit control
 | 
			
		||||
/**
 | 
			
		||||
 *	@file LexModula.cxx
 | 
			
		||||
 *	@author Dariusz "DKnoto" Knociński
 | 
			
		||||
 *	@date 2011/02/03
 | 
			
		||||
 *	@brief Lexer for Modula-2/3 documents.
 | 
			
		||||
 */
 | 
			
		||||
//	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 <ctype.h>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <string_view>
 | 
			
		||||
 | 
			
		||||
#include "ILexer.h"
 | 
			
		||||
#include "Scintilla.h"
 | 
			
		||||
#include "SciLexer.h"
 | 
			
		||||
 | 
			
		||||
#include "PropSetSimple.h"
 | 
			
		||||
#include "WordList.h"
 | 
			
		||||
#include "LexAccessor.h"
 | 
			
		||||
#include "Accessor.h"
 | 
			
		||||
#include "StyleContext.h"
 | 
			
		||||
#include "CharacterSet.h"
 | 
			
		||||
#include "LexerModule.h"
 | 
			
		||||
 | 
			
		||||
using namespace Lexilla;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_LEX_MODULA
 | 
			
		||||
#define DEBUG_STATE( p, c )\
 | 
			
		||||
		fprintf( stderr, "Unknown state: currentPos = %u, char = '%c'\n", static_cast<unsigned int>(p), c );
 | 
			
		||||
#else
 | 
			
		||||
#define DEBUG_STATE( p, c )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static inline bool IsDigitOfBase( unsigned ch, unsigned base ) {
 | 
			
		||||
	if( ch < '0' || ch > 'f' ) return false;
 | 
			
		||||
	if( base <= 10 ) {
 | 
			
		||||
		if( ch >= ( '0' + base ) ) return false;
 | 
			
		||||
	} else {
 | 
			
		||||
		if( ch > '9' ) {
 | 
			
		||||
			unsigned nb = base - 10;
 | 
			
		||||
			if( ( ch < 'A' ) || ( ch >= ( 'A' + nb ) ) ) {
 | 
			
		||||
				if( ( ch < 'a' ) || ( ch >= ( 'a' + nb ) ) ) {
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline unsigned IsOperator( StyleContext & sc, WordList & op ) {
 | 
			
		||||
	int i;
 | 
			
		||||
	char s[3];
 | 
			
		||||
 | 
			
		||||
	s[0] = sc.ch;
 | 
			
		||||
	s[1] = sc.chNext;
 | 
			
		||||
	s[2] = 0;
 | 
			
		||||
	for( i = 0; i < op.Length(); i++ ) {
 | 
			
		||||
		if( ( strlen( op.WordAt(i) ) == 2 ) &&
 | 
			
		||||
			( s[0] == op.WordAt(i)[0] && s[1] == op.WordAt(i)[1] ) ) {
 | 
			
		||||
			return 2;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	s[1] = 0;
 | 
			
		||||
	for( i = 0; i < op.Length(); i++ ) {
 | 
			
		||||
		if( ( strlen( op.WordAt(i) ) == 1 ) &&
 | 
			
		||||
			( s[0] == op.WordAt(i)[0] ) ) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool IsEOL( Accessor &styler, Sci_PositionU curPos ) {
 | 
			
		||||
	unsigned ch = styler.SafeGetCharAt( curPos );
 | 
			
		||||
	if( ( ch == '\r' && styler.SafeGetCharAt( curPos + 1 ) == '\n' ) ||
 | 
			
		||||
		( ch == '\n' && styler.SafeGetCharAt( curPos - 1 ) != '\r' ) ) {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool checkStatement(
 | 
			
		||||
	Accessor &styler,
 | 
			
		||||
	Sci_Position &curPos,
 | 
			
		||||
	const char *stt, bool spaceAfter = true ) {
 | 
			
		||||
	int len = static_cast<int>(strlen( stt ));
 | 
			
		||||
	int i;
 | 
			
		||||
	for( i = 0; i < len; i++ ) {
 | 
			
		||||
		if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if( spaceAfter ) {
 | 
			
		||||
		if( ! isspace( styler.SafeGetCharAt( curPos + i ) ) ) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	curPos += ( len - 1 );
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool checkEndSemicolon(
 | 
			
		||||
	Accessor &styler,
 | 
			
		||||
	Sci_Position &curPos, Sci_Position endPos )
 | 
			
		||||
{
 | 
			
		||||
	const char *stt = "END";
 | 
			
		||||
	int len = static_cast<int>(strlen( stt ));
 | 
			
		||||
	int i;
 | 
			
		||||
	for( i = 0; i < len; i++ ) {
 | 
			
		||||
		if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	while( isspace( styler.SafeGetCharAt( curPos + i ) ) ) {
 | 
			
		||||
		i++;
 | 
			
		||||
		if( ( curPos + i ) >= endPos ) return false;
 | 
			
		||||
	}
 | 
			
		||||
	if( styler.SafeGetCharAt( curPos + i ) != ';' ) {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	curPos += ( i - 1 );
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool checkKeyIdentOper(
 | 
			
		||||
 | 
			
		||||
	Accessor &styler,
 | 
			
		||||
	Sci_Position &curPos, Sci_Position endPos,
 | 
			
		||||
	const char *stt, const char etk ) {
 | 
			
		||||
	Sci_Position newPos = curPos;
 | 
			
		||||
	if( ! checkStatement( styler, newPos, stt ) )
 | 
			
		||||
		return false;
 | 
			
		||||
	newPos++;
 | 
			
		||||
	if( newPos >= endPos )
 | 
			
		||||
		return false;
 | 
			
		||||
	if( ! isspace( styler.SafeGetCharAt( newPos ) ) )
 | 
			
		||||
		return false;
 | 
			
		||||
	newPos++;
 | 
			
		||||
	if( newPos >= endPos )
 | 
			
		||||
		return false;
 | 
			
		||||
	while( isspace( styler.SafeGetCharAt( newPos ) ) ) {
 | 
			
		||||
		newPos++;
 | 
			
		||||
		if( newPos >= endPos )
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	if( ! isalpha( styler.SafeGetCharAt( newPos ) ) )
 | 
			
		||||
		return false;
 | 
			
		||||
	newPos++;
 | 
			
		||||
	if( newPos >= endPos )
 | 
			
		||||
		return false;
 | 
			
		||||
	char ch;
 | 
			
		||||
	ch = styler.SafeGetCharAt( newPos );
 | 
			
		||||
	while( isalpha( ch ) || isdigit( ch ) || ch == '_' ) {
 | 
			
		||||
		newPos++;
 | 
			
		||||
		if( newPos >= endPos ) return false;
 | 
			
		||||
		ch = styler.SafeGetCharAt( newPos );
 | 
			
		||||
	}
 | 
			
		||||
	while( isspace( styler.SafeGetCharAt( newPos ) ) ) {
 | 
			
		||||
		newPos++;
 | 
			
		||||
		if( newPos >= endPos ) return false;
 | 
			
		||||
	}
 | 
			
		||||
	if( styler.SafeGetCharAt( newPos ) != etk )
 | 
			
		||||
		return false;
 | 
			
		||||
	curPos = newPos;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void FoldModulaDoc( Sci_PositionU startPos,
 | 
			
		||||
						 Sci_Position length,
 | 
			
		||||
						 int , WordList *[],
 | 
			
		||||
						 Accessor &styler)
 | 
			
		||||
{
 | 
			
		||||
	Sci_Position curLine = styler.GetLine(startPos);
 | 
			
		||||
	int curLevel = SC_FOLDLEVELBASE;
 | 
			
		||||
	Sci_Position endPos = startPos + length;
 | 
			
		||||
	if( curLine > 0 )
 | 
			
		||||
		curLevel = styler.LevelAt( curLine - 1 ) >> 16;
 | 
			
		||||
	Sci_Position curPos = startPos;
 | 
			
		||||
	int style = styler.StyleAt( curPos );
 | 
			
		||||
	int visChars = 0;
 | 
			
		||||
	int nextLevel = curLevel;
 | 
			
		||||
 | 
			
		||||
	while( curPos < endPos ) {
 | 
			
		||||
		if( ! isspace( styler.SafeGetCharAt( curPos ) ) ) visChars++;
 | 
			
		||||
 | 
			
		||||
		switch( style ) {
 | 
			
		||||
		case SCE_MODULA_COMMENT:
 | 
			
		||||
			if( checkStatement( styler, curPos, "(*" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "*)" ) )
 | 
			
		||||
				nextLevel--;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_MODULA_DOXYCOMM:
 | 
			
		||||
			if( checkStatement( styler, curPos, "(**", false ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "*)" ) )
 | 
			
		||||
				nextLevel--;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_MODULA_KEYWORD:
 | 
			
		||||
			if( checkStatement( styler, curPos, "IF" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "BEGIN" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "TRY" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "LOOP" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "FOR" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "WHILE" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "REPEAT" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "UNTIL" ) )
 | 
			
		||||
				nextLevel--;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "WITH" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "CASE" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "TYPECASE" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkStatement( styler, curPos, "LOCK" ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkKeyIdentOper( styler, curPos, endPos, "PROCEDURE", '(' ) )
 | 
			
		||||
				nextLevel++;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkKeyIdentOper( styler, curPos, endPos, "END", ';' ) ) {
 | 
			
		||||
				Sci_Position cln = curLine;
 | 
			
		||||
				int clv_old = curLevel;
 | 
			
		||||
				Sci_Position pos;
 | 
			
		||||
				char ch;
 | 
			
		||||
				int clv_new;
 | 
			
		||||
				while( cln > 0 ) {
 | 
			
		||||
					clv_new = styler.LevelAt( cln - 1 ) >> 16;
 | 
			
		||||
					if( clv_new < clv_old ) {
 | 
			
		||||
						nextLevel--;
 | 
			
		||||
						pos = styler.LineStart( cln );
 | 
			
		||||
						while( ( ch = styler.SafeGetCharAt( pos, '\n' )) != '\n') {
 | 
			
		||||
							if( ch == 'P' ) {
 | 
			
		||||
								if( styler.StyleAt(pos) == SCE_MODULA_KEYWORD )	{
 | 
			
		||||
									if( checkKeyIdentOper( styler, pos, endPos,
 | 
			
		||||
														"PROCEDURE", '(' ) ) {
 | 
			
		||||
										break;
 | 
			
		||||
									}
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
							pos++;
 | 
			
		||||
						}
 | 
			
		||||
						clv_old = clv_new;
 | 
			
		||||
					}
 | 
			
		||||
					cln--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			if( checkKeyIdentOper( styler, curPos, endPos, "END", '.' ) )
 | 
			
		||||
				nextLevel--;
 | 
			
		||||
			else
 | 
			
		||||
			if( checkEndSemicolon( styler, curPos, endPos ) )
 | 
			
		||||
				nextLevel--;
 | 
			
		||||
			else {
 | 
			
		||||
				while( styler.StyleAt( curPos + 1 ) == SCE_MODULA_KEYWORD )
 | 
			
		||||
					curPos++;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if( IsEOL( styler, curPos ) || ( curPos == endPos - 1 ) ) {
 | 
			
		||||
			int efectiveLevel = curLevel | nextLevel << 16;
 | 
			
		||||
			if( visChars == 0 )
 | 
			
		||||
				efectiveLevel |= SC_FOLDLEVELWHITEFLAG;
 | 
			
		||||
			if( curLevel < nextLevel )
 | 
			
		||||
				efectiveLevel |= SC_FOLDLEVELHEADERFLAG;
 | 
			
		||||
			if( efectiveLevel != styler.LevelAt(curLine) ) {
 | 
			
		||||
				styler.SetLevel(curLine, efectiveLevel );
 | 
			
		||||
			}
 | 
			
		||||
			curLine++;
 | 
			
		||||
			curLevel = nextLevel;
 | 
			
		||||
			if( IsEOL( styler, curPos ) && ( curPos == endPos - 1 ) ) {
 | 
			
		||||
				styler.SetLevel( curLine, ( curLevel | curLevel << 16)
 | 
			
		||||
								| SC_FOLDLEVELWHITEFLAG);
 | 
			
		||||
			}
 | 
			
		||||
			visChars = 0;
 | 
			
		||||
		}
 | 
			
		||||
		curPos++;
 | 
			
		||||
		style = styler.StyleAt( curPos );
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool skipWhiteSpaces( StyleContext & sc ) {
 | 
			
		||||
	while( isspace( sc.ch ) ) {
 | 
			
		||||
		sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
		if( sc.More() )
 | 
			
		||||
			sc.Forward();
 | 
			
		||||
		else
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ColouriseModulaDoc(	Sci_PositionU startPos,
 | 
			
		||||
									Sci_Position length,
 | 
			
		||||
									int initStyle,
 | 
			
		||||
									WordList *wl[],
 | 
			
		||||
									Accessor &styler ) {
 | 
			
		||||
	WordList& keyWords		= *wl[0];
 | 
			
		||||
	WordList& reservedWords	= *wl[1];
 | 
			
		||||
	WordList& operators 	= *wl[2];
 | 
			
		||||
	WordList& pragmaWords 	= *wl[3];
 | 
			
		||||
	WordList& escapeCodes	= *wl[4];
 | 
			
		||||
	WordList& doxyKeys		= *wl[5];
 | 
			
		||||
 | 
			
		||||
	const int BUFLEN = 128;
 | 
			
		||||
 | 
			
		||||
	char	buf[BUFLEN];
 | 
			
		||||
	int		i, kl;
 | 
			
		||||
 | 
			
		||||
	Sci_Position  charPos = 0;
 | 
			
		||||
 | 
			
		||||
	StyleContext sc( startPos, length, initStyle, styler );
 | 
			
		||||
 | 
			
		||||
	while( sc.More() ) 	{
 | 
			
		||||
		switch( sc.state )	{
 | 
			
		||||
		case SCE_MODULA_DEFAULT:
 | 
			
		||||
			if( ! skipWhiteSpaces( sc ) ) break;
 | 
			
		||||
 | 
			
		||||
			if( sc.ch == '(' && sc.chNext == '*' ) {
 | 
			
		||||
				if( sc.GetRelative(2) == '*' ) {
 | 
			
		||||
					sc.SetState( SCE_MODULA_DOXYCOMM );
 | 
			
		||||
					sc.Forward();
 | 
			
		||||
				} else {
 | 
			
		||||
					sc.SetState( SCE_MODULA_COMMENT );
 | 
			
		||||
				}
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			if( isalpha( sc.ch ) ) {
 | 
			
		||||
				if( isupper( sc.ch ) && isupper( sc.chNext ) ) {
 | 
			
		||||
					for( i = 0; i < BUFLEN - 1; i++ ) {
 | 
			
		||||
						buf[i] = sc.GetRelative(i);
 | 
			
		||||
						if( !isalpha( buf[i] ) && !(buf[i] == '_') )
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
					kl = i;
 | 
			
		||||
					buf[kl] = 0;
 | 
			
		||||
 | 
			
		||||
					if( keyWords.InList( buf ) ) {
 | 
			
		||||
						sc.SetState( SCE_MODULA_KEYWORD );
 | 
			
		||||
						sc.Forward( kl );
 | 
			
		||||
						sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					if( reservedWords.InList( buf ) ) {
 | 
			
		||||
						sc.SetState( SCE_MODULA_RESERVED );
 | 
			
		||||
						sc.Forward( kl );
 | 
			
		||||
						sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
						continue;
 | 
			
		||||
					} else {
 | 
			
		||||
						/** check procedure identifier */
 | 
			
		||||
						sc.Forward( kl );
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					for( i = 0; i < BUFLEN - 1; i++ ) {
 | 
			
		||||
						buf[i] = sc.GetRelative(i);
 | 
			
		||||
						if( !isalpha( buf[i] ) &&
 | 
			
		||||
							!isdigit( buf[i] ) &&
 | 
			
		||||
							!(buf[i] == '_') )
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
					kl = i;
 | 
			
		||||
					buf[kl] = 0;
 | 
			
		||||
 | 
			
		||||
					sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
					sc.Forward( kl );
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			if( isdigit( sc.ch ) ) {
 | 
			
		||||
				sc.SetState( SCE_MODULA_NUMBER );
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			if( sc.ch == '\"' ) {
 | 
			
		||||
				sc.SetState( SCE_MODULA_STRING );
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			if( sc.ch == '\'' ) {
 | 
			
		||||
				charPos = sc.currentPos;
 | 
			
		||||
				sc.SetState( SCE_MODULA_CHAR );
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			if( sc.ch == '<' && sc.chNext == '*' ) {
 | 
			
		||||
				sc.SetState( SCE_MODULA_PRAGMA );
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
			} else {
 | 
			
		||||
				unsigned len = IsOperator( sc, operators );
 | 
			
		||||
				if( len > 0 ) {
 | 
			
		||||
					sc.SetState( SCE_MODULA_OPERATOR );
 | 
			
		||||
					sc.Forward( len );
 | 
			
		||||
					sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
					continue;
 | 
			
		||||
				} else {
 | 
			
		||||
					DEBUG_STATE( sc.currentPos, sc.ch );
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_MODULA_COMMENT:
 | 
			
		||||
			if( sc.ch == '*' && sc.chNext == ')' ) {
 | 
			
		||||
				sc.Forward( 2 );
 | 
			
		||||
				sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_MODULA_DOXYCOMM:
 | 
			
		||||
			switch( sc.ch ) {
 | 
			
		||||
			case '*':
 | 
			
		||||
				if( sc.chNext == ')' ) {
 | 
			
		||||
					sc.Forward( 2 );
 | 
			
		||||
					sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case '@':
 | 
			
		||||
				if( islower( sc.chNext ) ) {
 | 
			
		||||
					for( i = 0; i < BUFLEN - 1; i++ ) {
 | 
			
		||||
						buf[i] = sc.GetRelative(i+1);
 | 
			
		||||
						if( isspace( buf[i] ) ) break;
 | 
			
		||||
					}
 | 
			
		||||
					buf[i] = 0;
 | 
			
		||||
					kl = i;
 | 
			
		||||
 | 
			
		||||
					if( doxyKeys.InList( buf ) ) {
 | 
			
		||||
						sc.SetState( SCE_MODULA_DOXYKEY );
 | 
			
		||||
						sc.Forward( kl + 1 );
 | 
			
		||||
						sc.SetState( SCE_MODULA_DOXYCOMM );
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_MODULA_NUMBER:
 | 
			
		||||
			{
 | 
			
		||||
				buf[0] = sc.ch;
 | 
			
		||||
				for( i = 1; i < BUFLEN - 1; i++ ) {
 | 
			
		||||
					buf[i] = sc.GetRelative(i);
 | 
			
		||||
					if( ! isdigit( buf[i] ) )
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
				kl = i;
 | 
			
		||||
				buf[kl] = 0;
 | 
			
		||||
 | 
			
		||||
				switch( sc.GetRelative(kl) ) {
 | 
			
		||||
				case '_':
 | 
			
		||||
					{
 | 
			
		||||
						int base = atoi( buf );
 | 
			
		||||
						if( base < 2 || base > 16 ) {
 | 
			
		||||
							sc.SetState( SCE_MODULA_BADSTR );
 | 
			
		||||
						} else {
 | 
			
		||||
							int imax;
 | 
			
		||||
 | 
			
		||||
							kl++;
 | 
			
		||||
							for( i = 0; i < BUFLEN - 1; i++ ) {
 | 
			
		||||
								buf[i] = sc.GetRelative(kl+i);
 | 
			
		||||
								if( ! IsDigitOfBase( buf[i], 16 ) ) {
 | 
			
		||||
									break;
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
							imax = i;
 | 
			
		||||
							for( i = 0; i < imax; i++ ) {
 | 
			
		||||
								if( ! IsDigitOfBase( buf[i], base ) ) {
 | 
			
		||||
									sc.SetState( SCE_MODULA_BADSTR );
 | 
			
		||||
									break;
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
							kl += imax;
 | 
			
		||||
						}
 | 
			
		||||
						sc.SetState( SCE_MODULA_BASENUM );
 | 
			
		||||
						for( i = 0; i < kl; i++ ) {
 | 
			
		||||
							sc.Forward();
 | 
			
		||||
						}
 | 
			
		||||
						sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case '.':
 | 
			
		||||
					if( sc.GetRelative(kl+1) == '.' ) {
 | 
			
		||||
						kl--;
 | 
			
		||||
						for( i = 0; i < kl; i++ ) {
 | 
			
		||||
							sc.Forward();
 | 
			
		||||
						}
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
						sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
						continue;
 | 
			
		||||
					} else {
 | 
			
		||||
						bool doNext = false;
 | 
			
		||||
 | 
			
		||||
						kl++;
 | 
			
		||||
 | 
			
		||||
						buf[0] = sc.GetRelative(kl);
 | 
			
		||||
						if( isdigit( buf[0] ) ) {
 | 
			
		||||
							for( i = 0;; i++ ) {
 | 
			
		||||
								if( !isdigit(sc.GetRelative(kl+i)) )
 | 
			
		||||
									break;
 | 
			
		||||
							}
 | 
			
		||||
							kl += i;
 | 
			
		||||
							buf[0] = sc.GetRelative(kl);
 | 
			
		||||
 | 
			
		||||
							switch( buf[0] )
 | 
			
		||||
							{
 | 
			
		||||
							case 'E':
 | 
			
		||||
							case 'e':
 | 
			
		||||
							case 'D':
 | 
			
		||||
							case 'd':
 | 
			
		||||
							case 'X':
 | 
			
		||||
							case 'x':
 | 
			
		||||
								kl++;
 | 
			
		||||
								buf[0] = sc.GetRelative(kl);
 | 
			
		||||
								if( buf[0] == '-' || buf[0] == '+' ) {
 | 
			
		||||
									kl++;
 | 
			
		||||
								}
 | 
			
		||||
								buf[0] = sc.GetRelative(kl);
 | 
			
		||||
								if( isdigit( buf[0] ) ) {
 | 
			
		||||
									for( i = 0;; i++ ) {
 | 
			
		||||
										if( !isdigit(sc.GetRelative(kl+i)) ) {
 | 
			
		||||
											buf[0] = sc.GetRelative(kl+i);
 | 
			
		||||
											break;
 | 
			
		||||
										}
 | 
			
		||||
									}
 | 
			
		||||
									kl += i;
 | 
			
		||||
									doNext = true;
 | 
			
		||||
								} else {
 | 
			
		||||
									sc.SetState( SCE_MODULA_BADSTR );
 | 
			
		||||
								}
 | 
			
		||||
								break;
 | 
			
		||||
 | 
			
		||||
							default:
 | 
			
		||||
								doNext = true;
 | 
			
		||||
								break;
 | 
			
		||||
							}
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.SetState( SCE_MODULA_BADSTR );
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						if( doNext ) {
 | 
			
		||||
							if( ! isspace( buf[0] ) &&
 | 
			
		||||
								buf[0] != ')' &&
 | 
			
		||||
								buf[0] != '>' &&
 | 
			
		||||
								buf[0] != '<' &&
 | 
			
		||||
								buf[0] != '=' &&
 | 
			
		||||
								buf[0] != '#' &&
 | 
			
		||||
								buf[0] != '+' &&
 | 
			
		||||
								buf[0] != '-' &&
 | 
			
		||||
								buf[0] != '*' &&
 | 
			
		||||
								buf[0] != '/' &&
 | 
			
		||||
								buf[0] != ',' &&
 | 
			
		||||
								buf[0] != ';'
 | 
			
		||||
								) {
 | 
			
		||||
								sc.SetState( SCE_MODULA_BADSTR );
 | 
			
		||||
							} else {
 | 
			
		||||
								kl--;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					sc.SetState( SCE_MODULA_FLOAT );
 | 
			
		||||
					for( i = 0; i < kl; i++ ) {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
					sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
					continue;
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				default:
 | 
			
		||||
					for( i = 0; i < kl; i++ ) {
 | 
			
		||||
						sc.Forward();
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_MODULA_STRING:
 | 
			
		||||
			if( sc.ch == '\"' ) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
				continue;
 | 
			
		||||
			} else {
 | 
			
		||||
				if( sc.ch == '\\' ) {
 | 
			
		||||
					i = 1;
 | 
			
		||||
					if( IsDigitOfBase( sc.chNext, 8 ) ) {
 | 
			
		||||
						for( i = 1; i < BUFLEN - 1; i++ ) {
 | 
			
		||||
							if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )
 | 
			
		||||
								break;
 | 
			
		||||
						}
 | 
			
		||||
						if( i == 3 ) {
 | 
			
		||||
							sc.SetState( SCE_MODULA_STRSPEC );
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.SetState( SCE_MODULA_BADSTR );
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						buf[0] = sc.chNext;
 | 
			
		||||
						buf[1] = 0;
 | 
			
		||||
 | 
			
		||||
						if( escapeCodes.InList( buf ) ) {
 | 
			
		||||
							sc.SetState( SCE_MODULA_STRSPEC );
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.SetState( SCE_MODULA_BADSTR );
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					sc.Forward(i+1);
 | 
			
		||||
					sc.SetState( SCE_MODULA_STRING );
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_MODULA_CHAR:
 | 
			
		||||
			if( sc.ch == '\'' ) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			if( ( sc.currentPos - charPos ) == 1 ) {
 | 
			
		||||
				if( sc.ch == '\\' ) {
 | 
			
		||||
					i = 1;
 | 
			
		||||
					if( IsDigitOfBase( sc.chNext, 8 ) ) {
 | 
			
		||||
						for( i = 1; i < BUFLEN - 1; i++ ) {
 | 
			
		||||
							if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )
 | 
			
		||||
								break;
 | 
			
		||||
						}
 | 
			
		||||
						if( i == 3 ) {
 | 
			
		||||
							sc.SetState( SCE_MODULA_CHARSPEC );
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.SetState( SCE_MODULA_BADSTR );
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						buf[0] = sc.chNext;
 | 
			
		||||
						buf[1] = 0;
 | 
			
		||||
 | 
			
		||||
						if( escapeCodes.InList( buf ) ) {
 | 
			
		||||
							sc.SetState( SCE_MODULA_CHARSPEC );
 | 
			
		||||
						} else {
 | 
			
		||||
							sc.SetState( SCE_MODULA_BADSTR );
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					sc.Forward(i+1);
 | 
			
		||||
					sc.SetState( SCE_MODULA_CHAR );
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				sc.SetState( SCE_MODULA_BADSTR );
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.SetState( SCE_MODULA_CHAR );
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCE_MODULA_PRAGMA:
 | 
			
		||||
			if( sc.ch == '*' && sc.chNext == '>' ) {
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.Forward();
 | 
			
		||||
				sc.SetState( SCE_MODULA_DEFAULT );
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			if( isupper( sc.ch ) && isupper( sc.chNext ) ) {
 | 
			
		||||
				buf[0] = sc.ch;
 | 
			
		||||
				buf[1] = sc.chNext;
 | 
			
		||||
				for( i = 2; i < BUFLEN - 1; i++ ) {
 | 
			
		||||
					buf[i] = sc.GetRelative(i);
 | 
			
		||||
					if( !isupper( buf[i] ) )
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
				kl = i;
 | 
			
		||||
				buf[kl] = 0;
 | 
			
		||||
				if( pragmaWords.InList( buf ) ) {
 | 
			
		||||
					sc.SetState( SCE_MODULA_PRGKEY );
 | 
			
		||||
					sc.Forward( kl );
 | 
			
		||||
					sc.SetState( SCE_MODULA_PRAGMA );
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		sc.Forward();
 | 
			
		||||
	}
 | 
			
		||||
	sc.Complete();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *const modulaWordListDesc[] =
 | 
			
		||||
{
 | 
			
		||||
	"Keywords",
 | 
			
		||||
	"ReservedKeywords",
 | 
			
		||||
	"Operators",
 | 
			
		||||
	"PragmaKeyswords",
 | 
			
		||||
	"EscapeCodes",
 | 
			
		||||
	"DoxygeneKeywords",
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const LexerModule lmModula( SCLEX_MODULA, ColouriseModulaDoc, "modula", FoldModulaDoc,
 | 
			
		||||
					  modulaWordListDesc);
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user